Main Menu

Animation

Started by Tornado7, June 16, 2004, 06:03:19 PM

Previous topic - Next topic

Tornado7

Another task: Animation. I have to start an object animation when something happens. First consideration, even if I problably I already know the answer: is it possible to import a keyframed animation created in Maya/3D Studio into jPCT? If, as I suppose, the answer is no let try to see if I have understood that way to create animations in jPCT: I load a 3ds file in which I've created variuos poses of my obj to animate (every pose corresponds to a keyframe); I load this file as usual, i.e.:

Object3D[] animArray=Loader.load3DS(getDocumentBase(),"3ds/ferito_anim.3ds", 20f);

every element of the array animArray is one of my poses (I guess), so after defining and instanciating an animation:

Animation anim;  
anim=new Animation(n);

where  n is the number of keyframes (poses) that I want to use. What is pretty cloudy to me is the way to use mesh (that I've to pass to the method addKeyFrame), in your documentation you say:
"Mesh can't be instantiated directly", so in which way can I use them? After adding all my keyframes to the animation, it simply starts when I start the applet? In which you use the interpolation attributes?

Thanks a thousand of times

EgonOlsen

You are basically right. I really don't know if it's possible to store all your keyframes in one 3DS-file in a working way, but that's just my lack of experience with 3DS...so i suppose that it is possible. In that case, just load the file, get the Object3Ds from it, call build() on all of them and add their Meshes using Object3D.getMesh().cloneMesh() to the animation. But that requires the meshes to be equal in vertex order. I'm not sure if 3DS guarantees this... :?:
However, after adding your meshes somehow, you have to call animate() on the object to animate (use the first object from the 3DS-file as the base object for your animation for example).
I'm not sure, if this was clear enough. Creating animations on your own (i.e. without using the MD2-format) can be a bit tricky. But it's quite easy once you got the basics though.

The code for this task should look somehow like this (i typed this from the top of my head, so don't blame me if it doesn't work exactly like this):
Object3D[] animArray=Loader.load3DS(getDocumentBase(),"3ds/ferito_anim.3ds", 20f);
Object3D animateMe=animArray[0];
animateMe.build();
animateMe.setTexture(...);
...
Animation anim=new Animation(animArray.length);
anim.createSubSequence("plopp");
for (int i=0; i<animArray.length; i++) {
animArray[i].build();
anim.addKeyFrame(animArray[i].getMesh().cloneMesh());
}
animateMe.setAnimationSequence(anim);
...
animateMe.animate(xxx);

EgonOlsen

Btw: What is (a) ferito? Babelfish translates it with "hurt"...are you writing a pain simulator... :wink: ??

Tornado7

Ok, I'll try as soon as possible (after solving my previous problem that, as you can see in the forum is still here....).
Yes, ferito is a wounded; I've to create a simulator for an University Medical context.... I've to simulate situation like road accident, and so on...
Bye and thanks

Tornado7

So, I've modified the loadFerito() method as follow:


public void loadFerito(String name, float x, float y, float z){
     
     Object3D animateMe=null;  
     
     texMan=TextureManager.getInstance();
     texMan.addTexture(name+".jpg",new Texture(getDocumentBase(),"textures/feriti/"+name+".jpg"));
     Object3D[] animArray=Loader.load3DS(getDocumentBase(),"3ds/"+name+"_anim.3ds", 20f);
     animateMe=animArray[0];
     animateMe.setCenter(SimpleVector.ORIGIN);
     animateMe.translate (x, y+55, z);
     animateMe.rotateX((float)-Math.PI/2);
     animateMe.rotateMesh();
     animateMe.setRotationMatrix(new Matrix());
     
     animateMe.createTriangleStrips(2);
     animateMe.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
     animateMe.setCollisionOptimization(Object3D.COLLISION_DETECTION_OPTIMIZED);
     
     //animateMe.build();
       
     Animation anim=new Animation(animArray.length);
     anim.createSubSequence("standing-up");
     
     for (int i=0; i<animArray.length; i++) {
  animArray[i].build();
  anim.addKeyFrame(animArray[i].getMesh().cloneMesh(true));
     }
     
     animateMe.setAnimationSequence(anim);
     animateMe.animate(0);
     
     theWorld.addObject(animateMe);
     
 }

where animArray[0] contains the first ferito's pose and animArray[1] contains the second that is, at this moment, the last. Running the applet nothing happens... Do you see any problem in my code?
Bye

EgonOlsen

You have to call animate() in your rendering loop, not when initialising things. If you, for example, add 5 keyframes to an animation, animate(0) will display the first frame, animate(1) the last and animate(0.55) an inbetween state of the 3rd and 4th frame.
So in your renderloop, you have to do something like animate(t); t+=0.1f; for each frame (or time based...whatever). However, there are two more things to consider in your code:
You are doing a rotateMesh() on the animateMe-object. Later on, you are using this rotated mesh as the first keyframe. That won't work, i.e. it will look silly. Are you sure that you need to do the rotation? Or is that just a copy-and-paste-error from the example code? If you do, rotate the object instead, not the mesh.
Second, you have to chose the appropriate clamping mode for your animation. The default clamping mode is only suitable if the last frame of an animation is close to the first frame. i.e. the animation loops.

Hope this helps.

Tornado7

Ok, following your instructions now it works.... You ARE GREAT  :D

raft

hi,

i tried a similar approach. first animated my object in 3d max than exported each keyframe to a different file.

however it didnt work me. jpct complained about mismatch of mesh sizes of the initial object and keyframes. it seems as max exports objects with different mesh sizes (possibly making an optimization)

how can i handle this ? (sorry, :oops: it is a how to use max question)
and does anyone know a good md2 editor ?

r a f t

EgonOlsen

Could be that 3DS merges some vertices on the one model but not on the other...maybe loading them into an MD2 editor will fix the problem. However, i don't know very much about MD2 editors, but Milkshape can export to MD2. Maybe it's worth a try.

gummipolarbear

To export keyframes in 3D Max for loader:
Go to Tools>Snapshot. Click the radio button labeled Range, enter 0 for From and 5 for To and make sure the Mesh radio button is selected (it usually is by default). In Copies enter the number of frames, in this case 5. Select OK. You will now see a bunch of meshes including your original mesh, each one called Something01 through Something05 (with Something00 being your original mesh you snapshotted). Press H (the Select by Name hotkey) and a window will pop up listing all the objects in your scene. Now select Something01, hold down Shift, and while still holding Shift select Something05. This will select Something01 and Something05 as well as all the ones in between. Make sure you don't include Something00 (the source mesh that was snapshotted). Notice that Something01 is a copy of Something00. Now, while Something01 through Something05 is selected, go to File → Export Selected. Export the meshes as a .3ds file named xxx.3ds. Make sure you choose Export Selected and not just plain old Export. Once finished, close the scene without saving it.