
In Latin America we have a kind of "rolling curtain" whose name is : "persiana".
It has many thin plates (we use bamboo sometimes) who goes up when we like to open the curtain.
This movement is not easy to recreate using a mathematical or physical aproach. The best solution here is to use: animation.
When you create a object to animation using 3ds max (read the Help for the basics), you need to give a name for each of its parts. In our case the name of the file will be: totalwindow.
We have six parts (or subobjects):
We need, of course, to export the object to be a .MTX/.MTS file.
To look inside a .MTX file is not easy (in the ViewPoint site there are some documentation about). But we NEED to do it, this time:
We will find some important informations:
1 - At our "persiana" each thin plate has an independent animation. If the name of an object is: tp1, the name of its animation will be: tp1_ANIM. We can start, stop, rewind animations using the Atmosphere API. By example:
tp5Anim = window.scene.getTimeElem("tp5_ANIM");
// To "capture"/find the animation tp5_ANIM
tp5Anim.setSpeed(.1);//defining a speed for the animation
tp5Anim.start(); //starting the animation
We have the methods: stop(), rewind() and some others.
2 - When we need to "capture"/find Solid Objects we use, by example:
bstop = tank.getSolidObject(0).rootPrimitive.find(".../stop");
If we need to find a subobject of a ViewPoint object we need to use the instance name of the subobject. We only find this instance name inside the .MTX file. There are courious names. Look in the figure. The name of the thin plate tp5 is:
totalwindow_MESH_1
To "capture" this instance to Atmosphere we write a line of code like:
tp5Ins = window.scene.getInstance("totalwindow_MESH_1");
Here, window is the name (inside Atmosphere) of the total object.
We create this "name of the total object" using:
window = new Object();
window = stageModel.getViewpointObject("totalwindow");
In this case: totalwindow is the name of the ViewPoint object inside the Builder.
A complex ViewPoint Object is like a tree:
THE EXERCICE
We will import the ViewPoint Object (the window) inside the Builder and create around it, using Solid Objects (the usual Atmosphere objects), the wall and a "red button"(whose name will be: box1)
Our idea is: clicking the button, on the first time the "persiana" opens. The next click: the "persiana" closes; the next click it opens etc.
We created the animation having 100 frames:
In the first click, the animation needs to go from the frame 0 to the frame 50. In the second click it needs to go from 50 to 100 and rewind!!!
But how will we "capture" if the persiana is in the frame 50?
We will use the vertical position of the thin plate tp5 to discover it. Look again in the first figure of the .MTX file. In 3ds max, the up direction is not Y! It's Z!!!. The tp1 goes from the position 0 to 47.8 and returns to 0. In the frame 50 we have Z=47.8.
Now, look the complete program glued to the ViewPoint object:
box1 = stageModel.getSolidObject(0).rootPrimitive.find("./box1");
window = new Object();
window = stageModel.getViewpointObject("totalwindow");
//Some flags
trans=0;
toopen=0;
toclose=0;
instcreated = 0;
tp5Ins = false;
tp1Anim = window.scene.getTimeElem("tp1 _ANIM");
tp2Anim = window.scene.getTimeElem("tp2 _ANIM");
tp3Anim = window.scene.getTimeElem("tp3 _ANIM");
tp4Anim = window.scene.getTimeElem("tp4 _ANIM");
tp5Anim = window.scene.getTimeElem("tp5_ANIM");
tp1Anim.setSpeed(.1);
tp2Anim.setSpeed(.1);
tp3Anim.setSpeed(.1);
tp4Anim.setSpeed(.1);
tp5Anim.setSpeed(.1);
//By default a VP animation runs! We need to stop it.
tp1Anim.stop();
tp2Anim.stop();
tp3Anim.stop();
tp4Anim.stop();
tp5Anim.stop();
box1.onClick=function(){
if(tp5Ins.position[2]<47)toopen=1;//position[2] is Z, up in 3ds max!
if(tp5Ins.position[2]>47)toclose=1;//If the persiana is in the superior limit
}
timestep = function(){
if (window.loaded){
if(trans==0){ //To play only one time, in the load
//Creating Physical Model
windowPM = window.createConvexPhysicalModel(50);
windowPM.fixed = true;
windowPM.collide = true;
trans=1
}
if(tp5Ins == false){
if(instcreated==0){ //To play only one time
//Finding the thin plate tp5
tp5Ins = window.scene.getInstance("totalwindow_MESH_1");
}
if(tp5Ins != false){
instcreated=1;
chat.print("Captured instance.");
}
}
if(tp5Ins != false){
if(tp5Ins.position[2]<48 && toopen==1){
if(tp5Ins.position[2]>47){ //If finish the open
tp1Anim.stop();
tp2Anim.stop();
tp3Anim.stop();
tp4Anim.stop();
tp5Anim.stop();
toopen=0;
}
else{ //Begin to open
tp1Anim.start();
tp2Anim.start();
tp3Anim.start();
tp4Anim.start();
tp5Anim.start();
}
}
else{
if( toclose==1){
if(tp5Ins.position[2] < 1){ //If finish to close
tp1Anim.stop();
tp2Anim.stop();
tp3Anim.stop();
tp4Anim.stop();
tp5Anim.stop();
tp1Anim.rewind();
tp2Anim.rewind();
tp3Anim.rewind();
tp4Anim.rewind();
tp5Anim.rewind();
toclose=0;
}
else{ //Begining to close
tp1Anim.start();
tp2Anim.start();
tp3Anim.start();
tp4Anim.start();
tp5Anim.start();
}
}
}
}
}
}//WOW! So many!!
This technique can be used in many animations.
When you have pratice using animations they will be more easy than programming some movements.
Try the demo. The collison works here!!!! If you doesn't see the window or if doesn't work: rightclick | Navigation | Refresh:
PREVIOUS LESSON NEXT LESSON T. CONTENTS HOMEPAGE
