David Rose 22 лет назад
Родитель
Сommit
952e119a55
1 измененных файлов с 97 добавлено и 0 удалено
  1. 97 0
      direct/src/showutil/Rope.py

+ 97 - 0
direct/src/showutil/Rope.py

@@ -0,0 +1,97 @@
+from PandaModules import *
+import types
+
+class Rope(NodePath):
+    """
+    This class defines a Nurbs curve whose control vertices are
+    defined based on points relative to one or more nodes in space, so
+    that the "rope" will animate as the nodes move around.  It uses
+    the C++ RopeNode class to achieve fancy rendering effects like
+    thick lines built from triangle strips.
+    """
+
+    showRope = base.config.GetBool('show-rope', 1)
+    
+    def __init__(self, name = 'Rope'):
+        self.ropeNode = RopeNode(name)
+        self.curve = NurbsCurveEvaluator()
+        self.ropeNode.setCurve(self.curve)
+        NodePath.__init__(self, self.ropeNode)
+        self.name = name
+        
+    def setup(self, order, verts, knots = None):
+        # This must be called to define the shape of the curve
+        # initially, and may be called again as needed to adjust the
+        # curve's properties.
+
+        # order must be either 1, 2, 3, or 4, and is one more than the
+        # degree of the curve; most NURBS curves are order 4.
+
+        # verts is a list of (NodePath, point) tuples, defining the
+        # control vertices of the curve.  For each control vertex, the
+        # NodePath may refer to an arbitrary node in the scene graph,
+        # indicating the point should be interpreted in the coordinate
+        # space of that node (and it will automatically move when the
+        # node is moved), or it may be the empty NodePath or None to
+        # indicate the point should be interpreted in the coordinate
+        # space of the Rope itself.  Each point value may be either a
+        # 3-tuple or a 4-tuple (or a VBase3 or VBase4).  If it is a
+        # 3-component vector, it represents a 3-d point in space; a
+        # 4-component vector represents a point in 4-d homogeneous
+        # space; that is to say, a 3-d point and an additional weight
+        # factor (which should have been multiplied into the x y z
+        # components).
+
+        # knots is optional.  If specified, it should be a list of
+        # floats, and should be of length len(verts) + order.  If it
+        # is omitted, a default knot string is generated that consists
+        # of the first (order - 1) and last (order - 1) values the
+        # same, and the intermediate values incrementing by 1.
+        
+        self.order = order
+        self.verts = verts
+        self.knots = knots
+
+        self.recompute()
+
+    def recompute(self):
+        # Recomputes the curve after its properties have changed.
+        # Normally it is not necessary for the user to call this
+        # directly.
+        
+        if not self.showRope:
+            return
+        numVerts = len(self.verts)
+        self.curve.reset(numVerts)
+        self.curve.setOrder(self.order)
+        for i in range(numVerts):
+            nodePath, point = self.verts[i]
+            if isinstance(point, types.TupleType):
+                if (len(point) >= 4):
+                    self.curve.setVertex(i, VBase4(point[0], point[1], point[2], point[3]))
+                else:
+                    self.curve.setVertex(i, VBase3(point[0], point[1], point[2]))
+            else:
+                self.curve.setVertex(i, point)
+            if nodePath:
+                self.curve.setVertexSpace(i, nodePath)
+
+        if self.knots != None:
+            for i in range(len(self.knots)):
+                self.curve.setKnot(i, self.knots[i])
+
+        self.ropeNode.resetBound(self)
+
+    def getPoints(self, len):
+        # Returns a list of len points, evenly distributed in
+        # parametric space on the rope, in the coordinate space of the
+        # Rope itself.
+        
+        result = self.curve.evaluate(self)
+        numPts = len
+        ropePts = []
+        for i in range(numPts):
+            pt = Point3()
+            result.evalPoint(i / float(numPts - 1), pt)
+            ropePts.append(pt)
+        return ropePts