*** empty log message ***

This commit is contained in:
Mark Mine 2001-01-20 02:03:27 +00:00
parent cda6f2be96
commit e5ab222f36
8 changed files with 220 additions and 122 deletions

View File

@ -15,7 +15,7 @@ class DirectCameraControl(PandaObject):
self.coaMarker = loader.loadModel('models/misc/sphere') self.coaMarker = loader.loadModel('models/misc/sphere')
self.coaMarker.setName('DirectCameraCOAMarker') self.coaMarker.setName('DirectCameraCOAMarker')
self.coaMarker.setColor(1,0,0) self.coaMarker.setColor(1,0,0)
self.coaMarker.setPos(0,0,0) self.coaMarker.setPos(0,100,0)
useDirectRenderStyle(self.coaMarker) useDirectRenderStyle(self.coaMarker)
self.coaMarkerPos = Point3(0) self.coaMarkerPos = Point3(0)
self.camManipRef = direct.group.attachNewNode('camManipRef') self.camManipRef = direct.group.attachNewNode('camManipRef')
@ -56,27 +56,15 @@ class DirectCameraControl(PandaObject):
self.coaMarker.hide() self.coaMarker.hide()
# Check for a hit point based on # Check for a hit point based on
# current mouse position # current mouse position
# Allow intersection with unpickable objects
# And then spawn task to determine mouse mode # And then spawn task to determine mouse mode
numEntries = direct.iRay.pickGeom( node, hitPt, hitPtDist = direct.iRay.pickGeom(
render,direct.dr.mouseX,direct.dr.mouseY) fIntersectUnpickable = 1)
# Then filter out hidden nodes from entry list
indexList = []
for i in range(0,numEntries):
entry = direct.iRay.cq.getEntry(i)
node = entry.getIntoNode()
if node.isHidden():
pass
else:
# Not one of the widgets, use it
indexList.append(i)
coa = Point3(0) coa = Point3(0)
if(indexList): if node:
# Grab first point (it should be the closest) # Set center of action
minPt = indexList[0] coa.assign(hitPt)
# Find hit point in camera's space coaDist = hitPtDist
hitPt = direct.iRay.camToHitPt(minPt)
coa.set(hitPt[0],hitPt[1],hitPt[2])
coaDist = Vec3(coa - ZERO_POINT).length()
# Handle case of bad coa point (too close or too far) # Handle case of bad coa point (too close or too far)
if ((coaDist < (1.1 * direct.dr.near)) | if ((coaDist < (1.1 * direct.dr.near)) |
(coaDist > direct.dr.far)): (coaDist > direct.dr.far)):

View File

