*** empty log message ***
This commit is contained in:
parent
37b59ed463
commit
33c8db149d
|
|
@ -19,6 +19,8 @@ import sys
|
|||
import whrandom
|
||||
import __builtin__
|
||||
|
||||
visualizeZones = base.config.GetBool("visualize-zones", 0)
|
||||
|
||||
# Colors used by all color menus
|
||||
DEFAULT_COLORS = [
|
||||
Vec4(1,1,1,1),
|
||||
|
|
@ -501,6 +503,10 @@ class LevelEditor(NodePath, PandaObject):
|
|||
base.cam.node().setNear(1.0)
|
||||
base.cam.node().setFar(3000)
|
||||
direct.camera.setPos(0,-10,10)
|
||||
# Initialize drive mode
|
||||
self.configureDriveModeCollisionData()
|
||||
# Init visibility variables
|
||||
self.__zoneId = None
|
||||
# Hide (disable) grid initially
|
||||
self.showGrid(0)
|
||||
# Create variable for vis groups panel
|
||||
|
|
@ -626,9 +632,10 @@ class LevelEditor(NodePath, PandaObject):
|
|||
# Destory old toplevel node path and DNA
|
||||
# First the toplevel DNA
|
||||
self.DNAData.remove(self.DNAToplevel)
|
||||
# Then the toplevel Node Path
|
||||
self.NPToplevel.reparentTo(hidden)
|
||||
self.NPToplevel.removeNode()
|
||||
if self.NPToplevel.hasArcs():
|
||||
# Then the toplevel Node Path
|
||||
self.NPToplevel.reparentTo(hidden)
|
||||
self.NPToplevel.removeNode()
|
||||
|
||||
def createToplevel(self, dnaNode, nodePath = None):
|
||||
# When you create a new level, data is added to this node
|
||||
|
|
@ -659,6 +666,16 @@ class LevelEditor(NodePath, PandaObject):
|
|||
|
||||
def useDirectFly(self):
|
||||
""" Disable player camera controls/enable direct camera control """
|
||||
# Turn off collision traversal
|
||||
self.traversalOff()
|
||||
# Turn on collisions
|
||||
self.collisionsOff()
|
||||
# Turn on visiblity
|
||||
self.visibilityOff()
|
||||
# Reset cam
|
||||
base.camera.iPos(base.cam)
|
||||
base.cam.iPosHpr()
|
||||
# Renable mouse
|
||||
self.enableMouse()
|
||||
direct.enable()
|
||||
|
||||
|
|
@ -677,10 +694,17 @@ class LevelEditor(NodePath, PandaObject):
|
|||
""" Disable direct camera manipulation and enable player drive mode """
|
||||
direct.minimumConfiguration()
|
||||
direct.manipulationControl.disableManipulation()
|
||||
# Update vis data
|
||||
self.initVisibilityData()
|
||||
# Switch to drive mode
|
||||
base.useDrive()
|
||||
# Move cam up and back
|
||||
base.cam.setPos(0,-5,4)
|
||||
# And move down and forward to compensate
|
||||
base.camera.setPos(base.camera, 0, 5, -4)
|
||||
# Make sure we're where we want to be
|
||||
pos = direct.camera.getPos()
|
||||
pos.setZ(4.0)
|
||||
pos.setZ(0.0)
|
||||
hpr = direct.camera.getHpr()
|
||||
hpr.set(hpr[0], 0.0, 0.0)
|
||||
# Fine tune the drive mode
|
||||
|
|
@ -688,7 +712,232 @@ class LevelEditor(NodePath, PandaObject):
|
|||
base.mouseInterface.node().setHpr(hpr)
|
||||
base.mouseInterface.node().setForwardSpeed(20.0)
|
||||
base.mouseInterface.node().setReverseSpeed(20.0)
|
||||
# Turn on collisions
|
||||
if self.panel.fColl.get():
|
||||
self.collisionsOn()
|
||||
# Turn on visiblity
|
||||
if self.panel.fVis.get():
|
||||
self.visibilityOn()
|
||||
# Turn on collision traversal
|
||||
if self.panel.fColl.get() or self.panel.fVis.get():
|
||||
self.traversalOn()
|
||||
|
||||
def configureDriveModeCollisionData(self):
|
||||
"""initializeCollisions(self)
|
||||
Set up the local avatar for collisions
|
||||
"""
|
||||
# Set up the collision sphere
|
||||
# This is a sphere on the ground to detect barrier collisions
|
||||
self.cSphere = CollisionSphere(0.0, 0.0, 0.0, 1.5)
|
||||
self.cSphereNode = CollisionNode('cSphereNode')
|
||||
self.cSphereNode.addSolid(self.cSphere)
|
||||
self.cSphereNodePath = camera.attachNewNode(self.cSphereNode)
|
||||
self.cSphereNodePath.hide()
|
||||
self.cSphereBitMask = BitMask32.bit(0)
|
||||
self.cSphereNode.setFromCollideMask(self.cSphereBitMask)
|
||||
self.cSphereNode.setIntoCollideMask(BitMask32.allOff())
|
||||
|
||||
# Set up the collison ray
|
||||
# This is a ray cast from your head down to detect floor polygons
|
||||
self.cRay = CollisionRay(0.0, 0.0, 6.0, 0.0, 0.0, -1.0)
|
||||
self.cRayNode = CollisionNode('cRayNode')
|
||||
self.cRayNode.addSolid(self.cRay)
|
||||
self.cRayNodePath = camera.attachNewNode(self.cRayNode)
|
||||
self.cRayNodePath.hide()
|
||||
self.cRayBitMask = BitMask32.bit(1)
|
||||
self.cRayNode.setFromCollideMask(self.cRayBitMask)
|
||||
self.cRayNode.setIntoCollideMask(BitMask32.allOff())
|
||||
|
||||
# set up wall collision mechanism
|
||||
self.pusher = CollisionHandlerPusher()
|
||||
self.pusher.setInPattern("enter%in")
|
||||
self.pusher.setOutPattern("exit%in")
|
||||
|
||||
# set up floor collision mechanism
|
||||
self.lifter = CollisionHandlerFloor()
|
||||
self.lifter.setInPattern("on-floor")
|
||||
self.lifter.setOutPattern("off-floor")
|
||||
self.floorOffset = 0.1
|
||||
self.lifter.setOffset(self.floorOffset)
|
||||
|
||||
# Limit our rate-of-fall with the lifter.
|
||||
# If this is too low, we actually "fall" off steep stairs
|
||||
# and float above them as we go down. I increased this
|
||||
# from 8.0 to 16.0 to prevent this
|
||||
self.lifter.setMaxVelocity(16.0)
|
||||
|
||||
# set up the collision traverser
|
||||
self.cTrav = CollisionTraverser()
|
||||
|
||||
# activate the collider with the traverser and pusher
|
||||
self.pusher.addCollider(self.cSphereNode, base.drive.node())
|
||||
self.lifter.addCollider(self.cRayNode, base.drive.node())
|
||||
# A map of zone ID's to a list of nodes that are visible from
|
||||
# that zone.
|
||||
self.nodeDict = {}
|
||||
# A map of zone ID's to the particular node that corresponds
|
||||
# to that zone.
|
||||
self.zoneDict = {}
|
||||
# A list of all visible nodes
|
||||
self.nodeList = []
|
||||
# Flag for bootstrapping visibility
|
||||
self.fVisInit = 0
|
||||
|
||||
def traversalOn(self):
|
||||
base.cTrav = self.cTrav
|
||||
|
||||
def traversalOff(self):
|
||||
base.cTrav = 0
|
||||
|
||||
def collisionsOff(self):
|
||||
self.cTrav.removeCollider(self.cSphereNode)
|
||||
|
||||
def collisionsOn(self):
|
||||
self.collisionsOff()
|
||||
self.cTrav.addCollider(self.cSphereNode, self.pusher)
|
||||
|
||||
def toggleCollisions(self):
|
||||
if self.panel.fColl.get():
|
||||
print 'ON'
|
||||
self.collisionsOn()
|
||||
self.traversalOn()
|
||||
else:
|
||||
self.collisionsOff()
|
||||
if (not (self.panel.fColl.get() or self.panel.fVis.get())):
|
||||
self.traversalOff()
|
||||
|
||||
def initVisibilityData(self):
|
||||
# First make sure everything is shown
|
||||
self.showAllVisibles()
|
||||
# A map of zone ID's to a list of nodes that are visible from
|
||||
# that zone.
|
||||
self.nodeDict = {}
|
||||
# A map of zone ID's to the particular node that corresponds
|
||||
# to that zone.
|
||||
self.zoneDict = {}
|
||||
# A list of all visible nodes
|
||||
self.nodeList = []
|
||||
# NOTE: this should change to find the groupnodes in
|
||||
# the dna storage instead of searching through the tree
|
||||
for i in range(DNASTORE.getNumDNAVisGroups()):
|
||||
groupFullName = DNASTORE.getDNAVisGroupName(i)
|
||||
groupName = self.extractGroupName(groupFullName)
|
||||
zoneId = int(groupName)
|
||||
self.nodeDict[zoneId] = []
|
||||
self.zoneDict[zoneId] = self.NPToplevel.find("**/" + groupName)
|
||||
|
||||
# TODO: we only need to look from the top of the hood
|
||||
# down one level to find the vis groups as an optimization
|
||||
groupNode = self.NPToplevel.find("**/" + groupFullName)
|
||||
if groupNode.isEmpty():
|
||||
print "Could not find visgroup"
|
||||
self.nodeList.append(groupNode)
|
||||
for j in range(DNASTORE.getNumVisiblesInDNAVisGroup(i)):
|
||||
visName = DNASTORE.getVisibleName(i, j)
|
||||
visNode = self.NPToplevel.find("**/" + visName)
|
||||
self.nodeDict[zoneId].append(visNode)
|
||||
# Rename the floor polys to have the same name as the
|
||||
# visgroup they are in... This makes visibility possible.
|
||||
self.renameFloorPolys(self.nodeList)
|
||||
# Init vis flag
|
||||
self.fVisInit = 1
|
||||
|
||||
def extractGroupName(self, groupFullName):
|
||||
# The Idea here is that group names may have extra flags associated
|
||||
# with them that tell more information about what is special about
|
||||
# the particular vis zone. A normal vis zone might just be "13001",
|
||||
# but a special one might be "14356:safe_zone" or
|
||||
# "345:safe_zone:exit_zone"... These are hypotheticals. The main
|
||||
# idea is that there are colon separated flags after the initial
|
||||
# zone name.
|
||||
return(string.split(groupFullName, ":", 1)[0])
|
||||
|
||||
def renameFloorPolys(self, nodeList):
|
||||
for i in nodeList:
|
||||
# Get all the collision nodes in the vis group
|
||||
collNodePaths = i.findAllMatches("**/+CollisionNode")
|
||||
numCollNodePaths = collNodePaths.getNumPaths()
|
||||
visGroupName = i.node().getName()
|
||||
for j in range(numCollNodePaths):
|
||||
collNodePath = collNodePaths.getPath(j)
|
||||
bitMask = collNodePath.node().getIntoCollideMask()
|
||||
if bitMask.getBit(1):
|
||||
# Bit 1 is the floor collision bit. This renames
|
||||
# all floor collision polys to the same name as their
|
||||
# visgroup.
|
||||
collNodePath.node().setName(visGroupName)
|
||||
|
||||
def hideAllVisibles(self):
|
||||
for i in self.nodeList:
|
||||
i.hide()
|
||||
|
||||
def showAllVisibles(self):
|
||||
for i in self.nodeList:
|
||||
i.show()
|
||||
|
||||
def visibilityOn(self):
|
||||
self.visibilityOff()
|
||||
# Accept event
|
||||
self.accept("on-floor", self.enterZone)
|
||||
# Add collider
|
||||
self.cTrav.addCollider(self.cRayNode, self.lifter)
|
||||
# Reset lifter
|
||||
self.lifter.clear()
|
||||
# Reset flag
|
||||
self.fVisInit = 1
|
||||
|
||||
def visibilityOff(self):
|
||||
self.ignore("on-floor")
|
||||
self.cTrav.removeCollider(self.cRayNode)
|
||||
self.showAllVisibles()
|
||||
|
||||
def toggleVisibility(self):
|
||||
if self.panel.fVis.get():
|
||||
self.visibilityOn()
|
||||
self.traversalOn()
|
||||
else:
|
||||
self.visibilityOff()
|
||||
if (not (self.panel.fColl.get() or self.panel.fVis.get())):
|
||||
self.traversalOff()
|
||||
|
||||
def enterZone(self, newZone):
|
||||
"""
|
||||
Puts the toon in the indicated zone. newZone may either be a
|
||||
CollisionEntry object as determined by a floor polygon, or an
|
||||
integer zone id. It may also be None, to indicate no zone.
|
||||
"""
|
||||
# First entry into a zone, hide everything
|
||||
if self.fVisInit:
|
||||
self.hideAllVisibles()
|
||||
self.fVisInit = 0
|
||||
# Get zone id
|
||||
if isinstance(newZone, CollisionEntry):
|
||||
# Get the name of the collide node
|
||||
newZoneId = int(newZone.getIntoNode().getName())
|
||||
else:
|
||||
newZoneId = newZone
|
||||
# Ensure we have vis data
|
||||
assert(self.nodeDict)
|
||||
# Hide the old zone (if there is one)
|
||||
if self.__zoneId != None:
|
||||
for i in self.nodeDict[self.__zoneId]:
|
||||
i.hide()
|
||||
# Show the new zone
|
||||
if newZoneId != None:
|
||||
for i in self.nodeDict[newZoneId]:
|
||||
i.show()
|
||||
# Make sure we changed zones
|
||||
if newZoneId != self.__zoneId:
|
||||
if visualizeZones:
|
||||
# Set a color override on our zone to make it obvious what
|
||||
# zone we're in.
|
||||
if self.__zoneId != None:
|
||||
self.zoneDict[self.__zoneId].clearColor()
|
||||
if newZoneId != None:
|
||||
self.zoneDict[newZoneId].setColor(0, 0, 1, 1, 100)
|
||||
# The new zone is now old
|
||||
self.__zoneId = newZoneId
|
||||
|
||||
def enableMouse(self):
|
||||
""" Enable Pie Menu interaction (and disable player camera control) """
|
||||
# Turn off player camera control
|
||||
|
|
@ -4463,13 +4712,6 @@ class LevelEditorPanel(Pmw.MegaToplevel):
|
|||
buttonFrame4 = Frame(hull)
|
||||
self.driveMode = IntVar()
|
||||
self.driveMode.set(1)
|
||||
self.driveModeButton = Radiobutton(
|
||||
buttonFrame4,
|
||||
text = 'Drive Mode',
|
||||
value = 0,
|
||||
variable = self.driveMode,
|
||||
command = self.levelEditor.useDriveMode)
|
||||
self.driveModeButton.pack(side = LEFT, fill = X, expand = 1)
|
||||
self.directModeButton = Radiobutton(
|
||||
buttonFrame4,
|
||||
text = 'DIRECT Fly',
|
||||
|
|
@ -4477,7 +4719,35 @@ class LevelEditorPanel(Pmw.MegaToplevel):
|
|||
variable = self.driveMode,
|
||||
command = self.levelEditor.useDirectFly)
|
||||
self.directModeButton.pack(side = LEFT, fill = X, expand = 1)
|
||||
buttonFrame4.pack(fill = X, padx = 60)
|
||||
self.driveModeButton = Radiobutton(
|
||||
buttonFrame4,
|
||||
text = 'Drive Mode',
|
||||
value = 0,
|
||||
variable = self.driveMode,
|
||||
command = self.levelEditor.useDriveMode)
|
||||
self.driveModeButton.pack(side = LEFT, fill = X, expand = 1)
|
||||
|
||||
self.fColl = IntVar()
|
||||
self.fColl.set(1)
|
||||
direct.collButton = Checkbutton(
|
||||
buttonFrame4,
|
||||
text = 'Collide',
|
||||
width = 6,
|
||||
variable = self.fColl,
|
||||
command = self.levelEditor.toggleCollisions)
|
||||
direct.collButton.pack(side = LEFT, expand = 1, fill = X)
|
||||
|
||||
self.fVis = IntVar()
|
||||
self.fVis.set(1)
|
||||
direct.visButton = Checkbutton(
|
||||
buttonFrame4,
|
||||
text = 'Visibility',
|
||||
width = 6,
|
||||
variable = self.fVis,
|
||||
command = self.levelEditor.toggleVisibility)
|
||||
direct.visButton.pack(side = LEFT, expand = 1, fill = X)
|
||||
|
||||
buttonFrame4.pack(fill = X, padx = 15)
|
||||
|
||||
# Make sure input variables processed
|
||||
self.initialiseoptions(LevelEditorPanel)
|
||||
|
|
|
|||
Loading…
Reference in New Issue