ソースを参照

Added make live feature to make an object a base object to add another object

Gyedo Jeon 16 年 前
コミット
159f878ef3

+ 40 - 7
direct/src/leveleditor/LevelEditorUIBase.py

@@ -34,17 +34,44 @@ class PandaTextDropTarget(wx.TextDropTarget):
         # create ray from the camera to detect 3d position
         iRay = SelectionRay(self.view.camera)
         iRay.collider.setFromLens(self.view.camNode, mx, my)
-        iRay.collideWithBitMask(1)
-        iRay.ct.traverse(self.view.collPlane)
-
-        if iRay.getNumEntries() > 0:
-            entry = iRay.getEntry(0)
-            hitPt = entry.getSurfacePoint(entry.getFromNodePath())
+        hitPt = None
+        if self.editor.objectMgr.currLiveNP:
+            iRay.collideWithGeom()
+            iRay.ct.traverse(self.editor.objectMgr.currLiveNP)
+
+            def isEntryBackfacing(iRay, entry):
+                if not entry.hasSurfaceNormal():
+                    # Well, no way to tell.  Assume we're not backfacing.
+                    return 0
+
+                fromNodePath = entry.getFromNodePath()
+                v = Vec3(entry.getSurfacePoint(fromNodePath))
+                n = entry.getSurfaceNormal(fromNodePath)
+                # Convert to camera space for backfacing test
+                p2cam = iRay.collisionNodePath.getParent().getMat(self.view.camera)
+                v = Vec3(p2cam.xformPoint(v))
+                n = p2cam.xformVec(n)
+                # Normalize and check angle between to vectors
+                v.normalize()
+                return v.dot(n) >= 0                
+
+            for entry in iRay.getEntries():
+                if isEntryBackfacing(iRay, entry):
+                    pass
+                else:
+                    hitPt = entry.getSurfacePoint(entry.getFromNodePath())
+                    break
+        else:
+            iRay.collideWithBitMask(1)
+            iRay.ct.traverse(self.view.collPlane)
+            if iRay.getNumEntries() > 0:
+                entry = iRay.getEntry(0)
+                hitPt = entry.getSurfacePoint(entry.getFromNodePath())
 
+        if hitPt:
             # create a temp nodePath to get the position
             np = NodePath('temp')
             np.setPos(self.view.camera, hitPt)
-
             # update temp nodePath's HPR and scale with newobj's
             np.setHpr(newobj.getHpr())
             np.setScale(newobj.getScale())
@@ -92,6 +119,9 @@ class LevelEditorUIBase(WxAppShell):
         menuItem = self.menuEdit.Append(-1, "&Duplicate")
         self.Bind(wx.EVT_MENU, self.onDuplicate, menuItem)
 
+        menuItem = self.menuEdit.Append(-1, "Make &Live")
+        self.Bind(wx.EVT_MENU, self.onMakeLive, menuItem)
+
         menuItem = self.menuEdit.Append(-1, "&Undo")
         self.Bind(wx.EVT_MENU, self.editor.actionMgr.undo, menuItem)
 
@@ -263,6 +293,9 @@ class LevelEditorUIBase(WxAppShell):
     def onDuplicate(self, evt):
         self.editor.objectMgr.duplicateSelected()
 
+    def onMakeLive(self, evt):
+        self.editor.objectMgr.makeSelectedLive()
+
     def toggleGridSnap(self, evt):
         if self.gridSnapMenuItem.IsChecked():
             base.direct.manipulationControl.fGridSnap = 1

+ 14 - 0
direct/src/leveleditor/ObjectMgr.py

@@ -26,6 +26,8 @@ class ObjectMgr:
         self.lastUidMode = 0
         self.currNodePath = None   
 
+        self.currLiveNP = None
+
     def reset(self):
         base.direct.deselectAllCB()
 
@@ -602,3 +604,15 @@ class ObjectMgr:
         base.direct.deselectAllCB()
         for newNodePath in duplicatedNPs:
             base.direct.select(newNodePath, fMultiSelect = 1, fUndo=0)
+
+    def makeSelectedLive(self):
+        obj = self.findObjectByNodePath(base.direct.selected.last)
+        if obj:
+            if self.currLiveNP:
+                self.currLiveNP.clearColorScale()
+                if self.currLiveNP == obj[OG.OBJ_NP]:
+                    self.currLiveNP = None
+                    return
+
+            self.currLiveNP = obj[OG.OBJ_NP]
+            self.currLiveNP.setColorScale(0, 1, 0, 1)