from PandaObject import * from DirectGeometry import * import NodePath class Mopath(PandaObject): nameIndex = 1 def __init__(self, name = None): if (name == None): name = 'mopath%d' % self.nameIndex self.nameIndex = self.nameIndex + 1 self.name = name self.reset() def getMaxT(self): return self.maxT def loadFile(self, filename): nodePath = loader.loadModel(filename) if nodePath: self.__extractCurves(nodePath) if (self.xyzNurbsCurve != None): self.maxT = self.xyzNurbsCurve.getMaxT() elif (self.hprNurbsCurve != None): self.maxT = self.hprNurbsCurve.getMaxT() elif (self.tNurbsCurve != None): self.maxT = self.tNurbsCurve.getMaxT() else: print 'Mopath: no valid curves in file: %s' % filename nodePath.removeNode() else: print 'Mopath: no data in file: %s' % filename def reset(self): self.maxT = 0.0 self.loop = 0 self.xyzNurbsCurve = None self.hprNurbsCurve = None self.tNurbsCurve = None self.node = None def __extractCurves(self, nodePath): node = nodePath.node() if isinstance(node, ParametricCurve): if node.getCurveType() == PCTXYZ: self.xyzNurbsCurve = node elif node.getCurveType() == PCTHPR: self.hprNurbsCurve = node elif node.getCurveType() == PCTNONE: if (self.xyzNurbsCurve == None): self.xyzNurbsCurve = node else: print 'Mopath: got a PCT_NONE curve and an XYZ Curve!' elif (node.getCurveType() == PCTT): self.tNurbsCurve = node else: # Iterate over children if any for child in nodePath.getChildrenAsList(): self.__extractCurves(child) def getFinalState(self): """ getFinalState() """ pos = Point3(0) if (self.xyzNurbsCurve != None): self.xyzNurbsCurve.getPoint(self.maxT, pos) hpr = Point3(0) if (self.hprNurbsCurve != None): self.hprNurbsCurve.getPoint(self.maxT, hpr) return (pos, hpr) def goTo(self, node, time): if (self.xyzNurbsCurve == None) and (self.hprNurbsCurve == None): print 'Mopath: Mopath has no curves' return self.playbackTime = CLAMP(time, 0.0, self.maxT) if (self.xyzNurbsCurve != None): pos = Point3(0) self.xyzNurbsCurve.getPoint(self.playbackTime, pos) node.setPos(pos) if (self.hprNurbsCurve != None): hpr = Point3(0) self.hprNurbsCurve.getPoint(self.playbackTime, hpr) node.setHpr(hpr) def play(self, node, time = 0.0, loop = 0): if (self.xyzNurbsCurve == None) and (self.hprNurbsCurve == None): print 'Mopath: Mopath has no curves' return self.node = node self.loop = loop self.stop() t = taskMgr.spawnMethodNamed(self.__playTask, self.name + '-play') t.currentTime = time t.lastTime = globalClock.getFrameTime() def stop(self): taskMgr.removeTasksNamed(self.name + '-play') def __playTask(self, state): time = globalClock.getFrameTime() dTime = time - state.lastTime state.lastTime = time if (self.loop): cTime = (state.currentTime + dTime) % self.maxT else: cTime = state.currentTime + dTime if ((self.loop == 0) and (cTime > self.maxT)): self.stop() messenger.send(self.name + '-done') self.node = None return Task.done self.goTo(self.node, cTime) state.currentTime = cTime return Task.cont