Moving here from Pipeline.
I experimented with the new NURBS curve system, that enabled by “egg-load-old-curves 0” and try to make Mopath class to it. The problem is that I can’t interpolate the tangent through the evalTangent(), although the evalPoint() works fine. It seems that the tangent changing only on the control points.
My code (look at “goto()”):
from pandac.PandaModules import *
loadPrcFileData("", "egg-load-old-curves 0")
from direct.directbase import DirectStart
class NURBSMopath():
def __init__(self, curve, name = None):
if (name == None):
name = 'nurbsmopath'
self.name = name
self.duration = 1.0
self.node = None
self.loop = False
self.cnpRef = None
self.rope = None
self.evaluator = None
self.nurbs = None
self.tDisplace = 0
self.tCurrent = 0
self.loopNum = 0
if curve:
if isinstance(curve, str):
self.loadCurves(curve)
elif isinstance(curve, NodePath):
self.cnpRef = curve
self.__extractCurves(curve)
elif isinctance(curve, RopeNode):
self.setCurve(curve)
print self.name
def loadCurves(self, fname, parent = render):
if self.cnpRef:
self.cnpRef.detachNode()
self.cnpRef = loader.loadModel(fname, noCache=True)
self.cnpRef.reparentTo(parent)
if self.cnpRef:
if not self.__extractCurves(self.cnpRef):
print 'NURBSMopath: can\'t find any curves in file: %s' % fname
else:
print 'NURBSMopath: no data in file: %s' % fname
def setCurve(self, curve):
self.rope = NodePath(curve)
self.evaluator = curve.getCurve()
self.nurbs = self.evaluator.evaluate()
def __extractCurves(self, np):
node = np.node()
if isinstance(node, RopeNode):
self.setCurve(node)
return True
else:
for ch in np.getChildren():
if self.__extractCurves(ch):
return True
def __playTask(self, task):
start, stop = self.getRange()
delta = stop - start
scaled_duration = delta * self.duration
self.loopNum = int(task.time / scaled_duration)
if (not self.loop) and (self.loopNum > 0):
self.finish()
messenger.send(self.name + '-done')
self.node = None
return task.done
t = self.nurbs.getStartT() + (task.time - \
(self.loopNum * scaled_duration)) / self.duration + \
self.tDisplace
self.tCurrent = t
self.goto(t)
return task.cont
def getRange(self):
if self.nurbs:
return (self.nurbs.getStartT(), self.nurbs.getEndT())
else:
return (0, 0)
def goto(self, t):
if self.node:
p = Point3()
v = Vec3()
self.nurbs.evalPoint(t, p)
self.node.setPos(self.rope, p)
self.nurbs.evalTangent(t, v)
v = render.getRelativeVector(self.rope, v)
self.node.lookAt(self.node.getPos() + v)
def play(self, node, duration = 1.0, resume = False, loop = False):
if self.nurbs:
if not resume:
self.lastTime = 0
self.node = node
self.duration = duration
self.loop = loop
self.stop()
t = taskMgr.add(self.__playTask, self.name + '-play')
else:
print 'NURBSMopath: has no curve.'
def stop(self):
self.tDisplace = self.tCurrent
taskMgr.remove(self.name + '-play')
def finish(self):
start,stop = self.getRange()
self.tDisplace = 0
taskMgr.remove(self.name + '-play')
if __name__ == "__main__":
b = loader.loadModel('zup-axis')
b.reparentTo(render)
b.setScale(0.2)
nmp = NURBSMopath('curve.egg')
nmp.cnpRef.setH(45)
nmp.cnpRef.setPos(-10,0,-5)
nmp.cnpRef.setScale(1.5)
nmp.play(b, 10)
base.disableMouse()
base.camera.setPos(15,15,15)
base.camera.lookAt(0,0,0)
run()
and my Curve
<CoordinateSystem> { Z-up }
<Group> NurbsCurve {
<Transform> {
<Matrix4> {
1.000000 0.000000 0.000000 0.000000
0.000000 1.000000 0.000000 0.000000
0.000000 0.000000 1.000000 0.000000
-0.989243 -2.149168 0.000000 1.000000
}
}
<VertexPool> NurbsCurve {
<Vertex> 0 {
-2.489244 -2.149168 0.000000 1.000000
}
<Vertex> 1 {
-1.989243 -1.149168 0.000000 1.000000
}
<Vertex> 2 {
0.010757 -1.149168 0.000000 1.000000
}
<Vertex> 3 {
0.510757 -2.149168 0.000000 1.000000
}
<Vertex> 4 {
2.027631 -3.067276 0.000000 1.000000
}
<Vertex> 5 {
4.243067 -2.288880 0.000000 1.000000
}
<Vertex> 6 {
3.604383 0.465445 0.000000 1.000000
}
<Vertex> 7 {
0.091620 1.742813 0.000000 1.000000
}
}
<NURBSCurve> {
<Scalar> subdiv { 56 }
<Order> { 4 }
<Knots> { 0.00 0.09 0.18 0.27 0.36 0.45 0.55 0.64 0.73 0.82 0.91 1.00 }
<VertexRef> {
0 1 2 3 4 5 6 7
<Ref> { NurbsCurve }
}
}
}