mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -04:00
merged ai-telemetry branch to trunk
This commit is contained in:
parent
95f8fa1fb8
commit
330918c8f9
@ -1,24 +1,42 @@
|
||||
from AIBaseGlobal import *
|
||||
from PandaModules import NodePath
|
||||
import DistributedObjectAI
|
||||
import Task
|
||||
|
||||
class DistributedNodeAI(DistributedObjectAI.DistributedObjectAI):
|
||||
def __init__(self, air):
|
||||
class DistributedNodeAI(DistributedObjectAI.DistributedObjectAI, NodePath):
|
||||
def __init__(self, air, name=None):
|
||||
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
|
||||
if name is None:
|
||||
name = self.__class__.__name__
|
||||
NodePath.__init__(self, hidden.attachNewNode(name))
|
||||
|
||||
def delete(self):
|
||||
DistributedObjectAI.DistributedObjectAI.delete(self)
|
||||
|
||||
### setParent ###
|
||||
|
||||
def d_setParent(self, parentString):
|
||||
if type(parentString) == type(''):
|
||||
self.sendUpdate("setParentStr", [parentString])
|
||||
def b_setParent(self, parentToken):
|
||||
if type(parentToken) == types.StringType:
|
||||
self.setParentStr(parentToken)
|
||||
else:
|
||||
self.sendUpdate("setParent", [parentString])
|
||||
self.setParent(parentToken)
|
||||
self.d_setParent(parentToken)
|
||||
|
||||
def setParent(self, parentString):
|
||||
pass
|
||||
def d_setParent(self, parentToken):
|
||||
if type(parentToken) == type(''):
|
||||
self.sendUpdate("setParentStr", [parentToken])
|
||||
else:
|
||||
self.sendUpdate("setParent", [parentToken])
|
||||
|
||||
def setParentStr(self, parentToken):
|
||||
print 'setParentStr(%s): %s' % (self.doId, parentToken)
|
||||
self.do_setParent(parentToken)
|
||||
|
||||
def setParent(self, parentToken):
|
||||
print 'setParent(%s): %s' % (self.doId, parentToken)
|
||||
self.do_setParent(parentToken)
|
||||
|
||||
def do_setParent(self, parentToken):
|
||||
self.air.parentMgr.requestReparent(self, parentToken)
|
||||
|
||||
###### set pos and hpr functions #######
|
||||
|
||||
@ -47,8 +65,8 @@ class DistributedNodeAI(DistributedObjectAI.DistributedObjectAI):
|
||||
self.sendUpdate("setR", [r])
|
||||
|
||||
def setXY(self, x, y):
|
||||
pass
|
||||
|
||||
self.setX(x)
|
||||
self.setY(y)
|
||||
def d_setXY(self, x, y):
|
||||
self.sendUpdate("setXY", [x, y])
|
||||
|
||||
@ -61,19 +79,18 @@ class DistributedNodeAI(DistributedObjectAI.DistributedObjectAI):
|
||||
self.sendUpdate("setHpr", [h, p, r])
|
||||
|
||||
def setXYH(self, x, y, h):
|
||||
pass
|
||||
|
||||
self.setX(x)
|
||||
self.setY(y)
|
||||
self.setH(h)
|
||||
def d_setXYH(self, x, y, h):
|
||||
self.sendUpdate("setXYH", [x, y, h])
|
||||
|
||||
def setXYZH(self, x, y, z, h):
|
||||
pass
|
||||
|
||||
self.setPos(x, y, z)
|
||||
self.setH(h)
|
||||
def d_setXYZH(self, x, y, z, h):
|
||||
self.sendUpdate("setXYZH", [x, y, z, h])
|
||||
|
||||
# setPosHpr provided by NodePath
|
||||
def d_setPosHpr(self, x, y, z, h, p, r):
|
||||
self.sendUpdate("setPosHpr", [x, y, z, h, p, r])
|
||||
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
from PandaModules import *
|
||||
from ClockDelta import *
|
||||
import DistributedNode
|
||||
import DistributedSmoothNodeBase
|
||||
import Task
|
||||
|
||||
# This number defines our tolerance for out-of-sync telemetry packets.
|
||||
@ -67,7 +68,9 @@ def activateSmoothing(smoothing, prediction):
|
||||
|
||||
|
||||
|
||||
class DistributedSmoothNode(DistributedNode.DistributedNode):
|
||||
class DistributedSmoothNode(DistributedNode.DistributedNode,
|
||||
DistributedSmoothNodeBase.\
|
||||
DistributedSmoothNodeBase):
|
||||
"""DistributedSmoothNode class:
|
||||
|
||||
This specializes DistributedNode to add functionality to smooth
|
||||
@ -81,11 +84,16 @@ class DistributedSmoothNode(DistributedNode.DistributedNode):
|
||||
except:
|
||||
self.DistributedSmoothNode_initialized = 1
|
||||
DistributedNode.DistributedNode.__init__(self, cr)
|
||||
DistributedSmoothNodeBase.DistributedSmoothNodeBase.__init__(self)
|
||||
|
||||
self.smoother = SmoothMover()
|
||||
self.smoothStarted = 0
|
||||
self.lastSuggestResync = 0
|
||||
|
||||
def delete(self):
|
||||
DistributedSmoothNodeBase.DistributedSmoothNodeBase.delete(self)
|
||||
DistributedNode.DistributedNode.delete(self)
|
||||
|
||||
### Methods to handle computing and updating of the smoothed
|
||||
### position.
|
||||
|
||||
@ -162,76 +170,42 @@ class DistributedSmoothNode(DistributedNode.DistributedNode):
|
||||
self.smoother.setPhonyTimestamp()
|
||||
self.smoother.markPosition()
|
||||
|
||||
|
||||
|
||||
### distributed set pos and hpr functions ###
|
||||
|
||||
### These functions send the distributed update to set the
|
||||
### appropriate values on the remote side. These are
|
||||
### composite fields, with all the likely combinations
|
||||
### defined; each function maps (via the dc file) to one or
|
||||
### more component operations on the remote client.
|
||||
|
||||
def d_setSmStop(self):
|
||||
self.sendUpdate("setSmStop", [globalClockDelta.getFrameNetworkTime()])
|
||||
# distributed set pos and hpr functions
|
||||
# 'send' versions are inherited from DistributedSmoothNodeBase
|
||||
def setSmStop(self, timestamp):
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def d_setSmH(self, h):
|
||||
self.sendUpdate("setSmH", [h, globalClockDelta.getFrameNetworkTime()])
|
||||
def setSmH(self, h, timestamp):
|
||||
self.setComponentH(h)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def d_setSmXY(self, x, y):
|
||||
self.sendUpdate("setSmXY", [x, y, globalClockDelta.getFrameNetworkTime()])
|
||||
def setSmXY(self, x, y, timestamp):
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def d_setSmXZ(self, x, z):
|
||||
self.sendUpdate("setSmXZ", [x, z, globalClockDelta.getFrameNetworkTime()])
|
||||
def setSmXZ(self, x, z, timestamp):
|
||||
self.setComponentX(x)
|
||||
self.setComponentZ(z)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def d_setSmPos(self, x, y, z):
|
||||
self.sendUpdate("setSmPos", [x, y, z, globalClockDelta.getFrameNetworkTime()])
|
||||
def setSmPos(self, x, y, z, timestamp):
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentZ(z)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def d_setSmHpr(self, h, p, r):
|
||||
self.sendUpdate("setSmHpr", [h, p, r, globalClockDelta.getFrameNetworkTime()])
|
||||
def setSmHpr(self, h, p, r, timestamp):
|
||||
self.setComponentH(h)
|
||||
self.setComponentP(p)
|
||||
self.setComponentR(r)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def d_setSmXYH(self, x, y, h):
|
||||
self.sendUpdate("setSmXYH", [x, y, h, globalClockDelta.getFrameNetworkTime()])
|
||||
def setSmXYH(self, x, y, h, timestamp):
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentH(h)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def d_setSmXYZH(self, x, y, z, h):
|
||||
self.sendUpdate("setSmXYZH", [x, y, z, h, globalClockDelta.getFrameNetworkTime()])
|
||||
def setSmXYZH(self, x, y, z, h, timestamp):
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentZ(z)
|
||||
self.setComponentH(h)
|
||||
self.setComponentTLive(timestamp)
|
||||
|
||||
def d_setSmPosHpr(self, x, y, z, h, p, r):
|
||||
self.sendUpdate("setSmPosHpr", [x, y, z, h, p, r, globalClockDelta.getFrameNetworkTime()])
|
||||
def setSmPosHpr(self, x, y, z, h, p, r, timestamp):
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
@ -311,11 +285,6 @@ class DistributedSmoothNode(DistributedNode.DistributedNode):
|
||||
self.smoother.setTimestamp(local)
|
||||
self.smoother.markPosition()
|
||||
|
||||
def b_clearSmoothing(self):
|
||||
self.d_clearSmoothing()
|
||||
self.clearSmoothing()
|
||||
def d_clearSmoothing(self):
|
||||
self.sendUpdate("clearSmoothing", [0])
|
||||
def clearSmoothing(self, bogus = None):
|
||||
# Call this to invalidate all the old position reports
|
||||
# (e.g. just before popping to a new position).
|
||||
|
84
direct/src/distributed/DistributedSmoothNodeAI.py
Executable file
84
direct/src/distributed/DistributedSmoothNodeAI.py
Executable file
@ -0,0 +1,84 @@
|
||||
from AIBaseGlobal import *
|
||||
import DistributedNodeAI
|
||||
import DistributedSmoothNodeBase
|
||||
|
||||
class DistributedSmoothNodeAI(DistributedNodeAI.DistributedNodeAI,
|
||||
DistributedSmoothNodeBase.\
|
||||
DistributedSmoothNodeBase):
|
||||
def __init__(self, air, name=None):
|
||||
DistributedNodeAI.DistributedNodeAI.__init__(self, air, name)
|
||||
DistributedSmoothNodeBase.DistributedSmoothNodeBase.__init__(self)
|
||||
|
||||
def delete(self):
|
||||
DistributedSmoothNodeBase.DistributedSmoothNodeBase.delete(self)
|
||||
DistributedNodeAI.DistributedNodeAI.delete(self)
|
||||
|
||||
# distributed set pos and hpr functions
|
||||
# these are invoked by the DC system
|
||||
# 'send' (d_set*) versions are inherited from DistributedSmoothNodeBase
|
||||
def setSmStop(self, t):
|
||||
self.setComponentT(t)
|
||||
def setSmH(self, h, t):
|
||||
self.setComponentH(h)
|
||||
self.setComponentT(t)
|
||||
def setSmXY(self, x, y, t):
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentT(t)
|
||||
def setSmXZ(self, x, z, t):
|
||||
self.setComponentX(x)
|
||||
self.setComponentZ(z)
|
||||
self.setComponentT(t)
|
||||
def setSmPos(self, x, y, z, t):
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentZ(z)
|
||||
self.setComponentT(t)
|
||||
def setSmHpr(self, h, p, r, t):
|
||||
self.setComponentH(h)
|
||||
self.setComponentP(p)
|
||||
self.setComponentR(r)
|
||||
self.setComponentT(t)
|
||||
def setSmXYH(self, x, y, h, t):
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentH(h)
|
||||
self.setComponentT(t)
|
||||
def setSmXYZH(self, x, y, z, h, t):
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentZ(z)
|
||||
self.setComponentH(h)
|
||||
self.setComponentT(t)
|
||||
def setSmPosHpr(self, x, y, z, h, p, r, t):
|
||||
self.setComponentX(x)
|
||||
self.setComponentY(y)
|
||||
self.setComponentZ(z)
|
||||
self.setComponentH(h)
|
||||
self.setComponentP(p)
|
||||
self.setComponentR(r)
|
||||
self.setComponentT(t)
|
||||
|
||||
def clearSmoothing(self, bogus = None):
|
||||
pass
|
||||
|
||||
### component set pos and hpr functions ###
|
||||
|
||||
### These are the component functions that are invoked
|
||||
### remotely by the above composite functions.
|
||||
|
||||
# on the AI, the components are assigned immediately
|
||||
def setComponentX(self, x):
|
||||
self.setX(x)
|
||||
def setComponentY(self, y):
|
||||
self.setY(y)
|
||||
def setComponentZ(self, z):
|
||||
self.setZ(z)
|
||||
def setComponentH(self, h):
|
||||
self.setH(h)
|
||||
def setComponentP(self, p):
|
||||
self.setP(p)
|
||||
def setComponentR(self, r):
|
||||
self.setR(r)
|
||||
def setComponentT(self, t):
|
||||
pass
|
175
direct/src/distributed/DistributedSmoothNodeBase.py
Executable file
175
direct/src/distributed/DistributedSmoothNodeBase.py
Executable file
@ -0,0 +1,175 @@
|
||||
"""DistributedSmoothNodeBase module: contains the DistributedSmoothNodeBase class"""
|
||||
|
||||
from ClockDelta import *
|
||||
import Task
|
||||
|
||||
class DistributedSmoothNodeBase:
|
||||
"""common base class for DistributedSmoothNode and DistributedSmoothNodeAI
|
||||
"""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def delete(self):
|
||||
pass
|
||||
|
||||
### distributed set pos and hpr functions ###
|
||||
|
||||
### These functions send the distributed update to set the
|
||||
### appropriate values on the remote side. These are
|
||||
### composite fields, with all the likely combinations
|
||||
### defined; each function maps (via the dc file) to one or
|
||||
### more component operations on the remote client.
|
||||
|
||||
def d_setSmStop(self):
|
||||
self.sendUpdate("setSmStop", [globalClockDelta.getFrameNetworkTime()])
|
||||
def d_setSmH(self, h):
|
||||
self.sendUpdate("setSmH", [h, globalClockDelta.getFrameNetworkTime()])
|
||||
def d_setSmXY(self, x, y):
|
||||
self.sendUpdate("setSmXY", [x, y,
|
||||
globalClockDelta.getFrameNetworkTime()])
|
||||
def d_setSmXZ(self, x, z):
|
||||
self.sendUpdate("setSmXZ", [x, z,
|
||||
globalClockDelta.getFrameNetworkTime()])
|
||||
def d_setSmPos(self, x, y, z):
|
||||
self.sendUpdate("setSmPos", [x, y, z,
|
||||
globalClockDelta.getFrameNetworkTime()])
|
||||
def d_setSmHpr(self, h, p, r):
|
||||
self.sendUpdate("setSmHpr", [h, p, r,
|
||||
globalClockDelta.getFrameNetworkTime()])
|
||||
def d_setSmXYH(self, x, y, h):
|
||||
self.sendUpdate("setSmXYH", [x, y, h,
|
||||
globalClockDelta.getFrameNetworkTime()])
|
||||
def d_setSmXYZH(self, x, y, z, h):
|
||||
self.sendUpdate("setSmXYZH", [x, y, z, h,
|
||||
globalClockDelta.getFrameNetworkTime()])
|
||||
def d_setSmPosHpr(self, x, y, z, h, p, r):
|
||||
self.sendUpdate("setSmPosHpr", [x, y, z, h, p, r,
|
||||
globalClockDelta.getFrameNetworkTime()])
|
||||
|
||||
def b_clearSmoothing(self):
|
||||
self.d_clearSmoothing()
|
||||
self.clearSmoothing()
|
||||
def d_clearSmoothing(self):
|
||||
self.sendUpdate("clearSmoothing", [0])
|
||||
|
||||
### posHprBroadcast ###
|
||||
|
||||
def getPosHprBroadcastTaskName(self):
|
||||
# presumably, we have a doId at this point
|
||||
return "sendPosHpr-%s" % self.doId
|
||||
|
||||
def stopPosHprBroadcast(self):
|
||||
taskMgr.remove(self.getPosHprBroadcastTaskName())
|
||||
|
||||
def startPosHprBroadcast(self, period=.2):
|
||||
taskName = self.getPosHprBroadcastTaskName()
|
||||
# Set up telemetry optimization variables
|
||||
xyz = self.getPos()
|
||||
hpr = self.getHpr()
|
||||
|
||||
self.__storeX = xyz[0]
|
||||
self.__storeY = xyz[1]
|
||||
self.__storeZ = xyz[2]
|
||||
self.__storeH = hpr[0]
|
||||
self.__storeP = hpr[1]
|
||||
self.__storeR = hpr[2]
|
||||
self.__storeStop = 0
|
||||
self.__epsilon = 0.01
|
||||
self.__broadcastPeriod = period
|
||||
# Broadcast our initial position
|
||||
self.b_clearSmoothing()
|
||||
self.d_setSmPosHpr(self.__storeX, self.__storeY, self.__storeZ,
|
||||
self.__storeH, self.__storeP, self.__storeR)
|
||||
# remove any old tasks
|
||||
taskMgr.remove(taskName)
|
||||
# spawn the new task
|
||||
taskMgr.doMethodLater(self.__broadcastPeriod,
|
||||
self.posHprBroadcast, taskName)
|
||||
|
||||
def posHprBroadcast(self, task):
|
||||
self.d_broadcastPosHpr()
|
||||
taskName = self.taskName("sendPosHpr")
|
||||
taskMgr.doMethodLater(self.__broadcastPeriod,
|
||||
self.posHprBroadcast, taskName)
|
||||
return Task.done
|
||||
|
||||
def d_broadcastPosHpr(self):
|
||||
# send out the minimal bits to describe our new position
|
||||
xyz = self.getPos()
|
||||
hpr = self.getHpr()
|
||||
|
||||
if abs(self.__storeX - xyz[0]) > self.__epsilon:
|
||||
self.__storeX = xyz[0]
|
||||
newX = 1
|
||||
else:
|
||||
newX = 0
|
||||
|
||||
if abs(self.__storeY - xyz[1]) > self.__epsilon:
|
||||
self.__storeY = xyz[1]
|
||||
newY = 1
|
||||
else:
|
||||
newY = 0
|
||||
|
||||
if abs(self.__storeZ - xyz[2]) > self.__epsilon:
|
||||
self.__storeZ = xyz[2]
|
||||
newZ = 1
|
||||
else:
|
||||
newZ = 0
|
||||
|
||||
if abs(self.__storeH - hpr[0]) > self.__epsilon:
|
||||
self.__storeH = hpr[0]
|
||||
newH = 1
|
||||
else:
|
||||
newH = 0
|
||||
|
||||
if abs(self.__storeP - hpr[1]) > self.__epsilon:
|
||||
self.__storeP = hpr[1]
|
||||
newP = 1
|
||||
else:
|
||||
newP = 0
|
||||
|
||||
if abs(self.__storeR - hpr[2]) > self.__epsilon:
|
||||
self.__storeR = hpr[2]
|
||||
newR = 1
|
||||
else:
|
||||
newR = 0
|
||||
|
||||
# Check for changes:
|
||||
if not(newX or newY or newZ or newH or newP or newR):
|
||||
# No change
|
||||
# Send one and only one "stop" message.
|
||||
if not self.__storeStop:
|
||||
self.__storeStop = 1
|
||||
self.d_setSmStop()
|
||||
# print 'no change'
|
||||
elif (newH) and not(newX or newY or newZ or newP or newR):
|
||||
# Only change in H
|
||||
self.__storeStop = 0
|
||||
self.d_setSmH(self.__storeH)
|
||||
# print ("H change")
|
||||
elif (newX or newY) and not(newZ or newH or newP or newR):
|
||||
# Only change in X, Y
|
||||
self.__storeStop = 0
|
||||
self.d_setSmXY(self.__storeX, self.__storeY)
|
||||
# print ("XY change")
|
||||
elif (newX or newY or newZ) and not(newH or newP or newR):
|
||||
# Only change in X, Y, Z
|
||||
self.__storeStop = 0
|
||||
self.d_setSmPos(self.__storeX, self.__storeY, self.__storeZ)
|
||||
# print ("XYZ change")
|
||||
elif (newX or newY or newH) and not(newZ or newP or newR):
|
||||
# Only change in X, Y, H
|
||||
self.__storeStop = 0
|
||||
self.d_setSmXYH(self.__storeX, self.__storeY, self.__storeH)
|
||||
# print ("XYH change")
|
||||
elif (newX or newY or newZ or newH) and not(newP or newR):
|
||||
# Only change in X, Y, Z, H
|
||||
self.__storeStop = 0
|
||||
self.d_setSmXYZH(self.__storeX, self.__storeY, self.__storeZ, self.__storeH)
|
||||
# print ("XYZH change")
|
||||
else:
|
||||
# Other changes
|
||||
self.__storeStop = 0
|
||||
self.d_setSmPosHpr(self.__storeX, self.__storeY, self.__storeZ,
|
||||
self.__storeH, self.__storeP, self.__storeR)
|
||||
# print ("XYZHPR change")
|
@ -1,9 +1,9 @@
|
||||
"""ParentMgr module: contains the ParentMgr class"""
|
||||
|
||||
from ShowBaseGlobal import *
|
||||
import DirectNotifyGlobal
|
||||
|
||||
class ParentMgr:
|
||||
# This is now used on the AI as well.
|
||||
"""ParentMgr holds a table of nodes that avatars may be parented to
|
||||
in a distributed manner. All clients within a particular zone maintain
|
||||
identical tables of these nodes, and the nodes are referenced by 'tokens'
|
||||
|
@ -71,6 +71,10 @@ class ShowBase(DirectObject.DirectObject):
|
||||
|
||||
self.wantStats = self.config.GetBool('want-pstats', 0)
|
||||
|
||||
self.clientSleep = self.config.GetFloat('client-sleep', 0.)
|
||||
# magic-word override
|
||||
self.mwClientSleep = 0.
|
||||
|
||||
# Fill this in with a function to invoke when the user "exits"
|
||||
# the program by closing the main window.
|
||||
self.exitFunc = None
|
||||
@ -1106,6 +1110,12 @@ class ShowBase(DirectObject.DirectObject):
|
||||
# minimized, not just the main window. But it will do for
|
||||
# now until someone complains.
|
||||
time.sleep(0.1)
|
||||
else:
|
||||
# magic word overrides config
|
||||
if self.mwClientSleep:
|
||||
time.sleep(self.mwClientSleep)
|
||||
elif self.clientSleep:
|
||||
time.sleep(self.clientSleep)
|
||||
|
||||
# Lerp stuff needs this event, and it must be generated in
|
||||
# C++, not in Python.
|
||||
|
Loading…
x
Reference in New Issue
Block a user