Home arrow Articles arrow Tutorials arrow Advanced Scripting : Remembering Time

Menu
Home
Articles
Downloads
AoI Extensions Catalog
Portal Blog
Forum
Links
AoI Wiki
AoI Homepage
About Art of Illusion
Popular Downloads
Live Translation
Login Form





Lost Password?
The Cornell Box
Name:

Message:

Advanced Scripting : Remembering Time
User Rating: / 2
PoorBest 
Written by Francois Guillet   
Saturday, 28 July 2007

This article shows how to use the object script parameters feature in order to keep values that evolve with time.

 

One cool feature about object scripts (or scripted object) is that you can add parameters to them. Usually, one sets parameters using the 'Parameters' button in the edit window. This a far more user firendly way of specifying user parameters rather than to hack through the script and manually set variable like r=0.25; in the code.

But one can also use those parameters to store persistent information. People frequently ask how they can 'remember what time it was' in Art of Illusion. As a matter of fact, although the 'time' parameter allows one to make a scene change with time, nothing ensures that timings happen in sequence. The user is allowed to choose any position on the time scale and ask for a render. Thus, scenes have to be rendered whithout any knowledge of what "happened before". If your process needs to compute the state of the scene at time t going through time 0 (the start) up to now in little steps, you'll have to go through the whole time sequence for each render. But obviously, an animation follows the time axis step by step. We could make use of that instead of computing the whole time range over and over again. However, we must be able to remember the results of the computation of the frame before. Where can we save these results? By now you should be able to tell the answer. Yes, we'll use the script parameters for this job.
Let's suppose you've been given the following physics assignment: "simulate brownian motion using Art of Illusion."
Oh dear, what's this brownian motion to start with? Have a look here (this is the cultural/educational part of this tutorial). Ignore the complex mathematical stuff at the bottom of the article. What we need to simulate a brownian motion is a ball with random trajectory. This ball will move with a constant speed and direction for some time, then suddenly change direction and speed. It will keep these new parameters for some other time, then change again. etc.
Let's state some rules defining our Brownian motion. First, the ball speed will be chosen at random between -1 and 1 AoI unit per second in any axis. This will hopefully won't be so fast that the ball goes out of the field of view. We should change direction at a random time, say any time between 0 and 3 seconds.
Let's get to work! Create a scripted object and call this object 'Script' (default name, easy). Edit this script. The first part of the script is to find out if any parameters have been added to it. If not, we'll add the ones we need. But what do we need? Obviously, we need to know the time it was last time the script was run. Then there is the time last time the ball changed direction. We also need to know when the ball is supposed to change direction. We also need to know its position last time it changed direction. Position is a vector, so that's three parameters. The same is true for the speed along x, y and z. So that's a total of nine parameters. Let's go:

//let's get the scene and our script.
scene = script.getScene();
objectScript = scene.getObject("Script").object;
//we get also the current time
time = script.getTime();
//first, we need an initialize method
initialize() {
String[] names = new String[9];
double[] values = new double[9];
names[0] = "time";
values[0] = time;
names[1] = "lasttime";
values[1] = time;
names[2] = "nexttime";
values[2] = time+Math.random()*3.0;
names[3] = "positionx";
values[3] = 0.0;
names[4] = "positiony";
values[4] = 0.0;
names[5] = "positionz";
values[5] = 0.0;
names[6] = "speedx";
values[6] = Math.random()*2-1;
names[7] = "speedy";
values[7] = Math.random()*2-1;
names[8] = "speedz";
values[8] = Math.random()*2-1;
objectScript.setParameters(names, values);
}

int numParam = objectScript.getNumParameters();
if ( numParam == 0) {
//first time
initialize();
}

 

Some explanations are probably welcomed at this point. There will be other situations where we want to initialize the script, so we define this process in a method that can be called anywhere in the script. Initialization consists in putting sensible values in the parameters. In this case, we set the current time to now. Time of last direction and speed change is also set to now and the time for next direction change is computed. Position is set arbitrarily set to (0,0,0) and a random speed is computed.
So far, so good. If we make it past the number of parameters test then it means a simulation is under way. Is it a valid one? We have to check if it was run prior to the current time, "now". Let's check this. If the previous time is greater than the current time, we have t reinitialize the simulation. And if the simulation is valid, we also have to check if it's time to change direction.
if ( numParam == 0) {
//first time
initialize();
} else {
previoustime = objectScript.getParameterValue(0);
lasttime = objectScript.getParameterValue(1);
nexttime = objectScript.getParameterValue(2);
if (previoustime > time) {
//the simulation is not valid
initialize();
} else {
if (time > nexttime) {
//keep new position for reference
positionx = (nexttime-lasttime)*objectScript.getParameterValue(6) + objectScript.getParameterValue(3);
positiony = (nexttime-lasttime)*objectScript.getParameterValue(7) + objectScript.getParameterValue(4);
positionz = (nexttime-lasttime)*objectScript.getParameterValue(8) + objectScript.getParameterValue(5);
//and give the ball new trajectory parameters
objectScript.setParameterValue(1, nexttime);
objectScript.setParameterValue(2, nexttime + Math.random()*3.0);
objectScript.setParameterValue(3, positionx);
objectScript.setParameterValue(4, positiony);
objectScript.setParameterValue(5, positionz);
objectScript.setParameterValue(6, Math.random()*2-1);
objectScript.setParameterValue(7, Math.random()*2-1);
objectScript.setParameterValue(8, Math.random()*2-1);
}
}
}
That's a somewhat big piece of code. Just notice that updating parameters after a direction change is about the same as an initialization except we update the ball position.
Whatever happened, we're now ready to display the ball. Let's create the ball. Then we fetch trajectory data and compute the ball position knowing last position at previous direction change, time elapsed since then and speed. Finally we add the ball to the scene being rendered using the appropriate addObject method. Last but not least, we update the previous time parameter.

//create the ball

ball = new Sphere(0.1, 0.1, 0.1);
lasttime = objectScript.getParameterValue(1);
nexttime = objectScript.getParameterValue(2);

//compute position
positionx = (time-lasttime)*objectScript.getParameterValue(6) + objectScript.getParameterValue(3);
positiony = (time-lasttime)*objectScript.getParameterValue(7) + objectScript.getParameterValue(4);
positionz = (time-lasttime)*objectScript.getParameterValue(8) + objectScript.getParameterValue(5);

//compute ball coordinate system

coords = new CoordinateSystem(new Vec3(positionx, positiony, positionz), 0, 0, 0);

//and add object
script.addObject(ball, coords);
objectScript.setParameterValue(0, time);

And we're done! Get an animation preview with 10s to see the result. The default camera settings should let you see the ball wander. And each time you ask for another preview or render you get a different trajectory.




Leave a comment
RSS comments

Only registered users can leave comments.
Please login or register.

Powered by AkoComment Tweaked Special Edition v.1.4

Last Updated ( Saturday, 28 July 2007 )
 
< Prev   Next >