added VisibilityExtender
This commit is contained in:
parent
d588d7f477
commit
c268773ab4
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ class EntityCreatorAI(EntityCreatorBase.EntityCreatorBase):
|
|||
'model' : nothing,
|
||||
'nodepath': nothing,
|
||||
'path': nothing,
|
||||
'visibilityExtender': nothing,
|
||||
'zone': Functor(cLE, ZoneEntityAI.ZoneEntityAI),
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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"""
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue