Pārlūkot izejas kodu

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.

Justin Butler 17 gadi atpakaļ
vecāks
revīzija
4c09b6307b

+ 13 - 3
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;
+
 }
 
 ////////////////////////////////////////////////////////////////////

+ 2 - 1
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;

+ 36 - 17
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):

+ 5 - 1
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