*** empty log message ***

This commit is contained in:
Mark Mine 2001-02-11 06:43:45 +00:00
parent 862e472a19
commit f361e4d922
5 changed files with 515 additions and 239 deletions

View File

@ -175,6 +175,9 @@ class DirectJoybox(PandaObject):
self.enable()
def joyboxFly(self):
# Do nothing if no nodePath selected
if self.nodePath == None:
return
hprScale = (self.analogs.normalizeChannel(L_SLIDE, 0.1, 100) *
DirectJoybox.hprMultiplier)
posScale = (self.analogs.normalizeChannel(R_SLIDE, 0.1, 100) *
@ -215,6 +218,12 @@ class DirectJoybox(PandaObject):
self.modifier = [1,1,1,-1,1,0]
self.setMode(self.joyboxFly, 'Look At Mode')
def lookAroundMode(self):
self.mapping = [NULL_AXIS, NULL_AXIS, NULL_AXIS,
R_LEFT_RIGHT, R_FWD_BACK, NULL_AXIS]
self.modifier = [0,0,0,-1,-1,0]
self.setMode(self.joyboxFly, 'Lookaround Mode')
def demoMode(self):
self.mapping = [R_LEFT_RIGHT, R_FWD_BACK, L_FWD_BACK,
R_TWIST, NULL_AXIS, NULL_AXIS]
@ -227,12 +236,6 @@ class DirectJoybox(PandaObject):
self.modifier = [1,1,-1,-1,-1,1]
self.setMode(self.joyboxFly, 'HprXyz Mode')
def lookaroundMode(self):
self.mapping = [NULL_AXIS, NULL_AXIS, NULL_AXIS,
R_LEFT_RIGHT, R_FWD_BACK, NULL_AXIS]
self.modifier = [0,0,0,-1,-1,0]
self.setMode(self.joyboxFly, 'Lookaround Mode')
def walkthruMode(self):
self.mapping = [R_LEFT_RIGHT, R_FWD_BACK, L_TWIST,
R_TWIST, L_FWD_BACK, L_LEFT_RIGHT]
@ -243,6 +246,9 @@ class DirectJoybox(PandaObject):
self.setMode(self.orbitFly, 'Orbit Mode')
def orbitFly(self):
# Do nothing if no nodePath selected
if self.nodePath == None:
return
hprScale = (self.analogs.normalizeChannel(L_SLIDE, 0.1, 100) *
DirectJoybox.hprMultiplier)
posScale = (self.analogs.normalizeChannel(R_SLIDE, 0.1, 100) *

View File

@ -380,9 +380,9 @@ class DirectBoundingBox:
class SelectionRay:
def __init__(self, camera):
# Create a collision node path attached to the given camera
self.rayCollisionNodePath = camera.attachNewNode( CollisionNode() )
def __init__(self, parent):
# Create a collision node path attached to the given parent
self.rayCollisionNodePath = parent.attachNewNode( CollisionNode() )
# Don't pay the penalty of drawing this collision ray
self.rayCollisionNodePath.hide()
self.rayCollisionNode = self.rayCollisionNodePath.node()
@ -419,7 +419,7 @@ class SelectionRay:
index = -1
# Pick out the closest object that isn't a widget
for i in range(0,numEntries):
entry = direct.iRay.cq.getEntry(i)
entry = self.cq.getEntry(i)
node = entry.getIntoNode()
# Don't pick hidden nodes
if node.isHidden():
@ -443,8 +443,8 @@ class SelectionRay:
# Did we hit an object?
if(index >= 0):
# Yes!
# Find hit point in camera's space
hitPt = direct.iRay.camToHitPt(index)
# Find hit point in parent's space
hitPt = self.parentToHitPt(index)
hitPtDist = Vec3(hitPt - ZERO_POINT).length()
return (node, hitPt, hitPtDist)
else:
@ -460,11 +460,11 @@ class SelectionRay:
# Yes!
# Entry 0 is the closest hit point if multiple hits
minPt = 0
# Find hit point in camera's space
hitPt = direct.iRay.camToHitPt(minPt)
# Find hit point in parent's space
hitPt = self.parentToHitPt(minPt)
hitPtDist = Vec3(hitPt).length()
# Get the associated collision queue object
entry = direct.iRay.cq.getEntry(minPt)
entry = self.cq.getEntry(minPt)
# Extract the node
node = entry.getIntoNode()
# Return info
@ -481,6 +481,55 @@ class SelectionRay:
self.cq.sortEntries()
return self.numEntries
def pickGeom3D(self, targetNodePath = render, origin = Point3(0),
dir = Vec3(0,0,-1), fIntersectUnpickable = 0):
self.collideWithGeom()
numEntries = self.pick3D(targetNodePath, origin, dir)
# Init index
index = -1
# Pick out the closest object that isn't a widget
for i in range(0,numEntries):
entry = self.cq.getEntry(i)
node = entry.getIntoNode()
# Don't pick hidden nodes
if node.isHidden():
pass
# Can pick unpickable, use the first visible node
elif fIntersectUnpickable:
index = i
break
# Is it a named node?, If so, see if it has a name
elif issubclass(node.__class__, NamedNode):
name = node.getName()
if name in self.unpickable:
pass
else:
index = i
break
# Not hidden and not one of the widgets, use it
else:
index = i
break
# Did we hit an object?
if(index >= 0):
# Yes!
# Find hit point in parent's space
hitPt = self.parentToHitPt(index)
hitPtDist = Vec3(hitPt - ZERO_POINT).length()
return (node, hitPt, hitPtDist)
else:
return (None, ZERO_POINT, 0)
def pick3D(self, targetNodePath, origin, dir):
# Determine ray direction based upon the mouse coordinates
# Note! This has to be a cam object (of type ProjectionNode)
self.ray.setOrigin( origin )
self.ray.setDirection( dir )
self.ct.traverse( targetNodePath.node() )
self.numEntries = self.cq.getNumEntries()
self.cq.sortEntries()
return self.numEntries
def collideWithGeom(self):
self.rayCollisionNode.setIntoCollideMask(BitMask32().allOff())
self.rayCollisionNode.setFromCollideMask(BitMask32().allOff())
@ -496,10 +545,10 @@ class SelectionRay:
def objectToHitPt(self, index):
return self.cq.getEntry(index).getIntoIntersectionPoint()
def camToHitPt(self, index):
def parentToHitPt(self, index):
# Get the specified entry
entry = self.cq.getEntry(index)
hitPt = entry.getIntoIntersectionPoint()
# Convert point from object local space to camera space
# Convert point from object local space to parent's space
return entry.getInvWrtSpace().xformPoint(hitPt)

View File

@ -59,6 +59,8 @@ class DirectSession(PandaObject):
if joybox:
from DirectJoybox import *
self.joybox = DirectJoybox(joybox)
else:
self.joybox = None
else:
self.deviceManager = None

View File

@ -59,6 +59,13 @@ class DirectSessionPanel(AppShell):
self.nodePathDict['widget'] = direct.widget
self.nodePathNames = ['widget']
# Dictionary keeping track of all jb node paths selected so far
self.jbNodePathDict = {}
self.jbNodePathDict['none'] = 'No Node Path'
self.jbNodePathDict['widget'] = direct.widget
self.jbNodePathDict['camera'] = direct.camera
self.jbNodePathNames = ['camera', 'selected', 'none']
# Set up event hooks
self.actionEvents = [('undo', self.undoHook),
('pushUndo', self.pushUndoHook),
@ -108,7 +115,7 @@ class DirectSessionPanel(AppShell):
self.nodePathMenu.component('entryfield_entry'))
self.nodePathMenuBG = (
self.nodePathMenuEntry.configure('background')[3])
self.nodePathMenu.pack(side = 'left', fill = 'x', expand = 1)
self.nodePathMenu.pack(side = LEFT, fill = X, expand = 1)
self.bind(self.nodePathMenu, 'Select node path to manipulate')
self.undoButton = Button(menuFrame, text = 'Undo',
@ -117,7 +124,7 @@ class DirectSessionPanel(AppShell):
self.undoButton['state'] = 'normal'
else:
self.undoButton['state'] = 'disabled'
self.undoButton.pack(side = 'left', expand = 0)
self.undoButton.pack(side = LEFT, expand = 0)
self.bind(self.undoButton, 'Undo last operation')
self.redoButton = Button(menuFrame, text = 'Redo',
@ -126,7 +133,7 @@ class DirectSessionPanel(AppShell):
self.redoButton['state'] = 'normal'
else:
self.redoButton['state'] = 'disabled'
self.redoButton.pack(side = 'left', expand = 0)
self.redoButton.pack(side = LEFT, expand = 0)
self.bind(self.redoButton, 'Redo last operation')
# The master frame for the dials
@ -135,7 +142,7 @@ class DirectSessionPanel(AppShell):
# Scene Graph Explorer
sgeFrame = Frame(mainFrame)
self.sgeUpdate = Button(sgeFrame, text = 'Update Explorer')
self.sgeUpdate.pack(fill = 'x', expand = 0)
self.sgeUpdate.pack(fill = X, expand = 0)
self.SGE = SceneGraphExplorer.SceneGraphExplorer(
sgeFrame, nodePath = render,
scrolledCanvas_hull_width = 200,
@ -149,8 +156,8 @@ class DirectSessionPanel(AppShell):
notebook.pack(fill = BOTH, expand = 1)
envPage = notebook.add('Environment')
lightsPage = notebook.add('Lights')
renderPage = notebook.add('Render Style')
gridPage = notebook.add('Grid')
devicePage = notebook.add('Devices')
scenePage = notebook.add('Scene')
# Put this here so it isn't called right away
notebook['raisecommand'] = self.updateInfo
@ -165,7 +172,7 @@ class DirectSessionPanel(AppShell):
self.backgroundColor = VectorWidgets.ColorEntry(
bkgrdFrame, text = 'Background Color')
self.backgroundColor['command'] = self.setBackgroundColor
self.backgroundColor.pack(fill = 'x', expand = 0)
self.backgroundColor.pack(fill = X, expand = 0)
self.bind(self.backgroundColor, 'Set background color')
bkgrdFrame.pack(fill = BOTH, expand = 0)
@ -180,7 +187,7 @@ class DirectSessionPanel(AppShell):
entry_width = 20,
selectioncommand = self.selectDisplayRegionNamed,
scrolledlist_items = nameList)
self.drMenu.pack(fill = 'x', expand = 0)
self.drMenu.pack(fill = X, expand = 0)
self.bind(self.drMenu, 'Select display region to configure')
self.nearPlane = Floater.Floater(
@ -188,7 +195,7 @@ class DirectSessionPanel(AppShell):
text = 'Near Plane',
min = 0.01)
self.nearPlane['command'] = self.setNear
self.nearPlane.pack(fill = 'x', expand = 0)
self.nearPlane.pack(fill = X, expand = 0)
self.bind(self.nearPlane, 'Set near plane distance')
self.farPlane = Floater.Floater(
@ -196,36 +203,78 @@ class DirectSessionPanel(AppShell):
text = 'Far Plane',
min = 0.01)
self.farPlane['command'] = self.setFar
self.farPlane.pack(fill = 'x', expand = 0)
self.farPlane.pack(fill = X, expand = 0)
self.bind(self.farPlane, 'Set far plane distance')
self.hFov = Floater.Floater(
drFrame,
fovFrame = Frame(drFrame)
fovFloaterFrame = Frame(fovFrame)
self.hFov = EntryScale.EntryScale(
fovFloaterFrame,
text = 'Horizontal FOV',
min = 0.01, max = 179.9)
min = 0.01, max = 170.0)
self.hFov['command'] = self.setHFov
self.hFov.pack(fill = 'x', expand = 0)
self.hFov.pack(fill = X, expand = 0)
self.bind(self.hFov, 'Set horizontal field of view')
self.vFov = Floater.Floater(
drFrame,
self.vFov = EntryScale.EntryScale(
fovFloaterFrame,
text = 'Vertical FOV',
min = 0.01, max = 179.9)
min = 0.01, max = 170.0)
self.vFov['command'] = self.setVFov
self.vFov.pack(fill = 'x', expand = 0)
self.vFov.pack(fill = X, expand = 0)
self.bind(self.vFov, 'Set vertical field of view')
fovFloaterFrame.pack(side = LEFT, fill = X, expand = 1)
frame = Frame(fovFrame)
self.lockedFov = BooleanVar()
self.lockedFov.set(1)
self.lockedFovButton = Checkbutton(
drFrame,
text = 'FOV Locked',
anchor = 'w', justify = 'left',
frame,
text = 'Locked',
anchor = 'w', justify = LEFT,
variable = self.lockedFov)
self.lockedFovButton.pack(fill = 'x', expand = 0)
self.lockedFovButton.pack(fill = X, expand = 0)
self.resetFovButton = Button(
frame,
text = 'Reset',
command = self.resetFov)
self.resetFovButton.pack(fill = X, expand = 0)
frame.pack(side = LEFT, fill = X, expand = 0)
fovFrame.pack(fill = X, expand = 1)
drFrame.pack(fill = BOTH, expand = 0)
## Render Style ##
toggleFrame = Frame(envPage, borderwidth = 2, relief = 'sunken')
Label(toggleFrame, text = 'Toggle Render Style',
font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
self.toggleBackfaceButton = Button(
toggleFrame,
text = 'Backface',
command = base.toggleBackface)
self.toggleBackfaceButton.pack(side = LEFT, fill = X, expand = 1)
self.toggleLightsButton = Button(
toggleFrame,
text = 'Lights',
command = direct.lights.toggle)
self.toggleLightsButton.pack(side = LEFT, fill = X, expand = 1)
self.toggleTextureButton = Button(
toggleFrame,
text = 'Texture',
command = base.toggleTexture)
self.toggleTextureButton.pack(side = LEFT, fill = X, expand = 1)
self.toggleWireframeButton = Button(
toggleFrame,
text = 'Wireframe',
command = base.toggleWireframe)
self.toggleWireframeButton.pack(fill = X, expand = 1)
toggleFrame.pack(side = LEFT, fill = X, expand = 1)
## Lights page ##
# Lights #
lightFrame = Frame(lightsPage, borderwidth = 2, relief = 'sunken')
@ -258,15 +307,15 @@ class DirectSessionPanel(AppShell):
# Main light switch
mainSwitchFrame = Frame(lightFrame)
Label(mainSwitchFrame,
text = 'Lighting:').pack(side = 'left', expand = 0)
text = 'Lighting:').pack(side = LEFT, expand = 0)
self.enableLights = BooleanVar()
self.enableLightsButton = Checkbutton(
mainSwitchFrame,
text = 'Enabled/Disabled',
variable = self.enableLights,
command = self.toggleLights)
self.enableLightsButton.pack(side = 'left', fill = 'x', expand = 0)
mainSwitchFrame.pack(fill = 'x', expand = 0)
self.enableLightsButton.pack(side = LEFT, fill = X, expand = 0)
mainSwitchFrame.pack(fill = X, expand = 0)
# Widget to select a light to configure
nameList = direct.lights.nameList
@ -277,7 +326,7 @@ class DirectSessionPanel(AppShell):
entry_width = 20,
selectioncommand = self.selectLightNamed,
scrolledlist_items = nameList)
self.lightMenu.pack(side = 'left', fill = 'x', expand = 0)
self.lightMenu.pack(side = LEFT, fill = X, expand = 0)
self.bind(self.lightMenu, 'Select light to configure')
self.lightActive = BooleanVar()
@ -286,22 +335,22 @@ class DirectSessionPanel(AppShell):
text = 'On/Off',
variable = self.lightActive,
command = self.toggleActiveLight)
self.lightActiveButton.pack(side = 'left', fill = 'x', expand = 0)
self.lightActiveButton.pack(side = LEFT, fill = X, expand = 0)
# Pack light menu
lightMenuFrame.pack(fill = 'x', expand = 0, padx = 2)
lightMenuFrame.pack(fill = X, expand = 0, padx = 2)
self.lightColor = VectorWidgets.ColorEntry(
lightFrame, text = 'Light Color')
self.lightColor['command'] = self.setLightColor
self.lightColor.pack(fill = 'x', expand = 0, padx = 4)
self.lightColor.pack(fill = X, expand = 0, padx = 4)
self.bind(self.lightColor, 'Set active light color')
# Directional light controls
self.dSpecularColor = VectorWidgets.ColorEntry(
directionalPage, text = 'Specular Color')
self.dSpecularColor['command'] = self.setSpecularColor
self.dSpecularColor.pack(fill = 'x', expand = 0)
self.dSpecularColor.pack(fill = X, expand = 0)
self.bind(self.dSpecularColor,
'Set directional light specular color')
@ -309,7 +358,7 @@ class DirectSessionPanel(AppShell):
self.pSpecularColor = VectorWidgets.ColorEntry(
pointPage, text = 'Specular Color')
self.pSpecularColor['command'] = self.setSpecularColor
self.pSpecularColor.pack(fill = 'x', expand = 0)
self.pSpecularColor.pack(fill = X, expand = 0)
self.bind(self.pSpecularColor,
'Set point light specular color')
@ -318,7 +367,7 @@ class DirectSessionPanel(AppShell):
text = 'Constant Attenuation',
min = 0.0, max = 1.0, initialValue = 1.0)
self.pConstantAttenuation['command'] = self.setConstantAttenuation
self.pConstantAttenuation.pack(fill = 'x', expand = 0)
self.pConstantAttenuation.pack(fill = X, expand = 0)
self.bind(self.pConstantAttenuation,
'Set point light constant attenuation')
@ -327,7 +376,7 @@ class DirectSessionPanel(AppShell):
text = 'Linear Attenuation',
min = 0.0, max = 1.0, initialValue = 0.0)
self.pLinearAttenuation['command'] = self.setLinearAttenuation
self.pLinearAttenuation.pack(fill = 'x', expand = 0)
self.pLinearAttenuation.pack(fill = X, expand = 0)
self.bind(self.pLinearAttenuation,
'Set point light linear attenuation')
@ -336,7 +385,7 @@ class DirectSessionPanel(AppShell):
text = 'Quadratic Attenuation',
min = 0.0, max = 1.0, initialValue = 0.0)
self.pQuadraticAttenuation['command'] = self.setQuadraticAttenuation
self.pQuadraticAttenuation.pack(fill = 'x', expand = 0)
self.pQuadraticAttenuation.pack(fill = X, expand = 0)
self.bind(self.pQuadraticAttenuation,
'Set point light quadratic attenuation')
@ -344,7 +393,7 @@ class DirectSessionPanel(AppShell):
self.sSpecularColor = VectorWidgets.ColorEntry(
spotPage, text = 'Specular Color')
self.sSpecularColor['command'] = self.setSpecularColor
self.sSpecularColor.pack(fill = 'x', expand = 0)
self.sSpecularColor.pack(fill = X, expand = 0)
self.bind(self.sSpecularColor,
'Set spot light specular color')
@ -353,7 +402,7 @@ class DirectSessionPanel(AppShell):
text = 'Constant Attenuation',
min = 0.0, max = 1.0, initialValue = 1.0)
self.sConstantAttenuation['command'] = self.setConstantAttenuation
self.sConstantAttenuation.pack(fill = 'x', expand = 0)
self.sConstantAttenuation.pack(fill = X, expand = 0)
self.bind(self.sConstantAttenuation,
'Set spot light constant attenuation')
@ -362,7 +411,7 @@ class DirectSessionPanel(AppShell):
text = 'Linear Attenuation',
min = 0.0, max = 1.0, initialValue = 0.0)
self.sLinearAttenuation['command'] = self.setLinearAttenuation
self.sLinearAttenuation.pack(fill = 'x', expand = 0)
self.sLinearAttenuation.pack(fill = X, expand = 0)
self.bind(self.sLinearAttenuation,
'Set spot light linear attenuation')
@ -371,7 +420,7 @@ class DirectSessionPanel(AppShell):
text = 'Quadratic Attenuation',
min = 0.0, max = 1.0, initialValue = 0.0)
self.sQuadraticAttenuation['command'] = self.setQuadraticAttenuation
self.sQuadraticAttenuation.pack(fill = 'x', expand = 0)
self.sQuadraticAttenuation.pack(fill = X, expand = 0)
self.bind(self.sQuadraticAttenuation,
'Set spot light quadratic attenuation')
@ -380,7 +429,7 @@ class DirectSessionPanel(AppShell):
text = 'Exponent',
min = 0.0, max = 1.0, initialValue = 0.0)
self.sExponent['command'] = self.setExponent
self.sExponent.pack(fill = 'x', expand = 0)
self.sExponent.pack(fill = X, expand = 0)
self.bind(self.sExponent,
'Set spot light exponent')
@ -391,33 +440,6 @@ class DirectSessionPanel(AppShell):
lightFrame.pack(expand = 1, fill = BOTH)
## Render Style ##
toggleFrame = Frame(renderPage)
self.toggleBackfaceButton = Button(
toggleFrame,
text = 'Toggle backface',
command = base.toggleBackface)
self.toggleBackfaceButton.pack(fill = 'x', expand = 0)
self.toggleLightsButton = Button(
toggleFrame,
text = 'Toggle lights',
command = direct.lights.toggle)
self.toggleLightsButton.pack(fill = 'x', expand = 0)
self.toggleTextureButton = Button(
toggleFrame,
text = 'Toggle texture',
command = base.toggleTexture)
self.toggleTextureButton.pack(fill = 'x', expand = 0)
self.toggleWireframeButton = Button(
toggleFrame,
text = 'Toggle wireframe',
command = base.toggleWireframe)
self.toggleWireframeButton.pack(fill = 'x', expand = 0)
toggleFrame.pack(fill = BOTH, expand = 0)
## GRID PAGE ##
Label(gridPage, text = 'Grid',
font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
@ -425,28 +447,28 @@ class DirectSessionPanel(AppShell):
self.enableGridButton = Checkbutton(
gridPage,
text = 'Enabled/Disabled',
anchor = 'w', justify = 'left',
anchor = 'w', justify = LEFT,
variable = self.enableGrid,
command = self.toggleGrid)
self.enableGridButton.pack(fill = 'x', expand = 0)
self.enableGridButton.pack(fill = X, expand = 0)
self.xyzSnap = BooleanVar()
self.xyzSnapButton = Checkbutton(
gridPage,
text = 'XYZ Snap',
anchor = 'w', justify = 'left',
anchor = 'w', justify = LEFT,
variable = self.xyzSnap,
command = self.toggleXyzSnap)
self.xyzSnapButton.pack(fill = 'x', expand = 0)
self.xyzSnapButton.pack(fill = X, expand = 0)
self.hprSnap = BooleanVar()
self.hprSnapButton = Checkbutton(
gridPage,
text = 'HPR Snap',
anchor = 'w', justify = 'left',
anchor = 'w', justify = LEFT,
variable = self.hprSnap,
command = self.toggleHprSnap)
self.hprSnapButton.pack(fill = 'x', expand = 0)
self.hprSnapButton.pack(fill = X, expand = 0)
self.gridSpacing = Floater.Floater(
gridPage,
@ -454,7 +476,7 @@ class DirectSessionPanel(AppShell):
min = 0.1,
initialValue = direct.grid.getGridSpacing())
self.gridSpacing['command'] = direct.grid.setGridSpacing
self.gridSpacing.pack(fill = 'x', expand = 0)
self.gridSpacing.pack(fill = X, expand = 0)
self.gridSize = Floater.Floater(
gridPage,
@ -462,7 +484,7 @@ class DirectSessionPanel(AppShell):
min = 1.0,
initialValue = direct.grid.getGridSize())
self.gridSize['command'] = direct.grid.setGridSize
self.gridSize.pack(fill = 'x', expand = 0)
self.gridSize.pack(fill = X, expand = 0)
self.gridSnapAngle = Dial.Dial(
gridPage,
@ -472,8 +494,75 @@ class DirectSessionPanel(AppShell):
fRollover = 0,
initialValue = direct.grid.getSnapAngle())
self.gridSnapAngle['command'] = direct.grid.setSnapAngle
self.gridSnapAngle.pack(fill = 'x', expand = 0)
self.gridSnapAngle.pack(fill = X, expand = 0)
## DEVICE PAGE ##
Label(devicePage, text = 'DEVICES',
font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
if direct.joybox != None:
joyboxFrame = Frame(devicePage, borderwidth = 2, relief = 'sunken')
Label(joyboxFrame, text = 'Joybox',
font=('MSSansSerif', 14, 'bold')).pack(expand = 0)
self.enableJoybox = BooleanVar()
self.enableJoybox.set(1)
self.enableJoyboxButton = Checkbutton(
joyboxFrame,
text = 'Enabled/Disabled',
anchor = 'w', justify = LEFT,
variable = self.enableJoybox,
command = self.toggleJoybox)
self.enableJoyboxButton.pack(fill = X, expand = 0)
joyboxFrame.pack(fill = X, expand = 0)
self.jbModeMenu = Pmw.ComboBox(
joyboxFrame, labelpos = W, label_text = 'Joybox Mode:',
label_width = 16, entry_width = 20,
selectioncommand = self.selectJBModeNamed,
scrolledlist_items = ['Joe Mode', 'Drive Mode', 'Orbit Mode',
'Look At Mode', 'Look Around Mode',
'Walkthru Mode', 'Demo Mode',
'HPRXYZ Mode'])
self.jbModeMenu.selectitem('Joe Mode')
self.jbModeMenu.pack(fill = X, expand = 1)
self.jbNodePathMenu = Pmw.ComboBox(
joyboxFrame, labelpos = W, label_text = 'Joybox Node Path:',
label_width = 16, entry_width = 20,
selectioncommand = self.selectJBNodePathNamed,
scrolledlist_items = self.jbNodePathNames)
self.jbNodePathMenu.selectitem('camera')
self.jbNodePathMenuEntry = (
self.jbNodePathMenu.component('entryfield_entry'))
self.jbNodePathMenuBG = (
self.jbNodePathMenuEntry.configure('background')[3])
self.jbNodePathMenu.pack(fill = X, expand = 1)
self.bind(self.jbNodePathMenu,
'Select node path to manipulate using the joybox')
self.jbXyzSF = EntryScale.EntryScale(
joyboxFrame,
text = 'XYZ Scale Factor',
initialValue = 1.0,
hull_relief = RIDGE, hull_borderwidth = 2,
min = 1.0, max = 100.0)
self.jbXyzSF['command'] = (
lambda v: direct.joybox.setXyzMultiplier(v))
self.jbXyzSF.pack(fill = X, expand = 0)
self.bind(self.jbXyzSF, 'Set joybox XYZ speed multiplier')
self.jbHprSF = EntryScale.EntryScale(
joyboxFrame,
text = 'HPR Scale Factor',
initialValue = 1.0,
hull_relief = RIDGE, hull_borderwidth = 2,
min = 1.0, max = 100.0)
self.jbHprSF['command'] = (
lambda v: direct.joybox.setHprMultiplier(v))
self.jbHprSF.pack(fill = X, expand = 0)
self.bind(self.jbHprSF, 'Set joybox HPR speed multiplier')
notebook.setnaturalsize()
mainFrame.pack(fill = 'both', expand = 1)
@ -546,6 +635,59 @@ class DirectSessionPanel(AppShell):
self.addNodePathToDict(nodePath, self.nodePathNames,
self.nodePathMenu, self.nodePathDict)
def selectJBModeNamed(self, name):
if name == 'Joe Mode':
direct.joybox.joeMode()
elif name == 'Drive Mode':
direct.joybox.driveMode()
elif name == 'Orbit Mode':
direct.joybox.orbitMode()
elif name == 'Look At Mode':
direct.joybox.lookAtMode()
elif name == 'Look Around Mode':
direct.joybox.lookAroundMode()
elif name == 'Walkthru Mode':
direct.joybox.walkthruMode()
elif name == 'Demo Mode':
direct.joybox.demoMode()
elif name == 'HPRXYZ Mode':
direct.joybox.hprXyzMode()
def selectJBNodePathNamed(self, name):
if name == 'selected':
nodePath = direct.selected.last
# Add Combo box entry for this selected object
self.addJBNodePath(nodePath)
else:
# See if node path has already been selected
nodePath = self.jbNodePathDict.get(name, None)
if (nodePath == None):
# If not, see if listbox evals into a node path
try:
nodePath = eval(name)
if isinstance(nodePath, NodePath):
self.addJBNodePath(nodePath)
else:
# Good eval but not a node path, give up
nodePath = None
except:
# Bogus eval
nodePath = None
# Clear bogus entry from listbox
listbox = self.jbNodePathMenu.component('scrolledlist')
listbox.setlist(self.jbNodePathNames)
# Did we finally get something?
if (nodePath != None):
# Yes, select it!
if (nodePath == 'No Node Path'):
direct.joybox.setNodePath(None)
else:
direct.joybox.setNodePath(nodePath)
def addJBNodePath(self, nodePath):
self.addNodePathToDict(nodePath, self.jbNodePathNames,
self.jbNodePathMenu, self.jbNodePathDict)
def addNodePathToDict(self, nodePath, names, menu, dict):
if not nodePath:
return
@ -598,7 +740,7 @@ class DirectSessionPanel(AppShell):
if dr:
if self.lockedFov.get():
sf = hFov/dr.camNode.getHfov()
vFov = dr.camNode.getVfov() * sf
vFov = min(dr.camNode.getVfov() * sf, 170.0)
dr.camNode.setFov(hFov, vFov)
# Update scale
self.vFov.set(vFov, 0)
@ -611,7 +753,7 @@ class DirectSessionPanel(AppShell):
if dr:
if self.lockedFov.get():
sf = vFov/dr.camNode.getVfov()
hFov = dr.camNode.getHfov() * sf
hFov = min(dr.camNode.getHfov() * sf, 170.0)
dr.camNode.setFov(hFov, vFov)
# Update scale
self.hFov.set(hFov, 0)
@ -619,6 +761,13 @@ class DirectSessionPanel(AppShell):
# Just set horizontal
dr.camNode.setVfov(vFov)
def resetFov(self):
dr = self.activeDisplayRegion
if dr:
dr.camNode.setFov(45.0, 33.75)
self.hFov.set(45.0, 0)
self.vFov.set(33.75, 0)
# Lights #
def selectLightNamed(self, name):
self.activeLight = None
@ -723,6 +872,13 @@ class DirectSessionPanel(AppShell):
def toggleHprSnap(self):
direct.grid.setHprSnap(self.hprSnap.get())
## DEVICE CONTROLS
def toggleJoybox(self):
if self.enableJoybox.get():
direct.joybox.enable()
else:
direct.joybox.disable()
## UPDATE INFO ##
def updateInfo(self, page = 'Environment'):
if page == 'Environment':

View File

@ -5,36 +5,28 @@ from PandaObject import *
from Tkinter import *
from AppShell import *
from DirectGeometry import *
from DirectSelection import *
from tkFileDialog import *
import os
import Pmw
import Dial
import Floater
import EntryScale
import VectorWidgets
import __builtin__
"""
To Add
Num Segs lines between knots
Num Ticks
setCvColor <function setCvColor at 01BADDCC>
setColor <function setColor at 01B7B09C>
setHullColor <function setHullColor at 01BADA7C>
setKnotColor <function setKnotColor at 01BADA1C>
setShowCvs <function setShowCvs at 01BAD9BC>
setShowHull <function setShowHull at 01BAD8FC>
setShowKnots <function setShowKnots at 01BADB0C>
setNumSegs <function setNumSegs at 01B7B42C>
setNumTicks <function setNumTicks at 01B7B15C>
setTickColor <function setTickColor at 01B7B03C>
setTickScale <function setTickScale at 01B7CF6C>
"""
PRF_UTILITIES = [
'lambda: direct.camera.lookAt(render)',
'lambda: direct.camera.setZ(render, 0.0)',
'lambda s = self: s.playbackMarker.lookAt(render)',
'lambda s = self: s.playbackMarker.setZ(render, 0.0)',
'lambda s = self: s.followTerrain(10.0)']
class MopathRecorder(AppShell, PandaObject):
# Override class variables here
appname = 'Mopath Recorder Panel'
frameWidth = 450
frameHeight = 510
frameHeight = 535
usecommandarea = 0
usestatusarea = 0
count = 0
@ -67,8 +59,6 @@ class MopathRecorder(AppShell, PandaObject):
self.recorderNodePath = direct.group.attachNewNode(self.name)
self.tempCS = self.recorderNodePath.attachNewNode(
'mopathRecorderTempCS')
self.editCS = self.recorderNodePath.attachNewNode(
'mopathRecorderEditCS')
self.playbackMarker = loader.loadModel('models/directmodels/smiley')
self.playbackMarker.reparentTo(self.recorderNodePath)
self.playbackMarker.hide()
@ -95,14 +85,12 @@ class MopathRecorder(AppShell, PandaObject):
self.recNodePathDict['camera'] = direct.camera
self.recNodePathDict['widget'] = direct.widget
self.recNodePathDict['mopathRecorderTempCS'] = self.tempCS
self.recNodePathDict['edit CS'] = self.editCS
self.recNodePathNames = ['marker', 'camera', 'selected']
self.pbNodePathDict = {}
self.pbNodePathDict['marker'] = self.playbackMarker
self.pbNodePathDict['camera'] = direct.camera
self.pbNodePathDict['widget'] = direct.widget
self.pbNodePathDict['mopathRecorderTempCS'] = self.tempCS
self.pbNodePathDict['edit CS'] = self.editCS
self.pbNodePathNames = ['marker', 'camera', 'selected']
# Count of point sets recorded
self.pointSet = []
@ -112,6 +100,7 @@ class MopathRecorder(AppShell, PandaObject):
self.pointSetCount = 0
self.pointSetName = self.name + '-ps-' + `self.pointSetCount`
# User callback to call before recording point
self.samplingMode = 'Continuous'
self.preRecordFunc = None
# Hook to start/stop recording
self.startStopHook = 'f6'
@ -125,7 +114,7 @@ class MopathRecorder(AppShell, PandaObject):
self.numTicks = 1
# Number of segments to represent each parametric unit
# This just affects the visual appearance of the curve
self.numSegs = 20
self.numSegs = 40
# The nurbs curves
self.xyzNurbsCurve = None
self.hprNurbsCurve = None
@ -152,6 +141,10 @@ class MopathRecorder(AppShell, PandaObject):
self.cropFrom = 0.0
self.cropTo = 0.0
self.fAdjustingValues = 0
# For terrain following
self.iRayCS = self.recorderNodePath.attachNewNode(
'mopathRecorderIRayCS')
self.iRay = SelectionRay(self.iRayCS)
# Set up event hooks
self.actionEvents = [
('undo', self.undoHook),
@ -194,52 +187,6 @@ class MopathRecorder(AppShell, PandaObject):
'Save current curve as a new point set',
label = 'Save Point Set',
command = self.savePointSet)
self.menuBar.addcascademenu(
'Recorder', 'Show/Hide',
statusHelp = 'Show/Hide Mopath Recorder Objects',
tearoff = 1)
self.pathVis = BooleanVar()
self.pathVis.set(1)
self.menuBar.addmenuitem('Show/Hide', 'checkbutton',
'Toggle Path Visability',
label = 'Toggle Path Vis',
variable = self.pathVis,
command = self.setPathVis)
self.hullVis = BooleanVar()
self.hullVis.set(0)
self.menuBar.addmenuitem('Show/Hide', 'checkbutton',
'Toggle Hull Visability',
label = 'Toggle Hull Vis',
variable = self.hullVis,
command = self.setHullVis)
self.cvVis = BooleanVar()
self.cvVis.set(0)
self.menuBar.addmenuitem('Show/Hide', 'checkbutton',
'Toggle CV Visability',
label = 'Toggle CV Vis',
variable = self.cvVis,
command = self.setCvVis)
self.knotVis = BooleanVar()
self.knotVis.set(1)
self.menuBar.addmenuitem('Show/Hide', 'checkbutton',
'Toggle Knot Visability',
label = 'Toggle Knot Vis',
variable = self.knotVis,
command = self.setKnotVis)
self.tickVis = BooleanVar()
self.tickVis.set(0)
self.menuBar.addmenuitem('Show/Hide', 'checkbutton',
'Toggle Tick Visability',
label = 'Toggle Tick Vis',
variable = self.tickVis,
command = self.setTickVis)
self.markerVis = BooleanVar()
self.markerVis.set(1)
self.menuBar.addmenuitem('Show/Hide', 'checkbutton',
'Toggle Marker Visability',
label = 'Toggle Marker Vis',
variable = self.markerVis,
command = self.setMarkerVis)
self.menuBar.addmenuitem(
'Recorder', 'command',
'Toggle widget visability',
@ -281,6 +228,10 @@ class MopathRecorder(AppShell, PandaObject):
side = LEFT, fill = BOTH, expand = 1)
widget.configure(foreground = 'Red', relief = RAISED, borderwidth = 2,
anchor = CENTER, width = 16)
widget = self.createButton(frame, 'Recording', 'Add Keyframe',
'Add Keyframe To Current Path',
self.addKeyframe,
side = LEFT, expand = 1)
self.recordingType = StringVar()
self.recordingType.set('New Curve')
widget = self.createRadiobutton(
@ -381,6 +332,7 @@ class MopathRecorder(AppShell, PandaObject):
self.refinePage = self.mainNotebook.add('Refine')
self.extendPage = self.mainNotebook.add('Extend')
self.cropPage = self.mainNotebook.add('Crop')
self.stylePage = self.mainNotebook.add('Style')
## RECORD PAGE ##
recordFrame = Frame(self.recordPage, relief = SUNKEN,
@ -427,44 +379,18 @@ class MopathRecorder(AppShell, PandaObject):
frame.pack(expand = 1, fill = X)
# PreRecordFunc
frame = Frame(recordFrame)
widget = self.createLabeledEntry(
widget = self.createComboBox(
frame, 'Recording', 'Pre-Record Func',
'Function called before recording each point',
command = self.setPreRecordFunc)[0]
label = self.getWidget('Recording', 'Pre-Record Func-Label')
label.configure(width = 16, anchor = W)
'Function called before sampling each point',
PRF_UTILITIES, self.setPreRecordFunc,
history = 1, expand = 1)
widget.configure(label_width = 16, label_anchor = W)
widget.configure(entryfield_entry_state = 'normal')
self.createCheckbutton(frame, 'Recording', 'PRF Active',
'On: Pre Record Func enabled',
None, 0,
side = LEFT, fill = BOTH, expand = 0)
frame.pack(expand = 1, fill = X)
# Record type
frame = Frame(recordFrame)
self.samplingMode = StringVar()
self.samplingMode.set('Continuous')
widget = self.createRadiobutton(
frame, 'left',
'Recording', 'Continuous Sampling',
('New point added to curve fitter every frame'),
self.samplingMode, 'Continuous', self.setSamplingMode,
expand = 1)
widget['anchor'] = 'center'
widget = self.createRadiobutton(
frame, 'left',
'Recording', 'Keyframe Sampling',
('Add new point to curve fitter by pressing keyframe button'),
self.samplingMode, 'Keyframe', self.setSamplingMode,
expand = 1)
widget['anchor'] = 'center'
frame.pack(expand = 1, fill = X)
widget = self.createButton(recordFrame, 'Recording', 'Add Key Frame',
'Add Keyframe To Current Path',
self.addKeyframe,
side = LEFT, expand = 1)
widget.configure(state = 'disabled')
# Pack record frame
recordFrame.pack(fill = X, pady = 2)
@ -497,7 +423,7 @@ class MopathRecorder(AppShell, PandaObject):
font=('MSSansSerif', 12, 'bold')).pack()
widget = self.createEntryScale(
desampleFrame, 'Resample', 'Points Between Samples',
'Recompute curve using every nth point',
'Specify number of points to skip between samples',
min = 1, max = 100, resolution = 1,
command = self.setDesampleFrequency)
widget.component('hull')['relief'] = RIDGE
@ -516,6 +442,7 @@ class MopathRecorder(AppShell, PandaObject):
'Begin time of refine pass',
resolution = 0.01,
command = self.setRecordStart)
widget.onPress = self.setRefineMode
widget.onRelease = widget.onReturnRelease = (
lambda s = self: s.getPrePoints('Refine'))
widget = self.createEntryScale(
@ -524,18 +451,19 @@ class MopathRecorder(AppShell, PandaObject):
'Time when full control of node path is given during refine pass',
resolution = 0.01,
command = self.setControlStart)
widget.onRelease = widget.onReturnRelease = self.setRefineMode
widget.onPress = widget.onReturn = self.setRefineMode
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.setRefineMode
widget.onPress = widget.onReturn = self.setRefineMode
widget = self.createEntryScale(refineFrame, 'Refine Page', 'Refine To',
'Stop time of refine pass',
resolution = 0.01,
command = self.setRefineStop)
widget.onPress = self.setRefineMode
widget.onRelease = widget.onReturnRelease = self.getPostPoints
refineFrame.pack(fill = X)
@ -551,6 +479,7 @@ class MopathRecorder(AppShell, PandaObject):
'Begin time of extend pass',
resolution = 0.01,
command = self.setRecordStart)
widget.onPress = self.setExtendMode
widget.onRelease = widget.onReturnRelease = (
lambda s = self: s.getPrePoints('Extend'))
widget = self.createEntryScale(
@ -559,7 +488,7 @@ class MopathRecorder(AppShell, PandaObject):
'Time when full control of node path is given during extend pass',
resolution = 0.01,
command = self.setControlStart)
widget.onRelease = widget.onReturnRelease = self.setExtendMode
widget.onPress = widget.onReturn = self.setExtendMode
extendFrame.pack(fill = X)
## CROP PAGE ##
@ -588,6 +517,88 @@ class MopathRecorder(AppShell, PandaObject):
self.cropCurve, fill = NONE)
cropFrame.pack(fill = X)
## STYLE PAGE ##
styleFrame = Frame(self.stylePage, relief = SUNKEN,
borderwidth = 2)
label = Label(styleFrame, text = 'CURVE RENDERINNG STYLE',
font=('MSSansSerif', 12, 'bold'))
label.pack(fill = X)
self.sf = Pmw.ScrolledFrame(styleFrame, horizflex = 'elastic')
self.sf.pack(fill = 'both', expand = 1)
sfFrame = self.sf.interior()
frame = Frame(sfFrame)
widget = self.createCheckbutton(
frame, 'Style', 'Show Path',
'On: path is visible', self.setPathVis, 1,
side = LEFT, fill = X, expand = 1)
widget = self.createCheckbutton(
frame, 'Style', 'Show Knots',
'On: path knots are visible', self.setKnotVis, 1,
side = LEFT, fill = X, expand = 1)
widget = self.createCheckbutton(
frame, 'Style', 'Show CVs',
'On: path CVs are visible', self.setCvVis, 0,
side = LEFT, fill = X, expand = 1)
widget = self.createCheckbutton(
frame, 'Style', 'Show Hull',
'On: path hull is visible', self.setHullVis, 0,
side = LEFT, fill = X, expand = 1)
widget = self.createCheckbutton(
frame, 'Style', 'Show Marker',
'On: playback marker is visible', self.setMarkerVis, 0,
side = LEFT, fill = X, expand = 1)
frame.pack(fill = X, expand = 1)
# Sliders
widget = self.createEntryScale(
sfFrame, 'Style', 'Num Segs',
'Set number of segments used to approximate each parametric unit',
min = 1.0, max = 400, resolution = 1.0,
initialValue = 40,
command = self.setNumSegs, side = TOP)
widget.component('hull')['relief'] = RIDGE
widget = self.createEntryScale(
sfFrame, 'Style', 'Num Ticks',
'Set number of tick marks drawn for each unit of time',
min = 0.0, max = 10.0, resolution = 1.0,
initialValue = 0.0,
command = self.setNumTicks, side = TOP)
widget.component('hull')['relief'] = RIDGE
widget = self.createEntryScale(
sfFrame, 'Style', 'Tick Scale',
'Set visible size of time tick marks',
min = 0.01, max = 100.0, resolution = 0.01,
initialValue = 1.0,
command = self.setTickScale, side = TOP)
widget.component('hull')['relief'] = RIDGE
self.createColorEntry(
sfFrame, 'Style', 'Path Color',
'Color of curve',
command = self.setPathColor,
initialValue = [255.0,255.0,255.0,255.0])
self.createColorEntry(
sfFrame, 'Style', 'Knot Color',
'Color of knots',
command = self.setKnotColor,
initialValue = [0,0,255.0,255.0])
self.createColorEntry(
sfFrame, 'Style', 'CV Color',
'Color of CVs',
command = self.setCvColor,
initialValue = [255.0,0,0,255.0])
self.createColorEntry(
sfFrame, 'Style', 'Tick Color',
'Color of Ticks',
command = self.setTickColor,
initialValue = [255.0,0,0,255.0])
self.createColorEntry(
sfFrame, 'Style', 'Hull Color',
'Color of Hull',
command = self.setHullColor,
initialValue = [255.0,128.0,128.0,255.0])
styleFrame.pack(fill = X)
self.mainNotebook.setnaturalsize()
def pushUndo(self, fResetRedo = 1):
@ -761,33 +772,61 @@ class MopathRecorder(AppShell, PandaObject):
# Compute curve
self.computeCurves()
def setHullVis(self):
self.xyzNurbsCurveDrawer.setShowHull(self.hullVis.get())
def setPathVis(self):
if self.pathVis.get():
if self.getVariable('Style', 'Show Path').get():
self.curveNodePath.show()
else:
self.curveNodePath.hide()
def setCvVis(self):
self.xyzNurbsCurveDrawer.setShowCvs(self.cvVis.get())
def setKnotVis(self):
self.xyzNurbsCurveDrawer.setShowKnots(self.knotVis.get())
def setTickVis(self):
if self.tickVis.get():
self.xyzNurbsCurveDrawer.setNumTicks(self.numTicks)
else:
self.xyzNurbsCurveDrawer.setNumTicks(0)
self.xyzNurbsCurveDrawer.setShowKnots(
self.getVariable('Style', 'Show Knots').get())
def setCvVis(self):
self.xyzNurbsCurveDrawer.setShowCvs(
self.getVariable('Style', 'Show CVs').get())
def setHullVis(self):
self.xyzNurbsCurveDrawer.setShowHull(
self.getVariable('Style', 'Show Hull').get())
def setMarkerVis(self):
if self.markerVis.get():
if self.getVariable('Style', 'Show Marker').get():
self.playbackMarker.reparentTo(self.recorderNodePath)
else:
self.playbackMarker.reparentTo(hidden)
def setNumSegs(self, value):
self.numSegs = int(value)
self.xyzNurbsCurveDrawer.setNumSegs(self.numSegs)
def setNumTicks(self, value):
self.xyzNurbsCurveDrawer.setNumTicks(float(value))
def setTickScale(self, value):
self.xyzNurbsCurveDrawer.setTickScale(float(value))
def setPathColor(self, color):
self.xyzNurbsCurveDrawer.setColor(
color[0]/255.0,color[1]/255.0,color[2]/255.0)
self.xyzNurbsCurveDrawer.draw()
def setKnotColor(self, color):
self.xyzNurbsCurveDrawer.setKnotColor(
color[0]/255.0,color[1]/255.0,color[2]/255.0)
def setCvColor(self, color):
self.xyzNurbsCurveDrawer.setCvColor(
color[0]/255.0,color[1]/255.0,color[2]/255.0)
def setTickColor(self, color):
self.xyzNurbsCurveDrawer.setTickColor(
color[0]/255.0,color[1]/255.0,color[2]/255.0)
def setHullColor(self, color):
self.xyzNurbsCurveDrawer.setHullColor(
color[0]/255.0,color[1]/255.0,color[2]/255.0)
def setStartStopHook(self, event = None):
# Clear out old hook
self.ignore(self.startStopHook)
@ -821,11 +860,13 @@ class MopathRecorder(AppShell, PandaObject):
self.hprCurveFitter.reset()
self.xyzNurbsCurveDrawer.hide()
def setSamplingMode(self):
if self.samplingMode.get() == 'Keyframe':
self.getWidget('Recording', 'Add Key Frame')['state'] = 'normal'
else:
self.getWidget('Recording', 'Add Key Frame')['state'] = 'disabled'
def setSamplingMode(self, mode):
self.samplingMode = mode
def disableKeyframeButton(self):
self.getWidget('Recording', 'Add Keyframe')['state'] = 'disabled'
def enableKeyframeButton(self):
self.getWidget('Recording', 'Add Keyframe')['state'] = 'normal'
def setRecordingType(self, type):
self.recordingType.set(type)
@ -856,12 +897,15 @@ class MopathRecorder(AppShell, PandaObject):
# Reset curve fitters
self.xyzCurveFitter.reset()
self.hprCurveFitter.reset()
# Update sampling mode button if necessary
if self.samplingMode == 'Continuous':
self.disableKeyframeButton()
# Create a new point set to hold raw data
self.createNewPointSet()
# Record nopath's parent
self.nodePathParent = self['nodePath'].getParent()
# Keyframe mode?
if (self.samplingMode.get() == 'Keyframe'):
if (self.samplingMode == 'Keyframe'):
# Add hook
self.acceptKeyframeHook()
# Record first point
@ -891,14 +935,8 @@ class MopathRecorder(AppShell, PandaObject):
t = taskMgr.spawnMethodNamed(
self.recordTask, self.name + '-recordTask')
t.startTime = globalClock.getTime()
# Don't want to change record modes
self.getWidget('Recording', 'Continuous Sampling')['state'] = (
'disabled')
self.getWidget('Recording', 'Keyframe Sampling')['state'] = (
'disabled')
else:
if self.samplingMode.get() == 'Continuous':
if self.samplingMode == 'Continuous':
# Kill old task
taskMgr.removeTasksNamed(self.name + '-recordTask')
if ((self.recordingType.get() == 'Refine') |
@ -915,6 +953,9 @@ class MopathRecorder(AppShell, PandaObject):
self.addKeyframe(0)
# Ignore hook
self.ignoreKeyframeHook()
# Reset sampling mode
self.setSamplingMode('Continuous')
self.enableKeyframeButton()
# Clean up after refine or extend
if ((self.recordingType.get() == 'Refine') |
(self.recordingType.get() == 'Extend')):
@ -927,11 +968,6 @@ class MopathRecorder(AppShell, PandaObject):
self.setNewCurveMode()
# Compute curve
self.computeCurves()
# Now you can change record modes
self.getWidget('Recording', 'Continuous Sampling')['state'] = (
'normal')
self.getWidget('Recording', 'Keyframe Sampling')['state'] = (
'normal')
def recordTask(self, state):
# Record raw data point
@ -943,6 +979,8 @@ class MopathRecorder(AppShell, PandaObject):
# Make sure we're in a recording mode!
if (fToggleRecord &
(not self.getVariable('Recording', 'Record').get())):
# Set sampling mode
self.setSamplingMode('Keyframe')
# This will automatically add the first point
self.toggleRecordVar()
else:
@ -955,11 +993,10 @@ class MopathRecorder(AppShell, PandaObject):
x = t * t
return (3 * x) - (2 * t * x)
def setPreRecordFunc(self, event):
def setPreRecordFunc(self, func):
# Note: If func is one defined at command prompt, need to set
# __builtins__.func = func at command line
self.preRecordFunc = eval(
self.getVariable('Recording', 'Pre-Record Func').get())
self.preRecordFunc = eval(func)
# Update widget to reflect new value
self.getVariable('Recording', 'PRF Active').set(1)
@ -1336,8 +1373,24 @@ class MopathRecorder(AppShell, PandaObject):
for i in range(self.hprNurbsCurve.getNumKnots()):
self.hprNurbsCurve.setKnot(i, sf * self.hprNurbsCurve.getKnot(i))
self.hprNurbsCurve.recompute()
# Update info
self.updateWidgets()
# Scale point set
# Save handle to old point set
oldPointSet = self.pointSet
# Create new point set
self.createNewPointSet()
# Reset curve fitters
self.xyzCurveFitter.reset()
self.hprCurveFitter.reset()
# Now scale values
for time, pos, hpr in oldPointSet:
newTime = time * sf
# Update point set
self.pointSet.append([newTime, Point3(pos), Point3(hpr)])
# Add it to the curve fitters
self.xyzCurveFitter.addPoint(newTime, pos )
self.hprCurveFitter.addPoint(newTime, hpr)
# Compute curve
self.computeCurves()
def setRecordStart(self,value):
self.recordStart = value
@ -1620,6 +1673,14 @@ class MopathRecorder(AppShell, PandaObject):
self.xyzNurbsCurve.writeEgg(mopathFilename)
self.hprNurbsCurve.writeEgg(mopathFilename)
def followTerrain(self, height = 1.0):
self.iRay.rayCollisionNodePath.reparentTo(self['nodePath'])
node, hitPt, hitPtDist = self.iRay.pickGeom3D()
if node:
self['nodePath'].setZ(self['nodePath'], height - hitPtDist)
self.iRay.rayCollisionNodePath.reparentTo(self.recorderNodePath)
## WIDGET UTILITY FUNCTIONS ##
def addWidget(self, widget, category, text):
self.widgetDict[category + '-' + text] = widget
@ -1639,10 +1700,12 @@ class MopathRecorder(AppShell, PandaObject):
variable.set(initialValue)
label = Label(frame, text = text)
label.pack(side = LEFT, fill = X)
self.bind(label, balloonHelp)
self.widgetDict[category + '-' + text + '-Label'] = label
entry = Entry(frame, width = width, relief = relief,
textvariable = variable)
entry.pack(side = LEFT, fill = X, expand = expand)
self.bind(entry, balloonHelp)
self.widgetDict[category + '-' + text] = entry
self.variableDict[category + '-' + text] = variable
if command:
@ -1800,7 +1863,7 @@ class MopathRecorder(AppShell, PandaObject):
widget.selectitem(items[0])
# Bind selection command
widget['selectioncommand'] = command
widget.pack(side = side, expand = expand)
widget.pack(side = side, fill = fill, expand = expand)
# Bind help
self.bind(widget, balloonHelp)
# Record widget