mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 18:31:55 -04:00
fixes to smoothing
This commit is contained in:
parent
5f55dc8e08
commit
1ca01f215c
@ -666,6 +666,33 @@ get_reset_velocity_age() {
|
|||||||
return _reset_velocity_age;
|
return _reset_velocity_age;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SmoothMover::set_directional_velocity
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Sets the flag that indicates whether the avatar's
|
||||||
|
// direction is considered in computing the velocity.
|
||||||
|
// When this is true, velocity is automatically
|
||||||
|
// decomposed into a forward and a lateral velocity (and
|
||||||
|
// both may be positive or negative); when it is false,
|
||||||
|
// all velocity is always returned as forward velocity
|
||||||
|
// (and it is always positive).
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void SmoothMover::
|
||||||
|
set_directional_velocity(bool flag) {
|
||||||
|
_directional_velocity = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: SmoothMover::get_directional_velocity
|
||||||
|
// Access: Published, Static
|
||||||
|
// Description: Returns the current state of the 'directional
|
||||||
|
// velocity' flag. See set_directional_velocity().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool SmoothMover::
|
||||||
|
get_directional_velocity() {
|
||||||
|
return _directional_velocity;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: SmoothMover::get_avg_timestamp_delay
|
// Function: SmoothMover::get_avg_timestamp_delay
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -60,6 +60,7 @@ SmoothMover() {
|
|||||||
_prediction_mode = PM_off;
|
_prediction_mode = PM_off;
|
||||||
_delay = 0.2;
|
_delay = 0.2;
|
||||||
_accept_clock_skew = true;
|
_accept_clock_skew = true;
|
||||||
|
_directional_velocity = true;
|
||||||
_max_position_age = 0.25;
|
_max_position_age = 0.25;
|
||||||
_expected_broadcast_period = 0.2;
|
_expected_broadcast_period = 0.2;
|
||||||
_reset_velocity_age = 0.3;
|
_reset_velocity_age = 0.3;
|
||||||
@ -220,6 +221,10 @@ compute_smooth_position(double timestamp) {
|
|||||||
if (_smooth_position_known) {
|
if (_smooth_position_known) {
|
||||||
double age = timestamp - _smooth_timestamp;
|
double age = timestamp - _smooth_timestamp;
|
||||||
if (age > _reset_velocity_age) {
|
if (age > _reset_velocity_age) {
|
||||||
|
if (deadrec_cat.is_debug()) {
|
||||||
|
deadrec_cat.debug()
|
||||||
|
<< "points empty; reset velocity, age = " << age << "\n";
|
||||||
|
}
|
||||||
_smooth_forward_velocity = 0.0;
|
_smooth_forward_velocity = 0.0;
|
||||||
_smooth_lateral_velocity = 0.0;
|
_smooth_lateral_velocity = 0.0;
|
||||||
_smooth_rotational_velocity = 0.0;
|
_smooth_rotational_velocity = 0.0;
|
||||||
@ -258,7 +263,9 @@ compute_smooth_position(double timestamp) {
|
|||||||
|
|
||||||
if (deadrec_cat.is_spam()) {
|
if (deadrec_cat.is_spam()) {
|
||||||
deadrec_cat.spam()
|
deadrec_cat.spam()
|
||||||
<< "time = " << timestamp << ", " << _points.size() << " points, last = " << _last_point_before << ", " << _last_point_after << "\n";
|
<< "time = " << timestamp << ", " << _points.size()
|
||||||
|
<< " points, last = " << _last_point_before << ", "
|
||||||
|
<< _last_point_after << "\n";
|
||||||
deadrec_cat.spam(false)
|
deadrec_cat.spam(false)
|
||||||
<< " ";
|
<< " ";
|
||||||
for (int pi = 0; pi < (int)_points.size(); pi++) {
|
for (int pi = 0; pi < (int)_points.size(); pi++) {
|
||||||
@ -367,11 +374,12 @@ compute_smooth_position(double timestamp) {
|
|||||||
set_smooth_pos(point._pos, point._hpr, timestamp);
|
set_smooth_pos(point._pos, point._hpr, timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orig_timestamp - _last_heard_from > _reset_velocity_age) {
|
double age = timestamp - timestamp_before;
|
||||||
// Furthermore, if we haven't heard from this client in a while,
|
if (age > _reset_velocity_age) {
|
||||||
// reset the velocity. This decision is based entirely on our
|
if (deadrec_cat.is_spam()) {
|
||||||
// local timestamps, not on the other client's reported
|
deadrec_cat.spam()
|
||||||
// timestamps.
|
<< " reset_velocity, age = " << age << "\n";
|
||||||
|
}
|
||||||
_smooth_forward_velocity = 0.0;
|
_smooth_forward_velocity = 0.0;
|
||||||
_smooth_lateral_velocity = 0.0;
|
_smooth_lateral_velocity = 0.0;
|
||||||
_smooth_rotational_velocity = 0.0;
|
_smooth_rotational_velocity = 0.0;
|
||||||
@ -390,8 +398,17 @@ compute_smooth_position(double timestamp) {
|
|||||||
|
|
||||||
if (point_b._pos == point_a._pos && point_b._hpr == point_a._hpr) {
|
if (point_b._pos == point_a._pos && point_b._hpr == point_a._hpr) {
|
||||||
// The points are equivalent, so just return that.
|
// The points are equivalent, so just return that.
|
||||||
|
if (deadrec_cat.is_spam()) {
|
||||||
|
deadrec_cat.spam()
|
||||||
|
<< "Points are equivalent\n";
|
||||||
|
}
|
||||||
set_smooth_pos(point_b._pos, point_b._hpr, timestamp);
|
set_smooth_pos(point_b._pos, point_b._hpr, timestamp);
|
||||||
|
|
||||||
|
// This implies that velocity is 0.
|
||||||
|
_smooth_forward_velocity = 0.0;
|
||||||
|
_smooth_lateral_velocity = 0.0;
|
||||||
|
_smooth_rotational_velocity = 0.0;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// The points are different, so we have to do some work.
|
// The points are different, so we have to do some work.
|
||||||
double age = (point_a._timestamp - point_b._timestamp);
|
double age = (point_a._timestamp - point_b._timestamp);
|
||||||
@ -400,9 +417,18 @@ compute_smooth_position(double timestamp) {
|
|||||||
// If the first point is too old, assume there were a lot of
|
// If the first point is too old, assume there were a lot of
|
||||||
// implicit standing still messages that weren't sent. Insert a new
|
// implicit standing still messages that weren't sent. Insert a new
|
||||||
// sample point to reflect this.
|
// sample point to reflect this.
|
||||||
|
if (deadrec_cat.is_spam()) {
|
||||||
|
deadrec_cat.spam()
|
||||||
|
<< " first point too old: age = " << age << "\n";
|
||||||
|
}
|
||||||
SamplePoint new_point = point_b;
|
SamplePoint new_point = point_b;
|
||||||
new_point._timestamp = point_a._timestamp - _expected_broadcast_period;
|
new_point._timestamp = point_a._timestamp - _expected_broadcast_period;
|
||||||
if (new_point._timestamp > timestamp) {
|
if (deadrec_cat.is_spam()) {
|
||||||
|
deadrec_cat.spam()
|
||||||
|
<< " constructed new timestamp at " << new_point._timestamp
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
if (new_point._timestamp > point_b._timestamp) {
|
||||||
_points.insert(_points.begin() + point_after, new_point);
|
_points.insert(_points.begin() + point_after, new_point);
|
||||||
|
|
||||||
// Now we've monkeyed with the sequence. Start over.
|
// Now we've monkeyed with the sequence. Start over.
|
||||||
@ -655,9 +681,12 @@ linear_interpolate(int point_before, int point_after, double timestamp) {
|
|||||||
void SmoothMover::
|
void SmoothMover::
|
||||||
compute_velocity(const LVector3f &pos_delta, const LVecBase3f &hpr_delta,
|
compute_velocity(const LVector3f &pos_delta, const LVecBase3f &hpr_delta,
|
||||||
double age) {
|
double age) {
|
||||||
// Also compute the velocity. To get just the forward component
|
_smooth_rotational_velocity = hpr_delta[0] / age;
|
||||||
// of velocity, we need to project the velocity vector onto the y
|
|
||||||
// axis, as rotated by the current hpr.
|
if (_directional_velocity) {
|
||||||
|
// To get just the forward component of velocity, we need to project
|
||||||
|
// the velocity vector onto the y axis, as rotated by the current
|
||||||
|
// hpr.
|
||||||
if (!_computed_forward_axis) {
|
if (!_computed_forward_axis) {
|
||||||
LMatrix3f rot_mat;
|
LMatrix3f rot_mat;
|
||||||
compose_matrix(rot_mat, LVecBase3f(1.0, 1.0, 1.0), _smooth_hpr);
|
compose_matrix(rot_mat, LVecBase3f(1.0, 1.0, 1.0), _smooth_hpr);
|
||||||
@ -676,7 +705,11 @@ compute_velocity(const LVector3f &pos_delta, const LVecBase3f &hpr_delta,
|
|||||||
|
|
||||||
_smooth_forward_velocity = forward_distance / age;
|
_smooth_forward_velocity = forward_distance / age;
|
||||||
_smooth_lateral_velocity = lateral_distance / age;
|
_smooth_lateral_velocity = lateral_distance / age;
|
||||||
_smooth_rotational_velocity = hpr_delta[0] / age;
|
|
||||||
|
} else {
|
||||||
|
_smooth_forward_velocity = pos_delta.length();
|
||||||
|
_smooth_lateral_velocity = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
if (deadrec_cat.is_spam()) {
|
if (deadrec_cat.is_spam()) {
|
||||||
deadrec_cat.spam()
|
deadrec_cat.spam()
|
||||||
|
@ -146,6 +146,9 @@ PUBLISHED:
|
|||||||
INLINE void set_reset_velocity_age(double age);
|
INLINE void set_reset_velocity_age(double age);
|
||||||
INLINE double get_reset_velocity_age();
|
INLINE double get_reset_velocity_age();
|
||||||
|
|
||||||
|
INLINE void set_directional_velocity(bool flag);
|
||||||
|
INLINE bool get_directional_velocity();
|
||||||
|
|
||||||
void output(ostream &out) const;
|
void output(ostream &out) const;
|
||||||
void write(ostream &out) const;
|
void write(ostream &out) const;
|
||||||
|
|
||||||
@ -213,6 +216,7 @@ private:
|
|||||||
double _max_position_age;
|
double _max_position_age;
|
||||||
double _expected_broadcast_period;
|
double _expected_broadcast_period;
|
||||||
double _reset_velocity_age;
|
double _reset_velocity_age;
|
||||||
|
bool _directional_velocity;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "smoothMover.I"
|
#include "smoothMover.I"
|
||||||
|
@ -381,7 +381,6 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
|||||||
This assumes you have a client repository that knows its
|
This assumes you have a client repository that knows its
|
||||||
localAvatarDoId -- stored in self.cr.localAvatarDoId
|
localAvatarDoId -- stored in self.cr.localAvatarDoId
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if smoothing and EnableSmoothing:
|
if smoothing and EnableSmoothing:
|
||||||
if prediction and EnablePrediction:
|
if prediction and EnablePrediction:
|
||||||
# Prediction and smoothing.
|
# Prediction and smoothing.
|
||||||
|
@ -7,7 +7,7 @@ from direct.showbase.PythonUtil import randFloat, Enum
|
|||||||
class DistributedSmoothNodeBase:
|
class DistributedSmoothNodeBase:
|
||||||
"""common base class for DistributedSmoothNode and DistributedSmoothNodeAI
|
"""common base class for DistributedSmoothNode and DistributedSmoothNodeAI
|
||||||
"""
|
"""
|
||||||
BroadcastTypes = Enum('FULL, XYH')
|
BroadcastTypes = Enum('FULL, XYH, XY')
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.cnode = CDistributedSmoothNodeBase()
|
self.cnode = CDistributedSmoothNodeBase()
|
||||||
@ -51,6 +51,7 @@ class DistributedSmoothNodeBase:
|
|||||||
broadcastFuncs = {
|
broadcastFuncs = {
|
||||||
BT.FULL: self.cnode.broadcastPosHprFull,
|
BT.FULL: self.cnode.broadcastPosHprFull,
|
||||||
BT.XYH: self.cnode.broadcastPosHprXyh,
|
BT.XYH: self.cnode.broadcastPosHprXyh,
|
||||||
|
BT.XY: self.cnode.broadcastPosHprXy,
|
||||||
}
|
}
|
||||||
self.d_broadcastPosHpr = broadcastFuncs[self.broadcastType]
|
self.d_broadcastPosHpr = broadcastFuncs[self.broadcastType]
|
||||||
|
|
||||||
|
@ -235,6 +235,42 @@ broadcast_pos_hpr_xyh() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: CDistributedSmoothNodeBase::broadcast_pos_hpr_xy
|
||||||
|
// Access: Published
|
||||||
|
// Description: Examines only X and Y of the pos/hpr information,
|
||||||
|
// and broadcasts the appropriate messages.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void CDistributedSmoothNodeBase::
|
||||||
|
broadcast_pos_hpr_xy() {
|
||||||
|
LPoint3f xyz = _node_path.get_pos();
|
||||||
|
|
||||||
|
int flags = 0;
|
||||||
|
|
||||||
|
if (!IS_THRESHOLD_EQUAL(_store_xyz[0], xyz[0], smooth_node_epsilon)) {
|
||||||
|
_store_xyz[0] = xyz[0];
|
||||||
|
flags |= F_new_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_THRESHOLD_EQUAL(_store_xyz[1], xyz[1], smooth_node_epsilon)) {
|
||||||
|
_store_xyz[1] = xyz[1];
|
||||||
|
flags |= F_new_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags == 0) {
|
||||||
|
// No change. Send one and only one "stop" message.
|
||||||
|
if (!_store_stop) {
|
||||||
|
_store_stop = true;
|
||||||
|
d_setSmStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Any other change.
|
||||||
|
_store_stop = false;
|
||||||
|
d_setSmXY(_store_xyz[0], _store_xyz[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: CDistributedSmoothNodeBase::begin_send_update
|
// Function: CDistributedSmoothNodeBase::begin_send_update
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -56,6 +56,7 @@ PUBLISHED:
|
|||||||
|
|
||||||
void broadcast_pos_hpr_full();
|
void broadcast_pos_hpr_full();
|
||||||
void broadcast_pos_hpr_xyh();
|
void broadcast_pos_hpr_xyh();
|
||||||
|
void broadcast_pos_hpr_xy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
INLINE static bool only_changed(int flags, int compare);
|
INLINE static bool only_changed(int flags, int compare);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user