Raydium 3D Game Engine

Official forum for everything about Raydium, ManiaDrive, MeMak, ...
It is currently Thu Mar 28, 2024 8:02 am

All times are UTC




Post new topic Reply to topic  [ 39 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Sat Oct 11, 2008 1:10 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
I have been working with Cal3D (yes, re-invent the wheel was a bit stupid) and I got good results.
Currently I use cal3D as a common library, but i guess it should be added into raydium trunk cause cal3d is not installed by default in the most distros.

To avoid a problem like "RayODE vs BULLET" this time the animation is done in two layers: Raydium_anim_* functions (in fact an animation abstraction layer) and raydium_cal3d_* functions (the cal3d layer, that could be replaced without affecting raydium apps).
All basics functions are now supported, but one: texturing. Reason: I have found no one model using textures to make test :(

Image

Meanwhile, I prepared a video: http://www.guadagames.com/versusrx/test.avi


Last edited by vicentecarro on Mon Oct 13, 2008 11:42 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sun Oct 12, 2008 5:11 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Here the code for a testing application. This application loads a trooper model and allows you to rotate it with keys and move forward or stay (with page_up and page_down).
Just for showing the api implemented.

Code:
/*
    Raydium - CQFD Corp.
    http://raydium.org/
    Released under both BSD license and Lesser GPL library license.
    See "license.txt" file.
*/
#include "raydium/index.c"

int modelo;
int instancia;
int status=0;
int movement=-1;
int dummy;
int debug=0;
float angle=0.0f;
float radius=0.2f;
float fadein=0.5;
float fadeout=0.5;
float f[3];
float velocity=40.9;
float mov_timer;
dReal *pos;
dReal *vel;

//create sphere->ode object as base of the model
int create_void(void)
{
   int a;
   a=raydium_ode_object_create("void_dummy");   
   raydium_ode_object_sphere_add("void_dummy_0",a,0.2,radius,RAYDIUM_ODE_STANDARD,0,"");   
   raydium_ode_element_rotfriction_name ("void_dummy_0",0.005f);
   raydium_ode_element_material_name("void_dummy_0",RAYDIUM_ODE_MATERIAL_SOFT2);
   return a;   
}

//create the instance model
void create_model(void)
{
   dummy=create_void();
   //load the model
   modelo=raydium_anim_model_load("trooper/trooper.cfg");
   //creates one instance of the model.
   //Cause models can NOT be used directly.
   instancia=raydium_anim_instance_new(modelo);
   //apply meshes to the instance.
   //You could change meshes of an instance   
   raydium_anim_instance_attach_meshes(instancia);
   //Aply materials to the instance
   //You could change the set of materials to apply.
   raydium_anim_model_materials_apply(instancia,0);
   status=1;
   movement=0;
}

//setting up instance as walking
void model_walk(void)
{
   //we destroy animation number 2
   raydium_anim_action_remove(instancia,2);
   //we fade out animation 0 during a time of "fadeout" seconds
   raydium_anim_loop_clear(instancia,0,fadeout);
   //we apply animation 1 at full influence(1)
   raydium_anim_loop_set(instancia,1,1,fadein);
   //we fade out animation 2 during a time of "fadeout" seconds
   raydium_anim_loop_clear(instancia,2,fadeout);   
}

//setting up instance as stand up/idle
void model_idle(void)
{
   //we destroy animation number 2
   raydium_anim_action_remove(instancia,2);
   //we apply animation 0 at full influence(1) in just "fadein" seconds
   raydium_anim_loop_set(instancia,0,1,fadein);
   //we fade out animation 1 during a time of "fadeout" seconds   
   raydium_anim_loop_clear(instancia,1,fadeout);   
   //we fade out animation 2 during a time of "fadeout" seconds
   raydium_anim_loop_clear(instancia,2,fadeout);   
}

//setting up a action (animation 2)
void model_die(void)
{      
   //we launch animation 2. Fadeing in for 0.2 seconds and
   //fading out for 0 seconds. The animation will be stucked at end
   //of animation(last param = 1).
   raydium_anim_action_set(instancia,2,0.2,0,1);   
}

void display(void)
{   
   //update models.
   //we have to tell how much time has passed betwen this and the
   //previous frame.
   raydium_anim_update_animation(instancia,raydium_frame_time);   
   
   //update forces for applying to the dummy object
   f[0]=raydium_trigo_cos(angle-90.0f)*velocity;
   f[1]=raydium_trigo_sin(angle-90.0f)*velocity;
   f[2]=0.0f;
   
   //more updates
   if(movement==1)
   {
      //testing
      //instead of applying a force constanly,
      //this code is just applying the force each 0.5 seconds
      mov_timer+=raydium_frame_time;      
      if(mov_timer>0.5)
      {
         raydium_ode_element_addforce_name_3f("void_dummy_0",f[0],f[1],f[2]);
         mov_timer=0;
      }
   }
   else if(movement==0 )
   {
      //model_idle();
      //get linear velocity of the dummy object
      vel=raydium_ode_element_linearvelocity_get_name("void_dummy_0");
      float total;      
      total=sqrt(vel[0]*vel[0]+vel[1]*vel[1]+vel[2]*vel[2]);
      raydium_log("total: %3.3f",total);
      //sett up animations according the quantity of movement of the dummy
      raydium_anim_loop_set(instancia,0,1.0f-raydium_math_min(1,sqrt(total/1.80f)),0);
      raydium_anim_loop_set(instancia,1,raydium_math_min(1,sqrt(total/1.8f)),0);
   }
   
   //joy emulation   
   raydium_joy_key_emul();

   //escape
   if(raydium_key_last==1027)      exit(0);
      
   //debug
   if(raydium_key_last==1000+'d')   debug=debug?0:1;
   
   //captures
   if(raydium_key_last==7)raydium_capture_frame_auto();
   
   //create model
   if(raydium_key_last==1000+'1')create_model();   
   
   //model walk
   if(raydium_key_last==1000+'2')model_walk();

   //model idel
   if(raydium_key_last==1000+'3')model_idle();
   
   //model die
   if(raydium_key_last==1000+'4')model_die();
   
   //LOD to middle of polygons(aprox.)
   if(raydium_key_last==1000+'l')raydium_anim_model_lod_set(instancia,0.5);
   
   //rotating model
   if(raydium_key[GLUT_KEY_RIGHT])angle-=0.7;
   if(raydium_key[GLUT_KEY_LEFT])angle+=0.7;
   
   //forward model
   if(raydium_key[GLUT_KEY_PAGE_UP])
   {
      movement=1;
      model_walk();
   }
   //leave walking
   if(raydium_key[GLUT_KEY_PAGE_DOWN])
   {
      //model_idle();
      movement=0;
   }
   
   //starting frame
   raydium_clear_frame();
   
   //setting camera
   if(status>0)
   {
      pos=(float*)raydium_ode_element_pos_get_name("void_dummy_0");
      raydium_camera_orbitmove(pos[0]+(0.4*(raydium_math_cos(angle))),pos[1]+(0.4*(raydium_math_sin(angle))),pos[2]+1.1);
   }
   else
      raydium_camera_orbitmove(0,0,0.5);         
   
   
   //draw model
   if(status>0)
   {
      pos=(float*)raydium_ode_element_pos_get_name("void_dummy_0");
      glTranslatef(pos[0],pos[1],pos[2]-radius);
      glRotatef(angle,0,0,1);      
      raydium_anim_mesh_render(instancia);      
      glRotatef(-angle,0,0,1);
      glTranslatef(-pos[0],-pos[1],-pos[2]);
   }
   
   //draw ode stuff
   if(!debug)raydium_ode_draw_all(0);
   else raydium_ode_draw_all(RAYDIUM_ODE_DRAW_DEBUG);   
   
   raydium_rendering_finish();
}


int main(int argc, char **argv)
{
raydium_init_args(argc,argv);
raydium_window_create(1024,768,RAYDIUM_RENDERING_WINDOW,"Cal3D Animation test");

raydium_texture_filter_change(RAYDIUM_TEXTURE_FILTER_TRILINEAR);
raydium_window_view_perspective(60,0.01,2500); // fov 60 + near and far planes

raydium_fog_disable();   
raydium_light_enable();
raydium_light_on(0);

raydium_light_conf_7f(0,50,150,200,1000000,1,0.9,0.7); // id, pos, intensity and color (RGB)
raydium_background_color_change(1,0.9,0.7,1);

raydium_sky_box_cache();

raydium_ode_ground_set_name("cocorobix.tri");

raydium_callback(&display);

//destroy model and instance
raydium_anim_instances_destroy();
raydium_anim_models_destroy();
return(0);
}

// EOF


Obviously this code won't compile (animation api still not commited). Just pasted as information.


Top
 Profile  
 
PostPosted: Mon Oct 13, 2008 7:49 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
As usual, imageshack is broken ... Can you post again your pictures to CQFD ftp, or http://uppix.net/ (for instance) ?

edit: The video shows great results, so far !


Top
 Profile  
 
PostPosted: Mon Oct 13, 2008 11:44 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Updated main post with uppix uploaded picture.
Can I upload to CQFD ftp? How?

As this feature requires a new lib (libcal3d) i'm not really sure about how to do the commit...


Top
 Profile  
 
PostPosted: Tue Oct 14, 2008 12:15 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
Thank you.

(About CQFD FTP, you only have to use ftp://cqfd-corp.org/uploads for uploading, and your files will then be available with http://ftp.cqfd-corp.org/?M=D a few seconds later)

It seems that it's a quiet huge commit, so it would be a good idea to polish it as most as possible before committing anything. You can provide a patch+new files here, so we can have a look, if you want, so we can play a bit with all this and report you our comments. It will also allows "platform maintainers" to prepare the integration of Cal3D into their SDK.

But it seems OK for me to add this feature in Raydium's core (and not only as a contrib, for instance), once we've got a stable, simple and effective API, with documentation ... "Animation" is really missing currently in Raydium. (and MD2 support should then probably be removed)


Top
 Profile  
 
PostPosted: Tue Oct 14, 2008 12:44 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Ok, I'm doing a few ( a lot of them, in fact) pulish here and there.

Questions:
  • The proposed names for functions are ok? raydium_anim_ (for abstraction layer) and raydium_cal3d (for cal3d specifics)
  • Cal3d models have a folder with the name of the model and an external file with extension cfg. Filling raydium trunk folder with cal3d model folders and cgf files is not a good idea. So looks a subfolder is a must here. I can create directly a "anims" folder at trunk or inside data folder (but data folder is currently not a must in raydium, just an option). Suggestions?
  • Today all the functions are in anim.c and anim.h, however maybe we can split raydium_anim and raydium_cal3d functions in anim.c/hand cal3d.c/h files. Suggestions?


Top
 Profile  
 
PostPosted: Tue Oct 14, 2008 1:05 pm 
Offline

Joined: Sun Oct 09, 2005 10:46 pm
Posts: 759
Hello,

The first problem for windows sdk is to build cal3d.
What version did you use ?

I think that a patch is the better way to test it.

I'm ok with raydium_anim, less with raydium_cal3d perhaps to specific (but we also have raydium_ode !)

Anim sub folder in data folder seem's good for me.

Ok for all function in anim.c anim.h

This is just my thought.
Have a nice day
Ouille


Top
 Profile  
 
PostPosted: Tue Oct 14, 2008 1:07 pm 
Offline

Joined: Tue Jul 08, 2008 2:37 am
Posts: 181
As already written on IRC, animated models will be a wonderful achievement!

On IRC vicente wrote:
Do you think you will have problems to add cal3d in raydium?
Just to be sure, we're talking to use the CAL3D Character Animation Library within Raydium.
What version or revision are you currently using? The latest stable version is 0.11.0.
I've never done anything Cal3D related, but I'll try to create an universal binary based package of this library, which we can add to the other Raydium dependencies within the SDK.

Xfennec wrote:
... provide a patch+new files here, so we can have a look ... also allows "platform maintainers" to prepare ...
That would be great. A patch with your additions and perhaps an included demo as posted above.


Top
 Profile  
 
PostPosted: Tue Oct 14, 2008 1:12 pm 
Offline
User avatar

Joined: Sun Mar 16, 2003 2:53 am
Posts: 2591
Location: gnniiiii (Scrat)
I don't think we're going to provide any other "internal" animation library than Cal3D, so splitting the code in two files (anim.c and cal3d.c) does not seems necessary or even interesting for us. One feature, one file. Thinking of it, it's more a matter of public functions and private functions. As a Raydium user, I don't have to call any cal3d function, right ?

So, "raydium_anim_*" is ok to me, and internal functions could use somethig like "raydium_anim_cal3d_*", all in the same set of files. We just have to state into the documentation that cal3d functions are internal ones.

About Cal3D models "foldering", can you upload such file somewhere so I can see what it exactly looks like ?


Top
 Profile  
 
PostPosted: Tue Oct 14, 2008 3:08 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Ok, all read.


Top
 Profile  
 
PostPosted: Wed Oct 15, 2008 6:58 am 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
I almost forgot: Cal3D version used is the package for ubuntu, that is cal3d 0.11.0-3 (that I understand is the same as the official 0.11.0).

update: And here a package with 2 example models.
http://watari.ath.cx/~vicente/anims.tar.bz2


Top
 Profile  
 
PostPosted: Wed Oct 15, 2008 8:16 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
I got a textured sample and finally I have it working with textures.
There are a few issues with openlg materials, but better we fix it later, when i publish the patch.
Meanwhile, here a new capture:

Image


Top
 Profile  
 
PostPosted: Thu Oct 16, 2008 4:03 pm 
Offline

Joined: Thu Sep 25, 2008 4:29 pm
Posts: 18
Video Please :D


Top
 Profile  
 
PostPosted: Thu Oct 16, 2008 5:49 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Better than video. I'm preparing the patch.


Top
 Profile  
 
PostPosted: Thu Oct 16, 2008 7:11 pm 
Offline
User avatar

Joined: Thu Sep 29, 2005 2:59 pm
Posts: 828
Here the patch:
Code:
Index: Makefile
===================================================================
--- Makefile   (revisión: 798)
+++ Makefile   (copia de trabajo)
@@ -7,9 +7,9 @@
 CC = gcc
 AR = ar
 RANLIB = ranlib
-SYSTEM_LIBS =  -lGL -lGLU -lXinerama -lm -ljpeg -lopenal -lalut -lvorbis -lvorbisfile -logg -lresolv -lcrypt -lz -lcurl -lxml2 -lGLEW
+SYSTEM_LIBS =  -lGL -lGLU -lXinerama -lm -ljpeg -lopenal -lalut -lvorbis -lvorbisfile -logg -lresolv -lcrypt -lz -lcurl -lxml2 -lGLEW -lcal3d
 OTHER_LIBS =  raydium/ode/ode/src/libode.a raydium/php/libs/libphp5.a
-INCLUDE_PATH =  -Iraydium/ode/include/ -Iraydium/php/ -Iraydium/php/include -Iraydium/php/main/ -Iraydium/php/Zend -Iraydium/php/TSRM -I/usr/include/curl
+INCLUDE_PATH =  -Iraydium/ode/include/ -Iraydium/php/ -Iraydium/php/include -Iraydium/php/main/ -Iraydium/php/Zend -Iraydium/php/TSRM -I/usr/include/curl -I/usr/include/
 LIBS_PATH =  -L/usr/X11R6/lib/
 CFLAGS=-W
 COMPILE_OPTIONS=-g -D LIBRAY
@@ -17,7 +17,7 @@
 LINKING_OPTIONS=-Wl,-soname,libraydium.so.0
 AR_OPTIONS=
 
-HEADERS=raydium/headers/background.h raydium/headers/callback.h raydium/headers/camera.h raydium/headers/capture.h raydium/headers/clear.h raydium/headers/console.h raydium/headers/file.h raydium/headers/file_tri.h raydium/headers/fog.h raydium/headers/init.h raydium/headers/cli.h raydium/headers/internal.h raydium/headers/joy.h raydium/headers/key.h raydium/headers/land.h raydium/headers/light.h raydium/headers/log.h raydium/headers/main.h raydium/headers/mouse.h raydium/headers/network.h raydium/headers/normal.h raydium/headers/object.h raydium/headers/ode.h raydium/headers/osd.h raydium/headers/parser.h raydium/headers/particle2.h raydium/headers/php.h raydium/headers/profile.h raydium/headers/random.h raydium/headers/rayphp.h raydium/headers/register.h raydium/headers/render.h raydium/headers/signal.h raydium/headers/sky.h raydium/headers/sound.h raydium/headers/texture.h raydium/headers/timecall.h raydium/headers/math.h raydium/headers/vertex.h raydium/headers/window.h raydium/headers/reg_api.h raydium/headers/gui.h raydium/headers/live.h raydium/headers/video.h raydium/headers/shadow.h raydium/headers/myglut.h raydium/headers/web.h raydium/headers/hdr.h raydium/headers/shader.h raydium/headers/atexit.h raydium/headers/path.h raydium/headers/sprites.h
+HEADERS=raydium/headers/background.h raydium/headers/callback.h raydium/headers/camera.h raydium/headers/capture.h raydium/headers/clear.h raydium/headers/console.h raydium/headers/file.h raydium/headers/file_tri.h raydium/headers/fog.h raydium/headers/init.h raydium/headers/cli.h raydium/headers/internal.h raydium/headers/joy.h raydium/headers/key.h raydium/headers/land.h raydium/headers/light.h raydium/headers/log.h raydium/headers/main.h raydium/headers/mouse.h raydium/headers/network.h raydium/headers/normal.h raydium/headers/object.h raydium/headers/ode.h raydium/headers/osd.h raydium/headers/parser.h raydium/headers/particle2.h raydium/headers/php.h raydium/headers/profile.h raydium/headers/random.h raydium/headers/rayphp.h raydium/headers/register.h raydium/headers/render.h raydium/headers/signal.h raydium/headers/sky.h raydium/headers/sound.h raydium/headers/texture.h raydium/headers/timecall.h raydium/headers/math.h raydium/headers/vertex.h raydium/headers/window.h raydium/headers/reg_api.h raydium/headers/gui.h raydium/headers/live.h raydium/headers/video.h raydium/headers/shadow.h raydium/headers/myglut.h raydium/headers/web.h raydium/headers/hdr.h raydium/headers/shader.h raydium/headers/atexit.h raydium/headers/path.h raydium/headers/sprites.h raydium/headers/anim.h
 
 OBJECTS      = $(HEADERS:raydium/headers/%.h=raydium/compile/%.o)
 
Index: anim-test1.c
===================================================================
--- anim-test1.c   (revisión: 0)
+++ anim-test1.c   (revisión: 0)
@@ -0,0 +1,213 @@
+/*
+    Raydium - CQFD Corp.
+    http://raydium.org/
+    Released under both BSD license and Lesser GPL library license.
+    See "license.txt" file.
+*/
+
+#include "raydium/index.c"
+
+int modelo,modelo2;
+int instancia,instancia2;
+float instancia2_walk=0;
+int instancia2_flag=0;
+int rendermesh=0;
+int renderskel=1;
+
+void display(void)
+{      
+   raydium_anim_instance_update(instancia,raydium_frame_time);
+   raydium_anim_instance_update(instancia2,raydium_frame_time);
+   
+   raydium_joy_key_emul();
+
+   //escape
+   if(raydium_key_last==1027)      exit(0);   
+   
+   //F7 capture screen
+   if(raydium_key_last==7)raydium_capture_frame_auto();
+   //switch meshes
+   if(raydium_key_last==1)rendermesh=rendermesh?0:1;
+   //switch skel
+   if(raydium_key_last==2)renderskel=renderskel?0:1;
+   //meshes attachment
+   if(raydium_key_last==3)
+   {
+      raydium_anim_instance_attach_meshes(instancia);
+      raydium_anim_instance_attach_meshes(instancia2);
+   }
+   //materials apply
+   if(raydium_key_last==4)
+   {
+      raydium_anim_model_materials_apply(instancia,0);
+      raydium_anim_model_materials_apply(instancia2,0);
+   }   
+   //LOD setting
+   if(raydium_key_last==5)
+   {
+      raydium_anim_model_lod_set(instancia,0.05);
+      raydium_anim_model_lod_set(instancia2,0.05);
+   }
+   if(raydium_key_last==6)
+   {
+      raydium_anim_model_lod_set(instancia,1);
+      raydium_anim_model_lod_set(instancia2,1);
+   }
+   
+   //loop
+   if(raydium_key_last==1000+'1')
+   {
+      //remove actions
+      raydium_anim_action_remove(instancia,1);
+      raydium_anim_action_remove(instancia,5);         
+      raydium_anim_action_remove(instancia2,2);
+      //clear loops
+      raydium_anim_loop_clear(instancia,0,0.5);
+      raydium_anim_loop_clear(instancia,1,0.5);
+      raydium_anim_loop_clear(instancia,2,0.5);
+      raydium_anim_loop_clear(instancia,3,0.5);
+      raydium_anim_loop_clear(instancia,4,0.5);
+      raydium_anim_loop_clear(instancia,5,0.5);
+      raydium_anim_loop_clear(instancia2,1,3);
+      //setup loops
+      raydium_anim_loop_set(instancia,3,1,3);      
+      raydium_anim_loop_set(instancia2,0,1,3);         
+   }
+   //loop
+   if(raydium_key_last==1000+'2')
+   {
+      //remove actions
+      raydium_anim_action_remove(instancia,1);
+      raydium_anim_action_remove(instancia,5);         
+      raydium_anim_action_remove(instancia2,2);         
+      //clear loops      
+      raydium_anim_loop_clear(instancia,0,0.5);
+      raydium_anim_loop_clear(instancia,1,0.5);
+      raydium_anim_loop_clear(instancia,2,0.5);
+      raydium_anim_loop_clear(instancia,3,0.5);
+      raydium_anim_loop_clear(instancia,4,0.5);
+      raydium_anim_loop_clear(instancia,5,0.5);
+      raydium_anim_loop_clear(instancia2,0,3);
+      //set up loops
+      raydium_anim_loop_set(instancia,4,1,3);            
+      raydium_anim_loop_set(instancia2,1,1,3);      
+   }
+      //loop
+   if(raydium_key_last==1000+'3')
+   {
+      //remove actions
+      raydium_anim_action_remove(instancia,1);
+      raydium_anim_action_remove(instancia,5);         
+      raydium_anim_action_remove(instancia2,2);         
+      //clear loops      
+      raydium_anim_loop_clear(instancia,0,0.5);
+      raydium_anim_loop_clear(instancia,1,0.5);
+      raydium_anim_loop_clear(instancia,2,0.5);
+      raydium_anim_loop_clear(instancia,3,0.5);
+      raydium_anim_loop_clear(instancia,4,0.5);
+      raydium_anim_loop_clear(instancia2,0,3);
+      //set up loops
+      raydium_anim_loop_set(instancia,0,1,3);            
+         
+   }
+   //loop
+   if(raydium_key_last==1000+'4')
+   {
+      //remove actions
+      raydium_anim_action_remove(instancia,1);
+      raydium_anim_action_remove(instancia,5);         
+      raydium_anim_action_remove(instancia2,2);         
+      //clear loops      
+      raydium_anim_loop_clear(instancia,0,0.5);
+      raydium_anim_loop_clear(instancia,1,0.5);
+      raydium_anim_loop_clear(instancia,2,0.5);
+      raydium_anim_loop_clear(instancia,3,0.5);
+      raydium_anim_loop_clear(instancia,4,0.5);
+      raydium_anim_loop_clear(instancia,5,0.5);   
+      //launch action
+      raydium_anim_action_set(instancia,5,0.5f, 0.1f, 0);      
+            
+   }
+   //action   
+   if(raydium_key_last==1000+'5')
+   {
+      raydium_anim_loop_clear(instancia,3,0.3);
+      raydium_anim_loop_clear(instancia,4,0.3);
+      raydium_anim_action_set(instancia,1,1.0f, 0.3f, 1);   
+      raydium_anim_loop_clear(instancia2,1,0.3);            
+      raydium_anim_loop_clear(instancia2,0,0.3);
+      raydium_anim_action_set(instancia2,2,1.0f, 0.3f, 1);      
+   }
+   
+   
+   raydium_clear_frame();
+   raydium_camera_orbitmove(0,0,0.5);
+   
+   raydium_ode_draw_all(0);
+   
+   //render instances   
+   if(rendermesh)
+   {
+   raydium_anim_instance_render(instancia,1);
+   raydium_anim_instance_render(instancia2,1);      
+   }
+   if(renderskel)
+   {
+   raydium_anim_instance_render(instancia,2);
+   raydium_anim_instance_render(instancia2,2);      
+   }
+   raydium_osd_printf(5,5,14,0.45,"bitstream.tga","Elapsed time: %5.5f",raydium_frame_time);   
+   raydium_osd_printf(5,95,15,0.45,"bitstream.tga","F1: switch Render Mesh");   
+   raydium_osd_printf(5,92,15,0.45,"bitstream.tga","F2: switch Render Skeleton");
+   raydium_osd_printf(5,89,15,0.45,"bitstream.tga","F3: Aplly meshes (needed to mesh render)");
+   raydium_osd_printf(5,86,15,0.45,"bitstream.tga","F4: Aplly materials/textures");
+   raydium_osd_printf(5,83,15,0.45,"bitstream.tga","F5: LOD(level of detail) 10%% for \"paladin\"");
+   raydium_osd_printf(5,80,15,0.45,"bitstream.tga","F6: LOD(level of detail) 100%% for \"paladin\"");
+   raydium_osd_printf(5,77,15,0.45,"bitstream.tga","F7: Screen capture");
+   raydium_osd_printf(5,74,15,0.45,"bitstream.tga","1,2,3,4,5: Various animation loops/actions");
+
+   raydium_rendering_finish();
+}
+
+
+int main(int argc, char **argv)
+{
+raydium_init_args(argc,argv);
+raydium_window_create(800,600,RAYDIUM_RENDERING_WINDOW,"Cal3D Animation test 1");
+
+raydium_texture_filter_change(RAYDIUM_TEXTURE_FILTER_TRILINEAR);
+raydium_window_view_perspective(60,0.01,2500); // fov 60 + near and far planes
+
+raydium_fog_disable();   
+raydium_light_enable();
+raydium_light_on(0);
+
+raydium_light_conf_7f(0,50,150,200,1000000,1,0.9,0.7); // id, pos, intensity and color (RGB)
+raydium_background_color_change(1,0.9,0.7,1);
+
+raydium_sky_box_cache();
+raydium_anim_init();
+raydium_ode_ground_set_name("cocorobix.tri");
+
+//loading models
+raydium_log("Stating models load...");
+modelo=raydium_anim_model_load("paladin.cfg");
+modelo2=raydium_anim_model_load("trooper.cfg");
+raydium_log("End of model load.");
+//creating instances
+instancia=raydium_anim_instance_new(modelo);
+instancia2=raydium_anim_instance_new(modelo2);
+//placing/rotating instances
+raydium_anim_instance_move(instancia,0,-1,-1.28);
+raydium_anim_instance_rotate(instancia,140,0,0);
+raydium_anim_instance_move(instancia2,0,1,-1.3);
+raydium_anim_instance_rotate(instancia2,110,0,0);
+
+
+raydium_callback(&display);
+raydium_anim_instances_destroy();
+raydium_anim_models_destroy();
+return(0);
+}
+
+// EOF
Index: raydium/init.c
===================================================================
--- raydium/init.c   (revisión: 798)
+++ raydium/init.c   (copia de trabajo)
@@ -95,6 +95,7 @@
 raydium_osd_fade_init();
 raydium_console_init();
 raydium_gui_init();
+raydium_anim_init();
 //#ifndef WIN32
 raydium_live_init();
 //#endif
@@ -290,6 +291,7 @@
 raydium_sound_init();
 raydium_viewport_init();
 raydium_callback_set();
+raydium_anim_init();
 #ifdef PHP_SUPPORT
 raydium_php_init();
 #endif
Index: raydium/anim.c
===================================================================
--- raydium/anim.c   (revisión: 0)
+++ raydium/anim.c   (revisión: 0)
@@ -0,0 +1,836 @@
+/*
+    Raydium - CQFD Corp.
+    http://raydium.org/
+    Released under both BSD license and Lesser GPL library license.
+    See "license.txt" file.
+*/
+
+#ifndef DONT_INCLUDE_HEADERS
+#include "index.h"
+#else
+#include "headers/anim.h"
+#endif
+
+//TODO: dont place these here
+#define RAYDIUM_ANIM_MAX_ANIMATIONS 32
+#define RAYDIUM_ANIM_MAX_INSTANCES 16
+#define RAYDIUM_ANIM_MAX_MESHES 30
+#define RAYDIUM_ANIM_MAX_MATERIALS 30
+
+//usage of coremodels
+int raydium_anim_model_use   [RAYDIUM_ANIM_MAX_MODELS];
+int raydium_anim_animations   [RAYDIUM_ANIM_MAX_MODELS];
+int raydium_anim_meshes      [RAYDIUM_ANIM_MAX_MODELS];
+int raydium_anim_materials  [RAYDIUM_ANIM_MAX_MODELS];
+int raydium_anim_animationid   [RAYDIUM_ANIM_MAX_MODELS][RAYDIUM_ANIM_MAX_ANIMATIONS];
+int raydium_anim_instance_use   [RAYDIUM_ANIM_MAX_INSTANCES];
+int raydium_anim_instance_model   [RAYDIUM_ANIM_MAX_INSTANCES];
+int raydium_anim_mesh_use   [RAYDIUM_ANIM_MAX_MESHES];
+int raydium_anim_meshid      [RAYDIUM_ANIM_MAX_MODELS][RAYDIUM_ANIM_MAX_MESHES];
+int raydium_anim_material_use   [RAYDIUM_ANIM_MAX_MESHES];
+int raydium_anim_materialid      [RAYDIUM_ANIM_MAX_MODELS][RAYDIUM_ANIM_MAX_MATERIALS];
+float raydium_anim_instance_pos_rot[RAYDIUM_ANIM_MAX_INSTANCES][6];
+
+//instances
+struct CalModel *raydium_anim_instance[RAYDIUM_ANIM_MAX_INSTANCES];
+//coremodels
+struct CalCoreModel *raydium_anim_model[RAYDIUM_ANIM_MAX_MODELS];
+//instances, beware with the non-friendly name
+struct CalModel* model;
+
+/*********************************************************************/
+/*******************  ANIM FUNCTIONS           ***********************/
+/*********************************************************************/
+   
+void raydium_anim_init(void)
+{
+   int a,b;
+   for(a=0;a<RAYDIUM_ANIM_MAX_MODELS;a++)
+   {
+      raydium_anim_model_use[a]=0;
+      raydium_anim_animations[a]=0;
+      raydium_anim_meshes[a]=0;
+      for(b=0;b<RAYDIUM_ANIM_MAX_ANIMATIONS;b++)
+      {
+         raydium_anim_animationid[a][b]=-1;
+      }
+      for(b=0;b<RAYDIUM_ANIM_MAX_MESHES;b++)
+      {         
+         raydium_anim_meshid[a][b]=-1;
+      }
+      for(b=0;b<RAYDIUM_ANIM_MAX_MATERIALS;b++)
+      {
+         raydium_anim_materialid[a][b]=-1;
+      }
+   }
+   for(a=0;a<RAYDIUM_ANIM_MAX_INSTANCES;a++)
+   {
+      raydium_anim_instance_use[a]=0;
+      raydium_anim_instance[a]=NULL;
+      raydium_anim_instance_model[a]=-1;
+      raydium_anim_instance_pos_rot[a][0]=0;
+      raydium_anim_instance_pos_rot[a][1]=0;
+      raydium_anim_instance_pos_rot[a][2]=0;
+      raydium_anim_instance_pos_rot[a][3]=0;
+      raydium_anim_instance_pos_rot[a][4]=0;
+      raydium_anim_instance_pos_rot[a][5]=0;
+   }
+   for(a=0;a<RAYDIUM_ANIM_MAX_MESHES;a++)
+   {
+      raydium_anim_mesh_use[a]=0;      
+   }
+   for(a=0;a<RAYDIUM_ANIM_MAX_MATERIALS;a++)
+   {
+      raydium_anim_material_use[a]=0;      
+   }
+   //TODO:This path_Ext be placed here?
+   raydium_path_ext("./data/anims/","cfg");   
+}
+void raydium_anim_model_destroy(int a)
+{   
+   CalCoreModel_Delete(raydium_anim_model[a]);
+   //WARNING:!!!
+   raydium_log("CAL3D:The instances using this model should be already destroy");   
+}
+void raydium_anim_models_destroy(void)
+{
+   int a;
+   for(a=0;a<RAYDIUM_ANIM_MAX_MODELS;a++)
+   {
+      if(raydium_anim_model_use[a])
+      {
+         raydium_anim_model_destroy(a);
+      }
+   }
+}
+int raydium_anim_model_load(char *filename)
+{
+   int a;
+   for(a=0;a<RAYDIUM_ANIM_MAX_MODELS;a++)
+   {
+      if(raydium_anim_model_use[a]==0)
+      {         
+         #ifdef RAYDIUM_ANIM_CAL3D
+         raydium_log("using cal3d specifics");
+         //raydium_anim_cal3d_model_load_internal return (int)boolean
+         if(raydium_anim_cal3d_model_load_internal(a,filename))
+            {
+            raydium_anim_model_use[a]=1;
+            return a;         
+            }         
+         #endif
+         break;
+      }
+   }
+   return -1;
+}
+void raydium_anim_instance_destroy(int instance)
+{
+   if(raydium_anim_instance_use[instance])
+   {
+      raydium_anim_cal3d_instance_destroy(instance);
+   }   
+}
+void raydium_anim_instances_destroy()
+{
+   int a;
+   for(a=0;a<RAYDIUM_ANIM_MAX_INSTANCES;a++)
+   {
+      raydium_anim_instance_destroy(a);
+   }
+}
+int raydium_anim_instance_new(int model)
+{
+   int a;
+   for(a=0;a<RAYDIUM_ANIM_MAX_INSTANCES;a++)
+   {
+      if(raydium_anim_instance_use[a]==0)
+      {         
+         if(raydium_anim_cal3d_instance_new_internal(a,model))
+         {
+            raydium_anim_instance_use[a]=1;
+            raydium_anim_instance_model[a]=model;
+            raydium_log("Created a new instance(%d) of model %d",a,model);
+            
+            return a;
+         }
+         else
+         {
+            raydium_log("ANIM:ERROR: creating instance %d",a);
+            return -1;
+         }
+      }
+   }
+   return -1;
+}
+void raydium_anim_instance_attach_meshes(int instance)
+{
+   if(!raydium_anim_instance_use[instance])
+   {
+      raydium_log("ANIM:ERROR: Instance index %d not valid. ",instance);
+   }
+   else
+   {
+      raydium_anim_cal3d_instance_attach_meshes(instance);
+   }
+}
+void raydium_anim_instance_render_skeleton(int instance)
+{
+   if(raydium_anim_instance_use[instance])
+      raydium_anim_cal3d_instance_render_skeleton(instance);
+   else
+      raydium_log("ANIM:ERROR: Not such instance %d. Nothing to render.",instance);
+}
+void raydium_anim_instance_update(int instance,float delta_time)
+{
+   if(raydium_anim_instance_use[instance] && delta_time>=0.0f)
+      raydium_anim_cal3d_instance_update(instance,delta_time);
+}
+void raydium_anim_animation_scale(int model,int animation,float scale)
+{
+   if(raydium_anim_model_use[model])
+      raydium_anim_cal3d_animation_scale(model,animation,scale);
+   else
+      raydium_log("ANIM:ERROR: Invalid model index");
+}
+void raydium_anim_skeleton_scale(int model,float scale)
+{
+   if(raydium_anim_model_use[model])
+      raydium_anim_cal3d_skeleton_scale( model, scale);
+}
+void raydium_anim_loop_set(int instance,int animation, float influence, float delay_seconds)
+{   
+   raydium_anim_cal3d_loop_set( instance, animation, influence, delay_seconds);
+}
+void raydium_anim_action_remove(int instance,int animation)
+{
+   raydium_anim_cal3d_action_remove(instance,animation);
+}
+void raydium_anim_instance_render(int instance, int type)
+{
+   glPushMatrix();
+   glTranslatef(   raydium_anim_instance_pos_rot[instance][0],
+               raydium_anim_instance_pos_rot[instance][1],
+               raydium_anim_instance_pos_rot[instance][2]);
+   glRotatef(   raydium_anim_instance_pos_rot[instance][3],0,0,1);
+   glRotatef(   raydium_anim_instance_pos_rot[instance][4],0,1,0);
+   glRotatef(   raydium_anim_instance_pos_rot[instance][5],1,0,0);
+   
+   switch(type)
+   {
+      case RAYDIUM_ANIM_RENDER_NONE:
+         //do nothing
+      break;
+      case RAYDIUM_ANIM_RENDER_MESH:
+         raydium_anim_instance_render_mesh(instance);
+      break;
+      case RAYDIUM_ANIM_RENDER_SKELETON:
+         raydium_anim_instance_render_skeleton(instance);
+      break;
+   }
+   glPopMatrix();   
+}
+void raydium_anim_instance_move(int instance,float x, float y, float z)
+{
+   if(raydium_anim_instance_use[instance])
+   {
+      raydium_anim_instance_pos_rot[instance][0]=x;
+      raydium_anim_instance_pos_rot[instance][1]=y;      
+      raydium_anim_instance_pos_rot[instance][2]=z;   
+   }      
+}
+void raydium_anim_instance_move_relative(int instance,float x, float y, float z)
+{
+   if(raydium_anim_instance_use[instance])
+   {
+      raydium_anim_instance_pos_rot[instance][0]+=x;
+      raydium_anim_instance_pos_rot[instance][1]+=y;      
+      raydium_anim_instance_pos_rot[instance][2]+=z;   
+   }      
+}
+void raydium_anim_instance_rotate(int instance,float x, float y, float z)
+{
+   if(raydium_anim_instance_use[instance])
+   {
+      raydium_anim_instance_pos_rot[instance][3]=x;
+      raydium_anim_instance_pos_rot[instance][4]=y;      
+      raydium_anim_instance_pos_rot[instance][5]=z;   
+   }      
+}
+void raydium_anim_instance_rotate_relative(int instance,float x, float y, float z)
+{
+   if(raydium_anim_instance_use[instance])
+   {
+      raydium_anim_instance_pos_rot[instance][3]+=x;
+      raydium_anim_instance_pos_rot[instance][4]+=y;      
+      raydium_anim_instance_pos_rot[instance][5]+=z;   
+   }      
+}
+
+void raydium_anim_instance_render_mesh(int instance)
+{
+   if(raydium_anim_instance_use[instance])
+      raydium_anim_cal3d_instance_render_mesh(instance);
+   else
+      raydium_log("ANIM:ERROR: Invalid instance index.");
+}
+void raydium_anim_model_materials_apply(int instance, int set)
+{
+   raydium_anim_cal3d_model_materials_apply(instance,set);
+}
+void raydium_anim_model_lod_set(int instance, float lod_level)
+{
+   raydium_anim_cal3d_model_lod_set(instance,lod_level);
+}
+void raydium_anim_action_set(int instance,int animation, float fadein_seconds, float fadeout_seconds, int autolock)
+{
+   raydium_anim_cal3d_action_set(instance,animation, fadein_seconds, fadeout_seconds,autolock);
+}
+void raydium_anim_loop_clear(int instance,int animation, float delay_seconds)
+{
+   raydium_anim_cal3d_loop_clear(instance,animation, delay_seconds);
+}
+
+/*********************************************************************/
+/*******************  CAL3D FUNCTIONS           **********************/
+/*********************************************************************/
+
+void raydium_anim_cal3d_instance_render_skeleton(int instance)
+{
+float lines[1024][2][3];
+int nrLines;
+float points[1024][3];
+int nrPoints;
+struct CalSkeleton *tmpskel;
+if(!raydium_anim_instance_use[instance])
+   {
+   raydium_log("ANIM:ERROR: Instance index %d not valid. ",instance);
+   }
+else
+   {
+   // draw the bone lines
+   //tmpskel=(struct CalSkeleton *)CalModel_GetSkeleton(raydium_anim_instance[instance]);
+   //nrLines=CalSkeleton_GetBoneLines(tmpskel,&lines[0][0][0]);
+   nrLines=CalSkeleton_GetBoneLines(CalModel_GetSkeleton(raydium_anim_instance[instance]),&lines[0][0][0]);
+
+   glLineWidth(3.0f);
+   glColor3f(1.0f, 1.0f, 1.0f);
+   glBegin(GL_LINES);
+   int currLine;
+   for(currLine = 0; currLine < nrLines; currLine++)
+      {
+      glVertex3f(lines[currLine][0][0], lines[currLine][0][1], lines[currLine][0][2]);
+      glVertex3f(lines[currLine][1][0], lines[currLine][1][1], lines[currLine][1][2]);
+      }
+   glEnd();
+   glLineWidth(1.0f);
+
+   // draw the bone points
+   nrPoints = CalSkeleton_GetBonePoints(CalModel_GetSkeleton(raydium_anim_instance[instance]),&points[0][0]);
+
+   glPointSize(4.0f);
+   glBegin(GL_POINTS);
+   glColor3f(0.0f, 0.0f, 1.0f);
+   int currPoint;
+   for(currPoint = 0; currPoint < nrPoints; currPoint++)
+      {
+      glVertex3f(points[currPoint][0], points[currPoint][1], points[currPoint][2]);
+      }
+   glEnd();
+   glPointSize(1.0f);
+   }
+}
+
+void raydium_anim_cal3d_instance_update(int instance,float delta_time)
+{   
+   if(raydium_anim_instance_use[instance] && delta_time>0.0f)
+      CalModel_Update(raydium_anim_instance[instance],delta_time);
+}
+
+void raydium_anim_cal3d_animation_scale(int model,int animation,float scale)
+{   
+   if(raydium_anim_model_use[model])
+      CalCoreAnimation_Scale(CalCoreModel_GetCoreAnimation(raydium_anim_model[model],animation),scale);
+   else
+      raydium_log("ANIM:ERROR: Invalid model index");
+}
+
+void raydium_anim_cal3d_skeleton_scale(int model,float scale)
+{
+   if(raydium_anim_model_use[model])
+      CalCoreSkeleton_Scale(CalCoreModel_GetCoreSkeleton(raydium_anim_model[model]),(float)scale);
+   else
+      raydium_log("ANIM:ERROR: Invalid model index");
+}
+
+void raydium_anim_cal3d_instance_render_mesh(int instance)
+{
+   if(raydium_anim_instance[instance])
+   {      
+      int bWireframe=0;
+      // get the renderer of the model
+      struct CalRenderer *pCalRenderer;      
+      pCalRenderer = CalModel_GetRenderer(raydium_anim_instance[instance]);
+
+      // begin the rendering loop      
+      if(!CalRenderer_BeginRendering(pCalRenderer)) return;
+
+      // set wireframe mode if necessary
+      if(bWireframe)
+      {
+         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+      }
+
+      // set the global OpenGL states
+      //glEnable(GL_DEPTH_TEST);
+      glShadeModel(GL_SMOOTH);
+      
+
+      // we will use vertex arrays, so enable them
+      glEnableClientState(GL_VERTEX_ARRAY);
+      glEnableClientState(GL_NORMAL_ARRAY);
+
+      // get the number of meshes
+      int meshCount;      
+      meshCount = CalRenderer_GetMeshCount(pCalRenderer);
+
+      // render all meshes of the model
+      int meshId;
+      for(meshId = 0; meshId < meshCount; meshId++)
+         {
+         // get the number of submeshes
+         int submeshCount;      
+         submeshCount = CalRenderer_GetSubmeshCount(pCalRenderer,meshId);
+
+         // render all submeshes of the mesh
+         int submeshId;
+         for(submeshId = 0; submeshId < submeshCount; submeshId++)
+            {
+            // select mesh and submesh for further data access       
+            if(CalRenderer_SelectMeshSubmesh(pCalRenderer,meshId,submeshId))
+               {
+               unsigned char meshColor[4];
+               GLfloat materialColor[4];
+
+               // set the material ambient color         
+               CalRenderer_GetAmbientColor(pCalRenderer, &meshColor[0]);
+               materialColor[0] = meshColor[0] / 255.0f;  materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f;
+               //glMaterialfv(GL_FRONT, GL_AMBIENT, materialColor);
+
+               // set the material diffuse color         
+               CalRenderer_GetDiffuseColor(pCalRenderer,&meshColor[0]);
+               materialColor[0] = meshColor[0] / 255.0f;  materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f;
+               //glMaterialfv(GL_FRONT, GL_DIFFUSE, materialColor);
+
+               // set the vertex color if we have no lights
+               if(1)
+               {
+                  glColor4fv(materialColor);
+               }
+
+               // set the material specular color         
+               CalRenderer_GetSpecularColor(pCalRenderer,&meshColor[0]);
+               materialColor[0] = meshColor[0] / 255.0f;  materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f;
+               //glMaterialfv(GL_FRONT, GL_SPECULAR, materialColor);
+
+               // set the material shininess factor
+               float shininess;
+               shininess = 50.0f; //TODO: pCalRenderer->getShininess();
+               shininess = CalRenderer_GetShininess(pCalRenderer);
+               //glMaterialfv(GL_FRONT, GL_SHININESS, &shininess);
+
+               // get the transformed vertices of the submesh
+               static float meshVertices[30000][3];
+               int vertexCount;         
+               vertexCount = CalRenderer_GetVertices(pCalRenderer,&meshVertices[0][0]);
+
+               // get the transformed normals of the submesh
+               static float meshNormals[30000][3];         
+               CalRenderer_GetNormals(pCalRenderer, &meshNormals[0][0]);
+
+               // get the texture coordinates of the submesh
+               static float meshTextureCoordinates[30000][2];
+               int textureCoordinateCount;
+               textureCoordinateCount = CalRenderer_GetTextureCoordinates(pCalRenderer,0,&meshTextureCoordinates[0][0]);
+
+               // get the faces of the submesh
+               static CalIndex meshFaces[50000][3];
+               int faceCount;
+               faceCount = CalRenderer_GetFaces(pCalRenderer,&meshFaces[0][0]);
+
+               // set the vertex and normal buffers
+               glVertexPointer(3, GL_FLOAT, 0, &meshVertices[0][0]);
+               glNormalPointer(GL_FLOAT, 0, &meshNormals[0][0]);
+
+               // set the texture coordinate buffer and state if necessary
+               if(CalRenderer_GetMapCount(pCalRenderer)>0 && (textureCoordinateCount > 0))
+                  {
+                  glEnable(GL_TEXTURE_2D);
+                  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+                  glEnable(GL_COLOR_MATERIAL);
+
+                  // set the texture id we stored in the map user data          
+                  glBindTexture(GL_TEXTURE_2D, (GLuint)CalRenderer_GetMapUserData(pCalRenderer,0));
+                  // set the texture coordenates buffer
+                  glColor4f(1.0f, 1.0f, 1.0f,1.0f);
+                  glTexCoordPointer(2, GL_FLOAT, 0, &meshTextureCoordinates[0][0]);
+                  glColor4f(1.0f, 1.0f, 1.0f,1.0f);
+                  }
+
+               // draw the submesh
+
+               if(sizeof(CalIndex)==2)
+               glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_SHORT, &meshFaces[0][0]);
+               else
+               glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_INT, &meshFaces[0][0]);
+
+               // disable the texture coordinate state if necessary
+               if(CalRenderer_GetMapCount(pCalRenderer)>0  && (textureCoordinateCount > 0))
+                  {
+                  glDisable(GL_COLOR_MATERIAL);
+                  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+                  glDisable(GL_TEXTURE_2D);
+                  }
+               ////////////////////////////////////////////////////////////////////////////////
+               //to show vertex normals do if(1)
+               if(0)
+                  {
+                  glBegin(GL_LINES);
+                  glColor3f(1.0f, 1.0f, 1.0f);
+                  int vertexId;
+                  for(vertexId = 0; vertexId < vertexCount; vertexId++)
+                  {
+                  const float scale = 0.3f;
+                  glVertex3f(meshVertices[vertexId][0], meshVertices[vertexId][1], meshVertices[vertexId][2]);
+                  glVertex3f(meshVertices[vertexId][0] + meshNormals[vertexId][0] * scale, meshVertices[vertexId][1] + meshNormals[vertexId][1] * scale, meshVertices[vertexId][2] + meshNormals[vertexId][2] * scale);
+                  }
+                  glEnd();
+                  }
+               ////////////////////////////////////////////////////////////////////////////////
+               GLfloat one[]={0.8f, 0.8f, 0.8f, 1.f};
+                 GLfloat zero[]={0.0,0.0,0.0,0.0};
+               glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, one);
+               glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, zero);
+               glEnable(GL_TEXTURE_2D);
+               glBindTexture(GL_TEXTURE_2D,0);
+               }
+            }
+         }
+
+      // clear vertex array state
+      glDisableClientState(GL_NORMAL_ARRAY);
+      glDisableClientState(GL_VERTEX_ARRAY);
+
+      // reset wireframe mode if necessary
+      if(bWireframe)
+      {
+         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+      }
+
+      // end the rendering
+      CalRenderer_EndRendering(pCalRenderer);
+   }
+}
+
+void raydium_anim_cal3d_loop_set(int instance,int animation, float influence, float delay_seconds)
+{
+   if(raydium_anim_instance_use[instance])
+      if(delay_seconds>=0)
+         if(influence>=0 && influence<=1   )         
+            CalMixer_BlendCycle(CalModel_GetMixer(raydium_anim_instance[instance]),raydium_anim_animationid[raydium_anim_instance_model[instance]][animation],influence,delay_seconds);   
+         else
+            raydium_log("ANIM:ERROR: Influence must be betwen 0 and 1");
+      else
+         raydium_log("ANIM:ERROR: invalid delay time for setting loop in instance %d",instance);
+   else
+      raydium_log("ANIM:ERROR: Invalid instance index");
+}   
+
+void raydium_anim_cal3d_loop_clear(int instance,int animation, float delay_seconds)
+{
+   if(raydium_anim_instance_use[instance])   
+      if(delay_seconds>=0)         
+         CalMixer_ClearCycle(CalModel_GetMixer(raydium_anim_instance[instance]),raydium_anim_animationid[raydium_anim_instance_model[instance]][animation],delay_seconds);   
+      else
+         raydium_log("ANIM:ERROR: invalid delay time for clearing loop in instance %d",instance);
+   else
+      raydium_log("ANIM:ERROR: Invalid instance index.");
+}
+
+void raydium_anim_cal3d_action_set(int instance,int animation, float fadein_seconds, float fadeout_seconds, int autolock)
+{
+   if(raydium_anim_instance_use[instance])
+      if(fadein_seconds>=0 && fadeout_seconds>=0)
+         CalMixer_ExecuteAction(CalModel_GetMixer(raydium_anim_instance[instance]),raydium_anim_animationid[raydium_anim_instance_model[instance]][animation],fadein_seconds, fadeout_seconds,autolock);
+      else
+         raydium_log("ANIM:ERROR: Fadein_seconds and fadeout seconds must be positive");
+   else
+      raydium_log("ANIM:ERROR: Invalid instance index.");
+}
+
+void raydium_anim_cal3d_model_lod_set(int instance, float lod_level)
+{
+   if(raydium_anim_instance_use[instance])
+      CalModel_SetLodLevel(raydium_anim_instance[instance],lod_level);
+   else
+      raydium_log("ANIM:ERROR: Invalid instance index.");
+}
+
+void raydium_anim_cal3d_model_materials_apply(int instance, int set)
+{
+   if(raydium_anim_instance_use[instance])
+      CalModel_SetMaterialSet(raydium_anim_instance[instance],set);
+   else
+      raydium_log("ANIM:ERROR: Invalid instance index.");
+}
+
+void raydium_anim_cal3d_action_remove(int instance, int animation)
+{   
+   if(raydium_anim_instance_use[instance])
+      CalMixer_RemoveAction((CalModel_GetMixer(raydium_anim_instance[instance])),animation);
+   else   
+      raydium_log("ANIM:ERROR: Invalid instance index.");
+}
+
+int raydium_anim_cal3d_instance_new_internal(int num,int model)
+{
+   if(!raydium_anim_instance_use[num])
+   {
+      raydium_anim_instance[num]=CalModel_New(raydium_anim_model[num]);
+      
+      if(raydium_anim_instance[num])
+         {
+         
+         return 1;
+         }
+      else
+         {
+         return 0;
+         }
+   }
+   else
+   {
+      raydium_log("ANIM:ERROR: that instance alread in use. Bad index");
+      return 0;
+   }
+}
+void raydium_anim_cal3d_instance_destroy(int instance)
+{
+   CalModel_Delete(raydium_anim_instance[instance]);
+}
+
+void raydium_anim_cal3d_instance_attach_meshes(int instance)
+{
+   int b;
+   int model;
+   if(raydium_anim_instance[instance])
+      {
+      model   =   raydium_anim_instance_model[instance];   
+      for(b=0;b<raydium_anim_meshes[model];b++)
+      {
+         CalModel_AttachMesh(raydium_anim_instance[instance], raydium_anim_meshid[model][b]);      
+      }
+      raydium_log("Added %d meshes to model %d for instancde %d",raydium_anim_meshes[model],model,instance);
+      }
+   else
+      {
+      raydium_log("ANIM:ERROR: Instance index %d not valid. ",instance);
+      }   
+}
+
+int raydium_anim_cal3d_model_load_internal(int a,char *filename)
+{
+   FILE *file;
+   char str[RAYDIUM_MAX_NAME_LEN];
+   char strpath[RAYDIUM_MAX_NAME_LEN];
+   char filename2[RAYDIUM_MAX_NAME_LEN];
+   char newstr[RAYDIUM_MAX_NAME_LEN];
+   int ret;
+   int error;
+   char var[RAYDIUM_MAX_NAME_LEN];
+   char val_s[RAYDIUM_MAX_NAME_LEN];
+   GLfloat val_f[5];
+   int size;   
+   //   counters
+   int ani_count;
+   int mesh_count;
+   int mat_count;   
+   float scale;
+   
+   ani_count=0;
+   mesh_count=0;
+   mat_count=0;
+   scale=1.0f;
+   error=0;
+   
+   //check if a is available
+   if(!raydium_anim_model[a])
+   {
+      sprintf(str,"raydium_model_%d",a);
+      
+      raydium_anim_model[a]=(struct CalCoreModel*)CalCoreModel_New(str);
+      //the filename should be a cfg!!!
+      //TODO:check 4 last letters
+      //convert filename into ray-path-compatible format
+      raydium_path_resolv(filename,filename2,'r');
+      if(file=raydium_file_fopen(filename2,"r"))
+      {
+         raydium_log("readed file cfg");
+         while( (ret=raydium_parser_read(var,val_s,val_f,&size,file))!=RAYDIUM_PARSER_TYPE_EOF)
+            {
+               
+               //*** PATH ***
+               if(!strcasecmp(var,"path"))
+               {
+                  raydium_file_dirname(strpath,filename2);
+                  strcat(strpath,val_s);
+                  raydium_log("The path will be: \"%s\"",strpath);
+               }
+               
+               //*** SKELETON ***
+               if(!strcasecmp(var,"skeleton"))
+               {
+                  raydium_log("Readed: %s",(char*)val_s);
+                  sprintf(newstr,"%s%s",strpath,val_s);   
+                  //load the skeleton
+                  if(CalCoreModel_LoadCoreSkeleton(raydium_anim_model[a],newstr))
+                  {
+                     //aply scale
+                     CalCoreSkeleton_Scale(CalCoreModel_GetCoreSkeleton(raydium_anim_model[a]),scale);
+                     raydium_log("Successfully loaded %s",newstr);
+                  }   
+                  else
+                  {
+                     raydium_log("ANIM:ERROR: Loading file %s",newstr);
+                     error=1;
+                  }               
+               }
+               
+               //*** SCALE ***
+               if(!strcasecmp(var,"scale"))
+               {   
+                  scale=val_f[0];
+               }
+               
+               //*** ANIMS ***
+               if(!strcasecmp(var,"animation"))
+               {
+                  
+                  raydium_log("Readed: %s",(char*)val_s);
+                  sprintf(newstr,"%s%s",strpath,val_s);   
+                  //load the animation
+                  raydium_anim_animationid[a][ani_count]=CalCoreModel_LoadCoreAnimation(raydium_anim_model[a],newstr);                  
+                  if(raydium_anim_animationid[a][ani_count]!=-1)
+                  {
+                     CalCoreAnimation_Scale(CalCoreModel_GetCoreAnimation(raydium_anim_model[a],raydium_anim_animationid[a][ani_count]),scale);                        
+                     ani_count++;
+                     raydium_log("Successfully loaded animation: %s",newstr);
+                     raydium_anim_animations[a]++;
+                  }         
+                  else
+                  {
+                     error=1;
+                  }                  
+               }
+               
+               //*** MESH ***
+               if(!strcasecmp(var,"mesh"))
+               {   
+                  raydium_log("Readed: %s",(char*)val_s);
+                  sprintf(newstr,"%s%s",strpath,val_s);
+                  raydium_anim_meshid[a][mesh_count]=CalCoreModel_LoadCoreMesh(raydium_anim_model[a],newstr);   
+                  if(raydium_anim_meshid[a][mesh_count]!=-1)
+                  {
+                     CalCoreMesh_Scale(CalCoreModel_GetCoreMesh(raydium_anim_model[a],raydium_anim_meshid[a][mesh_count]),scale);
+                     mesh_count++;
+                     raydium_log("Successfully loaded mesh:%s",newstr);
+                     raydium_anim_meshes[a]++;                     
+                  }      
+                  else
+                  {
+                     error=1;
+                  }            
+               }
+               
+               //*** MATERIALS ***
+               if(   !strcasecmp(var,"material"))
+               {
+                  raydium_log("Readed: %s",(char*)val_s);
+                  sprintf(newstr,"%s%s",strpath,val_s);
+                  raydium_anim_materialid[a][mat_count]=CalCoreModel_LoadCoreMaterial(raydium_anim_model[a],newstr);   
+                  if(raydium_anim_materialid[a][mat_count]!=-1)
+                  {                     
+                     mat_count++;
+                     raydium_log("Successfully loaded material:%s",newstr);
+                     raydium_anim_materials[a]++;                                       
+                  }
+                  else
+                  {
+                     error=1;
+                  }                  
+               }      
+            }                  
+         fclose(file);   
+         int c;
+         for(c=0;c<(raydium_anim_materials[a]);c++)
+         {
+            //load textures, if any
+            // get the current core material
+            struct CalCoreMaterial *pCoreMaterial;
+            //pCoreMaterial = myCoreModel.getCoreMaterial(materialId);
+            pCoreMaterial=CalCoreModel_GetCoreMaterial(raydium_anim_model[a],raydium_anim_materialid[a][c]);
+            
+            // dont use, just helper -> CalCoreMaterial_GetMapCount(CalCoreModel_GetCoreMaterial(raydium_anim_model[a]))
+            // loop through all the maps of the current core material
+            int mapid;
+            for(mapid = 0; mapid < CalCoreMaterial_GetMapCount(pCoreMaterial); mapid++)
+            {
+               // get the filename of the map
+               char strFilename[RAYDIUM_MAX_NAME_LEN];
+               strcpy(strFilename,CalCoreMaterial_GetMapFilename(pCoreMaterial,mapid));
+
+               // load the texture from the file
+               //Cal::UserData textureId;
+               //struct CalUserData textureid;
+               GLuint textureid;
+               //textureId = (Cal::UserData)myTextureLoadingFunction(strFilename);
+               //TODO:Ugly way to allow this path for textures
+               sprintf(newstr,"%s%s",strpath,strFilename);
+               raydium_path_add(strpath);
+               textureid=raydium_texture_load(strFilename);
+
+               // store the texture id in the user data of the map
+               //pCoreMaterial->setMapUserData(mapId, textureId);
+               //CalCoreMaterial_SetMapUserData(mapid,textureid);
+               CalCoreMaterial_SetMapUserData(pCoreMaterial,mapid,(int*)textureid);         
+            
+            }
+            
+            CalCoreModel_CreateCoreMaterialThread(raydium_anim_model[a],c);
+            
+            CalCoreModel_SetCoreMaterialId(raydium_anim_model[a],c,0,c);
+            
+            //CalCoreModel_SetCoreMaterialId(raydium_anim_model[a],c,0,c);
+            
+            //m_calCoreModel->createCoreMaterialThread(materialId);
+            // initialize the material thread
+            //m_calCoreModel->setCoreMaterialId(materialId, 0, materialId);
+         }      
+      }
+      else
+      {
+         raydium_log("ANIM:ERROR: Couldn't open file \"%s\".",filename);
+         error=1;
+      }
+   }
+   else
+   {
+      raydium_log("ANIM:ERROR:raydium_anim_model[%d] was not unset",a);
+      error=1;
+   }
+   
+   if(error)
+      return 0;
+   else      
+      return 1;      
+}
Index: raydium/index.c
===================================================================
--- raydium/index.c   (revisión: 798)
+++ raydium/index.c   (copia de trabajo)
@@ -63,6 +63,7 @@
 #include "hdr.c"
 #include "shader.c"
 #include "register.c"
