diff --git a/direct/src/deadrec/smoothMover.I b/direct/src/deadrec/smoothMover.I index 8b4470471b..e6b7cd4041 100644 --- a/direct/src/deadrec/smoothMover.I +++ b/direct/src/deadrec/smoothMover.I @@ -273,13 +273,23 @@ get_sample_hpr() const { // actual receipt time. //////////////////////////////////////////////////////////////////// INLINE void SmoothMover:: -set_phony_timestamp() { +set_phony_timestamp(double timestamp, bool period_adjust) { 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 // 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; - _most_recent_timestamp = now; + _most_recent_timestamp = _sample._timestamp; + } //////////////////////////////////////////////////////////////////// diff --git a/direct/src/deadrec/smoothMover.h b/direct/src/deadrec/smoothMover.h index b519e1eb92..a30fac1df4 100644 --- a/direct/src/deadrec/smoothMover.h +++ b/direct/src/deadrec/smoothMover.h @@ -72,7 +72,8 @@ PUBLISHED: INLINE const LPoint3f &get_sample_pos() 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 bool has_most_recent_timestamp() const; diff --git a/direct/src/distributed/DistributedSmoothNode.py b/direct/src/distributed/DistributedSmoothNode.py index 4b14ec1b1b..e120c7f41a 100644 --- a/direct/src/distributed/DistributedSmoothNode.py +++ b/direct/src/distributed/DistributedSmoothNode.py @@ -179,15 +179,32 @@ class DistributedSmoothNode(DistributedNode.DistributedNode, self.smoother.setPhonyTimestamp() self.smoother.markPosition() - def _checkResume(self): + def _checkResume(self,timestamp): """ Determine if we were previously stopped and now need to resume movement by making sure any old stored positions reflect the node's current position """ if (self.stopped): - self.reloadPosition() - self.stopped = False + 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 # distributed set pos and hpr functions # 'send' versions are inherited from DistributedSmoothNodeBase @@ -195,50 +212,50 @@ class DistributedSmoothNode(DistributedNode.DistributedNode, self.setComponentTLive(timestamp) self.stopped = True def setSmH(self, h, timestamp=None): - self._checkResume() + self._checkResume(timestamp) self.setComponentH(h) self.setComponentTLive(timestamp) def setSmZ(self, z, timestamp=None): - self._checkResume() + self._checkResume(timestamp) self.setComponentZ(z) self.setComponentTLive(timestamp) def setSmXY(self, x, y, timestamp=None): - self._checkResume() + self._checkResume(timestamp) self.setComponentX(x) self.setComponentY(y) self.setComponentTLive(timestamp) def setSmXZ(self, x, z, timestamp=None): - self._checkResume() + self._checkResume(timestamp) self.setComponentX(x) self.setComponentZ(z) self.setComponentTLive(timestamp) def setSmPos(self, x, y, z, timestamp=None): - self._checkResume() + self._checkResume(timestamp) self.setComponentX(x) self.setComponentY(y) self.setComponentZ(z) self.setComponentTLive(timestamp) def setSmHpr(self, h, p, r, timestamp=None): - self._checkResume() + self._checkResume(timestamp) self.setComponentH(h) self.setComponentP(p) self.setComponentR(r) self.setComponentTLive(timestamp) def setSmXYH(self, x, y, h, timestamp): - self._checkResume() + self._checkResume(timestamp) self.setComponentX(x) self.setComponentY(y) self.setComponentH(h) self.setComponentTLive(timestamp) def setSmXYZH(self, x, y, z, h, timestamp=None): - self._checkResume() + self._checkResume(timestamp) self.setComponentX(x) self.setComponentY(y) self.setComponentZ(z) self.setComponentH(h) self.setComponentTLive(timestamp) def setSmPosHpr(self, x, y, z, h, p, r, timestamp=None): - self._checkResume() + self._checkResume(timestamp) self.setComponentX(x) self.setComponentY(y) self.setComponentZ(z) @@ -246,8 +263,9 @@ class DistributedSmoothNode(DistributedNode.DistributedNode, self.setComponentP(p) self.setComponentR(r) self.setComponentTLive(timestamp) + def setSmPosHprL(self, l, x, y, z, h, p, r, timestamp=None): - self._checkResume() + self._checkResume(timestamp) self.setComponentL(l) self.setComponentX(x) self.setComponentY(y) @@ -304,10 +322,11 @@ class DistributedSmoothNode(DistributedNode.DistributedNode, self.smoother.clearPositions(1) self.smoother.markPosition() - # jbutler: took this out, appears it is not needed since - # markPosition above stored the node's position, and this - # just reapplies the poition to the node - #self.forceToTruePosition() + # mark position only takes most recent position sent over the wire + # and applies it to the smoother's sample points, but we still + # need to make sure and apply that position to the actual node + # path + self.forceToTruePosition() @report(types = ['args'], dConfigParam = 'want-smoothnode-report') def setComponentTLive(self, timestamp): diff --git a/direct/src/distributed/DistributedSmoothNodeBase.py b/direct/src/distributed/DistributedSmoothNodeBase.py index 6eae16b8c6..c8338fa8c9 100755 --- a/direct/src/distributed/DistributedSmoothNodeBase.py +++ b/direct/src/distributed/DistributedSmoothNodeBase.py @@ -16,7 +16,7 @@ class DistributedSmoothNodeBase: BroadcastTypes = Enum('FULL, XYH, XY') def __init__(self): - pass + self.__broadcastPeriod = None def generate(self): self.cnode = CDistributedSmoothNodeBase() @@ -47,6 +47,10 @@ class DistributedSmoothNodeBase: # call this at any time to change the delay between broadcasts self.__broadcastPeriod = period + def getPosHprBroadcastPeriod(self): + # query the current delay between broadcasts + return self.__broadcastPeriod + def stopPosHprBroadcast(self): taskMgr.remove(self.getPosHprBroadcastTaskName()) # Delete this callback because it maintains a reference to self