Browse Source

Really long street

Mark Mine 20 years ago
parent
commit
68029e1ef5
1 changed files with 124 additions and 12 deletions
  1. 124 12
      direct/src/leveleditor/LevelEditor.py

+ 124 - 12
direct/src/leveleditor/LevelEditor.py

@@ -1220,7 +1220,8 @@ class LevelEditor(NodePath, PandaObject):
                                         snapPos[0], snapPos[1], zheight)
                                         snapPos[0], snapPos[1], zheight)
                     # Angle snap
                     # Angle snap
                     h = direct.grid.computeSnapAngle(selectedNode.getH())
                     h = direct.grid.computeSnapAngle(selectedNode.getH())
-                    selectedNode.setH(h)
+                    if direct.grid.getHprSnap():
+                        selectedNode.setH(h)
                     if selectedNode == direct.selected.last:
                     if selectedNode == direct.selected.last:
                         self.setLastAngle(h)
                         self.setLastAngle(h)
                     # Update DNA
                     # Update DNA
@@ -1465,6 +1466,7 @@ class LevelEditor(NodePath, PandaObject):
             self.snapList = self.getSnapPoint(dnaNode.getCode())
             self.snapList = self.getSnapPoint(dnaNode.getCode())
         # Select the instance
         # Select the instance
         direct.select(newNodePath)
         direct.select(newNodePath)
+        self.lastNodePath = newNodePath
         # Update grid to get ready for the next object
         # Update grid to get ready for the next object
         self.autoPositionGrid()
         self.autoPositionGrid()
 
 
@@ -2224,8 +2226,8 @@ class LevelEditor(NodePath, PandaObject):
                 return nodePath, dnaNode
                 return nodePath, dnaNode
         elif nodePath.hasParent():
         elif nodePath.hasParent():
             return self.findParentVisGroup(nodePath.getParent())
             return self.findParentVisGroup(nodePath.getParent())
-        else:
-            return None, None
+        # Fall through
+        return None, None
     
     
     def showGrid(self,flag):
     def showGrid(self,flag):
         """ toggle direct grid """
         """ toggle direct grid """
@@ -3380,25 +3382,25 @@ class LevelEditor(NodePath, PandaObject):
                         np.setY(maxPropOffset)
                         np.setY(maxPropOffset)
                         self.updateSelectedPose([np])
                         self.updateSelectedPose([np])
 
 
-    def getBuildingLength(self, dnaNode):
-        bldgLength = 0
+    def getBuildingWidth(self, bldg):
+        dnaNode = self.findDNANode(bldg)
+        bldgWidth = 0
         if DNAClassEqual(dnaNode, DNA_FLAT_BUILDING):
         if DNAClassEqual(dnaNode, DNA_FLAT_BUILDING):
-            bldgLength = dnaNode.getWidth()
+            bldgWidth = dnaNode.getWidth()
         elif DNAClassEqual(dnaNode, DNA_LANDMARK_BUILDING):
         elif DNAClassEqual(dnaNode, DNA_LANDMARK_BUILDING):
             objectCode = dnaNode.getCode()
             objectCode = dnaNode.getCode()
             if objectCode[-2:-1] == 'A':
             if objectCode[-2:-1] == 'A':
-                bldgLength = 25.0
+                bldgWidth = 25.0
             elif objectCode[-2:-1] == 'B':
             elif objectCode[-2:-1] == 'B':
-                bldgLength = 15.0
+                bldgWidth = 15.0
             elif objectCode[-2:-1] == 'C':
             elif objectCode[-2:-1] == 'C':
-                bldgLength = 20.0
-        return bldgLength
+                bldgWidth = 20.0
+        return bldgWidth
 
 
     def calcLongStreetLength(self, bldgs):
     def calcLongStreetLength(self, bldgs):
         streetLength = 0
         streetLength = 0
         for bldg in bldgs:
         for bldg in bldgs:
-            dnaNode = self.findDNANode(bldg)
-            streetLength += self.getBuildingLength(dnaNode)
+            streetLength += self.getBuildingWidth(bldg)
         return streetLength
         return streetLength
 
 
     def addStreetUnits(self, streetLength):
     def addStreetUnits(self, streetLength):
@@ -3431,6 +3433,112 @@ class LevelEditor(NodePath, PandaObject):
             ref = bldg
             ref = bldg
         self.addStreetUnits(streetLength)
         self.addStreetUnits(streetLength)
 
 