@ -2,8 +2,6 @@ from PandaObject import *
from DirectGeometry import * from DirectGeometry import *
MANIPULATION_MOVE_DELAY = 0.65 MANIPULATION_MOVE_DELAY = 0.65
UNPICKABLE = ['x-disc-visible', 'y-disc-visible', 'z-disc-visible',
'GridBack']
class DirectManipulationControl(PandaObject): class DirectManipulationControl(PandaObject):
def __init__(self): def __init__(self):
@ -24,7 +22,6 @@ class DirectManipulationControl(PandaObject):
self.fWidgetTop = 0 self.fWidgetTop = 0
self.fFreeManip = 1 self.fFreeManip = 1
self.fScaling = 0 self.fScaling = 0
self.unpickable = UNPICKABLE
self.mode = None self.mode = None
self.actionEvents = [ self.actionEvents = [
['handleMouse1', self.manipulationStart], ['handleMouse1', self.manipulationStart],
@ -35,26 +32,19 @@ class DirectManipulationControl(PandaObject):
[',', self.objectHandles.multiplyScalingFactorBy, 0.5], [',', self.objectHandles.multiplyScalingFactorBy, 0.5],
['<', self.objectHandles.multiplyScalingFactorBy, 0.5], ['<', self.objectHandles.multiplyScalingFactorBy, 0.5],
['F', self.objectHandles.growToFit], ['F', self.objectHandles.growToFit],
['p', self.plantSelectedNodePath],
] ]
def manipulationStart(self): def manipulationStart(self):
# Start out in select mode # Start out in select mode
self.mode = 'select' self.mode = 'select'
# Check for a widget hit point # Check for a widget hit point
numEntries = direct.iRay.pickWidget( node, hitPt, hitPtDist = direct.iRay.pickWidget()
render,direct.dr.mouseX,direct.dr.mouseY)
# Did we hit a widget? # Did we hit a widget?
if(numEntries): if node:
# Yes! # Yes!
# Entry 0 is the closest hit point if multiple hits self.hitPt.assign(hitPt)
minPt = 0 self.hitPtDist = hitPtDist
# Find hit point in camera's space
self.hitPt = direct.iRay.camToHitPt(minPt)
self.hitPtDist = Vec3(self.hitPt - ZERO_POINT).length()
# Get the associated collision queue object
entry = direct.iRay.cq.getEntry(minPt)
# Extract the node
node = entry.getIntoNode()
# Constraint determined by nodes name # Constraint determined by nodes name
self.constraint = node.getName() self.constraint = node.getName()
else: else:
@ -97,32 +87,11 @@ class DirectManipulationControl(PandaObject):
# depending on flag..... # depending on flag.....
if self.mode == 'select': if self.mode == 'select':
# Check for object under mouse # Check for object under mouse
numEntries = direct.iRay.pickGeom( node, hitPt, hitPtDist = direct.iRay.pickGeom()
render,direct.dr.mouseX,direct.dr.mouseY) if node:
# Pick out the closest object that isn't a widget # Record hit point information
index = -1 self.hitPt.assign(hitPt)
for i in range(0,numEntries): self.hitPtDist = hitPtDist
entry = direct.iRay.cq.getEntry(i)
node = entry.getIntoNode()
if node.isHidden():
pass
# 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
else:
# Not hidden and not one of the widgets, use it
index = i
# Did we hit an object?
if(index >= 0):
# Yes!
# Find hit point in camera's space
self.hitPt = direct.iRay.camToHitPt(index)
self.hitPtDist = Vec3(self.hitPt - ZERO_POINT).length()
# Find the node path from the node found above # Find the node path from the node found above
nodePath = render.findPathDownTo(node) nodePath = render.findPathDownTo(node)
# Select it # Select it
@ -479,15 +448,32 @@ class DirectManipulationControl(PandaObject):
self.initScaleMag) self.initScaleMag)
) )
direct.widget.setScale(currScale) direct.widget.setScale(currScale)
## Utility functions ##
def plantSelectedNodePath(self):
""" Move selected object to intersection point of cursor on scene """
# Check for intersection
node, hitPt, hitPtDist = direct.iRay.pickGeom(
fIntersectUnpickable = 1)
# MRM: Need to handle moving COA
if (node != None) & (direct.selected.last != None):
# Record undo point
direct.pushUndo(direct.selected)
# Record wrt matrix
direct.selected.getWrtAll()
# Move selected
direct.widget.setPos(direct.camera, hitPt)
# Move all the selected objects with widget
# Move the objects with the widget
direct.selected.moveWrtWidgetAll()
# Let everyone know that something was moved
messenger.send('manipulateObjectCleanup')
class ObjectHandles(NodePath,PandaObject): class ObjectHandles(NodePath,PandaObject):
def __init__(self): def __init__(self):
# Initialize the superclass # Initialize the superclass
NodePath.__init__(self) NodePath.__init__(self)
# Starts off deactivated
self.fActive = 0
# Load up object handles model and assign it to self # Load up object handles model and assign it to self
self.assign(loader.loadModel('models/misc/objectHandles')) self.assign(loader.loadModel('models/misc/objectHandles'))
self.node().setName('objectHandles') self.node().setName('objectHandles')
@ -540,6 +526,10 @@ class ObjectHandles(NodePath,PandaObject):
self.createGuideLines() self.createGuideLines()
self.hideGuides() self.hideGuides()
# Start with widget handles hidden
self.fActive = 1
self.toggleWidget()
# Make sure object handles are never lit or drawn in wireframe # Make sure object handles are never lit or drawn in wireframe
useDirectRenderStyle(self) useDirectRenderStyle(self)
@ -551,10 +541,10 @@ class ObjectHandles(NodePath,PandaObject):
def toggleWidget(self): def toggleWidget(self):
if self.fActive: if self.fActive:
self.reparentTo(hidden) self.scalingNode.reparentTo(hidden)
self.fActive = 0 self.fActive = 0
else: else:
self.reparentTo(direct.group) self.scalingNode.reparentTo(self)
self.fActive = 1 self.fActive = 1
def showWidgetIfActive(self): def showWidgetIfActive(self):

