mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 02:15:43 -04:00
*** empty log message ***
This commit is contained in:
parent
014066827c
commit
e3511ec268
@ -52,24 +52,34 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
self.recorderNodePath = direct.group.attachNewNode(self['name'])
|
self.recorderNodePath = direct.group.attachNewNode(self['name'])
|
||||||
self.tempCS = self.recorderNodePath.attachNewNode(
|
self.tempCS = self.recorderNodePath.attachNewNode(
|
||||||
'mopathRecorderTempCS')
|
'mopathRecorderTempCS')
|
||||||
|
self.transitionCS = self.recorderNodePath.attachNewNode(
|
||||||
|
'mopathRecorderTransitionCS')
|
||||||
self.playbackMarker = loader.loadModel('models/directmodels/happy')
|
self.playbackMarker = loader.loadModel('models/directmodels/happy')
|
||||||
self.playbackMarker.reparentTo(self.recorderNodePath)
|
self.playbackMarker.reparentTo(self.recorderNodePath)
|
||||||
|
self.playbackNodePath = None
|
||||||
|
self.lastPlaybackNodePath = None
|
||||||
# For node path selectors
|
# For node path selectors
|
||||||
self.recNodePathDict = {}
|
self.recNodePathDict = {}
|
||||||
self.recNodePathDict['marker'] = self.playbackMarker
|
self.recNodePathDict['marker'] = self.playbackMarker
|
||||||
self.recNodePathDict['camera'] = direct.camera
|
self.recNodePathDict['camera'] = direct.camera
|
||||||
self.recNodePathDict['widget'] = direct.widget
|
self.recNodePathDict['widget'] = direct.widget
|
||||||
|
self.recNodePathDict['mopathRecorderTempCS'] = self.tempCS
|
||||||
self.recNodePathNames = ['marker', 'camera', 'widget', 'selected']
|
self.recNodePathNames = ['marker', 'camera', 'widget', 'selected']
|
||||||
self.pbNodePathDict = {}
|
self.pbNodePathDict = {}
|
||||||
self.pbNodePathDict['marker'] = self.playbackMarker
|
self.pbNodePathDict['marker'] = self.playbackMarker
|
||||||
self.pbNodePathDict['camera'] = direct.camera
|
self.pbNodePathDict['camera'] = direct.camera
|
||||||
self.pbNodePathDict['widget'] = direct.widget
|
self.pbNodePathDict['widget'] = direct.widget
|
||||||
|
self.pbNodePathDict['mopathRecorderTempCS'] = self.tempCS
|
||||||
self.pbNodePathNames = ['marker', 'camera', 'widget', 'selected']
|
self.pbNodePathNames = ['marker', 'camera', 'widget', 'selected']
|
||||||
# Count of point sets recorded
|
# Count of point sets recorded
|
||||||
self.pointSet = []
|
self.pointSet = []
|
||||||
|
self.prePoints = []
|
||||||
|
self.postPoints = []
|
||||||
self.pointSetDict = {}
|
self.pointSetDict = {}
|
||||||
self.pointSetCount = 0
|
self.pointSetCount = 0
|
||||||
self.pointSetName = self['name'] + '-ps-' + `self.pointSetCount`
|
self.pointSetName = self['name'] + '-ps-' + `self.pointSetCount`
|
||||||
|
# User callback to call before recording point
|
||||||
|
self.preRecordFunc = None
|
||||||
# Hook to start/stop recording
|
# Hook to start/stop recording
|
||||||
self.startStopHook = 'f6'
|
self.startStopHook = 'f6'
|
||||||
self.keyframeHook = 'f12'
|
self.keyframeHook = 'f12'
|
||||||
@ -83,13 +93,14 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
self.numTicks = 1
|
self.numTicks = 1
|
||||||
# Number of segments to represent each parametric unit
|
# Number of segments to represent each parametric unit
|
||||||
# This just affects the visual appearance of the curve
|
# This just affects the visual appearance of the curve
|
||||||
self.numSegs = 2
|
self.numSegs = 5
|
||||||
# The nurbs curves
|
# The nurbs curves
|
||||||
self.xyzNurbsCurve = None
|
self.xyzNurbsCurve = None
|
||||||
self.hprNurbsCurve = None
|
self.hprNurbsCurve = None
|
||||||
# Curve drawers
|
# Curve drawers
|
||||||
self.nurbsCurveDrawer = NurbsCurveDrawer(NurbsCurve())
|
self.nurbsCurveDrawer = NurbsCurveDrawer(NurbsCurve())
|
||||||
self.nurbsCurveDrawer.setNumSegs(self.numSegs)
|
self.nurbsCurveDrawer.setNumSegs(self.numSegs)
|
||||||
|
self.nurbsCurveDrawer.setShowHull(0)
|
||||||
self.curveNodePath = self.recorderNodePath.attachNewNode(
|
self.curveNodePath = self.recorderNodePath.attachNewNode(
|
||||||
self.nurbsCurveDrawer.getGeomNode())
|
self.nurbsCurveDrawer.getGeomNode())
|
||||||
# Playback variables
|
# Playback variables
|
||||||
@ -99,6 +110,13 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
self.fEven = 0
|
self.fEven = 0
|
||||||
self.desampleFrequency = 1
|
self.desampleFrequency = 1
|
||||||
self.numSamples = 100
|
self.numSamples = 100
|
||||||
|
# Refining curves
|
||||||
|
self.fRefine = 0
|
||||||
|
self.refineStart = 0.0
|
||||||
|
self.controlStart = 0.0
|
||||||
|
self.controlStop = 0.0
|
||||||
|
self.refineStop = 0.0
|
||||||
|
self.fAdjustingValues = 0
|
||||||
# Set up event hooks
|
# Set up event hooks
|
||||||
self.undoEvents = [('undo', self.undoHook),
|
self.undoEvents = [('undo', self.undoHook),
|
||||||
('pushUndo', self.pushUndoHook),
|
('pushUndo', self.pushUndoHook),
|
||||||
@ -136,7 +154,7 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
variable = self.pathVis,
|
variable = self.pathVis,
|
||||||
command = self.setPathVis)
|
command = self.setPathVis)
|
||||||
self.hullVis = BooleanVar()
|
self.hullVis = BooleanVar()
|
||||||
self.hullVis.set(1)
|
self.hullVis.set(0)
|
||||||
self.menuBar.addmenuitem('Show/Hide', 'checkbutton',
|
self.menuBar.addmenuitem('Show/Hide', 'checkbutton',
|
||||||
'Toggle Hull Visability',
|
'Toggle Hull Visability',
|
||||||
label = 'Toggle Hull Vis',
|
label = 'Toggle Hull Vis',
|
||||||
@ -203,6 +221,66 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
self.redoButton.pack(side = LEFT, expand = 0)
|
self.redoButton.pack(side = LEFT, expand = 0)
|
||||||
self.bind(self.redoButton, 'Redo last operation')
|
self.bind(self.redoButton, 'Redo last operation')
|
||||||
|
|
||||||
|
# Playback controls
|
||||||
|
playbackFrame = Frame(interior, relief = SUNKEN,
|
||||||
|
borderwidth = 2)
|
||||||
|
Label(playbackFrame, text = 'PLAYBACK CONTROLS',
|
||||||
|
font=('MSSansSerif', 12, 'bold')).pack(fill = X)
|
||||||
|
# Playback modifiers
|
||||||
|
frame = Frame(playbackFrame)
|
||||||
|
# Playback node path
|
||||||
|
self.pbNodePathMenu = Pmw.ComboBox(
|
||||||
|
frame, labelpos = W, label_text = 'Playback Node Path:',
|
||||||
|
entry_width = 20,
|
||||||
|
selectioncommand = self.selectPlaybackNodePathNamed,
|
||||||
|
scrolledlist_items = self.pbNodePathNames)
|
||||||
|
self.pbNodePathMenu.selectitem('camera')
|
||||||
|
self.pbNodePathMenuEntry = (
|
||||||
|
self.pbNodePathMenu.component('entryfield_entry'))
|
||||||
|
self.pbNodePathMenuBG = (
|
||||||
|
self.pbNodePathMenuEntry.configure('background')[3])
|
||||||
|
self.pbNodePathMenu.pack(side = LEFT, fill = X, expand = 1)
|
||||||
|
self.bind(self.pbNodePathMenu,
|
||||||
|
'Select node path to fly along path during playback')
|
||||||
|
# Duration entry
|
||||||
|
self.createLabeledEntry(frame, 'Resample', 'Path Duration',
|
||||||
|
'Set total curve duration',
|
||||||
|
command = self.setPathDuration)
|
||||||
|
frame.pack(fill = X, expand = 1)
|
||||||
|
frame = Frame(playbackFrame)
|
||||||
|
widget = self.createEntryScale(
|
||||||
|
frame, 'Playback', 'Time', 'Set current playback time',
|
||||||
|
resolution = 0.01, command = self.playbackGoTo, side = LEFT)
|
||||||
|
widget.component('hull')['relief'] = RIDGE
|
||||||
|
# Kill playback task if drag slider
|
||||||
|
widget.component('scale').bind(
|
||||||
|
'<ButtonPress-1>', lambda e = None, s = self: s.stopPlayback())
|
||||||
|
self.createCheckbutton(frame, 'Playback', 'Loop',
|
||||||
|
'On: loop playback',
|
||||||
|
self.setLoopPlayback, self.loopPlayback,
|
||||||
|
side = LEFT, fill = BOTH, expand = 0)
|
||||||
|
frame.pack(fill = X, expand = 1)
|
||||||
|
# Start stop buttons
|
||||||
|
frame = Frame(playbackFrame)
|
||||||
|
widget = self.createButton(frame, 'Playback', '<<',
|
||||||
|
'Jump to start of playback',
|
||||||
|
self.jumpToStartOfPlayback,
|
||||||
|
side = LEFT, expand = 1)
|
||||||
|
widget['font'] = (('MSSansSerif', 12, 'bold'))
|
||||||
|
widget = self.createCheckbutton(frame, 'Playback', 'Play',
|
||||||
|
'Start/Stop playback',
|
||||||
|
self.startStopPlayback, 0,
|
||||||
|
side = LEFT, fill = BOTH, expand = 1)
|
||||||
|
widget.configure(anchor = 'center', justify = 'center',
|
||||||
|
relief = RAISED, font = ('MSSansSerif', 12, 'bold'))
|
||||||
|
widget = self.createButton(frame, 'Playback', '>>',
|
||||||
|
'Jump to end of playback',
|
||||||
|
self.jumpToEndOfPlayback,
|
||||||
|
side = LEFT, expand = 1)
|
||||||
|
widget['font'] = (('MSSansSerif', 12, 'bold'))
|
||||||
|
frame.pack(fill = X, expand = 1)
|
||||||
|
playbackFrame.pack(fill = X, pady = 2)
|
||||||
|
|
||||||
# Create notebook pages
|
# Create notebook pages
|
||||||
self.mainNotebook = Pmw.NoteBook(interior)
|
self.mainNotebook = Pmw.NoteBook(interior)
|
||||||
self.mainNotebook.pack(fill = BOTH, expand = 1)
|
self.mainNotebook.pack(fill = BOTH, expand = 1)
|
||||||
@ -277,7 +355,6 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
'Hook used to start/stop recording',
|
'Hook used to start/stop recording',
|
||||||
initialValue = self.startStopHook,
|
initialValue = self.startStopHook,
|
||||||
command = self.setStartStopHook)[0]
|
command = self.setStartStopHook)[0]
|
||||||
label['width'] = 14
|
|
||||||
self.setStartStopHook()
|
self.setStartStopHook()
|
||||||
widget.pack_forget()
|
widget.pack_forget()
|
||||||
widget.grid(row=3, column=0, sticky = NSEW)
|
widget.grid(row=3, column=0, sticky = NSEW)
|
||||||
@ -286,73 +363,27 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
'Hook used to add a new keyframe',
|
'Hook used to add a new keyframe',
|
||||||
initialValue = self.keyframeHook,
|
initialValue = self.keyframeHook,
|
||||||
command = self.setKeyframeHook)[0]
|
command = self.setKeyframeHook)[0]
|
||||||
label['width'] = 14
|
|
||||||
self.setKeyframeHook()
|
self.setKeyframeHook()
|
||||||
widget.pack_forget()
|
widget.pack_forget()
|
||||||
widget.grid(row=3, column=1, sticky = NSEW)
|
widget.grid(row=3, column=1, sticky = NSEW)
|
||||||
self.gridFrame.pack(fill = X, expand = 1)
|
# PreRecordFunc
|
||||||
# This gets the widgets to spread out
|
frame = Frame(self.gridFrame)
|
||||||
self.gridFrame.grid_columnconfigure(1,weight = 1)
|
widget = self.createLabeledEntry(
|
||||||
recordFrame.pack(fill = X, pady = 2)
|
frame, 'Recording', 'Pre Record Func',
|
||||||
# Playback controls
|
'Function called before recording each point',
|
||||||
playbackFrame = Frame(self.recordPage, relief = SUNKEN,
|
command = self.setPreRecordFunc)[0]
|
||||||
borderwidth = 2)
|
self.createCheckbutton(frame, 'Recording', 'PRF Active',
|
||||||
Label(playbackFrame, text = 'PLAYBACK CONTROLS',
|
'On: Pre Record Func enabled',
|
||||||
font=('MSSansSerif', 12, 'bold')).pack(fill = X)
|
None, 0,
|
||||||
# Playback modifiers
|
|
||||||
frame = Frame(playbackFrame)
|
|
||||||
# Playback node path
|
|
||||||
self.pbNodePathMenu = Pmw.ComboBox(
|
|
||||||
frame, labelpos = W, label_text = 'Playback Node Path:',
|
|
||||||
entry_width = 20,
|
|
||||||
selectioncommand = self.selectPlaybackNodePathNamed,
|
|
||||||
scrolledlist_items = self.pbNodePathNames)
|
|
||||||
self.pbNodePathMenu.selectitem('camera')
|
|
||||||
self.pbNodePathMenuEntry = (
|
|
||||||
self.pbNodePathMenu.component('entryfield_entry'))
|
|
||||||
self.pbNodePathMenuBG = (
|
|
||||||
self.pbNodePathMenuEntry.configure('background')[3])
|
|
||||||
self.pbNodePathMenu.pack(side = LEFT, fill = X, expand = 1)
|
|
||||||
self.bind(self.pbNodePathMenu,
|
|
||||||
'Select node path to fly along path during playback')
|
|
||||||
# Duration entry
|
|
||||||
self.createLabeledEntry(frame, 'Resample', 'Path Duration',
|
|
||||||
'Set total curve duration',
|
|
||||||
command = self.setPathDuration)
|
|
||||||
frame.pack(fill = X, expand = 1)
|
|
||||||
frame = Frame(playbackFrame)
|
|
||||||
widget = self.createEntryScale(
|
|
||||||
frame, 'Playback', 'Time', 'Set current playback time',
|
|
||||||
resolution = 0.01, command = self.setPlaybackTime, side = LEFT)
|
|
||||||
widget.component('hull')['relief'] = RIDGE
|
|
||||||
# Kill playback task if drag slider
|
|
||||||
widget.component('scale').bind(
|
|
||||||
'<ButtonPress-1>', lambda e = None, s = self: s.stopPlayback())
|
|
||||||
self.createCheckbutton(frame, 'Playback', 'Loop',
|
|
||||||
'On: loop playback',
|
|
||||||
self.setLoopPlayback, self.loopPlayback,
|
|
||||||
side = LEFT, fill = BOTH, expand = 0)
|
side = LEFT, fill = BOTH, expand = 0)
|
||||||
frame.pack(fill = X, expand = 1)
|
frame.grid(row=4, column=0, columnspan = 2, sticky = NSEW)
|
||||||
# Start stop buttons
|
|
||||||
frame = Frame(playbackFrame)
|
# Pack gridFrame
|
||||||
widget = self.createButton(frame, 'Playback', '<<',
|
self.gridFrame.pack(fill = X, expand = 1)
|
||||||
'Jump to start of playback',
|
|
||||||
self.jumpToStartOfPlayback,
|
# This gets the widgets to spread out
|
||||||
side = LEFT, expand = 1)
|
self.gridFrame.grid_columnconfigure(1,weight = 1)
|
||||||
widget['font'] = (('MSSansSerif', 12, 'bold'))
|
recordFrame.pack(fill = X, pady = 2)
|
||||||
widget = self.createCheckbutton(frame, 'Playback', 'Play',
|
|
||||||
'Start/Stop playback',
|
|
||||||
self.startStopPlayback, 0,
|
|
||||||
side = LEFT, fill = BOTH, expand = 1)
|
|
||||||
widget.configure(anchor = 'center', justify = 'center',
|
|
||||||
relief = RAISED, font = ('MSSansSerif', 12, 'bold'))
|
|
||||||
widget = self.createButton(frame, 'Playback', '>>',
|
|
||||||
'Jump to end of playback',
|
|
||||||
self.jumpToEndOfPlayback,
|
|
||||||
side = LEFT, expand = 1)
|
|
||||||
widget['font'] = (('MSSansSerif', 12, 'bold'))
|
|
||||||
frame.pack(fill = X, expand = 1)
|
|
||||||
playbackFrame.pack(fill = X, pady = 2)
|
|
||||||
# Desample
|
# Desample
|
||||||
desampleFrame = Frame(
|
desampleFrame = Frame(
|
||||||
self.recordPage, relief = SUNKEN, borderwidth = 2)
|
self.recordPage, relief = SUNKEN, borderwidth = 2)
|
||||||
@ -389,14 +420,31 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
label = Label(refineFrame, text = 'REFINE CURVE',
|
label = Label(refineFrame, text = 'REFINE CURVE',
|
||||||
font=('MSSansSerif', 12, 'bold'))
|
font=('MSSansSerif', 12, 'bold'))
|
||||||
label.pack(fill = X)
|
label.pack(fill = X)
|
||||||
self.createEntryScale(refineFrame, 'Refine Page', 'From',
|
widget = self.createEntryScale(refineFrame,
|
||||||
'Begin time of refine pass',
|
'Refine Page', 'Refine From',
|
||||||
resolution = 0.01,
|
'Begin time of refine pass',
|
||||||
command = self.setRefineStart)
|
resolution = 0.01,
|
||||||
self.createEntryScale(refineFrame, 'Refine Page', 'To',
|
command = self.setRefineStart)
|
||||||
'Stop time of refine pass',
|
widget.onRelease = widget.onReturnRelease = self.getPrePoints
|
||||||
resolution = 0.01,
|
widget = self.createEntryScale(
|
||||||
command = self.setRefineStop)
|
refineFrame, 'Refine Page',
|
||||||
|
'Control Start',
|
||||||
|
'Time when full control of node path is given during refine pass',
|
||||||
|
resolution = 0.01,
|
||||||
|
command = self.setControlStart)
|
||||||
|
widget.onRelease = widget.onReturnRelease = self.setRefineFlag
|
||||||
|
widget = self.createEntryScale(
|
||||||
|
refineFrame, 'Refine Page',
|
||||||
|
'Control Stop',
|
||||||
|
'Time when node path begins transition back to original curve',
|
||||||
|
resolution = 0.01,
|
||||||
|
command = self.setControlStop)
|
||||||
|
widget.onRelease = widget.onReturnRelease = self.setRefineFlag
|
||||||
|
widget = self.createEntryScale(refineFrame, 'Refine Page', 'Refine To',
|
||||||
|
'Stop time of refine pass',
|
||||||
|
resolution = 0.01,
|
||||||
|
command = self.setRefineStop)
|
||||||
|
widget.onRelease = widget.onReturnRelease = self.getPostPoints
|
||||||
refineFrame.pack(fill = X)
|
refineFrame.pack(fill = X)
|
||||||
|
|
||||||
offsetFrame = Frame(self.refinePage)
|
offsetFrame = Frame(self.refinePage)
|
||||||
@ -495,7 +543,6 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
self.fHasPoints = 1
|
self.fHasPoints = 1
|
||||||
# Compute curve
|
# Compute curve
|
||||||
self.computeCurves()
|
self.computeCurves()
|
||||||
|
|
||||||
|
|
||||||
def setTraceVis(self):
|
def setTraceVis(self):
|
||||||
print self.traceVis.get()
|
print self.traceVis.get()
|
||||||
@ -576,18 +623,35 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
self.nurbsCurveDrawer.hide()
|
self.nurbsCurveDrawer.hide()
|
||||||
# Create a new point set to hold raw data
|
# Create a new point set to hold raw data
|
||||||
self.createNewPointSet()
|
self.createNewPointSet()
|
||||||
# Continuous or keyframe?
|
# Record nopath's parent
|
||||||
if self.recordType.get() == 'Continuous':
|
self.nodePathParent = self['nodePath'].getParent()
|
||||||
|
# Refine, Continuous or keyframe?
|
||||||
|
if self.fRefine | (self.recordType.get() == 'Continuous'):
|
||||||
|
if self.fRefine:
|
||||||
|
# Turn off looping playback
|
||||||
|
self.loopPlayback = 0
|
||||||
|
# Update widget to reflect new value
|
||||||
|
self.getVariable('Playback', 'Loop').set(0)
|
||||||
|
# Select tempCS as playback nodepath
|
||||||
|
self.lastPlaybackNodePath = self.playbackNodePath
|
||||||
|
self.selectPlaybackNodePathNamed('mopathRecorderTempCS')
|
||||||
|
# Parent record node path to temp
|
||||||
|
self['nodePath'].reparentTo(self.tempCS)
|
||||||
|
# Align with temp
|
||||||
|
self['nodePath'].setPosHpr(0,0,0,0,0,0)
|
||||||
|
# Set playback start to refineStart
|
||||||
|
self.playbackGoTo(self.refineStart)
|
||||||
|
# start flying nodePath along path
|
||||||
|
self.startPlayback()
|
||||||
# Start new task
|
# Start new task
|
||||||
t = taskMgr.spawnMethodNamed(
|
t = taskMgr.spawnMethodNamed(
|
||||||
self.recordTask, self['name'] + '-recordTask')
|
self.recordTask, self['name'] + '-recordTask')
|
||||||
t.startTime = globalClock.getTime()
|
t.startTime = globalClock.getTime()
|
||||||
t.uponDeath = self.endRecordTask
|
|
||||||
else:
|
else:
|
||||||
# Add hook
|
# Add hook
|
||||||
self.acceptKeyframeHook()
|
self.acceptKeyframeHook()
|
||||||
# Record first point
|
# Record first point
|
||||||
self.startPos = self['nodePath'].getPos()
|
self.startPos = self['nodePath'].getPos(self.nodePathParent)
|
||||||
self.recordPoint(0.0)
|
self.recordPoint(0.0)
|
||||||
|
|
||||||
# Don't want to change record modes
|
# Don't want to change record modes
|
||||||
@ -604,8 +668,20 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
self.addKeyframe()
|
self.addKeyframe()
|
||||||
# Ignore hook
|
# Ignore hook
|
||||||
self.ignoreKeyframeHook()
|
self.ignoreKeyframeHook()
|
||||||
# Compute curve
|
if self.fRefine:
|
||||||
self.computeCurves()
|
# Reparent node path back to parent
|
||||||
|
self['nodePath'].wrtReparentTo(self.nodePathParent)
|
||||||
|
# Restore playback Node Path
|
||||||
|
self.playbackNodePath = self.lastPlaybackNodePath
|
||||||
|
# Merge prePoints, pointSet, postPoints
|
||||||
|
self.mergePoints()
|
||||||
|
# Clear out pre and post list
|
||||||
|
self.prePoints = []
|
||||||
|
self.postPoints = []
|
||||||
|
# Reset flag
|
||||||
|
self.fRefine = 0
|
||||||
|
# Compute curve
|
||||||
|
self.computeCurves()
|
||||||
# Now you can change record modes
|
# Now you can change record modes
|
||||||
self.getWidget('Recording', 'Continuous Recording')['state'] = (
|
self.getWidget('Recording', 'Continuous Recording')['state'] = (
|
||||||
'normal')
|
'normal')
|
||||||
@ -614,16 +690,61 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
|
|
||||||
def recordTask(self, state):
|
def recordTask(self, state):
|
||||||
# Record raw data point
|
# Record raw data point
|
||||||
time = globalClock.getTime() - state.startTime
|
time = self.refineStart + (globalClock.getTime() - state.startTime)
|
||||||
self.recordPoint(time)
|
self.recordPoint(time)
|
||||||
return Task.cont
|
return Task.cont
|
||||||
|
|
||||||
def endRecordTask(self, state):
|
def addKeyframe(self):
|
||||||
self.computeCurves()
|
time = (self.refineStart +
|
||||||
|
(Vec3(self['nodePath'].getPos(self.nodePathParent) -
|
||||||
|
self.startPos).length()))
|
||||||
|
self.recordPoint(time)
|
||||||
|
|
||||||
|
def easeInOut(self, t):
|
||||||
|
x = t * t
|
||||||
|
return (3 * x) - (2 * t * x)
|
||||||
|
|
||||||
|
def setPreRecordFunc(self, event):
|
||||||
|
try:
|
||||||
|
self.preRecordFunc = eval(
|
||||||
|
self.getVariable('Recording', 'Pre Record Func').get())
|
||||||
|
# Update widget to reflect new value
|
||||||
|
self.getVariable('Recording', 'PRF Active').set(1)
|
||||||
|
except NameError:
|
||||||
|
# See if you can find func in the globals dictionary
|
||||||
|
# Note: need to set __builtins__.func at command line
|
||||||
|
self.preRecordFunc = eval(
|
||||||
|
self.getVariable('Recording', 'Pre Record Func').get(),
|
||||||
|
globals())
|
||||||
|
# Update widget to reflect new value
|
||||||
|
self.getVariable('Recording', 'PRF Active').set(1)
|
||||||
|
|
||||||
def recordPoint(self, time):
|
def recordPoint(self, time):
|
||||||
pos = self['nodePath'].getPos()
|
# Call user define callback before recording point
|
||||||
hpr = self['nodePath'].getHpr()
|
if (self.getVariable('Recording', 'PRF Active').get() &
|
||||||
|
(self.preRecordFunc != None)):
|
||||||
|
self.preRecordFunc()
|
||||||
|
# Get point
|
||||||
|
pos = self['nodePath'].getPos(self.nodePathParent)
|
||||||
|
hpr = self['nodePath'].getHpr(self.nodePathParent)
|
||||||
|
# Blend between recordNodePath and self['nodePath']
|
||||||
|
if self.fRefine:
|
||||||
|
if (time < self.controlStart):
|
||||||
|
rPos = self.playbackNodePath.getPos(self.nodePathParent)
|
||||||
|
rHpr = self.playbackNodePath.getHpr(self.nodePathParent)
|
||||||
|
t = self.easeInOut(((time - self.refineStart)/
|
||||||
|
(self.controlStart - self.refineStart)))
|
||||||
|
# Transition between the recorded node path and the driven one
|
||||||
|
pos = (rPos * (1 - t)) + (pos * t)
|
||||||
|
hpr = (rHpr * (1 - t)) + (hpr * t)
|
||||||
|
elif (time > self.controlStop):
|
||||||
|
rPos = self.playbackNodePath.getPos(self.nodePathParent)
|
||||||
|
rHpr = self.playbackNodePath.getHpr(self.nodePathParent)
|
||||||
|
t = self.easeInOut(((time - self.controlStop)/
|
||||||
|
(self.refineStop - self.controlStop)))
|
||||||
|
# Transition between the recorded node path and the driven one
|
||||||
|
pos = (pos * (1 - t)) + (rPos * t)
|
||||||
|
hpr = (hpr * (1 - t)) + (rHpr * t)
|
||||||
# Add it to the point set
|
# Add it to the point set
|
||||||
self.pointSet.append([time, pos, hpr])
|
self.pointSet.append([time, pos, hpr])
|
||||||
# Add it to the curve fitters
|
# Add it to the curve fitters
|
||||||
@ -631,10 +752,6 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
self.hprCurveFitter.addPoint(time, hpr)
|
self.hprCurveFitter.addPoint(time, hpr)
|
||||||
self.fHasPoints = 1
|
self.fHasPoints = 1
|
||||||
|
|
||||||
def addKeyframe(self):
|
|
||||||
time = Vec3(self['nodePath'].getPos() - self.startPos).length()
|
|
||||||
self.recordPoint(time)
|
|
||||||
|
|
||||||
def computeCurves(self):
|
def computeCurves(self):
|
||||||
# MRM: Would be better if curvefitter had getNumPoints
|
# MRM: Would be better if curvefitter had getNumPoints
|
||||||
if not self.fHasPoints:
|
if not self.fHasPoints:
|
||||||
@ -642,11 +759,13 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
return
|
return
|
||||||
# Create curves
|
# Create curves
|
||||||
# XYZ
|
# XYZ
|
||||||
|
self.xyzCurveFitter.sortPoints()
|
||||||
self.xyzCurveFitter.computeTangents(1)
|
self.xyzCurveFitter.computeTangents(1)
|
||||||
self.xyzNurbsCurve = self.xyzCurveFitter.makeNurbs()
|
self.xyzNurbsCurve = self.xyzCurveFitter.makeNurbs()
|
||||||
self.nurbsCurveDrawer.setCurve(self.xyzNurbsCurve)
|
self.nurbsCurveDrawer.setCurve(self.xyzNurbsCurve)
|
||||||
self.nurbsCurveDrawer.draw()
|
self.nurbsCurveDrawer.draw()
|
||||||
# HPR
|
# HPR
|
||||||
|
self.hprCurveFitter.sortPoints()
|
||||||
self.hprCurveFitter.wrapHpr()
|
self.hprCurveFitter.wrapHpr()
|
||||||
self.hprCurveFitter.computeTangents(1)
|
self.hprCurveFitter.computeTangents(1)
|
||||||
self.hprNurbsCurve = self.hprCurveFitter.makeNurbs()
|
self.hprNurbsCurve = self.hprCurveFitter.makeNurbs()
|
||||||
@ -660,8 +779,18 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
maxT = '%.2f' % self.xyzNurbsCurve.getMaxT()
|
maxT = '%.2f' % self.xyzNurbsCurve.getMaxT()
|
||||||
self.getWidget('Playback', 'Time').configure(max = maxT)
|
self.getWidget('Playback', 'Time').configure(max = maxT)
|
||||||
self.getVariable('Resample', 'Path Duration').set(maxT)
|
self.getVariable('Resample', 'Path Duration').set(maxT)
|
||||||
self.getWidget('Refine Page', 'From').configure(max = maxT)
|
widget = self.getWidget('Refine Page', 'Refine From')
|
||||||
self.getWidget('Refine Page', 'To').configure(max = maxT)
|
widget.configure(max = maxT)
|
||||||
|
widget.set(0.0)
|
||||||
|
widget = self.getWidget('Refine Page', 'Control Start')
|
||||||
|
widget.configure(max = maxT)
|
||||||
|
widget.set(0.0)
|
||||||
|
widget = self.getWidget('Refine Page', 'Control Stop')
|
||||||
|
widget.configure(max = maxT)
|
||||||
|
widget.set(float(maxT))
|
||||||
|
widget = self.getWidget('Refine Page', 'Refine To')
|
||||||
|
widget.configure(max = maxT)
|
||||||
|
widget.set(float(maxT))
|
||||||
self.maxT = float(maxT)
|
self.maxT = float(maxT)
|
||||||
# Widgets depending on number of knots
|
# Widgets depending on number of knots
|
||||||
numKnots = self.xyzNurbsCurve.getNumKnots()
|
numKnots = self.xyzNurbsCurve.getNumKnots()
|
||||||
@ -767,7 +896,7 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
return
|
return
|
||||||
# Get node path's name
|
# Get node path's name
|
||||||
name = nodePath.getName()
|
name = nodePath.getName()
|
||||||
if name in ['parent', 'render', 'camera', 'marker']:
|
if name in ['mopathRecorderTempCS', 'widget', 'camera', 'marker']:
|
||||||
dictName = name
|
dictName = name
|
||||||
else:
|
else:
|
||||||
# Generate a unique name for the dict
|
# Generate a unique name for the dict
|
||||||
@ -784,9 +913,6 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
def setLoopPlayback(self):
|
def setLoopPlayback(self):
|
||||||
self.loopPlayback = self.getVariable('Playback', 'Loop').get()
|
self.loopPlayback = self.getVariable('Playback', 'Loop').get()
|
||||||
|
|
||||||
def setPlaybackTime(self, time):
|
|
||||||
self.playbackGoTo(time)
|
|
||||||
|
|
||||||
def playbackGoTo(self, time):
|
def playbackGoTo(self, time):
|
||||||
if (self.xyzNurbsCurve == None) & (self.hprNurbsCurve == None):
|
if (self.xyzNurbsCurve == None) & (self.hprNurbsCurve == None):
|
||||||
return
|
return
|
||||||
@ -795,7 +921,6 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
pos = Vec3(0)
|
pos = Vec3(0)
|
||||||
self.xyzNurbsCurve.getPoint(self.playbackTime, pos)
|
self.xyzNurbsCurve.getPoint(self.playbackTime, pos)
|
||||||
self.playbackNodePath.setPos(pos)
|
self.playbackNodePath.setPos(pos)
|
||||||
self.playbackNodePath.setPos(pos)
|
|
||||||
if self.hprNurbsCurve != None:
|
if self.hprNurbsCurve != None:
|
||||||
hpr = Vec3(0)
|
hpr = Vec3(0)
|
||||||
self.hprNurbsCurve.getPoint(self.playbackTime, hpr)
|
self.hprNurbsCurve.getPoint(self.playbackTime, hpr)
|
||||||
@ -819,12 +944,18 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
if self.loopPlayback:
|
if self.loopPlayback:
|
||||||
cTime = (state.startOffset + dTime) % self.maxT
|
cTime = (state.startOffset + dTime) % self.maxT
|
||||||
else:
|
else:
|
||||||
cTime = CLAMP(state.startOffset + dTime, 0.0, self.maxT)
|
cTime = state.startOffset + dTime
|
||||||
self.getWidget('Playback', 'Time').set(cTime)
|
|
||||||
# Stop task if not looping and at end of curve
|
# Stop task if not looping and at end of curve
|
||||||
if ((self.loopPlayback == 0) & ((cTime + 0.01) > self.maxT)):
|
# Or if refining curve and past refineStop
|
||||||
|
if (((self.loopPlayback == 0) & (cTime > self.maxT)) |
|
||||||
|
(self.fRefine & (cTime > self.refineStop))):
|
||||||
self.stopPlayback()
|
self.stopPlayback()
|
||||||
|
if self.fRefine:
|
||||||
|
# Kill record task
|
||||||
|
self.toggleRecordVar()
|
||||||
return Task.done
|
return Task.done
|
||||||
|
# Otherwise go to specified time
|
||||||
|
self.getWidget('Playback', 'Time').set(cTime)
|
||||||
return Task.cont
|
return Task.cont
|
||||||
|
|
||||||
def stopPlayback(self):
|
def stopPlayback(self):
|
||||||
@ -902,11 +1033,119 @@ class MopathRecorder(AppShell, PandaObject):
|
|||||||
# Update info
|
# Update info
|
||||||
self.updateCurveInfo()
|
self.updateCurveInfo()
|
||||||
|
|
||||||
|
def setRefineFlag(self, val = 1):
|
||||||
|
self.fRefine = val
|
||||||
|
|
||||||
def setRefineStart(self,value):
|
def setRefineStart(self,value):
|
||||||
print 'refine start'
|
self.refineStart = value
|
||||||
|
# Someone else is adjusting values, let them take care of it
|
||||||
|
if self.fAdjustingValues:
|
||||||
|
return
|
||||||
|
self.fAdjustingValues = 1
|
||||||
|
if self.refineStart > self.controlStart:
|
||||||
|
self.getWidget('Refine Page', 'Control Start').set(
|
||||||
|
self.refineStart)
|
||||||
|
if self.refineStart > self.controlStop:
|
||||||
|
self.getWidget('Refine Page', 'Control Stop').set(
|
||||||
|
self.refineStart)
|
||||||
|
if self.refineStart > self.refineStop:
|
||||||
|
self.getWidget('Refine Page', 'Refine To').set(self.refineStart)
|
||||||
|
self.fAdjustingValues = 0
|
||||||
|
|
||||||
|
def getPrePoints(self):
|
||||||
|
# Set flag so we know to do a refine pass
|
||||||
|
self.setRefineFlag(1)
|
||||||
|
# Reset prePoints
|
||||||
|
self.prePoints = []
|
||||||
|
# See if we need to save any points before refineStart
|
||||||
|
for i in range(len(self.pointSet)):
|
||||||
|
# Have we passed refineStart?
|
||||||
|
if self.refineStart < self.pointSet[i][0]:
|
||||||
|
# Get a copy of the points prior to refineStart
|
||||||
|
self.prePoints = self.pointSet[:i-1]
|
||||||
|
break
|
||||||
|
|
||||||
|
def setControlStart(self, value):
|
||||||
|
self.controlStart = value
|
||||||
|
# Someone else is adjusting values, let them take care of it
|
||||||
|
if self.fAdjustingValues:
|
||||||
|
return
|
||||||
|
self.fAdjustingValues = 1
|
||||||
|
if self.controlStart < self.refineStart:
|
||||||
|
self.getWidget('Refine Page', 'Refine From').set(
|
||||||
|
self.controlStart)
|
||||||
|
if self.controlStart > self.controlStop:
|
||||||
|
self.getWidget('Refine Page', 'Control Stop').set(
|
||||||
|
self.controlStart)
|
||||||
|
if self.controlStart > self.refineStop:
|
||||||
|
self.getWidget('Refine Page', 'Refine To').set(
|
||||||
|
self.controlStart)
|
||||||
|
self.fAdjustingValues = 0
|
||||||
|
|
||||||
|
def setControlStop(self, value):
|
||||||
|
self.controlStop = value
|
||||||
|
# Someone else is adjusting values, let them take care of it
|
||||||
|
if self.fAdjustingValues:
|
||||||
|
return
|
||||||
|
self.fAdjustingValues = 1
|
||||||
|
if self.controlStop < self.refineStart:
|
||||||
|
self.getWidget('Refine Page', 'Refine From').set(
|
||||||
|
self.controlStop)
|
||||||
|
if self.controlStop < self.controlStart:
|
||||||
|
self.getWidget('Refine Page', 'Control Start').set(
|
||||||
|
self.controlStop)
|
||||||
|
if self.controlStop > self.refineStop:
|
||||||
|
self.getWidget('Refine Page', 'Refine To').set(
|
||||||
|
self.controlStop)
|
||||||
|
self.fAdjustingValues = 0
|
||||||
|
|
||||||
def setRefineStop(self, value):
|
def setRefineStop(self, value):
|
||||||
print 'refine stop'
|
self.refineStop = value
|
||||||
|
# Someone else is adjusting values, let them take care of it
|
||||||
|
if self.fAdjustingValues:
|
||||||
|
return
|
||||||
|
self.fAdjustingValues = 1
|
||||||
|
if self.refineStop < self.refineStart:
|
||||||
|
self.getWidget('Refine Page', 'Refine From').set(
|
||||||
|
self.refineStop)
|
||||||
|
if self.refineStop < self.controlStart:
|
||||||
|
self.getWidget('Refine Page', 'Control Start').set(
|
||||||
|
self.refineStop)
|
||||||
|
if self.refineStop < self.controlStop:
|
||||||
|
self.getWidget('Refine Page', 'Control Stop').set(
|
||||||
|
self.refineStop)
|
||||||
|
self.fAdjustingValues = 0
|
||||||
|
|
||||||
|
def getPostPoints(self):
|
||||||
|
# Set flag so we know to do a refine pass
|
||||||
|
self.setRefineFlag(1)
|
||||||
|
# Reset postPoints
|
||||||
|
self.postPoints = []
|
||||||
|
# See if we need to save any points after refineStop
|
||||||
|
for i in range(len(self.pointSet)):
|
||||||
|
# Have we reached refineStop?
|
||||||
|
if self.refineStop < self.pointSet[i][0]:
|
||||||
|
# Get a copy of the points after refineStop
|
||||||
|
self.postPoints = self.pointSet[i:]
|
||||||
|
break
|
||||||
|
|
||||||
|
def mergePoints(self):
|
||||||
|
# Merge in pre points
|
||||||
|
self.pointSet = self.prePoints + self.pointSet
|
||||||
|
for time, pos, hpr in self.prePoints:
|
||||||
|
# Add it to the curve fitters
|
||||||
|
self.xyzCurveFitter.addPoint(time, pos )
|
||||||
|
self.hprCurveFitter.addPoint(time, hpr)
|
||||||
|
# And post points
|
||||||
|
# What is end time of pointSet?
|
||||||
|
endTime = self.pointSet[-1][0]
|
||||||
|
for time, pos, hpr in self.postPoints:
|
||||||
|
adjustedTime = endTime + (time - self.refineStop)
|
||||||
|
# Add it to point set
|
||||||
|
self.pointSet.append([adjustedTime, pos, hpr])
|
||||||
|
# Add it to the curve fitters
|
||||||
|
self.xyzCurveFitter.addPoint(adjustedTime, pos)
|
||||||
|
self.hprCurveFitter.addPoint(adjustedTime, hpr)
|
||||||
|
|
||||||
def resetOffset(self):
|
def resetOffset(self):
|
||||||
print 'reset offset'
|
print 'reset offset'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user