+    def loadStreetCurve(self):
+        path = '.'
+        streetCurveFilename = askopenfilename(
+            defaultextension = '.egg',
+            filetypes = (('Egg files', '*.egg'),
+                         ('Bam files', '*.bam'),
+                         ('Maya files', '*.mb'),
+                         ('All files', '*')),
+            initialdir = path,
+            title = 'Load Curve File',
+            parent = self.panel.component('hull'))
+        if streetCurveFilename:
+            modelFile = loader.loadModel(Filename.fromOsSpecific(streetCurveFilename))
+            curve = modelFile.find('**/+ClassicNurbsCurve')
+            if not curve.isEmpty():
+                return curve.node()
+            else:
+                return None
+        else:
+            return None
+
+    def duplicateFlatBuilding(self, oldDNANode):
+        # Yes, make a new copy of the dnaNode
+        dnaNode = oldDNANode.__class__(oldDNANode)
+        dnaNode.setWidth(oldDNANode.getWidth())
+        # Add the DNA to the active parent
+        self.DNAParent.add(dnaNode)
+        # And create the geometry
+        newNodePath = dnaNode.traverse(self.NPParent, DNASTORE, 1)
+        return newNodePath
+
+    def makeStreetAlongCurve(self):
+        curve = self.loadStreetCurve()
+        if curve == None:
+            return
+        direct.grid.fXyzSnap = 0
+        direct.grid.fHprSnap = 0
+        self.panel.fPlaneSnap.set(0)
+        bldgGroup = self.consolidateStreetBuildings()
+        bldgs = bldgGroup.getChildrenAsList()
+        currT = 0
+        endT = curve.getMaxT()
+        currPoint = Point3(0)
+        bldgIndex = 0
+        numBldgs = len(bldgs)
+        while currT < endT:
+            if bldgIndex < numBldgs:
+                # Use original
+                bldg = bldgs[bldgIndex]
+                bldgIndex += 1
+            else:
+                # Make a copy
+                oldBldg = bldgs[bldgIndex % numBldgs]
+                bldgIndex += 1
+                oldBldg.select()
+                oldDNANode = self.findDNANode(oldBldg)
+                nodeClass = DNAGetClassType(oldDNANode)
+                if nodeClass.eq(DNA_LANDMARK_BUILDING):
+                    self.addLandmark(oldDNANode.getCode(), oldDNANode.getBuildingType())
+                    bldg = self.lastNodePath
+                else:
+                    bldg = self.duplicateFlatBuilding(oldDNANode)
+            curve.getPoint(currT, currPoint)
+            bldg.setPos(currPoint)
+            bldgWidth = self.getBuildingWidth(bldg)
+            # Adjust grid orientation based upon next point along curve
+            print bldgIndex, currT
+            currT, currPoint = self.findBldgEndPoint(bldgWidth, curve, currT, currPoint, rd = 0)
+            bldg.lookAt(currPoint)
+            bldg.setH(bldg, 90)
+            self.updateSelectedPose([bldg])
+            self.adjustPropChildren(bldg)
+
+    def findBldgEndPoint(self, bldgWidth, curve, currT, currPoint,
+                         startT = None, endT = None, tolerance = 0.1, rd = 0):
+        if startT == None:
+            startT = currT
+        if endT == None:
+            endT = curve.getMaxT()
+        if rd > 100:
+            import pdb
+            pdb.set_trace()
+        midT = (startT + endT)/2.0
+        midPoint = Point3(0)
+        curve.getPoint(midT, midPoint)
+        separation = Vec3(midPoint - currPoint).length()
+        error = separation - bldgWidth
+        #print error, startT, midT
+        if abs(error) < tolerance:
+            return midT, midPoint
+        elif error > 0:
+            # Mid point was beyond building end point, focus on first half
+            return self.findBldgEndPoint(bldgWidth, curve, currT, currPoint, startT = startT, endT = midT,
+                                         rd = rd + 1)
+        else:
+            # End point beyond Mid point, focus on second half
+            # But make sure buildind end point is not beyond curve end point
+            endPoint = Point3(0)
+            curve.getPoint(endT, endPoint)
+            separation = Vec3(endPoint - currPoint).length()
+            if bldgWidth > separation:
+                # Must have reached end of the curve
+                return endT, endPoint
+            else:
+                return self.findBldgEndPoint(bldgWidth, curve, currT, currPoint, startT = midT, endT = endT,
+                                             rd = rd + 1)
 
 
 class LevelStyleManager:
 class LevelStyleManager:
     """Class which reads in style files and manages class variables"""
     """Class which reads in style files and manages class variables"""
@@ -4751,6 +4859,10 @@ class LevelEditorPanel(Pmw.MegaToplevel):
                             'Make Long Street',
                             'Make Long Street',
                             label = 'Make Long Street',
                             label = 'Make Long Street',
                             command = self.levelEditor.makeLongStreet)
                             command = self.levelEditor.makeLongStreet)
+        menuBar.addmenuitem('Level Editor', 'command',
+                            'Make Street Along Curve',
+                            label = 'Make Street Along Curve',
+                            command = self.levelEditor.makeStreetAlongCurve)
         menuBar.addmenuitem('Level Editor', 'command',
         menuBar.addmenuitem('Level Editor', 'command',
                             'Exit Level Editor Panel',
                             'Exit Level Editor Panel',
                             label = 'Exit',
                             label = 'Exit',