View File

@ -2,6 +2,9 @@ from PandaObject import *
from DirectGeometry import * from DirectGeometry import *
from DirectSelection import * from DirectSelection import *
UNPICKABLE = ['x-disc-visible', 'y-disc-visible', 'z-disc-visible',
'GridBack']
# MRM: To do: handle broken node paths in selected and deselected dicts # MRM: To do: handle broken node paths in selected and deselected dicts
class DirectNodePath(NodePath): class DirectNodePath(NodePath):
# A node path augmented with info, bounding box, and utility methods # A node path augmented with info, bounding box, and utility methods
@ -394,14 +397,70 @@ class SelectionRay:
self.ct = CollisionTraverser( RenderRelation.getClassType() ) self.ct = CollisionTraverser( RenderRelation.getClassType() )
# Let the traverser know about the queue and the collision node # Let the traverser know about the queue and the collision node
self.ct.addCollider(self.rayCollisionNode, self.cq ) self.ct.addCollider(self.rayCollisionNode, self.cq )
# List of objects that can't be selected
self.unpickable = UNPICKABLE
def pickGeom(self, targetNodePath, mouseX, mouseY): def pickGeom(self, targetNodePath = render, fIntersectUnpickable = 0):
self.collideWithGeom() self.collideWithGeom()
return self.pick(targetNodePath, mouseX, mouseY) numEntries = self.pick(targetNodePath,
direct.dr.mouseX,
direct.dr.mouseY)
# Init index
index = -1
# Pick out the closest object that isn't a widget
for i in range(0,numEntries):
entry = direct.iRay.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 camera's space
hitPt = direct.iRay.camToHitPt(index)
hitPtDist = Vec3(hitPt - ZERO_POINT).length()
return (node, hitPt, hitPtDist)
else:
return (None, ZERO_POINT, 0)
def pickWidget(self, targetNodePath, mouseX, mouseY): def pickWidget(self, targetNodePath = render):
self.collideWithWidget() self.collideWithWidget()
return self.pick(targetNodePath, mouseX, mouseY) numEntries = self.pick(targetNodePath,
direct.dr.mouseX,
direct.dr.mouseY)
# Did we hit a widget?
if numEntries:
# 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)
hitPtDist = Vec3(hitPt).length()
# Get the associated collision queue object
entry = direct.iRay.cq.getEntry(minPt)
# Extract the node
node = entry.getIntoNode()
# Return info
return (node, hitPt, hitPtDist)
else:
return (None, ZERO_POINT, 0)
def pick(self, targetNodePath, mouseX, mouseY): def pick(self, targetNodePath, mouseX, mouseY):
# Determine ray direction based upon the mouse coordinates # Determine ray direction based upon the mouse coordinates

View File

@ -79,9 +79,8 @@ class DirectSession(PandaObject):
['SGENodePath_Delete', self.removeNodePath], ['SGENodePath_Delete', self.removeNodePath],
] ]
self.keyEvents = ['left', 'right', 'up', 'down', self.keyEvents = ['left', 'right', 'up', 'down',
'escape', 'space', 'delete', 'escape', 'delete', 'control', 'control-up',
'shift', 'shift-up', 'alt', 'alt-up', 'shift', 'shift-up', 'alt', 'alt-up',
'control', 'control-up',
'page_up', 'page_down', 'tab', 'page_up', 'page_down', 'tab',
'[', '{', ']', '}', '[', '{', ']', '}',
'b', 'c', 'f', 'l', 's', 't', 'v', 'w'] 'b', 'c', 'f', 'l', 's', 't', 'v', 'w']
@ -213,8 +212,8 @@ class DirectSession(PandaObject):
elif (input == ']') | (input == '}'): elif (input == ']') | (input == '}'):
self.redo() self.redo()
def select(self, nodePath, fMultiselect = 0, fResetAncestry = 1): def select(self, nodePath, fMultiSelect = 0, fResetAncestry = 1):
dnp = self.selected.select(nodePath, fMultiselect) dnp = self.selected.select(nodePath, fMultiSelect)
if dnp: if dnp:
messenger.send('preSelectNodePath', [dnp]) messenger.send('preSelectNodePath', [dnp])
if fResetAncestry: if fResetAncestry:
@ -465,6 +464,7 @@ class DirectSession(PandaObject):
# UTILITY FUNCTIONS # UTILITY FUNCTIONS
def useObjectHandles(self): def useObjectHandles(self):
self.widget = self.manipulationControl.objectHandles self.widget = self.manipulationControl.objectHandles
self.widget.reparentTo(direct.group)
def hideReadout(self): def hideReadout(self):
self.readout.reparentTo(hidden) self.readout.reparentTo(hidden)

