Removed default bitmask from persp coll plane

This commit is contained in:
Gyedo Jeon 2010-05-18 01:09:31 +00:00
parent a617a5cb97
commit 385f6e5920
3 changed files with 401 additions and 375 deletions

View File

@ -1,367 +1,394 @@
""" """
Base class for Level Editor Base class for Level Editor
You should write your own LevelEditor class inheriting this. You should write your own LevelEditor class inheriting this.
Refer LevelEditor.py for example. Refer LevelEditor.py for example.
""" """
from direct.showbase.DirectObject import * from direct.showbase.DirectObject import *
from direct.directtools.DirectUtil import * from direct.directtools.DirectUtil import *
from direct.gui.DirectGui import * from direct.gui.DirectGui import *
from FileMgr import * from FileMgr import *
from ActionMgr import * from ActionMgr import *
from MayaConverter import * from MayaConverter import *
class LevelEditorBase(DirectObject): class LevelEditorBase(DirectObject):
""" Base Class for Panda3D LevelEditor """ """ Base Class for Panda3D LevelEditor """
def __init__(self): def __init__(self):
#loadPrcFileData('startup', 'window-type none') #loadPrcFileData('startup', 'window-type none')
self.currentFile = None self.currentFile = None
self.fNeedToSave = False self.fNeedToSave = False
self.actionEvents = [] self.actionEvents = []
#self.objectMgr = ObjectMgr(self) #self.objectMgr = ObjectMgr(self)
self.fileMgr = FileMgr(self) self.fileMgr = FileMgr(self)
self.actionMgr = ActionMgr() self.actionMgr = ActionMgr()
self.NPParent = render self.fMoveCamera = False
# define your own config file in inherited class self.NPParent = render
self.settingsFile = None
# define your own config file in inherited class
# you can show/hide specific properties by using propertiesMask and this mode self.settingsFile = None
self.mode = BitMask32()
# you can show/hide specific properties by using propertiesMask and this mode
def initialize(self): self.mode = BitMask32()
""" You should call this in your __init__ method of inherited LevelEditor class """
# specifiy what obj can be 'selected' as objects def initialize(self):
base.direct.selected.addTag('OBJRoot') """ You should call this in your __init__ method of inherited LevelEditor class """
# specifiy what obj can be 'selected' as objects
self.actionEvents.extend([ base.direct.selected.addTag('OBJRoot')
# Node path events
('DIRECT-select', self.select), self.actionEvents.extend([
('DIRECT-delete', self.handleDelete), # Node path events
('DIRECT-preDeselectAll', self.deselectAll), ('DIRECT-select', self.select),
('DIRECT_deselectAll', self.deselectAllCB), ('DIRECT-delete', self.handleDelete),
('preRemoveNodePath', self.removeNodePathHook), ('DIRECT-preDeselectAll', self.deselectAll),
('DIRECT_deselectedNodePath', self.deselectAllCB), ('DIRECT_deselectAll', self.deselectAllCB),
('DIRECT_selectedNodePath_fMulti_fTag_fLEPane', self.selectedNodePathHook), ('preRemoveNodePath', self.removeNodePathHook),
('DIRECT_deselectAll', self.deselectAll), ('DIRECT_deselectedNodePath', self.deselectAllCB),
('LE-Undo', self.actionMgr.undo), ('DIRECT_selectedNodePath_fMulti_fTag_fLEPane', self.selectedNodePathHook),
('LE-Redo', self.actionMgr.redo), ('DIRECT_deselectAll', self.deselectAll),
('LE-Duplicate', self.objectMgr.duplicateSelected), ('LE-Undo', self.actionMgr.undo),
('DIRECT_manipulateObjectCleanup', self.cleanUpManipulating), ('LE-Redo', self.actionMgr.redo),
('LE-MakeLive', self.objectMgr.makeSelectedLive), ('LE-Duplicate', self.objectMgr.duplicateSelected),
('LE-NewScene', self.ui.onNew), ('DIRECT_manipulateObjectCleanup', self.cleanUpManipulating),
('LE-SaveScene', self.ui.onSave), ('LE-MakeLive', self.objectMgr.makeSelectedLive),
('LE-OpenScene', self.ui.onOpen), ('LE-NewScene', self.ui.onNew),
('LE-Quit', self.ui.quit), ('LE-SaveScene', self.ui.onSave),
('DIRECT-mouse3', self.handleMouse3), ('LE-OpenScene', self.ui.onOpen),
('DIRECT-toggleWidgetVis', self.toggleWidget), ('LE-Quit', self.ui.quit),
]) ('DIRECT-mouse1', self.handleMouse1),
('DIRECT-mouse1Up', self.handleMouse1Up),
# Add all the action events ('DIRECT-mouse2', self.handleMouse2),
for event in self.actionEvents: ('DIRECT-mouse2Up', self.handleMouse2Up),
if len(event) == 3: ('DIRECT-mouse3', self.handleMouse3),
self.accept(event[0], event[1], event[2]) ('DIRECT-mouse3Up', self.handleMouse3Up),
else: ('DIRECT-toggleWidgetVis', self.toggleWidget),
self.accept(event[0], event[1]) ])
# editor state text display such as edit mode # Add all the action events
self.statusReadout = OnscreenText( for event in self.actionEvents:
pos = (-1.2, 0.9), bg=Vec4(1,1,1,1), if len(event) == 3:
scale = 0.05, align = TextNode.ALeft, self.accept(event[0], event[1], event[2])
mayChange = 1, font = TextNode.getDefaultFont()) else:
self.statusReadout.setText("") self.accept(event[0], event[1])
# Make sure readout is never lit or drawn in wireframe
useDirectRenderStyle(self.statusReadout) # editor state text display such as edit mode
self.statusReadout.reparentTo(hidden) self.statusReadout = OnscreenText(
self.statusLines = [] pos = (-1.2, 0.9), bg=Vec4(1,1,1,1),
taskMgr.doMethodLater(5, self.updateStatusReadoutTimeouts, 'updateStatus') scale = 0.05, align = TextNode.ALeft,
mayChange = 1, font = TextNode.getDefaultFont())
self.loadSettings() self.statusReadout.setText("")
self.reset() # Make sure readout is never lit or drawn in wireframe
useDirectRenderStyle(self.statusReadout)
def setTitleWithFilename(self, filename=""): self.statusReadout.reparentTo(hidden)
title = self.ui.appname self.statusLines = []
if filename != "": taskMgr.doMethodLater(5, self.updateStatusReadoutTimeouts, 'updateStatus')
filenameshort = os.path.basename(filename)
title = title + " (%s)"%filenameshort self.loadSettings()
self.ui.SetLabel(title) self.reset()
def removeNodePathHook(self, nodePath): def setTitleWithFilename(self, filename=""):
if nodePath is None: title = self.ui.appname
return if filename != "":
base.direct.deselect(nodePath) filenameshort = os.path.basename(filename)
self.objectMgr.removeObjectByNodePath(nodePath) title = title + " (%s)"%filenameshort
self.ui.SetLabel(title)
if (base.direct.selected.last != None and nodePath.compareTo(base.direct.selected.last)==0):
# if base.direct.selected.last is refering to this def removeNodePathHook(self, nodePath):
# removed obj, clear the reference if nodePath is None:
if (hasattr(__builtins__,'last')): return
__builtins__.last = None base.direct.deselect(nodePath)
else: self.objectMgr.removeObjectByNodePath(nodePath)
__builtins__['last'] = None
base.direct.selected.last = None if (base.direct.selected.last != None and nodePath.compareTo(base.direct.selected.last)==0):
# if base.direct.selected.last is refering to this
def toggleWidget(self): # removed obj, clear the reference
if self.objectMgr.currNodePath: if (hasattr(__builtins__,'last')):
obj = self.objectMgr.findObjectByNodePath(self.objectMgr.currNodePath) __builtins__.last = None
if obj and not obj[OG.OBJ_DEF].movable: else:
return __builtins__['last'] = None
base.direct.toggleWidgetVis() base.direct.selected.last = None
def handleMouse3(self, modifiers): def toggleWidget(self):
if base.direct.fAlt or modifiers == 4: if self.objectMgr.currNodePath:
return obj = self.objectMgr.findObjectByNodePath(self.objectMgr.currNodePath)
if obj and not obj[OG.OBJ_DEF].movable:
self.ui.onRightDown() return
base.direct.toggleWidgetVis()
def handleDelete(self):
oldSelectedNPs = base.direct.selected.getSelectedAsList() def handleMouse1(self, modifiers):
oldUIDs = [] if base.direct.fAlt or modifiers == 4:
for oldNP in oldSelectedNPs: self.fMoveCamera = True
obj = self.objectMgr.findObjectByNodePath(oldNP) return
if obj:
oldUIDs.append(obj[OG.OBJ_UID]) def handleMouse1Up(self):
self.fMoveCamera = False
action = ActionDeleteObj(self)
self.actionMgr.push(action) def handleMouse2(self, modifiers):
action() if base.direct.fAlt or modifiers == 4:
self.fMoveCamera = True
for uid in oldUIDs: return
self.ui.sceneGraphUI.delete(uid)
def handleMouse2Up(self):
## reply = wx.MessageBox("Do you want to delete selected?", "Delete?", self.fMoveCamera = False
## wx.YES_NO | wx.ICON_QUESTION)
## if reply == wx.YES: def handleMouse3(self, modifiers):
## base.direct.removeAllSelected() if base.direct.fAlt or modifiers == 4:
## else: self.fMoveCamera = True
## # need to reset COA return
## dnp = base.direct.selected.last
## # Update camera controls coa to this point self.ui.onRightDown()
## # Coa2Camera = Coa2Dnp * Dnp2Camera
## mCoa2Camera = dnp.mCoa2Dnp * dnp.getMat(base.direct.camera) def handleMouse3Up(self):
## row = mCoa2Camera.getRow(3) self.fMoveCamera = False
## coa = Vec3(row[0], row[1], row[2])
## base.direct.cameraControl.updateCoa(coa) def handleDelete(self):
oldSelectedNPs = base.direct.selected.getSelectedAsList()
def cleanUpManipulating(self, selectedNPs): oldUIDs = []
for np in selectedNPs: for oldNP in oldSelectedNPs:
obj = self.objectMgr.findObjectByNodePath(np) obj = self.objectMgr.findObjectByNodePath(oldNP)
if obj: if obj:
action = ActionTransformObj(self, obj[OG.OBJ_UID], Mat4(np.getMat())) oldUIDs.append(obj[OG.OBJ_UID])
self.actionMgr.push(action)
action() action = ActionDeleteObj(self)
self.actionMgr.push(action)
def select(self, nodePath, fMultiSelect=0, fSelectTag=1, fResetAncestry=1, fLEPane=0, fUndo=1): action()
if fUndo:
# Select tagged object if present for uid in oldUIDs:
if fSelectTag: self.ui.sceneGraphUI.delete(uid)
for tag in base.direct.selected.tagList:
if nodePath.hasNetTag(tag): ## reply = wx.MessageBox("Do you want to delete selected?", "Delete?",
nodePath = nodePath.findNetTag(tag) ## wx.YES_NO | wx.ICON_QUESTION)
break ## if reply == wx.YES:
action = ActionSelectObj(self, nodePath, fMultiSelect) ## base.direct.removeAllSelected()
self.actionMgr.push(action) ## else:
action() ## # need to reset COA
else: ## dnp = base.direct.selected.last
base.direct.selectCB(nodePath, fMultiSelect, fSelectTag, fResetAncestry, fLEPane, fUndo) ## # Update camera controls coa to this point
## # Coa2Camera = Coa2Dnp * Dnp2Camera
def selectedNodePathHook(self, nodePath, fMultiSelect = 0, fSelectTag = 1, fLEPane = 0): ## mCoa2Camera = dnp.mCoa2Dnp * dnp.getMat(base.direct.camera)
# handle unpickable nodepath ## row = mCoa2Camera.getRow(3)
if nodePath.getName() in base.direct.iRay.unpickable: ## coa = Vec3(row[0], row[1], row[2])
base.direct.deselect(nodePath) ## base.direct.cameraControl.updateCoa(coa)
return
def cleanUpManipulating(self, selectedNPs):
if fMultiSelect == 0 and fLEPane == 0: for np in selectedNPs:
oldSelectedNPs = base.direct.selected.getSelectedAsList() obj = self.objectMgr.findObjectByNodePath(np)
for oldNP in oldSelectedNPs: if obj:
obj = self.objectMgr.findObjectByNodePath(oldNP) action = ActionTransformObj(self, obj[OG.OBJ_UID], Mat4(np.getMat()))
if obj: self.actionMgr.push(action)
self.ui.sceneGraphUI.deSelect(obj[OG.OBJ_UID]) action()
self.objectMgr.selectObject(nodePath, fLEPane)
self.ui.buildContextMenu(nodePath) def select(self, nodePath, fMultiSelect=0, fSelectTag=1, fResetAncestry=1, fLEPane=0, fUndo=1):
if fUndo:
def deselectAll(self, np=None): # Select tagged object if present
if len(base.direct.selected.getSelectedAsList()) ==0: if fSelectTag:
return for tag in base.direct.selected.tagList:
action = ActionDeselectAll(self) if nodePath.hasNetTag(tag):
self.actionMgr.push(action) nodePath = nodePath.findNetTag(tag)
action() break
action = ActionSelectObj(self, nodePath, fMultiSelect)
def deselectAllCB(self, dnp=None): self.actionMgr.push(action)
self.objectMgr.deselectAll() action()
else:
def reset(self): base.direct.selectCB(nodePath, fMultiSelect, fSelectTag, fResetAncestry, fLEPane, fUndo)
if self.fNeedToSave:
reply = wx.MessageBox("Do you want to save current scene?", "Save?", def selectedNodePathHook(self, nodePath, fMultiSelect = 0, fSelectTag = 1, fLEPane = 0):
wx.YES_NO | wx.ICON_QUESTION) # handle unpickable nodepath
if reply == wx.YES: if nodePath.getName() in base.direct.iRay.unpickable:
result = self.ui.onSave() base.direct.deselect(nodePath)
if result == False: return
return
if fMultiSelect == 0 and fLEPane == 0:
base.direct.deselectAll() oldSelectedNPs = base.direct.selected.getSelectedAsList()
self.ui.reset() for oldNP in oldSelectedNPs:
self.objectMgr.reset() obj = self.objectMgr.findObjectByNodePath(oldNP)
self.actionMgr.reset() if obj:
self.ui.perspView.camera.setPos(-19, -19, 19) self.ui.sceneGraphUI.deSelect(obj[OG.OBJ_UID])
self.ui.perspView.camera.lookAt(Point3(0, 0, 0)) self.objectMgr.selectObject(nodePath, fLEPane)
self.ui.leftView.camera.setPos(600, 0, 0) self.ui.buildContextMenu(nodePath)
self.ui.frontView.camera.setPos(0, -600, 0)
self.ui.topView.camera.setPos(0, 0, 600) def deselectAll(self, np=None):
self.resetOrthoCam(self.ui.topView) if len(base.direct.selected.getSelectedAsList()) ==0:
self.resetOrthoCam(self.ui.frontView) return
self.resetOrthoCam(self.ui.leftView) action = ActionDeselectAll(self)
self.fNeedToSave = False self.actionMgr.push(action)
self.setTitleWithFilename() action()
def resetOrthoCam(self, view): def deselectAllCB(self, dnp=None):
base.direct.drList[base.camList.index(NodePath(view.camNode))].orthoFactor = 0.1 self.objectMgr.deselectAll()
x = view.ClientSize.GetWidth() * 0.1
y = view.ClientSize.GetHeight() * 0.1 def reset(self):
view.camLens.setFilmSize(x, y) if self.fNeedToSave:
reply = wx.MessageBox("Do you want to save current scene?", "Save?",
def save(self): wx.YES_NO | wx.ICON_QUESTION)
self.ui.SetCursor(wx.StockCursor(wx.CURSOR_WAIT)) if reply == wx.YES:
if self.currentFile: result = self.ui.onSave()
self.fileMgr.saveToFile(self.currentFile) if result == False:
self.ui.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) return
def saveAs(self, fileName): base.direct.deselectAll()
self.ui.SetCursor(wx.StockCursor(wx.CURSOR_WAIT)) self.ui.reset()
self.fileMgr.saveToFile(fileName) self.objectMgr.reset()
self.currentFile = fileName self.actionMgr.reset()
self.ui.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) self.ui.perspView.camera.setPos(-19, -19, 19)
self.ui.perspView.camera.lookAt(Point3(0, 0, 0))
def load(self, fileName): self.ui.leftView.camera.setPos(600, 0, 0)
self.ui.SetCursor(wx.StockCursor(wx.CURSOR_WAIT)) self.ui.frontView.camera.setPos(0, -600, 0)
self.reset() self.ui.topView.camera.setPos(0, 0, 600)
self.fileMgr.loadFromFile(fileName) self.resetOrthoCam(self.ui.topView)
self.currentFile = fileName self.resetOrthoCam(self.ui.frontView)
self.ui.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) self.resetOrthoCam(self.ui.leftView)
self.fNeedToSave = False
def saveSettings(self): self.setTitleWithFilename()
if self.settingsFile is None:
return def resetOrthoCam(self, view):
base.direct.drList[base.camList.index(NodePath(view.camNode))].orthoFactor = 0.1
try: x = view.ClientSize.GetWidth() * 0.1
f = open(self.settingsFile, 'w') y = view.ClientSize.GetHeight() * 0.1
f.write('gridSize\n%f\n'%self.ui.perspView.grid.gridSize) view.camLens.setFilmSize(x, y)
f.write('gridSpacing\n%f\n'%self.ui.perspView.grid.gridSpacing)
f.write('hotKey\n%s\n'%base.direct.hotKeyMap) def save(self):
f.close() self.ui.SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
except: if self.currentFile:
pass self.fileMgr.saveToFile(self.currentFile)
self.ui.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
def loadSettings(self):
if self.settingsFile is None: def saveAs(self, fileName):
return self.ui.SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
self.fileMgr.saveToFile(fileName)
self.ui.SetCursor(wx.StockCursor(wx.CURSOR_WAIT)) self.currentFile = fileName
try: self.ui.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
f = open(self.settingsFile, 'r')
configLines = f.readlines() def load(self, fileName):
f.close() self.ui.SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
self.reset()
gridSize = 100.0 self.fileMgr.loadFromFile(fileName)
gridSpacing = 5.0 self.currentFile = fileName
for i in range(0, len(configLines)): self.ui.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
line = configLines[i]
i = i + 1 def saveSettings(self):
if line.startswith('gridSize'): if self.settingsFile is None:
gridSize = float(configLines[i]) return
elif line.startswith('gridSpacing'):
gridSpacing = float(configLines[i]) try:
elif line.startswith('hotKey'): f = open(self.settingsFile, 'w')
customHotKeyMap = eval(configLines[i]) f.write('gridSize\n%f\n'%self.ui.perspView.grid.gridSize)
customHotKeyDict = {} f.write('gridSpacing\n%f\n'%self.ui.perspView.grid.gridSpacing)
for hotKey in customHotKeyMap.keys(): f.write('hotKey\n%s\n'%base.direct.hotKeyMap)
desc = customHotKeyMap[hotKey] f.close()
customHotKeyDict[desc[1]] = hotKey except:
pass
overriddenKeys = []
for key in base.direct.hotKeyMap.keys(): def loadSettings(self):
desc = base.direct.hotKeyMap[key] if self.settingsFile is None:
if desc[1] in customHotKeyDict.keys(): return
overriddenKeys.append(key)
self.ui.SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
for key in overriddenKeys: try:
del base.direct.hotKeyMap[key] f = open(self.settingsFile, 'r')
configLines = f.readlines()
base.direct.hotKeyMap.update(customHotKeyMap) f.close()
self.ui.updateGrids(gridSize, gridSpacing) gridSize = 100.0
self.ui.updateMenu() gridSpacing = 5.0
except: for i in range(0, len(configLines)):
pass line = configLines[i]
self.ui.SetCursor(wx.StockCursor(wx.CURSOR_ARROW)) i = i + 1
if line.startswith('gridSize'):
def convertMaya(self, modelname, callBack, obj=None, isAnim=False): gridSize = float(configLines[i])
if obj and isAnim: elif line.startswith('gridSpacing'):
mayaConverter = MayaConverter(self.ui, self, modelname, callBack, obj, isAnim) gridSpacing = float(configLines[i])
else: elif line.startswith('hotKey'):
reply = wx.MessageBox("Is it an animation file?", "Animation?", customHotKeyMap = eval(configLines[i])
wx.YES_NO | wx.ICON_QUESTION) customHotKeyDict = {}
if reply == wx.YES: for hotKey in customHotKeyMap.keys():
mayaConverter = MayaConverter(self.ui, self, modelname, callBack, None, True) desc = customHotKeyMap[hotKey]
else: customHotKeyDict[desc[1]] = hotKey
mayaConverter = MayaConverter(self.ui, self, modelname, callBack, None, False)
mayaConverter.Show() overriddenKeys = []
for key in base.direct.hotKeyMap.keys():
def convertFromMaya(self, modelname, callBack): desc = base.direct.hotKeyMap[key]
mayaConverter = MayaConverter(self.ui, self, modelname, callBack, None, False) if desc[1] in customHotKeyDict.keys():
mayaConverter.Show() overriddenKeys.append(key)
def updateStatusReadout(self, status, color=None): for key in overriddenKeys:
if status: del base.direct.hotKeyMap[key]
# add new status line, first check to see if it already exists
alreadyExists = False base.direct.hotKeyMap.update(customHotKeyMap)
for currLine in self.statusLines:
if (status == currLine[1]): self.ui.updateGrids(gridSize, gridSpacing)
alreadyExists = True self.ui.updateMenu()
break except:
if (alreadyExists == False): pass
time = globalClock.getRealTime() + 15 self.ui.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))
self.statusLines.append([time,status,color])
def convertMaya(self, modelname, callBack, obj=None, isAnim=False):
# update display of new status lines if obj and isAnim:
self.statusReadout.reparentTo(aspect2d) mayaConverter = MayaConverter(self.ui, self, modelname, callBack, obj, isAnim)
statusText = "" else:
lastColor = None reply = wx.MessageBox("Is it an animation file?", "Animation?",
for currLine in self.statusLines: wx.YES_NO | wx.ICON_QUESTION)
statusText += currLine[1] + '\n' if reply == wx.YES:
lastColor = currLine[2] mayaConverter = MayaConverter(self.ui, self, modelname, callBack, None, True)
self.statusReadout.setText(statusText) else:
if (lastColor): mayaConverter = MayaConverter(self.ui, self, modelname, callBack, None, False)
self.statusReadout.textNode.setCardColor( mayaConverter.Show()
lastColor[0], lastColor[1], lastColor[2], lastColor[3])
self.statusReadout.textNode.setCardAsMargin(0.1, 0.1, 0.1, 0.1) def convertFromMaya(self, modelname, callBack):
else: mayaConverter = MayaConverter(self.ui, self, modelname, callBack, None, False)
self.statusReadout.textNode.setCardColor(1,1,1,1) mayaConverter.Show()
self.statusReadout.textNode.setCardAsMargin(0.1, 0.1, 0.1, 0.1)
def updateStatusReadout(self, status, color=None):
def updateStatusReadoutTimeouts(self,task=None): if status:
removalList = [] # add new status line, first check to see if it already exists
for currLine in self.statusLines: alreadyExists = False
if (globalClock.getRealTime() >= currLine[0]): for currLine in self.statusLines:
removalList.append(currLine) if (status == currLine[1]):
for currRemoval in removalList: alreadyExists = True
self.statusLines.remove(currRemoval) break
self.updateStatusReadout(None) if (alreadyExists == False):
# perform doMethodLater again after delay time = globalClock.getRealTime() + 15
# This crashes when CTRL-C'ing, so this is a cheap hack. self.statusLines.append([time,status,color])
#return 2
from direct.task import Task # update display of new status lines
return Task.again self.statusReadout.reparentTo(aspect2d)
statusText = ""
def propMeetsReq(self, typeName, parentNP): lastColor = None
if self.ui.parentToSelectedMenuItem.IsChecked(): for currLine in self.statusLines:
if base.direct.selected.last: statusText += currLine[1] + '\n'
parent = base.le.objectMgr.findObjectByNodePath(base.direct.selected.last) lastColor = currLine[2]
if parent: self.statusReadout.setText(statusText)
parentNP[0] = parent[OG.OBJ_NP] if (lastColor):
else: self.statusReadout.textNode.setCardColor(
parentNP[0] = None lastColor[0], lastColor[1], lastColor[2], lastColor[3])
return True self.statusReadout.textNode.setCardAsMargin(0.1, 0.1, 0.1, 0.1)
else:
self.statusReadout.textNode.setCardColor(1,1,1,1)
self.statusReadout.textNode.setCardAsMargin(0.1, 0.1, 0.1, 0.1)
def updateStatusReadoutTimeouts(self,task=None):
removalList = []
for currLine in self.statusLines:
if (globalClock.getRealTime() >= currLine[0]):
removalList.append(currLine)
for currRemoval in removalList:
self.statusLines.remove(currRemoval)
self.updateStatusReadout(None)
# perform doMethodLater again after delay
# This crashes when CTRL-C'ing, so this is a cheap hack.
#return 2
from direct.task import Task
return Task.again
def propMeetsReq(self, typeName, parentNP):
if self.ui.parentToSelectedMenuItem.IsChecked():
if base.direct.selected.last:
parent = base.le.objectMgr.findObjectByNodePath(base.direct.selected.last)
if parent:
parentNP[0] = parent[OG.OBJ_NP]
else:
parentNP[0] = None
return True