+#include "anim.h"
 #ifdef PHP_SUPPORT
 #include "php.c"
 #include "rayphp.c"
Index: raydium/index.h
===================================================================
--- raydium/index.h   (revisión: 798)
+++ raydium/index.h   (copia de trabajo)
@@ -57,6 +57,7 @@
 #include "headers/hdr.h"
 #include "headers/shader.h"
 #include "headers/register.h"
+#include "headers/anim.h"
 #ifdef PHP_SUPPORT
 #include "headers/php.h"
 #include "headers/rayphp.h"
Index: raydium/headers/anim.h
===================================================================
--- raydium/headers/anim.h   (revisión: 0)
+++ raydium/headers/anim.h   (revisión: 0)
@@ -0,0 +1,227 @@
+#ifndef _ANIM_H
+#define _ANIM_H
+#include <cal3d/cal3d_wrapper.h>
+
+//TODO:This should be in other place
+#define RAYDIUM_ANIM_CAL3D
+#define RAYDIUM_ANIM_MAX_MODELS 20
+#define RAYDIUM_ANIM_RENDER_NONE 0
+#define RAYDIUM_ANIM_RENDER_MESH 1
+#define RAYDIUM_ANIM_RENDER_SKELETON 2
+
+//-----------------------------------------------------------
+//Doxygen testing doc
+/*! \page animatedmodels Animated Models
+
+Raydium allows you to use Animated Models in Cal3D(http://home.gna.org/cal3d/) format.
+It's important to know well how cal3d animation works before starting to suing it.
+
+A common cal3d model is compound of:
+
+-.cfg file with a few parameters and a list of used files
+-.csf file with the unique skeleton per model
+-.caf or .xaf files, each one is 1 animation loop/action for the current model
+-.crf or .xrf files, each one is a material
+-.cmf or .xmf files, each one is a mesh to apply in the model
+*
+Note: "x-starting" files are XML files and easy to edit. By other side "c-starting" files are binary compiled files. They can not be edited but are faster to load.
+
+
+So raydium will load the cfg file an, internally, it will load all needed subfiles.
+The models can NOT be used directly so, once loaded the model you MUST create instances of the model for your application.
+Then you can apply loops or actions to each instance independently.
+
+
+Types of animations:
+
+Even if the animation files are the same, you can apply that animation as a loop or as an action.
+Loops: the animation loops forever (until you deactivate it)
+Actions: The animation will play just once, and you can set a lock. If the action is locked, the instance will be keep in the last frame of the animation, else it will return to the previous animation fame(if any).
+
+Mixing:
+
+To achieve good animations you will have to mix diferent animations at time.
+For example your model could be walking and sometimes it could throw an arrow.
+
+TODO: more explanation about mixing
+*/
+
+//-----------------------------------------------------------
+
+
+/*=
+Animation System
+2200
+Raydium allows you to use Animated Models in Cal3D(http://home.gna.org/cal3d/) format.
+It's important to know well how cal3d animation works before starting to suing it.
+
+A common cal3d model is compound of:
+
+-.cfg file with a few parameters and a list of used files
+-.csf file with the unique skeleton per model
+-.caf or .xaf files, each one is 1 animation loop/action for the current model
+-.crf or .xrf files, each one is a material
+-.cmf or .xmf files, each one is a mesh to apply in the model
+*
+Note: "x-starting" files are XML files and easy to edit. By other side "c-starting" files are binary compiled files. They can not be edited but are faster to load.
+
+
+So raydium will load the cfg file an, internally, it will load all needed subfiles.
+The models can NOT be used directly so, once loaded the model you MUST create instances of the model for your application.
+Then you can apply loops or actions to each instance independently.
+
+
+Types of animations:
+
+Even if the animation files are the same, you can apply that animation as a loop or as an action.
+Loops: the animation loops forever (until you deactivate it)
+Actions: The animation will play just once, and you can set a lock. If the action is locked, the instance will be keep in the last frame of the animation, else it will return to the previous animation fame(if any).
+
+Mixing:
+
+To achieve good animations you will have to mix diferent animations at time.
+For example your model could be walking and sometimes it could throw an arrow.
+
+TODO: more explanation about mixing
+
+**/
+
+// Introduction
+/**
+EXPERIMENTAL: DONT USE!
+Animation system
+Based on Cal3D.
+**/
+
+
+__rayapi int raydium_anim_model_load(char *filename);
+/**
+EXPERIMENTAL: DONT USE!
+This function loads a model.
+Currently only Cal3D models are allowed. So you have to specify a *.cfg file in
+the ##filename##.
+
+##Parameters:##
+##model##:the index of the model to instanciate
+
+##Returns:##
+the index of the new model, or -1 if fails
+
+##Example:##
+%%(c)
+int paladin_model;
+int create_model_paladin(void)
+   {
+   paladin_model=raydium_anim_model_load("paladin.cfg");
+   return
+   }
+%%
+**/
+
+__rayapi int raydium_anim_cal3d_model_load_internal(int a,char *filename);
+/**
+EXPERIMENTAL: DONT USE!
+Internal.
+**/
+
+__rayapi void raydium_anim_models_destroy(void);
+/**
+EXPERIMENTAL: DONT USE!
+Destroy all models used in raydium.
+Beware. You should destroy all instances BEFORE call this function.
+**/
+
+__rayapi void raydium_anim_init(void);
+/**
+EXPERIMENTAL: DONT USE!
+Init the animation system of raydium.
+**/
+
+
+__rayapi int raydium_anim_instance_new(int model);
+/**
+EXPERIMENTAL: DONT USE!
+Creates a new instance from a ##model##.
+
+##Parameters:##
+##model##:the index of the model to instanciate
+
+##Returns:##
+The index of the new instance
+
+##Example:##
+%%(c)
+int paladin_instance[2];
+int paladin_model;
+void create_paladin_instances(void)
+   {
+      paladin_model=create_model_paladin();
+      paladin_instance[0]=raydium_anim_instance_new(paladin_model);
+      paladin_instance[1]=raydium_anim_instance_new(paladin_model);      
+   }
+%%
+**/
+
+__rayapi void raydium_anim_instance_update(int instance,float time);
+/**
+EXPERIMENTAL: DONT USE!
+This function is a must if you want to animate you models(instances).
+
+##Parameters:##
+##instance##:the index of the instance
+##time##: The time betwen the last call to thin function and this call.
+Commonly this value is equal to ##raydium_frame_time##
+
+##Returns:##
+
+##Example:##
+%%(c)
+void display(void)
+   {
+   if(raydium_key_last==1027)
+   exit(0);
+   raydium_clear_frame();
+   raydium_camera_freemove(RAYDIUM_CAMERA_FREEEMOVE_NORMAL);   
+   raydium_ode_draw_all(0);
+   raydium_anim_instance_update(character,raydium_frame_time);   
+   raydium_anim_instance_render_mesh(character);
+   raydium_rendering_finish();
+   }
+%%
+**/
+__rayapi void raydium_anim_instance_update(int instance,float delta_time);
+__rayapi void raydium_anim_instance_render_skeleton(int instance);
+__rayapi int raydium_anim_model_load(char *filename);
+__rayapi int raydium_anim_instance_new(int model);
+__rayapi void raydium_anim_instances_destroy();
+__rayapi void raydium_anim_models_destroy(void);
+__rayapi void raydium_anim_instance_attach_meshes(int instance);
+__rayapi void raydium_anim_cal3d_instance_attach_meshes(int instance);
+__rayapi void raydium_anim_cal3d_instance_render_mesh(int instance);
+__rayapi void raydium_anim_loop_set(int instance,int animation, float influence, float delay_seconds);
+__rayapi void raydium_anim_cal3d_loop_set(int instance,int animation, float influence, float delay_seconds);
+__rayapi void raydium_anim_loop_clear(int instance,int animation, float delay_seconds);
+__rayapi void raydium_anim_cal3d_loop_clear(int instance,int animation, float delay_seconds);
+__rayapi void raydium_anim_action_set(int instance,int animation, float fadein_seconds, float fadeout_seconds, int autolock);
+__rayapi void raydium_anim_cal3d_action_set(int instance,int animation, float fadein_seconds, float fadeout_seconds, int autolock);
+__rayapi void raydium_anim_cal3d_model_lod_set(int instance, float lod_level);
+__rayapi void raydium_anim_model_lod_set(int instance, float lod_level);
+__rayapi void raydium_anim_cal3d_model_materials_apply(int instance, int set);
+__rayapi void raydium_anim_model_materials_apply(int instance, int set);
+__rayapi void raydium_anim_instance_render_mesh(int instance);
+__rayapi void raydium_anim_cal3d_action_remove(int instance, int animation);
+__rayapi void raydium_anim_action_remove(int instance,int animation);
+__rayapi void raydium_anim_cal3d_instance_render_skeleton(int instance);
+__rayapi void raydium_anim_skeleton_scale(int model,float scale);
+__rayapi void raydium_anim_cal3d_instance_update(int instance, float time);
+__rayapi void raydium_anim_cal3d_animation_scale(int model,int animation,float scale);
+__rayapi void raydium_anim_cal3d_skeleton_scale(int model,float scale);
+__rayapi void raydium_anim_cal3d_instance_destroy(int instance);
+__rayapi void raydium_anim_instance_render(int instance, int type);
+__rayapi void raydium_anim_instance_move(int instance,float x, float y, float z);
+__rayapi void raydium_anim_instance_move_relative(int instance,float x, float y, float z);
+__rayapi void raydium_anim_instance_rotate(int instance,float x, float y, float z);
+__rayapi void raydium_anim_instance_rotate_relative(int instance,float x, float y, float z);
+
+#endif
+



Here the data folder(needed for tests):
http://www.guadagames.com/versusrx/data.tar.bz2

After apply the patch, do "make" and after that:
./odyncomp.sh anim-test1.c

The app has OSD instructions.

TODO:
Complete the doc(W.I.P)
New test app with moving character(W.I.P.)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 39 posts ]  Go to page 1, 2, 3  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group