mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
Smoother movement fixes for better stopping/starting and timestamp issues. Fixes problem where distributed smooth objects will stop movement at the wrong location or will slide around when first being generated.
This commit is contained in:
parent
05d992e886
commit
4c09b6307b
@ -273,13 +273,23 @@ get_sample_hpr() const {
|
|||||||
// actual receipt time.
|
// actual receipt time.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE void SmoothMover::
|
INLINE void SmoothMover::
|
||||||
set_phony_timestamp() {
|
set_phony_timestamp(double timestamp, bool period_adjust) {
|
||||||
double now = ClockObject::get_global_clock()->get_frame_time();
|
double now = ClockObject::get_global_clock()->get_frame_time();
|
||||||
|
if (timestamp != 0.0)
|
||||||
|
// we were given a specific timestamp to use
|
||||||
|
now = timestamp;
|
||||||
|
|
||||||
// adjust by _delay when creating the timestamp since other
|
// adjust by _delay when creating the timestamp since other
|
||||||
// timestamps received from network updates are adjusted by this
|
// timestamps received from network updates are adjusted by this
|
||||||
_sample._timestamp = now - _delay;
|
if (period_adjust) {
|
||||||
|
_sample._timestamp = now - _expected_broadcast_period;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
_sample._timestamp = now;
|
||||||
|
|
||||||
_has_most_recent_timestamp = true;
|
_has_most_recent_timestamp = true;
|
||||||
_most_recent_timestamp = now;
|
_most_recent_timestamp = _sample._timestamp;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -72,7 +72,8 @@ PUBLISHED:
|
|||||||
INLINE const LPoint3f &get_sample_pos() const;
|
INLINE const LPoint3f &get_sample_pos() const;
|
||||||
INLINE const LVecBase3f &get_sample_hpr() const;
|
INLINE const LVecBase3f &get_sample_hpr() const;
|
||||||
|
|
||||||
INLINE void set_phony_timestamp();
|
INLINE void set_phony_timestamp(double timestamp = 0.0, bool period_adjust = false);
|
||||||
|
|
||||||
INLINE void set_timestamp(double timestamp);
|
INLINE void set_timestamp(double timestamp);
|
||||||
|
|
||||||
INLINE bool has_most_recent_timestamp() const;
|
INLINE bool has_most_recent_timestamp() const;
|
||||||
|
@ -179,14 +179,31 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
|||||||
self.smoother.setPhonyTimestamp()
|
self.smoother.setPhonyTimestamp()
|
||||||
self.smoother.markPosition()
|
self.smoother.markPosition()
|
||||||
|
|
||||||
def _checkResume(self):
|
def _checkResume(self,timestamp):
|
||||||
"""
|
"""
|
||||||
Determine if we were previously stopped and now need to
|
Determine if we were previously stopped and now need to
|
||||||
resume movement by making sure any old stored positions
|
resume movement by making sure any old stored positions
|
||||||
reflect the node's current position
|
reflect the node's current position
|
||||||
"""
|
"""
|
||||||
if (self.stopped):
|
if (self.stopped):
|
||||||
self.reloadPosition()
|
currTime = globalClock.getFrameTime()
|
||||||
|
now = currTime - self.smoother.getExpectedBroadcastPeriod()
|
||||||
|
last = self.smoother.getMostRecentTimestamp()
|
||||||
|
if (now > last):
|
||||||
|
# only set a new timestamp postion if we still have
|
||||||
|
# a position being smoothed to (so we don't interrupt
|
||||||
|
# any current smoothing and only do this if the object
|
||||||
|
# is actually locally stopped)
|
||||||
|
if (timestamp == None):
|
||||||
|
# no timestamp, use current time
|
||||||
|
local = 0.0
|
||||||
|
else:
|
||||||
|
local = globalClockDelta.networkToLocalTime(
|
||||||
|
timestamp, currTime)
|
||||||
|
|
||||||
|
self.smoother.setPhonyTimestamp(local,True)
|
||||||
|
self.smoother.markPosition()
|
||||||
|
|
||||||
self.stopped = False
|
self.stopped = False
|
||||||
|
|
||||||
# distributed set pos and hpr functions
|
# distributed set pos and hpr functions
|
||||||
@ -195,50 +212,50 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
|||||||
self.setComponentTLive(timestamp)
|
self.setComponentTLive(timestamp)
|
||||||
self.stopped = True
|
self.stopped = True
|
||||||
def setSmH(self, h, timestamp=None):
|
def setSmH(self, h, timestamp=None):
|
||||||
self._checkResume()
|
self._checkResume(timestamp)
|
||||||
self.setComponentH(h)
|
self.setComponentH(h)
|
||||||
self.setComponentTLive(timestamp)
|
self.setComponentTLive(timestamp)
|
||||||
def setSmZ(self, z, timestamp=None):
|
def setSmZ(self, z, timestamp=None):
|
||||||
self._checkResume()
|
self._checkResume(timestamp)
|
||||||
self.setComponentZ(z)
|
self.setComponentZ(z)
|
||||||
self.setComponentTLive(timestamp)
|
self.setComponentTLive(timestamp)
|
||||||
def setSmXY(self, x, y, timestamp=None):
|
def setSmXY(self, x, y, timestamp=None):
|
||||||
self._checkResume()
|
self._checkResume(timestamp)
|
||||||
self.setComponentX(x)
|
self.setComponentX(x)
|
||||||
self.setComponentY(y)
|
self.setComponentY(y)
|
||||||
self.setComponentTLive(timestamp)
|
self.setComponentTLive(timestamp)
|
||||||
def setSmXZ(self, x, z, timestamp=None):
|
def setSmXZ(self, x, z, timestamp=None):
|
||||||
self._checkResume()
|
self._checkResume(timestamp)
|
||||||
self.setComponentX(x)
|
self.setComponentX(x)
|
||||||
self.setComponentZ(z)
|
self.setComponentZ(z)
|
||||||
self.setComponentTLive(timestamp)
|
self.setComponentTLive(timestamp)
|
||||||
def setSmPos(self, x, y, z, timestamp=None):
|
def setSmPos(self, x, y, z, timestamp=None):
|
||||||
self._checkResume()
|
self._checkResume(timestamp)
|
||||||
self.setComponentX(x)
|
self.setComponentX(x)
|
||||||
self.setComponentY(y)
|
self.setComponentY(y)
|
||||||
self.setComponentZ(z)
|
self.setComponentZ(z)
|
||||||
self.setComponentTLive(timestamp)
|
self.setComponentTLive(timestamp)
|
||||||
def setSmHpr(self, h, p, r, timestamp=None):
|
def setSmHpr(self, h, p, r, timestamp=None):
|
||||||
self._checkResume()
|
self._checkResume(timestamp)
|
||||||
self.setComponentH(h)
|
self.setComponentH(h)
|
||||||
self.setComponentP(p)
|
self.setComponentP(p)
|
||||||
self.setComponentR(r)
|
self.setComponentR(r)
|
||||||
self.setComponentTLive(timestamp)
|
self.setComponentTLive(timestamp)
|
||||||
def setSmXYH(self, x, y, h, timestamp):
|
def setSmXYH(self, x, y, h, timestamp):
|
||||||
self._checkResume()
|
self._checkResume(timestamp)
|
||||||
self.setComponentX(x)
|
self.setComponentX(x)
|
||||||
self.setComponentY(y)
|
self.setComponentY(y)
|
||||||
self.setComponentH(h)
|
self.setComponentH(h)
|
||||||
self.setComponentTLive(timestamp)
|
self.setComponentTLive(timestamp)
|
||||||
def setSmXYZH(self, x, y, z, h, timestamp=None):
|
def setSmXYZH(self, x, y, z, h, timestamp=None):
|
||||||
self._checkResume()
|
self._checkResume(timestamp)
|
||||||
self.setComponentX(x)
|
self.setComponentX(x)
|
||||||
self.setComponentY(y)
|
self.setComponentY(y)
|
||||||
self.setComponentZ(z)
|
self.setComponentZ(z)
|
||||||
self.setComponentH(h)
|
self.setComponentH(h)
|
||||||
self.setComponentTLive(timestamp)
|
self.setComponentTLive(timestamp)
|
||||||
def setSmPosHpr(self, x, y, z, h, p, r, timestamp=None):
|
def setSmPosHpr(self, x, y, z, h, p, r, timestamp=None):
|
||||||
self._checkResume()
|
self._checkResume(timestamp)
|
||||||
self.setComponentX(x)
|
self.setComponentX(x)
|
||||||
self.setComponentY(y)
|
self.setComponentY(y)
|
||||||
self.setComponentZ(z)
|
self.setComponentZ(z)
|
||||||
@ -246,8 +263,9 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
|||||||
self.setComponentP(p)
|
self.setComponentP(p)
|
||||||
self.setComponentR(r)
|
self.setComponentR(r)
|
||||||
self.setComponentTLive(timestamp)
|
self.setComponentTLive(timestamp)
|
||||||
|
|
||||||
def setSmPosHprL(self, l, x, y, z, h, p, r, timestamp=None):
|
def setSmPosHprL(self, l, x, y, z, h, p, r, timestamp=None):
|
||||||
self._checkResume()
|
self._checkResume(timestamp)
|
||||||
self.setComponentL(l)
|
self.setComponentL(l)
|
||||||
self.setComponentX(x)
|
self.setComponentX(x)
|
||||||
self.setComponentY(y)
|
self.setComponentY(y)
|
||||||
@ -304,10 +322,11 @@ class DistributedSmoothNode(DistributedNode.DistributedNode,
|
|||||||
self.smoother.clearPositions(1)
|
self.smoother.clearPositions(1)
|
||||||
self.smoother.markPosition()
|
self.smoother.markPosition()
|
||||||
|
|
||||||
# jbutler: took this out, appears it is not needed since
|
# mark position only takes most recent position sent over the wire
|
||||||
# markPosition above stored the node's position, and this
|
# and applies it to the smoother's sample points, but we still
|
||||||
# just reapplies the poition to the node
|
# need to make sure and apply that position to the actual node
|
||||||
#self.forceToTruePosition()
|
# path
|
||||||
|
self.forceToTruePosition()
|
||||||
|
|
||||||
@report(types = ['args'], dConfigParam = 'want-smoothnode-report')
|
@report(types = ['args'], dConfigParam = 'want-smoothnode-report')
|
||||||
def setComponentTLive(self, timestamp):
|
def setComponentTLive(self, timestamp):
|
||||||
|
@ -16,7 +16,7 @@ class DistributedSmoothNodeBase:
|
|||||||
BroadcastTypes = Enum('FULL, XYH, XY')
|
BroadcastTypes = Enum('FULL, XYH, XY')
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
self.__broadcastPeriod = None
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
self.cnode = CDistributedSmoothNodeBase()
|
self.cnode = CDistributedSmoothNodeBase()
|
||||||
@ -47,6 +47,10 @@ class DistributedSmoothNodeBase:
|
|||||||
# call this at any time to change the delay between broadcasts
|
# call this at any time to change the delay between broadcasts
|
||||||
self.__broadcastPeriod = period
|
self.__broadcastPeriod = period
|
||||||
|
|
||||||
|
def getPosHprBroadcastPeriod(self):
|
||||||
|
# query the current delay between broadcasts
|
||||||
|
return self.__broadcastPeriod
|
||||||
|
|
||||||
def stopPosHprBroadcast(self):
|
def stopPosHprBroadcast(self):
|
||||||
taskMgr.remove(self.getPosHprBroadcastTaskName())
|
taskMgr.remove(self.getPosHprBroadcastTaskName())
|
||||||
# Delete this callback because it maintains a reference to self
|
# Delete this callback because it maintains a reference to self
|
||||||
|
Loading…
x
Reference in New Issue
Block a user