added VisibilityExtender

This commit is contained in:
Darren Ranalli 2003-11-08 23:19:29 +00:00
parent d588d7f477
commit c268773ab4
9 changed files with 122 additions and 38 deletions

View File

@ -330,7 +330,7 @@ class DistributedLevel(DistributedObject.DistributedObject,
def showZone(self, zoneNum):
zone = self.zoneNum2node[zoneNum]
zone.show()
zone.unstash()
zone.clearColor()
def setColorZones(self, fColorZones):
@ -339,10 +339,10 @@ class DistributedLevel(DistributedObject.DistributedObject,
def hideZone(self, zoneNum):
zone = self.zoneNum2node[zoneNum]
if self.fColorZones:
zone.show()
zone.unstash()
zone.setColor(1,0,0)
else:
zone.hide()
zone.stash()
def setTransparency(self, alpha, zone=None):
self.geom.setTransparency(1)
@ -418,10 +418,10 @@ class DistributedLevel(DistributedObject.DistributedObject,
zoneNum = self.curZoneNum
zoneEntId = self.zoneNum2entId[zoneNum]
zoneSpec = self.levelSpec.getEntitySpec(zoneEntId)
zoneEnt = self.getEntity(zoneEntId)
# use dicts to efficiently ensure that there are no duplicates
visibleZoneNums = list2dict([zoneNum])
visibleZoneNums.update(list2dict(zoneSpec['visibility']))
visibleZoneNums.update(list2dict(zoneEnt.getVisibleZoneNums()))
# we should not have the uberZone in the list at this point
assert not 0 in visibleZoneNums

View File

@ -83,27 +83,6 @@ class DistributedLevelAI(DistributedObjectAI.DistributedObjectAI,
Inheritors, override if desired."""
return EntityCreatorAI.EntityCreatorAI(level=self)
def getEntityZoneId(self, entId):
"""figure out what network zoneId an entity is in"""
# this func is called before the entity has been created; look
# into the spec data, since we can't yet get a handle on the
# object itself at this point
spec = self.levelSpec.getEntitySpec(entId)
type = spec['type']
if type == 'zone':
if not hasattr(self, 'zoneNum2zoneId'):
# we haven't even started creating our zone entities yet;
# we have no idea yet which zoneNums map to which
# network zoneIds. just return None.
return None
# If the entity *is* the zone, it will not yet be in the
# table; but since zone entities are currently not distributed,
# it's fine to return None.
return self.zoneNum2zoneId.get(spec['modelZoneNum'])
if not spec.has_key('parentEntId'):
return None
return self.getEntityZoneId(spec['parentEntId'])
if __debug__:
# level editors should call this func to tweak attributes of level
# entities

View File

@ -10,6 +10,7 @@ import LevelMgr
import ZoneEntity
import ModelEntity
import PathEntity
import VisibilityExtender
# some useful constructor functions
# ctor functions must take (level, entId)
@ -37,6 +38,7 @@ class EntityCreator(EntityCreatorBase.EntityCreatorBase):
'model' : ModelEntity.ModelEntity,
'nodepath': BasicEntities.NodePathEntity,
'path' : PathEntity.PathEntity,
'visibilityExtender': VisibilityExtender.VisibilityExtender,
'zone': ZoneEntity.ZoneEntity,
})

View File

@ -52,6 +52,7 @@ class EntityCreatorAI(EntityCreatorBase.EntityCreatorBase):
'model' : nothing,
'nodepath': nothing,
'path': nothing,
'visibilityExtender': nothing,
'zone': Functor(cLE, ZoneEntityAI.ZoneEntityAI),
})

View File

@ -10,6 +10,7 @@ class Entity(EntityTypeDesc):
('type', None),
('name', '<unnamed>', 'string'),
('comment', '', 'string'),
('parentEntId', 0, 'entId', {'type':'nodepath'}),
)
class LevelMgr(Entity):
@ -39,7 +40,6 @@ class EditMgr(Entity):
class Nodepath(Entity):
type = 'nodepath'
attribs = (
('parentEntId', 0, 'entId', {'type':'nodepath'}),
('pos', Point3(0,0,0), 'pos'),
('hpr', Vec3(0,0,0), 'hpr'),
)
@ -48,7 +48,6 @@ class Zone(Nodepath):
type = 'zone'
permanent = 1
delAttribs = (
'parentEntId',
'pos',
'hpr',
)
@ -101,4 +100,10 @@ class Path(Nodepath):
('scale', 1, 'pos'),
('pathIndex', 0, 'int'),
)
class VisibilityExtender(Entity):
type = 'visibilityExtender'
attribs = (
('event', None, 'entId', {'output':'bool'}),
('newZones', [], 'visZoneList'),
)

View File

@ -195,6 +195,8 @@ class Level:
entity.setAttribInit(key, value)
# entity is initialized, add it to the list of entities
# if this assert fails, check distributed entities to make sure
# they're calling down to Entity.destroy
assert not entId in self.entities
self.entities[entId] = entity
@ -214,8 +216,21 @@ class Level:
def getEntityZoneId(self, entId):
"""return network zoneId of zone that contains the entity"""
# this is called during entity creation on the AI; we have to
# handle this carefully, since the information required to
# produce a zoneId is not available until the level's zone
# entities have been instantiated.
zoneEntId = self.getEntityZoneEntId(entId)
return self.zoneEntId2zoneId[entId]
# fundamental entities (levelMgr) are responsible for creating
# tables like 'zoneEntId2zoneId'; if those tables haven't been
# created yet, just return None
if not hasattr(self, 'zoneNum2zoneId'):
return None
# this might return None if all of our zone entities haven't
# been created yet. this could be a problem if zone entities
# are ever distributed. it also means that no distributed entities
# should be created before the zone entities.
return self.zoneEntId2zoneId.get(zoneEntId)
def getZoneId(self, dummy=None, zoneNum=None, entId=None):
"""look up network zoneId by zoneNum or entId"""

View File

@ -111,9 +111,6 @@ class LevelSpec:
# if it's a zone, this is our entity
if type == 'zone':
return entId
# if we have no parentEntId, assume we're in the UberZone
if not spec.has_key('parentEntId'):
return LevelConstants.UberZoneEntId
# keep looking up the heirarchy for a zone entity
return self.getEntityZoneEntId(spec['parentEntId'])
@ -188,8 +185,7 @@ class LevelSpec:
for name, desc in attribDescs.items():
spec[name] = desc.getDefaultValue()
spec['type'] = entType
if 'parentEntId' in spec:
spec['parentEntId'] = parentEntId
spec['parentEntId'] = parentEntId
if self.hasLevel():
# notify the level

View File

@ -0,0 +1,59 @@
"""VisibilityExtender module: contains the VisibilityExtender class"""
import Entity
class VisibilityExtender(Entity.Entity):
def __init__(self, level, entId):
Entity.Entity.__init__(self, level, entId)
self.initVisExt()
def initVisExt(self):
self.extended = 0
self.zoneEntId = self.getZoneEntId()
self.eventName = 'switch-%s' % self.event
self.accept(self.eventName, self.handleEvent)
def destroyVisExt(self):
self.ignore(self.eventName)
if self.extended:
self.retract()
def handleEvent(self, doExtend):
if doExtend:
if not self.extended:
self.extend()
else:
if self.extended:
self.retract()
def extend(self):
"""extend the visibility list"""
assert not self.extended
zoneEnt = self.level.getEntity(self.getZoneEntId())
zoneEnt.incrementRefCounts(self.newZones)
self.extended = 1
self.level.handleVisChange()
def retract(self):
"""un-extend the visibility list"""
assert self.extended
zoneEnt = self.level.getEntity(self.getZoneEntId())
zoneEnt.decrementRefCounts(self.newZones)
self.extended = 0
self.level.handleVisChange()
def destroy(self):
self.destroyVisExt()
Entity.Entity.destroy(self)
if __debug__:
def setNewZones(self, newZones):
# we need to call destroyVisExt before accepting the new
# zone set
self.destroyVisExt()
self.newZones = newZones
self.initVisExt()
def attribChanged(self, *args):
self.destroyVisExt()
self.initVisExt()

View File

@ -10,13 +10,40 @@ class ZoneEntity(ZoneEntityBase.ZoneEntityBase, BasicEntities.NodePathAttribs):
self.nodePath = self.level.getZoneNode(self.modelZoneNum)
BasicEntities.NodePathAttribs.initNodePathAttribs(self, doReparent=0)
# dict of zoneNum to 'visible' reference count
self.visibleZoneNums = {}
# inc ref counts for the zones that are always visible from this zone
self.incrementRefCounts(self.visibility)
def destroy(self):
# no need to dec our reference counts
BasicEntities.NodePathAttribs.destroy(self)
ZoneEntityBase.ZoneEntityBase.destroy(self)
def getNodePath(self):
return self.nodePath
def setVisibility(self, visibility):
self.visibility = visibility
self.level.handleVisChange()
def getVisibleZoneNums(self):
return self.visibleZoneNums.keys()
# call these with lists of zoneNums to increment or decrement their
# 'visible' reference counts
# zone is visible as long as its ref count is nonzero
def incrementRefCounts(self, zoneNumList):
for zoneNum in zoneNumList:
self.visibleZoneNums.setdefault(zoneNum, 0)
self.visibleZoneNums[zoneNum] += 1
def decrementRefCounts(self, zoneNumList):
for zoneNum in zoneNumList:
self.visibleZoneNums[zoneNum] -= 1
if self.visibleZoneNums[zoneNum] == 0:
del self.visibleZoneNums[zoneNum]
if __debug__:
def setVisibility(self, visibility):
self.decrementRefCounts(self.visibility)
self.visibility = visibility
self.incrementRefCounts(self.visibility)
self.level.handleVisChange()