Open topic with navigation
Creating Your Own Actions
Actions are useful Vizard constructs that help organize the behavior
of nodes and views. The
Vizard API makes it easy to create custom actions to handle your application
specific tasks.
Actions are classes that inherit from viz.ActionClass.
Actions
then have a variety of methods they can override to provide functionality.
Heres a
list:
begin(self,object)
update(self,elapsed,object)
pause(self,state)
end(self,object)
Action classes can also check there current execution state with these
methods:
finished(self)
paused(self)
Code Examples
Here is how the spin action is implemented:
import viz
class VizSpinAction(viz.ActionClass):
def begin(self,object):
self.data = self._actiondata_.data
self.elapsed = 0
self.duration = self.data[4]
self.totalAngle = 0
self.finalAngle = self.duration
* self.data[3]
def update(self,elapsed,object):
self.elapsed += elapsed
#If spinning
for a finite duration, check if time has passed
if self.duration > 0.0 and self.elapsed > self.duration:
self._overtime_
= self.elapsed - self.duration
object.setAxisAngle(self.data[0],self.data[1],self.data[2],self.finalAngle-self.totalAngle,viz.REL_LOCAL)
self.end(object)
else:
inc = self.data[3]*elapsed
self.totalAngle
+= inc
object.setAxisAngle(self.data[0],self.data[1],self.data[2],inc,viz.REL_LOCAL)
def spin(x,y,z,speed,dur=viz.FOREVER):
bla = viz.ActionData()
bla.data =[x,y,z,speed,dur]
bla.actionclass=VizSpinAction
return bla
viz.go()
node = viz.add('logo.wrl')
node.addAction(vizact.spin(0,1,0,90))
Here is an action that rotates an avatar's head
to watch a node:
import viz
class WatchNodeAction(viz.ActionClass):
"""Makes avatar head
follow node object around"""
def begin(self,object):
"""Called
once when action starts"""
#Get the
node the avatar should look at
self.nodeToLookAt
= self._actiondata_.data[0]
#Get time
the avatar will look at object
self.duration
= self._actiondata_.data[1]
self.headBone
= self._actiondata_.data[2]
self.blendIn
= self._actiondata_.data[3]
self.timeElapsed
= 0
#Get the
head bone and lock it
self.head
= object.getBone(self.headBone)
self.head.lock()
self.startQuat
= self.head.getQuat()
def update(self,elapsed,object):
"""Called
every frame to update action"""
self.timeElapsed
+= elapsed #time avatar has looked
at node
p =
self.timeElapsed / self.blendIn
#If looking
for a finite duration, check if time has passed
if
self.duration > 0.0 and self.timeElapsed
> self.duration:
#duration passed, end action
self.head.lookAt(
self.nodeToLookAt.getPosition(), 0, viz.AVATAR_WORLD )
self.end(object) #End the action and clear it from the
action queue
elif
p < 1.0:
#blend in head look
self.head.lookAt(
self.nodeToLookAt.getPosition(), 0, viz.AVATAR_WORLD )
targetQuat
= self.head.getQuat()
nextQuad
= vizmat.slerp(self.startQuat,targetQuat,p)
self.head.setQuat(nextQuad)
else:
#Done with blend in, just look at node
self.head.lookAt(self.nodeToLookAt.getPosition(), 0, viz.AVATAR_WORLD)
def end(self,object):
if
self.head:
self.head.unlock()
viz.ActionClass.end(self,object)
#Function to construct the action instance
def watchNode(
nodeToLookAt, duration =
viz.FOREVER, headBone = 'Bip01 Head',
blendIn = .2 ):
action = viz.ActionData()
action.data = [ nodeToLookAt, duration, headBone, blendIn ]
action.actionclass = WatchNodeAction
return action
viz.go()
viz.MainView.setPosition( 0, 0, 0 )
#Setup ball for the avatar to track
ball = viz.addChild('beachball.osgb',scale=[0.2]*3)
path = viz.addAnimationPath()
points = [ [0,0,1], [-0.3,0,1], [0,0.3,1], [0.3,0,1], [0,-0.3,1], [0,0,1.5], [0,0,1] ]
for x,pos in enumerate(points):
path.addControlPoint(0.5*x,pos=pos)
path.setLoopMode(viz.LOOP)
path.play()
viz.link(path,ball)
male = viz.add( 'vcc_male.cfg' )
male.setPosition( 0, -1.5, 2 )
male.setEuler( 180, 0, 0 )
male.idlepose(-1)
#Apply the action to the avatar
male.addAction( watchNode(ball, viz.FOREVER) )
def endHeadWatch():
#blend head to neutral orientation
head = male.getBone('Bip01 Head')
headQuat = head.getQuat(viz.AVATAR_LOCAL)
male.endAction()
head.lock()
head.setQuat(headQuat, viz.AVATAR_LOCAL)
male.addAction(
vizact.headto( 0,0,0, 20, bone = 'Bip01
Head'), 1 )
vizact.onkeydown('
',endHeadWatch)
See also
In this section:
Action Basics
Action synchronization and management
Sequences
Dynamic parameters
Node commands as actions
Actions command table
Other sections:
Tutorial: Using actions
Task basics
Director
basics
Timer
basics
Animation
path basics
Event
Basics