View File

@ -69,10 +69,7 @@ class PandaTextDropTarget(wx.TextDropTarget):
break break
if hitPt is None: if hitPt is None:
if self.view.name == 'persp': iRay.collideWithBitMask(BitMask32.bit(21))
iRay.collideWithBitMask(1)
else:
iRay.collideWithBitMask(BitMask32.bit(21))
iRay.ct.traverse(self.view.collPlane) iRay.ct.traverse(self.view.collPlane)
if iRay.getNumEntries() > 0: if iRay.getNumEntries() > 0:
entry = iRay.getEntry(0) entry = iRay.getEntry(0)

View File

@ -226,15 +226,17 @@ class Viewport(wx.Panel, DirectObject):
v.grid = DirectGrid(parent=render) v.grid = DirectGrid(parent=render)
collPlane = CollisionNode('PerspGridCol') collPlane = CollisionNode('PerspGridCol')
collPlane.addSolid(CollisionPlane(Plane(0, 0, 1, 0))) collPlane.addSolid(CollisionPlane(Plane(0, 0, 1, 0)))
oldBitmask = collPlane.getIntoCollideMask() #oldBitmask = collPlane.getIntoCollideMask()
collPlane.setIntoCollideMask(BitMask32.bit(21)|oldBitmask) #collPlane.setIntoCollideMask(BitMask32.bit(21)|oldBitmask)
collPlane.setIntoCollideMask(BitMask32.bit(21))
v.collPlane = NodePath(collPlane) v.collPlane = NodePath(collPlane)
v.collPlane.reparentTo(v.grid) v.collPlane.reparentTo(v.grid)
collPlane2 = CollisionNode('PerspGridCol2') collPlane2 = CollisionNode('PerspGridCol2')
collPlane2.addSolid(CollisionPlane(Plane(0, 0, -1, 0))) collPlane2.addSolid(CollisionPlane(Plane(0, 0, -1, 0)))
oldBitmask = collPlane2.getIntoCollideMask() #oldBitmask = collPlane2.getIntoCollideMask()
collPlane2.setIntoCollideMask(BitMask32.bit(21)|oldBitmask) #collPlane2.setIntoCollideMask(BitMask32.bit(21)|oldBitmask)
collPlane2.setIntoCollideMask(BitMask32.bit(21))
v.collPlane2 = NodePath(collPlane2) v.collPlane2 = NodePath(collPlane2)
v.collPlane2.reparentTo(v.grid) v.collPlane2.reparentTo(v.grid)