merged ai-telemetry branch to trunk

This commit is contained in:
Darren Ranalli 2004-05-10 22:02:40 +00:00
parent 95f8fa1fb8
commit 330918c8f9
6 changed files with 315 additions and 60 deletions

View File

@ -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])

View File

@ -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).

View 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

View 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")

View File

@ -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'

View File

@ -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.