View File

@ -60,6 +60,7 @@ classRenameDictionary = {
'LVecBase2f' : 'VBase2', 'LVecBase2f' : 'VBase2',
'LVector2f' : 'Vec2', 'LVector2f' : 'Vec2',
'LPoint2f' : 'Point2', 'LPoint2f' : 'Point2',
'LQuaternionf' : 'Quat',
'LMatrix4d' : 'Mat4D', 'LMatrix4d' : 'Mat4D',
'LMatrix3d' : 'Mat3D', 'LMatrix3d' : 'Mat3D',
'LVecBase4d' : 'VBase4D', 'LVecBase4d' : 'VBase4D',
@ -71,6 +72,7 @@ classRenameDictionary = {
'LVecBase2d' : 'VBase2D', 'LVecBase2d' : 'VBase2D',
'LVector2d' : 'Vec2D', 'LVector2d' : 'Vec2D',
'LPoint2d' : 'Point2D', 'LPoint2d' : 'Point2D',
'LQuaterniond' : 'QuatD',
'Plane' : 'PlaneBase', 'Plane' : 'PlaneBase',
'Planef' : 'Plane', 'Planef' : 'Plane',
'Planed' : 'PlaneD', 'Planed' : 'PlaneD',

View File

@ -59,23 +59,23 @@ class ParticlePanel(AppShell):
## SYSTEM PAGE ## ## SYSTEM PAGE ##
# Create system floaters # Create system floaters
systemFloaterDefs = ( systemFloaterDefs = (
('System Pool size', ('System Pool Size',
'Size of particle pool', 'Size of particle pool',
self.setSystemPoolSize, self.setSystemPoolSize,
1.0, 1.0), 1.0, 1.0),
('System Birth rate', ('System Birth Rate',
'Seconds between particle births', 'Seconds between particle births',
self.setSystemBirthRate, self.setSystemBirthRate,
0.0, None), 0.0, None),
('System Litter size', ('System Litter Size',
'Number of particle created at each birth', 'Number of particle created at each birth',
self.setSystemLitterSize, self.setSystemLitterSize,
1.0, 1.0), 1.0, 1.0),
('System Litter spread', ('System Litter Spread',
'Variation in litter size', 'Variation in litter size',
self.setSystemLitterSpread, self.setSystemLitterSpread,
0.0, 1.0), 0.0, 1.0),
('System lifespan', ('System Lifespan',
'Age in seconds at which system should die', 'Age in seconds at which system should die',
self.setSystemLifespan, self.setSystemLifespan,
0.0, None) 0.0, None)
@ -83,17 +83,17 @@ class ParticlePanel(AppShell):
self.createFloaters(systemPage, systemFloaterDefs) self.createFloaters(systemPage, systemFloaterDefs)
# Checkboxes # Checkboxes
self.systemLocalVelocity = self.createCheckbutton( self.systemLocalVelocity = self.createCheckbutton(
systemPage, 'Local velocity', systemPage, 'System Local Velocity',
self.toggleSystemLocalVelocity, 0) self.toggleSystemLocalVelocity, 0)
self.systemGrowsOlder = self.createCheckbutton( self.systemGrowsOlder = self.createCheckbutton(
systemPage, 'System grows older', systemPage, 'System Grows Older',
self.toggleSystemGrowsOlder, 0) self.toggleSystemGrowsOlder, 0)
# Vector widgets # Vector widgets
pos = self.createVector3Entry(systemPage, 'Pos', pos = self.createVector3Entry(systemPage, 'System Pos',
'Particle system position', 'Particle system position',
command = self.setSystemPos) command = self.setSystemPos)
pos.addMenuItem('Popup Placer Panel', Placer.Placer) pos.addMenuItem('Popup Placer Panel', Placer.Placer)
hpr = self.createVector3Entry(systemPage, 'Hpr', hpr = self.createVector3Entry(systemPage, 'System Hpr',
'Particle system orientation', 'Particle system orientation',
fGroup_labels = ('H', 'P', 'R'), fGroup_labels = ('H', 'P', 'R'),
command = self.setSystemHpr) command = self.setSystemHpr)
@ -107,27 +107,27 @@ class ParticlePanel(AppShell):
('Point', 'Z Spin', 'Oriented'), ('Point', 'Z Spin', 'Oriented'),
self.selectFactoryType) self.selectFactoryType)
factoryWidgets = ( factoryWidgets = (
('Life span', ('Factory Life Span',
'Average lifespan in seconds', 'Average lifespan in seconds',
self.setFactoryLifeSpan, self.setFactoryLifeSpan,
0.0, None), 0.0, None),
('Life span spread', ('Factory Life Span Spread',
'Variation in lifespan', 'Variation in lifespan',
self.setFactoryLifeSpanSpread, self.setFactoryLifeSpanSpread,
0.0, None), 0.0, None),
('Mass', ('Factory Mass',
'Average particle mass', 'Average particle mass',
self.setFactoryParticleMass, self.setFactoryParticleMass,
0.0, None), 0.0, None),
('Mass spread', ('Factory Mass Spread',
'Variation in particle mass', 'Variation in particle mass',
self.setFactoryParticleMassSpread, self.setFactoryParticleMassSpread,
0.0, None), 0.0, None),
('Terminal velocity', ('Factory Terminal Velocity',
'Average particle terminal velocity', 'Average particle terminal velocity',
self.setFactoryTerminalVelocity, self.setFactoryTerminalVelocity,
0.0, None), 0.0, None),
('Terminal vel. spread', ('Factory Terminal Vel. Spread',
'Variation in terminal velocity', 'Variation in terminal velocity',
self.setFactoryTerminalVelocitySpread, self.setFactoryTerminalVelocitySpread,
0.0, None)) 0.0, None))
@ -138,13 +138,13 @@ class ParticlePanel(AppShell):
factoryPointPage = self.factoryNotebook.add('Point') factoryPointPage = self.factoryNotebook.add('Point')
# Z spin page # # Z spin page #
zSpinPage = self.factoryNotebook.add('Z Spin') zSpinPage = self.factoryNotebook.add('Z Spin')
self.createAngleDial(zSpinPage, 'Initial angle', self.createAngleDial(zSpinPage, 'Z Spin Initial Angle',
'Starting angle in degrees', 'Starting angle in degrees',
command = self.setFactoryZSpinInitialAngle) command = self.setFactoryZSpinInitialAngle)
self.createAngleDial(zSpinPage, 'Final angle', self.createAngleDial(zSpinPage, 'Z Spin Final Angle',
'Final angle in degrees', 'Final angle in degrees',
command = self.setFactoryZSpinFinalAngle) command = self.setFactoryZSpinFinalAngle)
self.createAngleDial(zSpinPage, 'Angle spread', self.createAngleDial(zSpinPage, 'Z Spin Angle Spread',
'Spread of the final angle', 'Spread of the final angle',
command = self.setFactoryZSpinAngleSpread) command = self.setFactoryZSpinAngleSpread)
# Oriented page # # Oriented page #
@ -164,18 +164,19 @@ class ParticlePanel(AppShell):
self.emitterNotebook = Pmw.NoteBook(emitterPage, tabpos = None) self.emitterNotebook = Pmw.NoteBook(emitterPage, tabpos = None)
# Box page # # Box page #
boxPage = self.emitterNotebook.add('Box') boxPage = self.emitterNotebook.add('Box')
self.createVector3Entry(boxPage, 'Point 1', self.createVector3Entry(boxPage, 'Box Emitter Min',
'Point defining emitter box', 'Min point defining emitter box',
command = self.setEmitterBoxPoint1) command = self.setEmitterBoxPoint1)
self.createVector3Entry(boxPage, 'Point 2', self.createVector3Entry(boxPage, 'Box Emitter Max',
'Point defining emitter box', 'Max point defining emitter box',
command = self.setEmitterBoxPoint2, command = self.setEmitterBoxPoint2,
initialValue = (1.0, 1.0, 1.0)) initialValue = (1.0, 1.0, 1.0))
self.createVector3Entry(boxPage, 'Velocity vector', self.createVector3Entry(boxPage, 'Velocity vector',
'Initial particle velocity vector', 'Initial particle velocity vector',
command = self.setEmitterBoxVelocityVector) command = self.setEmitterBoxVelocityVector)
# Disc page # # Disc page #
discPage = self.emitterNotebook.add('Disc') discPage = self.emitterNotebook.add('Disc')
self.emitter
self.createFloater(discPage, 'Radius', 'Radius of disc', self.createFloater(discPage, 'Radius', 'Radius of disc',
command = self.setEmitterDiscRadius) command = self.setEmitterDiscRadius)
self.createAngleDial(discPage, 'Inner angle', self.createAngleDial(discPage, 'Inner angle',
@ -195,23 +196,24 @@ class ParticlePanel(AppShell):
self.toggleEmitterDiscCubicLerping, 0) self.toggleEmitterDiscCubicLerping, 0)
# Line page # # Line page #
linePage = self.emitterNotebook.add('Line') linePage = self.emitterNotebook.add('Line')
self.createVector3Entry(linePage, 'Point 1', self.createVector3Entry(linePage, 'Line Emitter Min',
'Point defining emitter line', 'Min point defining emitter line',
command = self.setEmitterLinePoint1) command = self.setEmitterLinePoint1)
self.createVector3Entry(linePage, 'Point 2', self.createVector3Entry(linePage, 'Line Emitter Max',
'Point defining emitter line', 'Max point defining emitter line',
command = self.setEmitterLinePoint2, command = self.setEmitterLinePoint2,
initialValue = (1.0, 0.0, 0.0)) initialValue = (1.0, 0.0, 0.0))
self.createVector3Entry(linePage, 'Velocity Vector', self.createVector3Entry(linePage, 'Line Emitter Velocity',
'Initial particle velocity vector', 'Initial particle velocity vector',
command = self.setEmitterLineVelocityVector, command = self.setEmitterLineVelocityVector,
initialValue = (0.0, 0.0, 1.0)) initialValue = (0.0, 0.0, 1.0))
# Point page # # Point page #
emitterPointPage = self.emitterNotebook.add('Point') emitterPointPage = self.emitterNotebook.add('Point')
self.createVector3Entry(emitterPointPage, 'Position', self.createVector3Entry(emitterPointPage, 'Point Emitter Position',
'Position of emitter point', 'Position of emitter point',
command = self.setEmitterPointPosition) command = self.setEmitterPointPosition)
self.createVector3Entry(emitterPointPage, 'Velocity vector', self.createVector3Entry(emitterPointPage,
'Point Emitter Velocity',
'Initial particle velocity vector', 'Initial particle velocity vector',
command = self.setEmitterPointVelocityVector, command = self.setEmitterPointVelocityVector,
initialValue = (0.0, 0.0, 1.0)) initialValue = (0.0, 0.0, 1.0))
@ -374,11 +376,12 @@ class ParticlePanel(AppShell):
def createCheckbutton(self, parent, text, command, initialState): def createCheckbutton(self, parent, text, command, initialState):
bool = BooleanVar() bool = BooleanVar()
bool.set(initialState) bool.set(initialState)
cb = Checkbutton(parent, text = text, anchor = W, widget = Checkbutton(parent, text = text, anchor = W,
variable = bool) variable = bool)
# Do this after the widget so command isn't called on creation # Do this after the widget so command isn't called on creation
cb.command = command widget['command'] = command
cb.pack(fill = X) widget.pack(fill = X)
self.widgetDict['text'] = widget
return bool return bool
def createFloaters(self, parent, widgetDefinitions): def createFloaters(self, parent, widgetDefinitions):
@ -412,6 +415,7 @@ class ParticlePanel(AppShell):
widget['command'] = command widget['command'] = command
widget.pack(fill = X) widget.pack(fill = X)
self.bind(widget, balloonHelp) self.bind(widget, balloonHelp)
self.widgetDict['text'] = widget
return widget return widget
def createVector3Entry(self, parent, text, balloonHelp, def createVector3Entry(self, parent, text, balloonHelp,
@ -423,6 +427,7 @@ class ParticlePanel(AppShell):
widget['command'] = command widget['command'] = command
widget.pack(fill = X) widget.pack(fill = X)
self.bind(widget, balloonHelp) self.bind(widget, balloonHelp)
self.widgetDict['text'] = widget
return widget return widget
def createColorEntry(self, parent, text, balloonHelp, def createColorEntry(self, parent, text, balloonHelp,
@ -434,6 +439,7 @@ class ParticlePanel(AppShell):
widget['command'] = command widget['command'] = command
widget.pack(fill = X) widget.pack(fill = X)
self.bind(widget, balloonHelp) self.bind(widget, balloonHelp)
self.widgetDict['text'] = widget
return widget return widget
def createOptionMenu(self, parent, text, balloonHelp, items, command): def createOptionMenu(self, parent, text, balloonHelp, items, command):
@ -447,6 +453,7 @@ class ParticlePanel(AppShell):
widget['command'] = command widget['command'] = command
widget.pack(fill = X) widget.pack(fill = X)
self.bind(widget.component('menubutton'), balloonHelp) self.bind(widget.component('menubutton'), balloonHelp)
self.widgetDict['text'] = widget
return optionVar return optionVar
### PARTICLE SYSTEM COMMANDS ### ### PARTICLE SYSTEM COMMANDS ###
@ -500,6 +507,39 @@ class ParticlePanel(AppShell):
def selectEmitterType(self, type): def selectEmitterType(self, type):
self.emitterNotebook.selectpage(type) self.emitterNotebook.selectpage(type)
self.particles.setEmitter(type) self.particles.setEmitter(type)
self.updateEmitterWidgets()
def updateEmitterWidgets(self):
emitter = self.particles.emitter
if isinstance(emitter, BoxEmitter):
min = emitter.getMinBound()
self.emitterBoxPoint1VectorEntry.set(
[min[0], min[1], min[2]])
max = emitter.getMaxBound()
self.emitterBoxPoint2VectorEntry.set(
[max[0], max[1], max[2]])
elif isinstance(emitter, DiscEmitter):
radius = emitter.getRadius()
cubicLerping = emitter.getCubicLerping()
innerAngle = emitter.getInnerAngle()
getInnerMagnitude
getOuterAngle
getOuterMagnitude
elif isinstance(emitter, LineEmitter):
pass
elif isinstance(emitter, PointEmitter):
pass
elif isinstance(emitter, RectangleEmitter):
pass
elif isinstance(emitter, RingEmitter):
pass
elif isinstance(emitter, SphereVolumeEmitter):
pass
elif isinstance(emitter, SphereSurfaceEmitter):
pass
elif isinstance(emitter, TangentRingEmitter):
pass
# Box # # Box #
def setEmitterBoxPoint1(self, point): def setEmitterBoxPoint1(self, point):
self.particles.emitter.setMinBound(Point3(point[0], self.particles.emitter.setMinBound(Point3(point[0],

View File

@ -64,6 +64,7 @@ class Placer(AppShell):
self.initPos = Vec3(0) self.initPos = Vec3(0)
self.initHpr = Vec3(0) self.initHpr = Vec3(0)
self.initScale = Vec3(1) self.initScale = Vec3(1)
self.deltaHpr = Vec3(0)
# Offset for orbital mode # Offset for orbital mode
self.posOffset = Vec3(0) self.posOffset = Vec3(0)
@ -450,7 +451,7 @@ class Placer(AppShell):
else: else:
if name == 'widget': if name == 'widget':
# Record relationship between selected nodes and widget # Record relationship between selected nodes and widget
direct.selected.getWrtAll() direct.selected.getWrtAll()
# Update active node path # Update active node path
self.setActiveNodePath(nodePath) self.setActiveNodePath(nodePath)
@ -459,10 +460,19 @@ class Placer(AppShell):
if self['nodePath']: if self['nodePath']:
self.nodePathMenuEntry.configure( self.nodePathMenuEntry.configure(
background = self.nodePathMenuBG) background = self.nodePathMenuBG)
# Check to see if node path and ref node path are the same
if ((self.refCS != None) &
(self.refCS.id() == self['nodePath'].id())):
# Yes they are, use temp CS as ref
# This calls updatePlacer
self.setReferenceNodePath(self.tempCS)
# update listbox accordingly
self.refNodePathMenu.selectitem('self')
else:
# Record initial value and initialize the widgets
self.updatePlacer()
# Record initial position # Record initial position
self.updateResetValues(self['nodePath']) self.updateResetValues(self['nodePath'])
# Record initial value and initialize the widgets
self.updatePlacer()
else: else:
# Flash entry # Flash entry
self.nodePathMenuEntry.configure(background = 'Pink') self.nodePathMenuEntry.configure(background = 'Pink')
@ -494,7 +504,12 @@ class Placer(AppShell):
# Clear bogus entry from listbox # Clear bogus entry from listbox
listbox = self.refNodePathMenu.component('scrolledlist') listbox = self.refNodePathMenu.component('scrolledlist')
listbox.setlist(self.refNodePathNames) listbox.setlist(self.refNodePathNames)
# Update ref node path accordingly # Check to see if node path and ref node path are the same
if (nodePath != None) & (nodePath.id() == self['nodePath'].id()):
# Yes they are, use temp CS and update listbox accordingly
nodePath = self.tempCS
self.refNodePathMenu.selectitem('self')
# Update ref node path
self.setReferenceNodePath(nodePath) self.setReferenceNodePath(nodePath)
def setReferenceNodePath(self, nodePath): def setReferenceNodePath(self, nodePath):
@ -594,6 +609,8 @@ class Placer(AppShell):
taskMgr.removeTasksNamed('followSelectedNodePath') taskMgr.removeTasksNamed('followSelectedNodePath')
# Record relationship between selected nodes and widget # Record relationship between selected nodes and widget
direct.selected.getWrtAll() direct.selected.getWrtAll()
# Record initial state
self.deltaHpr = self['nodePath'].getHpr(self.refCS)
# Update placer to reflect new state # Update placer to reflect new state
self.updatePlacer() self.updatePlacer()
@ -609,7 +626,6 @@ class Placer(AppShell):
def xformRelative(self, value, axis): def xformRelative(self, value, axis):
nodePath = self['nodePath'] nodePath = self['nodePath']
if (nodePath != None) & (self.refCS != None): if (nodePath != None) & (self.refCS != None):
if axis == 'x': if axis == 'x':
nodePath.setX(self.refCS, value) nodePath.setX(self.refCS, value)
@ -617,12 +633,15 @@ class Placer(AppShell):
nodePath.setY(self.refCS, value) nodePath.setY(self.refCS, value)
elif axis == 'z': elif axis == 'z':
nodePath.setZ(self.refCS, value) nodePath.setZ(self.refCS, value)
elif axis == 'h': else:
nodePath.setH(self.refCS, value) if axis == 'h':
elif axis == 'p': self.deltaHpr.setX(value)
nodePath.setP(self.refCS, value) elif axis == 'p':
elif axis == 'r': self.deltaHpr.setY(value)
nodePath.setR(self.refCS, value) elif axis == 'r':
self.deltaHpr.setZ(value)
# Put node path at new hpr
nodePath.setHpr(self.refCS, self.deltaHpr)
def xformOrbit(self, value, axis): def xformOrbit(self, value, axis):
nodePath = self['nodePath'] nodePath = self['nodePath']

View File

@ -163,11 +163,11 @@ class VectorEntry(Pmw.MegaWidget):
def getAt(self,index): def getAt(self,index):
return self._value[index] return self._value[index]
def set(self, value): def set(self, value, fCommand = 0):
for i in range(self['dim']): for i in range(self['dim']):
self._value[i] = value[i] self._value[i] = value[i]
self.variableList[i].set(self.entryFormat % value[i]) self.variableList[i].set(self.entryFormat % value[i])
self.action() self.action(fCommand)
def setAt(self, index, value): def setAt(self, index, value):
self.variableList[index].set(self.entryFormat % value) self.variableList[index].set(self.entryFormat % value)
@ -207,9 +207,9 @@ class VectorEntry(Pmw.MegaWidget):
if self._floaters: if self._floaters:
self._floaters.set(self._value, 0) self._floaters.set(self._value, 0)
def action(self): def action(self, fCommand = 0):
self._refreshFloaters() self._refreshFloaters()
if self['command']: if fCommand & (self['command'] != None):
self['command'](self._value) self['command'](self._value)
def reset(self): def reset(self):