WorldViz User Forum

WorldViz User Forum (https://forum.worldviz.com/index.php)
-   Vizard (https://forum.worldviz.com/forumdisplay.php?f=17)
-   -   Timer Actions problem (https://forum.worldviz.com/showthread.php?t=1957)

whj 04-08-2009 12:35 PM

Timer Actions problem
 
Hello,

I wrote a small script basically want to play some animation paths in a specific schedule and every animation path can be played more than once.

In this script, I create an animation path for a ball and another animation path for a duck. The array time_to_go[] and object[] make a schedule for the ball and duck. Here I would like firstly duck start to move; and after 3 seconds, ball start to move; and after another 3 seconds, ball start to move again. Then done.

unfortunately the ball will start the 3rd time after my schedule. Could somebody help me diagnose what's wrong with it.

Thanks,


Code:

import viz
import math
viz.go()


viz.clearcolor(0.5,0.5,1)
viz.add('tut_ground.wrl')

#Add 2 models.
#One is a ball, the other is a duck.
model = []
ball = viz.add('ball.wrl')
duck = viz.add('duck.cfg')
model.append(ball)
model.append(duck)


#Add the path.
#path[0] is for the ball, path[1] is for the duck.
path = []
for x in range(2):
        pa = viz.addAnimationPath()
        path.append(pa)

positions = [ [5,1,6], [0,1,3], [-150,1,6] ]
for x in range(len(positions)):
    cp = viz.addControlPoint()
    cp.setPosition(positions[x])
    path[0].add(cp,x+1)
    path[1].add(cp,x+1)

for x in range(2):
        path[x].constantspeed(viz.ON,10)
        path[x].loop(viz.OFF)
        path[x].translatemode(viz.BEZIER)
        path[x].setAutoRotate(viz.ON)

#Link the model to a path.
ball.link(path[0])
duck.link(path[1])



def mytimer(num):
        for x in range(2):
                pos = model[x].getPosition()
                if pos[0] < -15 :
                        path[x].pause()
                        path[x].reset()
                        model[x].setPosition(0,0,0)


def donothing():
    pass


#The following arrays means:
#Firstly: duck start to move
#After 3 seconds, ball start to move
#After another 3 seconds, ball start to move again
time_to_go = [0, 3, 6]
object = [1, 0, 0] #1 means duck, 0 means ball


#Create an array of timer action
myTimerAction = []
for x in range(3):
        if (x == 0) :
                myTimerAction.append(vizact.ontimer2(0, 1, donothing))
                path[object[0]].play()
        else:
                wait = time_to_go[x] - time_to_go[0]
                myTimerAction.append(vizact.ontimer2(wait, 1, path[object[x]].play))
       

       
viz.callback(viz.TIMER_EVENT,mytimer)
viz.starttimer(0,0,viz.PERPETUAL)


whj 04-08-2009 07:33 PM

Seems like I can play a lot of animation paths in a specific schedule, but every animation path can be played only once. Otherwise it would be messed up. Any hint?

Jeff 04-09-2009 09:41 AM

It looks like you are creating 2 vizact.ontimer2 objects for the ball when you only need one that repeats once. Try changing the 3 to a 2 in this for loop
Code:

#Create an array of timer action
myTimerAction = []
for x in range(3):


whj 04-09-2009 09:52 AM

Hi,

I think the 3 is actually len(time_to_go) or len(object). Because I define 3 events. I just put "donothing" as the first event (for duck action), and put ball actions as the 2nd and the 3rd event.

Thanks,
Haojie

whj 04-09-2009 12:45 PM

Seems to me that the array of myTimerAction got initialized correctly, but after path[x].pause() and path[x].reset(), the animation path were messed up. Any suggestion?

Jeff 04-09-2009 05:33 PM

This code loops three times
Code:

object = [1, 0, 0] #1 means duck, 0 means ball
#Create an array of timer action
myTimerAction = []
for x in range(3):
        if (x == 0) :
                myTimerAction.append(vizact.ontimer2(0, 1, donothing))
                path[object[0]].play()
        else:
                wait = time_to_go[x] - time_to_go[0]
                myTimerAction.append(vizact.ontimer2(wait, 1, path[object[x]].play))

The first time the duck's animation path is played. The second time a timer object is created that will repeat one time, so the ball's path will be played twice and the third time another timer object is created that will repeat one time, and the ball's path should be played two more times for a total of four times. I think the reason you see the ball move around three times has something to do with your reset code.

whj 04-09-2009 07:41 PM

I don't understand that "a timer object is created that will repeat one time, so the ball's path will be played twice." Why will it REPEAT one time? I thought the ball should be play only two times in a total. How do you suggest to change my reset code?

Thanks a lot!

Jeff 04-10-2009 02:15 PM

Because you have repeats set to 1 this timer will be called twice and the path will be played twice.
Code:

vizact.ontimer2(wait, 1, path[object[x]].play)
Rather than go through your loop 3 times just go through 2 times. The first loop plays the duck's path. The second loop will create a timer that expires twice, playing the ball's path twice, which I think is what you want

whj 04-10-2009 02:43 PM

Oh!!! I always thought the second argument of vizact.ontimer2 was the number of times to active the timer. Sorry about that. I should set it to 0. I'll correct it and see what happened....

Thanks a lot!

whj 04-10-2009 03:44 PM

Thank you, Jeff. It works!

Now I make a little change on the reset part. I would like to reset the object (duck or ball) right before being played. But I got the following error:

Traceback (most recent call last):
File "C:\Program Files\WorldViz\Vizard30/python\vizact.py", line 2980, in __ontimer
val = event.call()
File "C:\Program Files\WorldViz\Vizard30/python\vizact.py", line 2803, in _callStatic
return self.func(*self.args,**self.kwargs)
TypeError: 'NoneType' object is not callable



Could you please help me find the problem again? Thanks!


Code:

import viz
import math
viz.go()


viz.clearcolor(0.5,0.5,1)
viz.add('tut_ground.wrl')

#Add 2 models.
#One is a ball, the other is a duck.
model = []
ball = viz.add('ball.wrl')
duck = viz.add('duck.cfg')
model.append(ball)
model.append(duck)


#Add the path.
#path[0] is for the ball, path[1] is for the duck.
path = []
for x in range(2):
        pa = viz.addAnimationPath()
        path.append(pa)

positions = [ [5,1,6], [0,1,3], [-150,1,6] ]
for x in range(len(positions)):
    cp = viz.addControlPoint()
    cp.setPosition(positions[x])
    path[0].add(cp,x+1)
    path[1].add(cp,x+1)

for x in range(2):
        path[x].constantspeed(viz.ON,10)
        path[x].loop(viz.OFF)
        path[x].translatemode(viz.BEZIER)
        path[x].setAutoRotate(viz.ON)

#Link the model to a path.
ball.link(path[0])
duck.link(path[1])



def mytimer(num):
        pass

def reset(k):
        path[k].pause()
        path[k].reset()
        model[k].setPosition(0,0,0)
       

#The following arrays means:
#Firstly: duck start to move
#After 3 seconds, ball start to move
#After another 3 seconds, ball start to move again
time_to_go = [0, 3, 6]
object = [1, 0, 0] #1 means duck, 0 means ball


#Create an array of timer action
for x in range(len(object)):
        if (x == 0) :
                path[object[0]].play()
        else:
                wait = time_to_go[x] - time_to_go[0]
                vizact.ontimer2(wait, 0, reset(object[x]))
                vizact.ontimer2(wait+0.00001, 0, path[object[x]].play)
       

       
viz.callback(viz.TIMER_EVENT,mytimer)
viz.starttimer(0,0,viz.PERPETUAL)


Jeff 04-11-2009 06:55 PM

The error is in this line
Code:

vizact.ontimer2(wait, 0, reset(object[x]))
You need to pass the argument to your function like this
Code:

vizact.ontimer2(wait, 0, reset, object[x])

whj 04-12-2009 08:48 AM

Thank you so much for your help, especially at weekend. :)


All times are GMT -7. The time now is 10:27 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Copyright 2002-2023 WorldViz LLC