Selaa lähdekoodia

Added routines to synchronize the clock across cluster machines

Mark Mine 21 vuotta sitten
vanhempi
sitoutus
18d54db4c8

+ 18 - 0
direct/src/cluster/ClusterClient.py

@@ -70,11 +70,24 @@ class ClusterClient(DirectObject.DirectObject):
                                           serverConfig.filmSize,
                                           serverConfig.filmOffset)
                 self.serverList.append(server)
+        self.notify.debug('pre startTimeTask')
+        self.startSynchronizeTimeTask()
         self.notify.debug('pre startMoveCam')
         self.startMoveCamTask()
         self.notify.debug('post startMoveCam')
         self.startMoveSelectedTask()
 
+    def startSynchronizeTimeTask(self):
+        self.notify.debug('broadcasting frame time')
+        taskMgr.add(self.synchronizeTimeTask, "synchronizeTimeTask", -40)
+
+    def synchronizeTimeTask(self,task):
+        frameTime = globalClock.getFrameTime()
+        dt = globalClock.getDt()
+        for server in self.serverList:
+            server.sendTimeData(frameTime, dt)
+        return Task.cont
+
     def startMoveCamTask(self):
         self.notify.debug('adding move cam')
         taskMgr.add(self.moveCameraTask, "moveCamTask", 49)
@@ -280,6 +293,11 @@ class DisplayConnection:
         datagram = self.msgHandler.makeExitDatagram()
         self.cw.send(datagram, self.tcpConn)
 
+    def sendTimeData(self,frameTime, dt):
+        ClusterClient.notify.debug("send time data...")
+        datagram = self.msgHandler.makeTimeDataDatagram(frameTime, dt)
+        self.cw.send(datagram, self.tcpConn)
+
 class ClusterConfigItem:
     def __init__(self, serverConfigName, serverName, serverPort):
         self.serverConfigName = serverConfigName

+ 5 - 2
direct/src/cluster/ClusterConfig.py

@@ -28,10 +28,13 @@ ClientConfigs = {
     'two-server'          : [{'display name' : 'master',
                               'display mode' : 'client',
                               'pos' : Vec3(0),
-                              'hpr' : Vec3(30,0,0)},
+                              #'hpr' : Vec3(30,0,0)},
+                              'hpr' : Vec3(0,0,0)},
                              {'display name' : 'la',
                               'pos' : Vec3(0),
-                              'hpr' : Vec3(-30,0,0)}
+                              #'hpr' : Vec3(-30,0,0)
+                              'hpr' : Vec3(0,0,0)
+                              }
                              ],
     'mono-cave'   : [{'display name' : 'la',
                       'pos' : Vec3(-0.105, -0.020, 5.000),

+ 16 - 0
direct/src/cluster/ClusterMsgs.py

@@ -17,6 +17,7 @@ CLUSTER_SWAP_READY = 4
 CLUSTER_SWAP_NOW   = 5
 CLUSTER_COMMAND_STRING = 6
 CLUSTER_SELECTED_MOVEMENT = 7
+CLUSTER_TIME_DATA = 8
 CLUSTER_EXIT = 100
 
 #Port number for cluster rendering
@@ -225,6 +226,21 @@ class ClusterMsgHandler:
         datagram.addUint8(CLUSTER_EXIT)
         return datagram
         
+    def makeTimeDataDatagram(self,frameTime, dt):
+        datagram = PyDatagram()
+        datagram.addUint32(self.packetNumber)
+        self.packetNumber = self.packetNumber + 1
+        datagram.addUint8(CLUSTER_TIME_DATA)
+        datagram.addFloat32(frameTime)
+        datagram.addFloat32(dt)
+        return datagram
+
+    def parseTimeDataDatagram(self, dgi):
+        frameTime=dgi.getFloat32()
+        dt=dgi.getFloat32()
+        self.notify.debug('time data=%f %f' % (frameTime, dt))
+        return (frameTime, dt)
+
 
 
 

+ 14 - 0
direct/src/cluster/ClusterServer.py

@@ -50,6 +50,8 @@ class ClusterServer(DirectObject.DirectObject):
         if clusterSyncFlag:
             self.startSwapCoordinator()
             base.graphicsEngine.setAutoFlip(0)
+        # Set global clock mode to non-real time
+        globalClock.setMode(ClockObject.MNonRealTime)
         # Send verification of startup to client
         self.daemon = DirectD()
         # These must be passed in as bootstrap arguments and stored in
@@ -166,6 +168,9 @@ class ClusterServer(DirectObject.DirectObject):
         elif (type == CLUSTER_SWAP_NOW):
             self.notify.debug('swapping')
             base.graphicsEngine.flipFrame()
+        elif (type == CLUSTER_TIME_DATA):
+            self.notify.debug('time data')
+            self.handleTimeData(dgi)
         else:
             self.notify.warning("Received unknown packet type:" % type)
         return type
@@ -197,6 +202,14 @@ class ClusterServer(DirectObject.DirectObject):
         if last:
             last.setPosHprScale(x,y,z,h,p,r,sx,sy,sz)
 
+    def handleTimeData(self,dgi):
+        """ Update cameraJig position to reflect latest position """
+        (frameTime, dt) = self.msgHandler.parseTimeDataDatagram(dgi)
+        # Use frame time from client for both real and frame time
+        globalClock.setRealTime(frameTime)
+        globalClock.setFrameTime(frameTime)
+        globalClock.setDt(dt)
+
     def handleCommandString(self, dgi):
         """ Handle arbitrary command string from client """
         command = self.msgHandler.parseCommandStringDatagram(dgi)
@@ -205,3 +218,4 @@ class ClusterServer(DirectObject.DirectObject):
         except:
             pass
         
+