diff --git a/direct/src/directutil/DirectManipulation.py b/direct/src/directutil/DirectManipulation.py index 67ecef49ae..09b5a53b18 100644 --- a/direct/src/directutil/DirectManipulation.py +++ b/direct/src/directutil/DirectManipulation.py @@ -29,31 +29,17 @@ class DirectManipulationControl(PandaObject): def manipulationStart(self, chan): # Start out in select mode self.mode = 'select' - # Check for a widget hit point numEntries = self.direct.iRay.pickWidget( render,chan.mouseX,chan.mouseY) # Did we hit a widget? if(numEntries): # Yes! - - # Find the closest hit point if multiple hits - # Start off with first point + # Entry 0 is the closest hit point if multiple hits minPt = 0 # Find hit point in camera's space self.hitPt = self.direct.iRay.camToHitPt(minPt) self.hitPtDist = Vec3(self.hitPt - ZERO_POINT).length() - # Check other intersection points, sorting them - # TBD: Use TBS C++ function to do this - if numEntries > 1: - for i in range(1,numEntries): - hitPt = self.direct.iRay.camToHitPt(i) - dist = Vec3(hitPt - ZERO_POINT).length() - if (dist < self.hitPtDist): - self.hitPtDist = dist - self.hitPt = hitPt - minPt = i - # Get the associated collision queue object entry = self.direct.iRay.cq.getEntry(minPt) # Extract the node @@ -63,7 +49,6 @@ class DirectManipulationControl(PandaObject): else: # Nope, off the widget, no constraint self.constraint = None - # Check to see if we are moving the object # We are moving the object if we either wait long enough """ @@ -73,7 +58,6 @@ class DirectManipulationControl(PandaObject): 'manip-switch-to-move'), 'manip-move-wait') """ - # Or if we move far enough self.moveDir = None watchMouseTask = Task.Task(self.watchMouseTask) @@ -108,45 +92,31 @@ class DirectManipulationControl(PandaObject): # Check for object under mouse numEntries = self.direct.iRay.pickGeom( render,self.chan.mouseX,self.chan.mouseY) - # Filter out widgets from entry list - indexList = [] + # Pick out the closest object that isn't a widget + index = -1 for i in range(0,numEntries): entry = self.direct.iRay.cq.getEntry(i) node = entry.getIntoNode() if node.isHidden(): pass # Is it a named node?, If so, see if it has a name - if issubclass(node.__class__, NamedNode): + elif issubclass(node.__class__, NamedNode): name = node.getName() - if name not in VISIBLE_DISCS: - indexList.append(i) + if name in VISIBLE_DISCS: + pass + else: + index = i + break else: - # Not one of the widgets, use it - indexList.append(i) + # Not hidden and not one of the widgets, use it + index = i # Did we hit an object? - if(indexList): + if(index >= 0): # Yes! - # Find the closest hit point if multiple hits - # Start off with first point - minPt = indexList[0] # Find hit point in camera's space - self.hitPt = self.direct.iRay.camToHitPt(minPt) + self.hitPt = self.direct.iRay.camToHitPt(index) self.hitPtDist = Vec3(self.hitPt - ZERO_POINT).length() - # Check other intersection points, sorting them - # TBD: Use TBS C++ function to do this - if len(indexList) > 1: - for i in range(1,len(indexList)): - entryNum = indexList[i] - hitPt = self.direct.iRay.camToHitPt(entryNum) - dist = Vec3(hitPt - ZERO_POINT).length() - if (dist < self.hitPtDist): - self.hitPtDist = dist - self.hitPt = hitPt - minPt = entryNum - # Get the associated collision queue object - entry = self.direct.iRay.cq.getEntry(minPt) - # Extract the node - node = entry.getIntoNode() + # Find the node path from the node found above nodePath = render.findPathDownTo(node) # Select it self.direct.select(nodePath) diff --git a/direct/src/directutil/DirectSelection.py b/direct/src/directutil/DirectSelection.py index f95fa93f0b..0a73e86122 100644 --- a/direct/src/directutil/DirectSelection.py +++ b/direct/src/directutil/DirectSelection.py @@ -353,6 +353,7 @@ class SelectionRay: self.ray.setProjection( base.cam.node(), mouseX, mouseY ) self.ct.traverse( targetNodePath.node() ) self.numEntries = self.cq.getNumEntries() + self.cq.sortEntries() return self.numEntries def collideWithGeom(self): diff --git a/direct/src/leveleditor/LevelEditor.py b/direct/src/leveleditor/LevelEditor.py index 3b28f46ead..d05c40db2c 100644 --- a/direct/src/leveleditor/LevelEditor.py +++ b/direct/src/leveleditor/LevelEditor.py @@ -16,7 +16,7 @@ import string class LevelEditor(NodePath, PandaObject): - def __init__(self,direct): + def __init__(self,direct,parent = None): # Initialize superclass NodePath.__init__(self) self.assign(hidden.attachNewNode( NamedNode('LevelEditor'))) @@ -119,7 +119,7 @@ class LevelEditor(NodePath, PandaObject): # Default is to use the toontown central color palette self.editToontownCentral() - self.panel = LevelEditorPanel(self) + self.panel = LevelEditorPanel(self, parent) self.enable() @@ -373,7 +373,6 @@ class LevelEditor(NodePath, PandaObject): self.grid.ignore('insert') self.ignore('selectedNodePath') self.ignore('preRemoveNodePath') - #self.ignore('preSelectNodePath') self.ignore('toggleMapViz') self.ignore('reparentNodePath') self.ignore('createNewLevelGroup') @@ -460,8 +459,9 @@ class LevelEditor(NodePath, PandaObject): self.accept('createNewLevelGroup', self.createNewLevelGroup) self.accept('setNodePathName', self.setNodePathName) self.accept('manipulateObjectCleanup', self.updateSelectedPose) - self.accept('SGESelectNodePath', self.selectNodePath) - self.accept('SGEFlashNodePath', self.preSelectNodePath) + #self.accept('SGESelectNodePath', self.selectNodePath) + self.accept('SGESelectNodePath', self.flashNodePath) + self.accept('SGEFlashNodePath', self.flashNodePath) self.accept('SGEIsolateNodePath', self.isolateNodePath) self.accept('SGEToggle VizNodePath', self.toggleNodePathViz) self.accept('SGESet ParentNodePath', self.setGroupParent) @@ -796,28 +796,31 @@ class LevelEditor(NodePath, PandaObject): if self.activeMenu: self.activeMenu.removePieMenuTask() - def preSelectNodePath(self, aNodePath): - taskMgr.removeTasksNamed('preselectNodePath') - t = Task.Task(self.preSelectNodePathTask) + def flashNodePath(self, aNodePath): + taskMgr.removeTasksNamed('flashNodePath') + t = Task.Task(self.flashNodePathTask) t.aNodePath = aNodePath t.initState = t.hidden = aNodePath.isHidden() - t.count = 0 + t.flashCount = 0 + t.frameCount = 0 t.uponDeath = self.preSelectDone - taskMgr.spawnTaskNamed(t, 'preselectNodePath') + taskMgr.spawnTaskNamed(t, 'flashNodePath') - def preSelectNodePathTask(self, state): + def flashNodePathTask(self, state): aNodePath = state.aNodePath initState = state.initState hidden = state.hidden - count = state.count - if (state.count < 21): - if (state.count % 5) == 0: + flashCount = state.flashCount + frameCount = state.frameCount + if (flashCount < 4): + if (frameCount % 3) == 0: if hidden: aNodePath.show() else: aNodePath.hide() state.hidden = not state.hidden - state.count = count + 1 + state.flashCount = flashCount + 1 + state.frameCount = frameCount + 1 return Task.cont else: return Task.done @@ -923,7 +926,12 @@ class LevelEditor(NodePath, PandaObject): self.levelMap.reparentTo(hidden) def toggleNodePathViz(self, aNodePath): - pass + # First kill the flashing task + taskMgr.removeTasksNamed('flashNodePath') + if aNodePath.isHidden(): + aNodePath.show() + else: + aNodePath.hide() def setXyzSnap(self, flag): self.grid.setXyzSnap(flag) @@ -2203,7 +2211,7 @@ class LevelEditor(NodePath, PandaObject): self.loadDNAFromFile(dnaFilename) def saveToSpecifiedDNAFile(self): - path = os.path.expandvars('$DIRECT\\etc\\') + path = os.path.join(os.path.expandvars('$DIRECT'), 'etc') if not os.path.isdir(path): print 'LevelEditor Warning: Invalid DNA save directory!' print 'Using: C:\\' @@ -2273,7 +2281,8 @@ class LevelEditor(NodePath, PandaObject): self.createNewLevelGroup() def outputDNADefaultFile(self): - file = os.path.expandvars('$DIRECT\\etc\\' + self.dnaOutputFile) + file = os.path.join(os.path.expandvars('$DIRECT'),'etc', + self.dnaOutputFile) self.outputDNA(file) def outputDNA(self,filename):