Poodletooth-iLand/panda/direct/distributed/GridParent.py
2015-03-03 17:10:12 -05:00

101 lines
4 KiB
Python

from pandac.PandaModules import *
#
# GridParent.py
# Any object that can be parented to the ocean grid
# (or any grid whose size is too large to represent in 16 bits),
# should derive from GridParent. Can be used on client and AI code.
# GridParent will put a node inbetween the object and the grid so
# that the object is broadcasting its position relative to the gridCell
# it lies in.
class GridParent:
# this lets GridParents share CellOrigins
GridZone2CellOrigin = {}
GridZone2count = {}
@staticmethod
def getCellOrigin(grid, zoneId):
tup = (grid, zoneId)
if tup not in GridParent.GridZone2count:
GridParent.GridZone2count[tup] = 0
# For readability when debugging, append the zone to the name
GridParent.GridZone2CellOrigin[tup] = grid.attachNewNode("cellOrigin-%s" % zoneId)
# Get grid cell origin
cellPos = grid.getZoneCellOrigin(zoneId)
# Set the gridNode's position
GridParent.GridZone2CellOrigin[tup].setPos(*cellPos)
GridParent.GridZone2count[tup] += 1
return GridParent.GridZone2CellOrigin[tup]
@staticmethod
def releaseCellOrigin(grid, zoneId):
tup = (grid, zoneId)
GridParent.GridZone2count[tup] -= 1
if GridParent.GridZone2count[tup] == 0:
del GridParent.GridZone2count[tup]
GridParent.GridZone2CellOrigin[tup].removeNode()
del GridParent.GridZone2CellOrigin[tup]
def __init__(self, av):
# The object on the grid will need to broadcast his position relative to
# his current grid cell in order to use 16 bit
# telemetry. To do this, we will have a node attached to the
# grid cell origin, and the object will wrtReparent himself to it when
# crossing into that grid cell. We don't need to create a node for each
# cell origin. We just need two nodes: one that we are currently parented
# to, and the other that we will wrtReparentTo. Just before wrtReparenting
# to the new node, set it's position to the new grid cell origin.
self.av = av
self.grid = None
# NOTE: this node gets renamed when it is put on a zone, so if you
# are looking for it by name, try cellOrigin*.
self.ownCellOrigin = NodePath("cellOrigin")
self.cellOrigin = self.ownCellOrigin
def delete(self):
if self.av:
if self.av.getParent() == self.cellOrigin:
self.av.detachNode()
del self.av
self.av = None
# Remove the gridNodes
if self.ownCellOrigin is not None:
self.ownCellOrigin.removeNode()
self.ownCellOrigin = None
if self.grid is not None:
self.releaseCellOrigin(self.grid, self.zoneId)
self.grid = None
self.zoneId = None
def setGridParent(self, grid, zoneId, teleport=0):
# If teleport=0, preserve the avatar's absolute position. If teleport=1
# the avatars previous world position is invalid, so don't wrtReparent,
# just do a regular reparent, and let the cellOrigin give us our new position
# Also, if the avatar has no parent, then force teleport=1
if self.av.getParent().isEmpty():
teleport = 1
if not teleport:
# Stick the avatar under hidden while we move the cellOrigin into
# position so we do not lose the avatars absolute position.
self.av.wrtReparentTo(hidden)
if self.grid is not None:
self.releaseCellOrigin(self.grid, self.zoneId)
self.grid = grid
self.zoneId = zoneId
self.cellOrigin = self.getCellOrigin(self.grid, self.zoneId)
# Reparent our avatar to this node
if not teleport:
self.av.wrtReparentTo(self.cellOrigin)
else:
self.av.reparentTo(self.cellOrigin)
#print "gridParent: reparent to %s" % self.av
#print "gridParent: pos = %s, %s" % (self.av.getPos(), self.av.getParent().getPos())