Joined: Thu Sep 29, 2005 2:59 pm Posts: 828
|
Here again.
Well, I have got it running at last. But it's a bit tricky.
You can follow this steps:
- First: Modify the raydium_ode_element_fix function
You have to edit the ode file in the raydium folder. The file will be in a path like this: /yourpath/raydium/trunk/raydium/ode.c
Then search the function raydium_ode_element_fix. You have to change that function with this one:
Code: int raydium_ode_element_fix(char *name, int *elem, int nelems, signed char keepgeoms) { dReal aabb[6]; dReal aabbR[6]; dReal bounding[3]; dReal position[3]; int group; int elemN; int i,j; int done; dReal *data; dMass m; dReal mass;
if(keepgeoms) raydium_log("ODE: element_fix: keepgeoms not implemented yet !");
if(raydium_ode_element_find(name)>=0) { raydium_log("ODE: Error: Cannot fix elements as \"%s\": name already exists",name); return -1; }
if(nelems<1) { raydium_log("ODE: Error: Must fix at least one element"); return -1; }
for(i=0;i<nelems;i++) if(!raydium_ode_element_isvalid(elem[i])) { raydium_log("ODE: Error: Cannot fix elements: one element is not valid"); return -1; }
for(i=0;i<nelems;i++) if(raydium_ode_element[elem[i]].state!=RAYDIUM_ODE_STANDARD) { raydium_log("ODE: Error: Cannot fix non standard elements"); return -1; }
group=raydium_ode_element[elem[0]].object; for(i=0;i<nelems;i++) if(raydium_ode_element[elem[i]].object!=group) { raydium_log("ODE: Error: Cannot fix elements: not owned by the same object"); return -1; } raydium_log("Step 1"); // 2 - create new element (using AABB from elements) dGeomGetAABB(raydium_ode_element[elem[0]].geom,aabbR); raydium_log("Step 2"); for(i=0;i<nelems;i++) { dGeomGetAABB(raydium_ode_element[elem[i]].geom,aabb); for(j=0;j<6;j+=2) { aabbR[j ]=raydium_trigo_min(aabb[j ],aabbR[j ]); aabbR[j+1]=raydium_trigo_max(aabb[j+1],aabbR[j+1]); } } raydium_log("Step 3"); bounding[0]=aabbR[1]-aabbR[0]; bounding[1]=aabbR[3]-aabbR[2]; bounding[2]=aabbR[5]-aabbR[4];
position[0]=aabbR[0]+(bounding[0]/2.f); position[1]=aabbR[2]+(bounding[1]/2.f); position[2]=aabbR[4]+(bounding[2]/2.f);
// Now, we can create an new box element with some dummy values: elemN=raydium_ode_object_box_add(name,group,0.1f,bounding[0],bounding[1],bounding[2],RAYDIUM_ODE_STANDARD,0,""); raydium_ode_element[elemN].state=RAYDIUM_ODE_FIXING; raydium_ode_element_move(elemN,position); raydium_log("Step 4"); // 3 - save elements to new element done=0; mass=0; for(i=0;i<nelems;i++) for(j=0;j<RAYDIUM_ODE_ELEMENT_MAX_FIXING;j++) if(raydium_ode_element[elemN].fixed_elements[j]==NULL) { raydium_ode_element[elemN].fixed_elements[j]=malloc(sizeof(raydium_ode_ElementInternalSave)); strcpy(raydium_ode_element[elemN].fixed_elements[j]->name,raydium_ode_element[elem[i]].name); raydium_ode_element[elemN].fixed_elements[j]->type=dGeomGetClass(raydium_ode_element[elem[i]].geom); dGeomBoxGetLengths(raydium_ode_element[elem[i]].geom,raydium_ode_element[elemN].fixed_elements[j]->box_sizes); //raydium_ode_element[elemN].fixed_elements[j]->sphere_radius=dGeomSphereGetRadius(raydium_ode_element[elem[i]].geom); dBodyGetMass(raydium_ode_element[elem[i]].body,&m); raydium_ode_element[elemN].fixed_elements[j]->mass=m.mass; raydium_ode_element[elemN].fixed_elements[j]->object=raydium_ode_element[elem[i]].object; raydium_ode_element[elemN].fixed_elements[j]->mesh=raydium_ode_element[elem[i]].mesh; raydium_ode_element[elemN].fixed_elements[j]->slip=raydium_ode_element[elem[i]].slip; raydium_ode_element[elemN].fixed_elements[j]->cfm=raydium_ode_element[elem[i]].cfm; raydium_ode_element[elemN].fixed_elements[j]->erp=raydium_ode_element[elem[i]].erp;
data=(dReal *)dGeomGetPosition(raydium_ode_element[elem[i]].geom); memcpy(raydium_ode_element[elemN].fixed_elements[j]->rel_pos,data,sizeof(dReal)*3); raydium_ode_element[elemN].fixed_elements[j]->rel_pos[0]-=position[0]; raydium_ode_element[elemN].fixed_elements[j]->rel_pos[1]-=position[1]; raydium_ode_element[elemN].fixed_elements[j]->rel_pos[2]-=position[2]; dGeomGetQuaternion(raydium_ode_element[elem[i]].geom,raydium_ode_element[elemN].fixed_elements[j]->rel_rot); raydium_ode_element[elemN].fixed_elements[j]->user_data=raydium_ode_element[elem[i]].user_data; raydium_ode_element[elemN].fixed_elements[j]->user_tag=raydium_ode_element[elem[i]].user_tag; dBodyGetMass(raydium_ode_element[elem[i]].body,&m); raydium_ode_element[elemN].fixed_elements[j]->OnBlow=raydium_ode_element[elem[i]].OnBlow; raydium_ode_element[elemN].fixed_elements[j]->OnDelete=raydium_ode_element[elem[i]].OnDelete; mass+=m.mass; done++; j=RAYDIUM_ODE_ELEMENT_MAX_FIXING; // jump to next element to save } raydium_log("Step 5"); if(done!=nelems) raydium_log("ODE: Error: only %i/%i elems were fixed to %s ! Continue anyway...",done,nelems,name);
// 4 - delete elements for(i=0;i<nelems;i++) raydium_ode_element_delete(elem[i],1); // delete joints, too /!\ (must fix this)
// 5 - compute new mass dMassSetBox(&m,1,bounding[0],bounding[1],bounding[2]); dMassAdjust(&m,mass); dBodySetMass(raydium_ode_element[elemN].body,&m);
return elemN; }
- Second: Create a testing file
Now, create a new file with name, for example, joinelements.c. Put this content in the file:
Code: /* Raydium - CQFD Corp. http://raydium.org/ Released under both BSD license and Lesser GPL library license. See "license.txt" file. */
// This file is a default skeleton. Replace all [ ... ] sections with yours. // Have fun !
#include "raydium/index.c" int debug=1;
void createbigone() { int a; int b[4]; a=raydium_ode_object_create("thebigoneobject"); b[0]=raydium_ode_object_box_add("element1",a,1,RAYDIUM_ODE_AUTODETECT,0,0,RAYDIUM_ODE_STANDARD,0,"crate.tri"); raydium_ode_element_move_3f(b[0],1,1,2); b[1]=raydium_ode_object_box_add("element2",a,1,RAYDIUM_ODE_AUTODETECT,0,0,RAYDIUM_ODE_STANDARD,0,"crate.tri"); raydium_ode_element_move_3f(b[1],-1,1,2); b[2]=raydium_ode_object_box_add("element3",a,1,RAYDIUM_ODE_AUTODETECT,0,0,RAYDIUM_ODE_STANDARD,0,"crate.tri"); raydium_ode_element_move_3f(b[2],-1,2,3); b[3]=raydium_ode_object_box_add("element4",a,1,RAYDIUM_ODE_AUTODETECT,0,0,RAYDIUM_ODE_STANDARD,0,"crate.tri"); raydium_ode_element_move_3f(b[3],1,3,4);
//joining the four elements raydium_ode_element_fix("bigelement",b,4,0); }
void display(void) { raydium_joy_key_emul();
if(raydium_key_last==1027) exit(0); if(raydium_key_last==1000+'c') createbigone(); if(raydium_key_last==1000+'d') debug=debug?0:1;
raydium_clear_frame(); /* [ place your camera here ] */ raydium_camera_look_at(10,-2,2,0,0,0); /* [ draw here ] */ raydium_ode_draw_all(0);
if(debug) 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(640,480,RAYDIUM_RENDERING_WINDOW,"My app");
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();
/* [ place base scene here ] */ raydium_ode_ground_set_name("cocorobix.tri");
raydium_callback(&display); return(0); }
// EOF
- Third: Try it
Now the easy part. Just launch the test file with:
Code: ./odyncomp.sh joinelements.c Press 'c' key to create the joint object. Press 'd' key to toogle the debug mode.
That's all. Tell me if it worked for you
|
|