33 #include <libFreeWRL.h>
40 # warning "RigidBodyPhysics: ODE isn't build to use double-precision"
44 #include "../vrml_parser/Structs.h"
45 #include "../vrml_parser/CRoutes.h"
46 #include "../main/headers.h"
48 #include "../world_script/fieldSet.h"
49 #include "../x3d_parser/Bindable.h"
50 #include "Collision.h"
51 #include "quaternion.h"
53 #include "../opengl/Frustum.h"
54 #include "../opengl/Material.h"
55 #include "../opengl/OpenGL_Utils.h"
56 #include "../input/EAIHelpers.h"
59 #include "LinearAlgebra.h"
67 void *Component_RigidBodyPhysics_constructor(){
72 void Component_RigidBodyPhysics_init(
struct tComponent_RigidBodyPhysics *t){
75 t->prv = Component_RigidBodyPhysics_constructor();
81 void Component_RigidBodyPhysics_clear(
struct tComponent_RigidBodyPhysics *t){
91 return NODE_NEEDS_COMPILING;
102 #define NNC(A) NNC0(X3D_NODE(A))
103 #define MNC(A) MNC0(X3D_NODE(A))
108 void rbp_run_physics();
174 #define NUM 100 // max number of objects
175 #define DENSITY (1.0) // density of all objects
176 #define GPB 3 // maximum number of geometries per body
177 #define MAX_CONTACTS 8 // maximum number of contact points per body
178 #define MAX_FEEDBACKNUM 20
179 #define GRAVITY REAL(0.5)
180 #define USE_GEOM_OFFSET 1
184 typedef struct MyObject {
190 static int nextobj=0;
191 static dWorldID world = NULL;
192 static dSpaceID space = NULL;;
193 static MyObject obj[NUM];
194 static dJointGroupID contactgroup;
195 static int selected = -1;
196 static int show_aabb = 0;
197 static int show_contacts = 0;
198 static int random_pos = 1;
199 static int write_world = 0;
200 static int show_body = 0;
202 typedef struct MyFeedback {
206 static int doFeedback=0;
207 static MyFeedback feedbacks[MAX_FEEDBACKNUM];
212 static struct Vector *x3dworlds = NULL;
213 static struct Vector *x3dcollisionsensors = NULL;
214 static struct Vector *x3dcollisioncollections = NULL;
228 switch(X3D_NODE(csensor)->_nodeType){
229 case NODE_CollisionSensor:
232 case NODE_CollisionCollection:
241 if(csens && !csens->enabled) csens = NULL;
248 switch(X3D_NODE(csensor)->_nodeType){
249 case NODE_CollisionSensor:
256 case NODE_CollisionCollection:
262 if(ccol && !ccol->enabled) ccol = NULL;
267 static int static_contacts_n = 0;
268 static struct X3D_Contact *static_contacts_initializer = NULL;
269 static int static_contacts_initialized = FALSE;
274 static void nearCallback (
void *data, dGeomID o1, dGeomID o2)
276 if (dGeomIsSpace (o1) || dGeomIsSpace (o2)) {
278 dSpaceCollide2 (o1,o2,data,&nearCallback);
280 if (dGeomIsSpace (o1)) {
283 dSpaceCollide ((dSpaceID)o1,data,&nearCallback);
285 if (dGeomIsSpace (o2)) {
288 dSpaceCollide ((dSpaceID)o2,data,&nearCallback);
292 void *cdata1, *cdata2;
297 static int count = 0;
299 dContact contact[MAX_CONTACTS];
303 dBodyID b1 = dGeomGetBody(o1);
304 dBodyID b2 = dGeomGetBody(o2);
305 if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact))
return;
310 cdata1 = dGeomGetData(o1);
311 cdata2 = dGeomGetData(o2);
312 xshape1 = getCollidableShapeFromData(cdata1);
313 xshape2 = getCollidableShapeFromData(cdata2);
314 xcol1 = getCollisionCollectionFromCsensor(xshape1->_csensor);
315 xcol2 = getCollisionCollectionFromCsensor(xshape2->_csensor);
316 xsens1 = getCollisionSensorFromCsensor(xshape1->_csensor);
317 xsens2 = getCollisionSensorFromCsensor(xshape2->_csensor);
318 if(0)
if(count < 20){
319 if(xsens1) printf(
"have csens1 %x\n",xsens1);
320 if(xsens2) printf(
"have csens2 %x\n",xsens2);
321 if(xcol1) printf(
"have ccol1 %x\n",xcol1);
322 if(xcol2) printf(
"have ccol2 %x\n",xcol2);
324 if(xcol1 && !xcol1->enabled )
return;
325 if(xcol2 && !xcol2->enabled )
return;
326 if(xshape1 && !xshape1->enabled)
return;
327 if(xshape2 && !xshape2->enabled)
return;
330 xcol = xcol1 ? xcol1 : xcol2;
334 for (i=0; i<MAX_CONTACTS; i++) {
336 contact[i].surface.mode = dContactBounce;
337 contact[i].surface.mu = .1;
338 contact[i].surface.mu2 = 0;
339 contact[i].surface.bounce = .2;
340 contact[i].surface.bounce_vel = 0.1;
341 contact[i].surface.soft_cfm = 0.01;
344 contact[i].surface.mode = xcol->_appliedParametersMask;
345 contact[i].surface.mu = xcol->slipFactors.c[0];
346 contact[i].surface.mu2 = xcol->slipFactors.c[1];
347 contact[i].surface.bounce = xcol->bounce;
348 contact[i].surface.bounce_vel = xcol->minBounceSpeed;
349 contact[i].surface.soft_cfm = xcol->softnessConstantForceMix;
350 contact[i].surface.soft_erp = xcol->softnessErrorCorrection;
351 contact[i].surface.motion1 = xcol->surfaceSpeed.c[0];
352 contact[i].surface.motion2 = xcol->surfaceSpeed.c[1];
358 if (numc = dCollide (o1,o2,MAX_CONTACTS,&contact[0].geom,
sizeof(dContact)))
360 const dReal ss[3] = {0.02,0.02,0.02};
363 for (i=0; i<numc; i++) {
364 dJointID c = dJointCreateContact (world,contactgroup,contact+i);
365 dJointAttach (c,b1,b2);
368 if (doFeedback && (b1==obj[selected].body || b2==obj[selected].body))
370 if (fbnum<MAX_FEEDBACKNUM)
372 feedbacks[fbnum].first = b1==obj[selected].body;
373 dJointSetFeedback (c,&feedbacks[fbnum++].fb);
377 if(xsens1 || xsens2){
382 dSurfaceParameters *surface;
383 if(!static_contacts_initialized){
387 static_contacts_initializer = createNewX3DNode0(NODE_Contact);
388 static_contacts_initialized = TRUE;
391 if(static_contacts_n >= 100) static_contacts_n = 99;
392 k = static_contacts_n -1;
393 ct = &static_contacts_p[k];
394 memcpy(ct,static_contacts_initializer,
sizeof(
struct X3D_Contact));
395 surface = &contact[i].surface;
397 ct->appliedParameters.p = xcol ? xcol->appliedParameters.p : NULL;
398 ct->appliedParameters.n = xcol ? xcol->appliedParameters.n : 0;
399 ct->_appliedParameters = contact[i].surface.mode;
400 ct->body1 = b1 ? dBodyGetData(b1) : NULL;
401 ct->body2 = b2 ? dBodyGetData(b2) : NULL;
402 ct->bounce = (float)surface->bounce;
404 ct->contactNormal.c[0] = contact[i].geom.normal[0];
405 ct->contactNormal.c[1] = contact[i].geom.normal[1];
406 ct->contactNormal.c[2] = contact[i].geom.normal[2];
408 ct->depth = (
float)contact[i].geom.depth;
409 ct->frictionCoefficients.c[0] = (float)surface->mu;
410 ct->frictionCoefficients.c[1] = (
float)surface->mu2;
413 ct->frictionDirection.c[0] = contact[i].fdir1[0];
414 ct->frictionDirection.c[1] = contact[i].fdir1[1];
415 ct->geometry1 = X3D_NODE(xshape1);
416 ct->geometry2 = X3D_NODE(xshape2);
417 ct->minBounceSpeed = (float)surface->bounce_vel;
419 ct->position.c[0] = contact[i].geom.pos[0];
420 ct->position.c[1] = contact[i].geom.pos[1];
421 ct->position.c[2] = contact[i].geom.pos[2];
422 ct->slipCoefficients.c[0] = (
float)surface->mu;
423 ct->slipCoefficients.c[1] = (float)surface->mu2;
424 ct->softnessConstantForceMix = (
float)surface->soft_cfm;
425 ct->softnessErrorCorrection = (float)surface->soft_erp;
426 ct->surfaceSpeed.c[0]= (
float)surface->motion1;
427 ct->surfaceSpeed.c[1]= (float)surface->motion2;
428 if(xsens1 && xsens1->enabled){
431 if(xsens1->contacts.p == NULL)
432 xsens1->contacts.p = malloc(100 *
sizeof(
void*));
437 xsens1->contacts.p[xsens1->contacts.n] = X3D_NODE(ct);
438 xsens1->contacts.n++;
443 if(xsens1->intersections.p == NULL)
444 xsens1->intersections.p = malloc(100 *
sizeof(
void*));
449 xsens1->intersections.p[xsens1->intersections.n] = X3D_NODE(xshape1);
450 xsens1->intersections.n++;
453 if(xsens2 && xsens2->enabled && (xsens2 != xsens1 || (xsens1 && !xsens1->enabled))){
454 if(xsens2->contacts.p == NULL)
455 xsens2->contacts.p = malloc(100 *
sizeof(
void*));
460 xsens2->contacts.p[xsens2->contacts.n] = X3D_NODE(ct);
461 xsens2->contacts.n++;
466 if(xsens2 && xsens2->enabled){
467 if(xsens2->intersections.p == NULL)
468 xsens2->intersections.p = malloc(100 *
sizeof(
void*));
473 xsens2->intersections.p[xsens2->intersections.n] = X3D_NODE(xshape2);
474 xsens2->intersections.n++;
482 static int init_rbp_once = 0;
487 if(!init_rbp_once && world && space && contactgroup){
488 init_rbp_once = TRUE;
491 memset (obj,0,
sizeof(obj));
503 return init_rbp_once;
514 dJointGroupDestroy (contactgroup);
515 dSpaceDestroy (space);
516 dWorldDestroy (world);
523 FORCEOUT_ALL = 0xFFFFFFFF,
524 FORCEOUT_NONE = 0x00000000,
526 FORCEOUT_motor1Angle = 1 << 0,
527 FORCEOUT_motor1AngleRate= 1 << 1,
528 FORCEOUT_motor2Angle = 1 << 2,
529 FORCEOUT_motor2AngleRate= 1 << 3,
530 FORCEOUT_motor3Angle = 1 << 4,
531 FORCEOUT_motor3AngleRate= 1 << 5,
533 FORCEOUT_body1AnchorPoint=1 << 6,
534 FORCEOUT_body1Axis = 1 << 7,
535 FORCEOUT_body2AnchorPoint=1 << 8,
536 FORCEOUT_body2Axis = 1 << 9,
537 FORCEOUT_hinge1Angle = 1 << 10,
538 FORCEOUT_hinge1AngleRate= 1 << 11,
539 FORCEOUT_hinge2Angle = 1 << 12,
540 FORCEOUT_hinge2AngleRate= 1 << 13,
542 FORCEOUT_angle = 1 << 14,
543 FORCEOUT_angleRate = 1 << 15,
545 FORCEOUT_separation = 1 << 16,
546 FORCEOUT_separationRate = 1 << 17,
550 static struct force_output_fieldname {
552 unsigned int bitmask;
553 } force_output_fieldnames [] = {
554 {
"ALL", FORCEOUT_ALL},
555 {
"NONE", FORCEOUT_NONE},
557 {
"motor1Angle", FORCEOUT_motor1Angle},
558 {
"motor1AngleRate", FORCEOUT_motor1AngleRate},
559 {
"motor2Angle", FORCEOUT_motor2Angle},
560 {
"motor2AngleRate", FORCEOUT_motor2AngleRate},
561 {
"motor3Angle", FORCEOUT_motor3Angle},
562 {
"motor3AngleRate", FORCEOUT_motor3AngleRate},
564 {
"body1AnchorPoint" ,FORCEOUT_body1AnchorPoint},
565 {
"body1Axis" ,FORCEOUT_body1Axis},
566 {
"body2AnchorPoint" ,FORCEOUT_body2AnchorPoint},
567 {
"body2Axis" ,FORCEOUT_body2Axis},
568 {
"hinge1Angle" ,FORCEOUT_hinge1Angle},
569 {
"hinge1AngleRate" ,FORCEOUT_hinge1AngleRate},
570 {
"hinge2Angle" ,FORCEOUT_hinge2Angle},
571 {
"hinge2AngleRate" ,FORCEOUT_hinge2AngleRate},
573 {
"angle" ,FORCEOUT_angle},
574 {
"angleRate" ,FORCEOUT_angleRate},
576 {
"separation" ,FORCEOUT_separation},
577 {
"separationRate" ,FORCEOUT_separationRate},
583 unsigned int forceout_from_names(
int n,
struct Uni_String **p){
585 unsigned int ret = 0;
586 if(!strcmp(p[0]->strptr,
"ALL"))
return FORCEOUT_ALL;
587 if(!strcmp(p[0]->strptr,
"NONE"))
return FORCEOUT_NONE;
592 if(!strcmp(p[i]->strptr,force_output_fieldnames[j].fieldname)){
593 ret |= force_output_fieldnames[j].bitmask;
596 }
while(force_output_fieldnames[j].fieldname != NULL);
602 void setTransformsAndGeom_E(dSpaceID space,
void *csensor,
struct X3D_Node* parent,
struct X3D_Node **nodes,
int n){
624 if(node->_nodeType == NODE_CollidableShape || node->_nodeType == NODE_CollidableOffset || node->_nodeType == NODE_CollisionSpace){
625 float *translation, *rotation;
627 translation = collidable->translation.c;
628 rotation = collidable->rotation.c;
630 switch(node->_nodeType){
631 case NODE_CollidableShape:
639 gid = dCreateGeomTransform (space);
640 dGeomTransformSetCleanup (gid,1);
642 if(shape && shape->geometry){
645 switch(shape->geometry->_nodeType){
649 sides[0] = box->size.c[0]; sides[1] = box->size.c[1], sides[2] = box->size.c[2];
650 shapegid = dCreateBox(0,sides[0],sides[1],sides[2]);
657 sides[0] = cyl->radius;
658 sides[1] = cyl->height;
659 shapegid = dCreateCylinder(0,sides[0],sides[1]);
663 case NODE_TriangleSet:
667 dTriMeshDataID new_tmdata;
670 int index_count = coord->point.n;
671 dTriIndex * indices = malloc(index_count*
sizeof(dTriIndex));
672 for(j=0;j<index_count/3;j++){
674 indices[j*3 +k] = j*3 + k;
676 new_tmdata = dGeomTriMeshDataCreate();
677 dGeomTriMeshDataBuildSingle(new_tmdata, coord->point.p, 3 *
sizeof(
float), coord->point.n,
678 &indices[0], index_count, 3 *
sizeof(dTriIndex));
680 shapegid = dCreateTriMesh(0, new_tmdata, 0, 0, 0);
689 sides[0] = sphere->radius;
690 shapegid = dCreateSphere(0,sides[0]);
697 cshape->_csensor = csensor;
698 dGeomTransformSetGeom (gid,shapegid);
699 dGeomSetData(gid,cshape);
703 case NODE_CollisionSpace:
709 cspace->_space = dHashSpaceCreate (space);
710 dGeomSetData(cspace->_space,cspace);
713 setTransformsAndGeom_E(cspace->_space,csensor,X3D_NODE(cspace),cspace->collidables.p,1);
717 case NODE_CollidableOffset:
723 struct X3D_Node *nodelistitem = X3D_NODE(coff->collidable);
724 nodelist[0] = nodelistitem;
725 setTransformsAndGeom_E(space,csensor,X3D_NODE(coff),nodelist,1);
733 switch(parent->_nodeType){
734 case NODE_CollidableOffset:
739 float *translation, *rotation;
740 translation = coff->_initialTranslation.c;
741 rotation = coff->_initialRotation.c;
742 dGeomSetPosition (gid,translation[0],translation[1],translation[2]);
743 dRFromAxisAndAngle (Rtx,rotation[0],rotation[1],rotation[2],rotation[3]);
744 dGeomSetRotation (gid,Rtx);
752 dGeomSetBody (gid,rb->_body);
756 case NODE_CollisionSpace:
758 case NODE_CollisionCollection:
760 case NODE_RigidBodyCollection:
763 if(node->_nodeType == NODE_CollidableShape){
767 if(!cshape2->_initialized){
769 float *translation, *rotation, *initialtranslation, *initialrotation;
770 translation = cshape2->translation.c;
771 rotation = cshape2->rotation.c;
772 initialtranslation = cshape2->_initialTranslation.c;
773 initialrotation = cshape2->_initialRotation.c;
774 if(!vecsame3f(initialtranslation,translation)){
775 dGeomSetPosition (gid,translation[0],translation[1],translation[2]);
776 veccopy3f(initialtranslation,translation);
778 if(!vecsame4f(initialrotation,rotation)){
780 dRFromAxisAndAngle (Rtx,rotation[0],rotation[1],rotation[2],rotation[3]);
781 dGeomSetRotation (gid,Rtx);
782 veccopy4f(initialrotation,rotation);
784 cshape2->_initialized = TRUE;
798 static int rbp_pause = FALSE;
799 static double STEP_SIZE = .02;
906 int static_did_physics_since_last_Tick = FALSE;
907 void rbp_run_physics(){
930 static double lasttime;
931 static double remainder = 0.0;
932 static int done_once = 0;
934 thistime = TickTime();
936 double deltime = thistime - lasttime + remainder;
937 nstep = (int) floor( deltime / STEP_SIZE );
938 remainder = deltime - (nstep * STEP_SIZE);
944 if(nstep < 1)
return;
946 static_did_physics_since_last_Tick = TRUE;
953 if(x3dcollisionsensors){
955 for(i=0;i<x3dcollisionsensors->n;i++){
958 csens->contacts.n = 0;
961 csens->intersections.n = 0;
966 ccol->_csensor = csens;
971 if(x3dcollisioncollections){
976 for(i=0;i<x3dcollisioncollections->n;i++){
979 csens = ccol->_csensor;
981 unsigned int mask = 0;
983 for(k=0;k<ccol->appliedParameters.n;k++){
986 const char *ap = ccol->appliedParameters.p[k]->strptr;
987 if(!strcmp(ap,
"BOUNCE")){
988 mask |= dContactBounce;
989 }
else if(!strcmp(ap,
"USER_FRICTION")){
990 mask |= dContactFDir1;
991 }
else if(!strcmp(ap,
"FRICTION_COEFFICIENT-2")){
993 }
else if(!strcmp(ap,
"ERROR_REDUCTION")){
994 mask |= dContactSoftERP;
995 }
else if(!strcmp(ap,
"CONSTANT_FORCE")){
996 mask |= dContactSoftCFM;
997 }
else if(!strcmp(ap,
"SPEED-1")){
998 mask |= dContactMotion1;
999 }
else if(!strcmp(ap,
"SPEED-2")){
1000 mask |= dContactMotion2;
1001 }
else if(!strcmp(ap,
"SLIP-1")){
1002 mask |= dContactSlip1;
1003 }
else if(!strcmp(ap,
"SLIP-2")){
1004 mask |= dContactSlip2;
1007 ccol->_appliedParametersMask = mask;
1012 csensor = csens ? (
void*)csens : (
void*)ccol;
1013 setTransformsAndGeom_E(space, csensor, X3D_NODE(ccol), ccol->collidables.p, ccol->collidables.n);
1018 for(j=0;j<vectorSize(x3dworlds);j++){
1024 if(!x3dworld->enabled)
continue;
1026 if(NNC(x3dworld) || x3dworld->_world == NULL){
1027 x3dworld->_world = world;
1028 if(x3dworld->contactSurfaceThickness > 0)
1029 dWorldSetContactSurfaceLayer (x3dworld->_world, x3dworld->contactSurfaceThickness);
1030 dWorldSetGravity (x3dworld->_world, x3dworld->gravity.c[0], x3dworld->gravity.c[1], x3dworld->gravity.c[2]);
1031 dWorldSetERP (x3dworld->_world, x3dworld->errorCorrection);
1032 dWorldSetCFM (x3dworld->_world, x3dworld->constantForceMix);
1033 dWorldSetAutoDisableFlag (x3dworld->_world, x3dworld->autoDisable);
1034 dWorldSetAutoDisableLinearThreshold (x3dworld->_world, x3dworld->disableLinearSpeed);
1035 dWorldSetAutoDisableAngularThreshold (x3dworld->_world, x3dworld->disableAngularSpeed);
1036 dWorldSetAutoDisableTime (x3dworld->_world, x3dworld->disableTime);
1037 if(x3dworld->maxCorrectionSpeed > -1)
1038 dWorldSetContactMaxCorrectingVel (x3dworld->_world, x3dworld->maxCorrectionSpeed);
1042 if(x3dworld->set_contacts.n){
1045 for (kk=0; kk < x3dworld->set_contacts.n; kk++) {
1050 dJointID c = dJointCreateContact (world,contactgroup,&contact);
1052 contact.surface.mode = ct->_appliedParameters;
1053 contact.surface.mu = ct->slipCoefficients.c[0];
1054 contact.surface.mu2 = ct->slipCoefficients.c[1];
1055 contact.surface.bounce = ct->bounce;
1056 contact.surface.bounce_vel = ct->minBounceSpeed;
1057 contact.surface.soft_cfm = ct->softnessConstantForceMix;
1058 contact.surface.soft_erp = ct->softnessErrorCorrection;
1059 contact.surface.motion1 = ct->surfaceSpeed.c[0];
1060 contact.surface.motion2 = ct->surfaceSpeed.c[1];
1061 float2double(contact.geom.pos,ct->position.c,3);
1062 float2double(contact.fdir1,ct->frictionDirection.c,2);
1063 float2double(contact.geom.normal,ct->contactNormal.c,3);
1067 b1 = body1 ? body1->_body : NULL;
1068 b2 = body2 ? body2->_body : NULL;
1069 if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact))
continue;
1070 dJointAttach (c,b1,b2);
1072 x3dworld->set_contacts.n = 0;
1075 for(i=0;i<x3dworld->bodies.n;i++){
1076 int isNewBody = FALSE;
1077 int method_anchor_fixed_with_fixed_joint = 1;
1079 if(method_anchor_fixed_with_fixed_joint){
1080 if(!x3dbody->_body){
1081 x3dbody->_body = dBodyCreate (x3dworld->_world);
1082 dBodySetData (x3dbody->_body,(
void*) x3dbody);
1087 dJointID anchorID = dJointCreateFixed(x3dworld->_world,x3dworld->_group);
1088 dJointAttach(anchorID,x3dbody->_body,0);
1089 dJointSetFixed (anchorID);
1094 if(!x3dbody->_body && !x3dbody->fixed){
1096 x3dbody->_body = dBodyCreate (x3dworld->_world);
1097 dBodySetData (x3dbody->_body,(
void*) x3dbody);
1102 if(x3dbody->enabled)
1103 dBodyEnable (x3dbody->_body);
1105 dBodyDisable(x3dbody->_body);
1156 float *translation, *rotation;
1157 translation = x3dbody->position.c;
1158 rotation = x3dbody->orientation.c;
1160 for(k=0;k<x3dbody->geometry.n;k++){
1169 nodelistitem = X3D_NODE(collidable);
1170 nodelist[0] = nodelistitem;
1171 setTransformsAndGeom_E(space,NULL,X3D_NODE(x3dbody), nodelist,1);
1173 if(verify_translate(translation)){
1175 dBodySetPosition (x3dbody->_body, (dReal)translation[0],(dReal)translation[1],(dReal)translation[2]);
1177 if(verify_rotate(rotation)){
1182 vrmlrot_to_quaternion(&quat,rotation[0],rotation[1],rotation[2],rotation[3]);
1183 dquat[0] = quat.w; dquat[1] = quat.x, dquat[2] = quat.y, dquat[3] = quat.z;
1184 dBodySetQuaternion(x3dbody->_body,dquat);
1187 dRFromAxisAndAngle (R,rotation[0],rotation[1],rotation[2],rotation[3]);
1188 dBodySetRotation(x3dbody->_body,R);
1198 if(x3dbody->autoDamp){
1199 dBodySetAngularDamping(x3dbody->_body, x3dbody->angularDampingFactor);
1200 dBodySetLinearDamping(x3dbody->_body, x3dbody->linearDampingFactor);
1202 dBodySetDampingDefaults(x3dbody->_body);
1204 if(x3dbody->massDensityModel){
1207 switch(x3dbody->massDensityModel->_nodeType){
1210 struct X3D_Box *box = (
struct X3D_Box*)x3dbody->massDensityModel;
1211 sides[0] = box->size.c[0]; sides[1] = box->size.c[1], sides[2] = box->size.c[2];
1212 dMassSetBox (&m,DENSITY,sides[0],sides[1],sides[2]);
1218 sides[0] = cyl->radius;
1219 sides[1] = cyl->height;
1220 dMassSetCylinder (&m,DENSITY,3,sides[0],sides[1]);
1227 sides[0] = sphere->radius;
1228 dMassSetSphere (&m,DENSITY,sides[0]);
1235 float *I = x3dbody->inertia.c;
1236 dMassSetParameters (&m, DENSITY,
1243 dMassAdjust(&m,x3dbody->mass);
1244 dMassTranslate (&m,x3dbody->centerOfMass.c[0],x3dbody->centerOfMass.c[1],x3dbody->centerOfMass.c[2]);
1245 dBodySetMass (x3dbody->_body, &m);
1248 dMassSetSphere (&m,DENSITY,.01);
1249 dMassAdjust(&m,x3dbody->mass);
1250 dMassTranslate (&m,x3dbody->centerOfMass.c[0],x3dbody->centerOfMass.c[1],x3dbody->centerOfMass.c[2]);
1251 dBodySetMass (x3dbody->_body, &m);
1253 if(x3dbody->useFiniteRotation){
1254 if(!vecsame3f(x3dbody->__old_finiteRotationAxis.c,x3dbody->finiteRotationAxis.c)){
1255 dBodySetFiniteRotationAxis (x3dbody->_body, x3dbody->finiteRotationAxis.c[0],x3dbody->finiteRotationAxis.c[1],x3dbody->finiteRotationAxis.c[2]);
1256 veccopy3f(x3dbody->__old_finiteRotationAxis.c,x3dbody->finiteRotationAxis.c);
1259 dBodySetFiniteRotationMode (x3dbody->_body, x3dbody->useFiniteRotation ? 1 : 0);
1262 if(!x3dbody->useGlobalGravity){
1263 dBodySetGravityMode(x3dbody->_body,0);
1267 speed = veclength3f(x3dbody->linearVelocity.c);
1269 if(!vecsame3f(x3dbody->__old_linearVelocity.c,x3dbody->linearVelocity.c)){
1270 dBodySetLinearVel(x3dbody->_body, x3dbody->linearVelocity.c[0],x3dbody->linearVelocity.c[1],x3dbody->linearVelocity.c[2]);
1271 veccopy3f(x3dbody->__old_linearVelocity.c,x3dbody->linearVelocity.c);
1274 speed = veclength3f(x3dbody->angularVelocity.c);
1276 if(!vecsame3f(x3dbody->__old_angularVelocity.c,x3dbody->angularVelocity.c)){
1277 dBodySetAngularVel(x3dbody->_body, x3dbody->angularVelocity.c[0],x3dbody->angularVelocity.c[1],x3dbody->angularVelocity.c[2]);
1278 veccopy3f(x3dbody->__old_angularVelocity.c,x3dbody->angularVelocity.c);
1281 dBodySetAutoDisableFlag (x3dbody->_body, x3dbody->autoDisable ? 1 : 0);
1282 dBodySetAutoDisableLinearThreshold (x3dbody->_body, x3dbody->disableLinearSpeed);
1283 dBodySetAutoDisableAngularThreshold (x3dbody->_body, x3dbody->disableAngularSpeed);
1284 dBodySetAutoDisableTime (x3dbody->_body, x3dbody->disableTime);
1285 if(x3dbody->forces.n){
1289 for(kf=0;kf<x3dbody->forces.n;kf++){
1290 float *force = x3dbody->forces.p[kf].c;
1291 dBodyAddForce(x3dbody->_body, force[0], force[1], force[2]);
1294 if(x3dbody->torques.n){
1298 for(kf=0;kf<x3dbody->torques.n;kf++){
1299 float *torque = x3dbody->torques.p[kf].c;
1300 dBodyAddTorque(x3dbody->_body, torque[0], torque[1], torque[2]);
1309 for(i=0;i<x3dworld->joints.n;i++){
1312 switch(joint->_nodeType){
1313 case NODE_BallJoint:
1319 dBodyID body1ID, body2ID;
1324 body1ID = xbody1 ? xbody1->_body : NULL;
1325 body2ID = xbody2 ? xbody2->_body : NULL;
1326 jointID = dJointCreateBall (x3dworld->_world,x3dworld->_group);
1327 dJointAttach (jointID,body1ID,body2ID);
1328 jnt->_joint = jointID;
1329 dJointSetBallAnchor(jnt->_joint, jnt->anchorPoint.c[0],jnt->anchorPoint.c[1], jnt->anchorPoint.c[2]);
1330 jnt->_forceout = forceout_from_names(jnt->forceOutput.n,jnt->forceOutput.p);
1333 if(!vecsame3f(jnt->__old_anchorPoint.c,jnt->anchorPoint.c)){
1334 dJointSetBallAnchor(jnt->_joint, jnt->anchorPoint.c[0],jnt->anchorPoint.c[1], jnt->anchorPoint.c[2]);
1335 veccopy3f(jnt->__old_anchorPoint.c,jnt->anchorPoint.c);
1337 jnt->_forceout = forceout_from_names(jnt->forceOutput.n,jnt->forceOutput.p);
1342 case NODE_SingleAxisHingeJoint:
1347 dBodyID body1ID, body2ID;
1352 body1ID = xbody1 ? xbody1->_body : NULL;
1353 body2ID = xbody2 ? xbody2->_body : NULL;
1354 jointID = dJointCreateHinge (x3dworld->_world,x3dworld->_group);
1355 dJointAttach (jointID,body1ID,body2ID);
1356 jnt->_joint = jointID;
1362 if(!vecsame3f(jnt->__old_anchorPoint.c,jnt->anchorPoint.c)){
1363 dJointSetHingeAnchor (jointID,jnt->anchorPoint.c[0],jnt->anchorPoint.c[1],jnt->anchorPoint.c[2]);
1364 veccopy3f(jnt->__old_anchorPoint.c,jnt->anchorPoint.c);
1366 axislen = veclength3f(jnt->axis.c);
1369 jnt->axis.c[0] = jnt->axis.c[1] = 0.0f;
1370 jnt->axis.c[2] = 1.0f;
1372 if(!vecsame3f(jnt->__old_axis.c,jnt->axis.c)){
1373 dJointSetHingeAxis (jointID,jnt->axis.c[0],jnt->axis.c[1],jnt->axis.c[2]);
1374 veccopy3f(jnt->__old_axis.c,jnt->axis.c);
1376 jnt->_forceout = forceout_from_names(jnt->forceOutput.n,jnt->forceOutput.p);
1377 dJointSetHingeParam (jnt->_joint,dParamLoStop,jnt->minAngle);
1378 dJointSetHingeParam (jnt->_joint,dParamHiStop,jnt->maxAngle);
1379 dJointSetHingeParam (jnt->_joint,dParamBounce,jnt->stopBounce);
1380 dJointSetHingeParam (jnt->_joint,dParamStopERP,jnt->stopErrorCorrection);
1385 case NODE_DoubleAxisHingeJoint:
1390 int method_extension_axis1Angle;
1394 dBodyID body1ID, body2ID;
1399 body1ID = xbody1 ? xbody1->_body : NULL;
1400 body2ID = xbody2 ? xbody2->_body : NULL;
1401 jointID = dJointCreateHinge2 (x3dworld->_world,x3dworld->_group);
1403 dJointAttach (jointID,body1ID,body2ID);
1404 jnt->_joint = jointID;
1405 dJointSetHinge2Anchor(jnt->_joint,jnt->anchorPoint.c[0],jnt->anchorPoint.c[1],jnt->anchorPoint.c[2]);
1408 dJointSetHinge2Axis1(jnt->_joint,jnt->axis1.c[0],jnt->axis1.c[1],jnt->axis1.c[2]);
1410 dJointSetHinge2Axis2(jnt->_joint,jnt->axis2.c[0],jnt->axis2.c[1],jnt->axis2.c[2]);
1414 float axislen = veclength3f(jnt->axis1.c);
1417 jnt->axis1.c[0] = jnt->axis1.c[1] = 0.0f;
1418 jnt->axis1.c[2] = 1.0f;
1420 if(!vecsame3f(jnt->__old_axis1.c,jnt->axis1.c)){
1421 dJointSetHinge2Axis1(jnt->_joint,jnt->axis1.c[0],jnt->axis1.c[1],jnt->axis1.c[2]);
1422 veccopy3f(jnt->__old_axis1.c,jnt->axis1.c);
1424 if(!vecsame3f(jnt->__old_anchorPoint.c,jnt->anchorPoint.c)){
1425 dJointSetHinge2Anchor(jnt->_joint,jnt->anchorPoint.c[0],jnt->anchorPoint.c[1],jnt->anchorPoint.c[2]);
1426 veccopy3f(jnt->__old_anchorPoint.c,jnt->anchorPoint.c);
1428 if(!vecsame3f(jnt->__old_axis2.c,jnt->axis2.c)){
1429 dJointSetHinge2Axis2(jnt->_joint,jnt->axis2.c[0],jnt->axis2.c[1],jnt->axis2.c[2]);
1430 veccopy3f(jnt->__old_axis2.c,jnt->axis2.c);
1432 jnt->_forceout = forceout_from_names(jnt->forceOutput.n,jnt->forceOutput.p);
1433 dJointSetHinge2Param (jnt->_joint,dParamBounce1,jnt->stopBounce1);
1434 dJointSetHinge2Param (jnt->_joint,dParamStopERP1,jnt->stopErrorCorrection1);
1435 dJointSetHinge2Param (jnt->_joint,dParamSuspensionERP,jnt->suspensionErrorCorrection);
1436 dJointSetHinge2Param (jnt->_joint,dParamSuspensionCFM,jnt->suspensionForce);
1438 dJointSetHinge2Param (jnt->_joint,dParamFMax,jnt->maxTorque1);
1439 dJointSetHinge2Param (jnt->_joint,dParamLoStop,jnt->minAngle1);
1440 dJointSetHinge2Param (jnt->_joint,dParamHiStop,jnt->maxAngle1);
1441 dJointSetHinge2Param (jnt->_joint,dParamFudgeFactor,0.1);
1447 dJointSetHinge2Param (jnt->_joint,dParamVel2,jnt->desiredAngularVelocity2);
1448 dJointSetHinge2Param (jnt->_joint,dParamFMax2,jnt->maxTorque2);
1450 avel = jnt->desiredAngularVelocity1;
1451 method_extension_axis1Angle = 0;
1452 if(method_extension_axis1Angle){
1456 double agap = jnt->axis1Angle - dJointGetHinge2Angle1 (jnt->_joint);
1458 double avel = agap / .1 * jnt->desiredAngularVelocity1;
1459 if (agap > 0.1) avel = jnt->desiredAngularVelocity1;
1460 if (agap < -0.1) avel = -jnt->desiredAngularVelocity1;
1462 dJointSetHinge2Param (jnt->_joint,dParamVel,avel);
1466 case NODE_SliderJoint:
1471 dBodyID body1ID, body2ID;
1476 body1ID = xbody1 ? xbody1->_body : NULL;
1477 body2ID = xbody2 ? xbody2->_body : NULL;
1478 jointID = dJointCreateSlider (x3dworld->_world,x3dworld->_group);
1479 dJointAttach (jointID,body1ID,body2ID);
1480 jnt->_joint = jointID;
1483 float axislen = veclength3f(jnt->axis.c);
1486 jnt->axis.c[0] = jnt->axis.c[1] = 0.0f;
1487 jnt->axis.c[2] = 1.0f;
1489 if(!vecsame3f(jnt->__old_axis.c,jnt->axis.c)){
1490 dJointSetSliderAxis (jnt->_joint,jnt->axis.c[0],jnt->axis.c[1],jnt->axis.c[2]);
1491 veccopy3f(jnt->__old_axis.c,jnt->axis.c);
1493 jnt->_forceout = forceout_from_names(jnt->forceOutput.n,jnt->forceOutput.p);
1494 dJointSetSliderParam (jnt->_joint,dParamBounce,jnt->stopBounce);
1495 dJointSetSliderParam (jnt->_joint,dParamStopERP,jnt->stopErrorCorrection);
1501 case NODE_UniversalJoint:
1508 dBodyID body1ID, body2ID;
1513 body1ID = xbody1 ? xbody1->_body : NULL;
1514 body2ID = xbody2 ? xbody2->_body : NULL;
1515 jointID = dJointCreateUniversal (x3dworld->_world,x3dworld->_group);
1516 dJointAttach (jointID,body1ID,body2ID);
1517 jnt->_joint = jointID;
1520 dJointSetUniversalAnchor (jnt->_joint,jnt->anchorPoint.c[0],jnt->anchorPoint.c[1],jnt->anchorPoint.c[2]);
1524 if(!vecsame3f(jnt->__old_anchorPoint.c,jnt->anchorPoint.c)){
1525 dJointSetUniversalAnchor (jnt->_joint,jnt->anchorPoint.c[0],jnt->anchorPoint.c[1],jnt->anchorPoint.c[2]);
1526 veccopy3f(jnt->__old_anchorPoint.c,jnt->anchorPoint.c);
1529 axislen = veclength3f(jnt->axis1.c);
1532 jnt->axis1.c[0] = jnt->axis1.c[1] = 0.0f;
1533 jnt->axis1.c[2] = 1.0f;
1535 axislen = veclength3f(jnt->axis2.c);
1538 jnt->axis2.c[0] = jnt->axis2.c[2] = 0.0f;
1539 jnt->axis2.c[1] = 1.0f;
1541 if(!vecsame3f(jnt->__old_axis1.c,jnt->axis1.c)){
1542 dJointSetUniversalAxis1 (jnt->_joint,jnt->axis1.c[0],jnt->axis1.c[1],jnt->axis1.c[2]);
1543 veccopy3f(jnt->__old_axis1.c,jnt->axis1.c);
1545 if(!vecsame3f(jnt->__old_axis2.c,jnt->axis2.c)){
1546 dJointSetUniversalAxis2(jnt->_joint,jnt->axis2.c[0],jnt->axis2.c[1],jnt->axis2.c[2]);
1547 veccopy3f(jnt->__old_axis2.c,jnt->axis2.c);
1549 jnt->_forceout = forceout_from_names(jnt->forceOutput.n,jnt->forceOutput.p);
1550 dJointSetUniversalParam (jnt->_joint,dParamBounce1,jnt->stop1Bounce);
1551 dJointSetUniversalParam (jnt->_joint,dParamStopERP1,jnt->stop1ErrorCorrection);
1552 dJointSetUniversalParam (jnt->_joint,dParamBounce2,jnt->stop2Bounce);
1553 dJointSetUniversalParam (jnt->_joint,dParamStopERP2,jnt->stop2ErrorCorrection);
1559 case NODE_MotorJoint:
1570 dBodyID body1ID, body2ID;
1575 body1ID = xbody1 ? xbody1->_body : NULL;
1576 body2ID = xbody2 ? xbody2->_body : NULL;
1577 jointID = dJointCreateAMotor (x3dworld->_world,x3dworld->_group);
1578 dJointAttach (jointID,body1ID,body2ID);
1579 jnt->_joint = jointID;
1580 dJointSetAMotorMode (jnt->_joint,dAMotorUser);
1585 dJointSetAMotorNumAxes (jnt->_joint,jnt->enabledAxes);
1587 if(jnt->enabledAxes >0 ){
1588 axislen = veclength3f(jnt->motor1Axis.c);
1591 jnt->motor1Axis.c[0] = jnt->motor1Axis.c[1] = 0.0f;
1592 jnt->motor1Axis.c[2] = 1.0f;
1595 if(!vecsame3f(jnt->__old_motor1Axis.c,jnt->motor1Axis.c)){
1596 dJointSetAMotorAxis (jnt->_joint,0,0, jnt->motor1Axis.c[0],jnt->motor1Axis.c[1],jnt->motor1Axis.c[2]);
1597 veccopy3f(jnt->__old_motor1Axis.c,jnt->motor1Axis.c);
1599 if(jnt->__old_axis1Angle != jnt->axis1Angle){
1600 dJointSetAMotorAngle (jnt->_joint, 0, jnt->axis1Angle);
1601 jnt->__old_axis1Angle = jnt->axis1Angle;
1604 if(jnt->enabledAxes >1 ){
1605 axislen = veclength3f(jnt->motor2Axis.c);
1608 jnt->motor2Axis.c[0] = jnt->motor2Axis.c[1] = 0.0f;
1609 jnt->motor2Axis.c[2] = 1.0f;
1612 if(!vecsame3f(jnt->__old_motor2Axis.c,jnt->motor2Axis.c)){
1613 dJointSetAMotorAxis (jnt->_joint,1,1, jnt->motor2Axis.c[0],jnt->motor2Axis.c[1],jnt->motor2Axis.c[2]);
1614 veccopy3f(jnt->__old_motor2Axis.c,jnt->motor2Axis.c);
1616 if(jnt->__old_axis2Angle != jnt->axis2Angle){
1617 dJointSetAMotorAngle (jnt->_joint, 1, jnt->axis2Angle);
1618 jnt->__old_axis2Angle = jnt->axis2Angle;
1622 if(jnt->enabledAxes >2 ){
1623 axislen = veclength3f(jnt->motor3Axis.c);
1626 jnt->motor3Axis.c[0] = jnt->motor3Axis.c[1] = 0.0f;
1627 jnt->motor3Axis.c[2] = 1.0f;
1630 if(!vecsame3f(jnt->__old_motor3Axis.c,jnt->motor3Axis.c)){
1631 dJointSetAMotorAxis (jnt->_joint,2,2, jnt->motor3Axis.c[0],jnt->motor3Axis.c[1],jnt->motor3Axis.c[2]);
1632 veccopy3f(jnt->__old_motor3Axis.c,jnt->motor3Axis.c);
1634 if(jnt->__old_axis3Angle != jnt->axis3Angle){
1635 dJointSetAMotorAngle (jnt->_joint, 2, jnt->axis3Angle);
1636 jnt->__old_axis3Angle = jnt->axis3Angle;
1640 jnt->_forceout = forceout_from_names(jnt->forceOutput.n,jnt->forceOutput.p);
1642 dJointSetAMotorParam (jnt->_joint,dParamBounce1,jnt->stop1Bounce);
1643 dJointSetAMotorParam (jnt->_joint,dParamStopERP1,jnt->stop1ErrorCorrection);
1644 dJointSetAMotorParam (jnt->_joint,dParamBounce2,jnt->stop2Bounce);
1645 dJointSetAMotorParam (jnt->_joint,dParamStopERP2,jnt->stop2ErrorCorrection);
1646 dJointSetAMotorParam (jnt->_joint,dParamBounce3,jnt->stop3Bounce);
1647 dJointSetAMotorParam (jnt->_joint,dParamStopERP3,jnt->stop3ErrorCorrection);
1652 dJointAddAMotorTorques(jnt->_joint, jnt->axis1Torque, jnt->axis2Torque, jnt->axis3Torque);
1659 if(jnt->autoCalc == FALSE){
1661 if(jnt->enabledAxes >0)
1662 dJointSetAMotorAngle (jnt->_joint, 0, jnt->axis1Angle);
1663 if(jnt->enabledAxes >1)
1664 dJointSetAMotorAngle (jnt->_joint, 1, jnt->axis2Angle);
1665 if(jnt->enabledAxes >2)
1666 dJointSetAMotorAngle (jnt->_joint, 2, jnt->axis3Angle);
1676 dSpaceCollide (space,0,&nearCallback);
1678 if(x3dworld->preferAccuracy){
1680 double step_fraction = STEP_SIZE;
1681 dWorldStep (x3dworld->_world,step_fraction);
1685 double step_fraction = STEP_SIZE / (double)x3dworld->iterations;
1686 for(nstep=0;nstep<x3dworld->iterations;nstep++)
1687 dWorldQuickStep (x3dworld->_world,step_fraction);
1693 for(i=0;i<x3dworld->bodies.n;i++){
1700 const dReal *dpos, *dquat;
1705 dpos = dBodyGetPosition (x3dbody->_body);
1707 dquat = dBodyGetQuaternion(x3dbody->_body);
1708 quat.x = dquat[1], quat.y = dquat[2], quat.z = dquat[3], quat.w = dquat[0];
1709 quaternion_to_vrmlrot(&quat,&xyza[0],&xyza[1],&xyza[2],&xyza[3]);
1711 x3dbody->position.c[0] = dpos[0];x3dbody->position.c[1] = dpos[1];x3dbody->position.c[2] = dpos[2];
1712 double2float(x3dbody->orientation.c,xyza,4);
1713 MARK_EVENT(X3D_NODE(x3doffset),offsetof(
struct X3D_RigidBody,position));
1714 MARK_EVENT(X3D_NODE(x3doffset),offsetof(
struct X3D_RigidBody,orientation));
1716 for(k=0;k<x3dbody->geometry.n;k++){
1717 float *translation, *rotation;
1719 translation = x3doffset->translation.c;
1720 rotation = x3doffset->rotation.c;
1722 if(x3doffset->_nodeType == NODE_CollidableOffset){
1725 double geomT[3], geomR[4];
1727 float2double(geomT,x3doffset->_initialTranslation.c,3);
1728 float2double(geomR,x3doffset->_initialRotation.c,4);
1729 vrmlrot_to_quaternion(&geomQ,geomR[0],geomR[1],geomR[2],geomR[3]);
1730 quaternion_rotationd(geomT,&quat,geomT);
1731 double2float(translation,geomT,3);
1732 vecadd3f(translation,translation,x3dbody->position.c);
1733 quaternion_multiply(&geomQ,&quat,&geomQ);
1734 quaternion_to_vrmlrot(&geomQ,&geomR[0],&geomR[1],&geomR[2],&geomR[3]);
1735 double2float(rotation,geomR,4);
1737 if(x3doffset->_nodeType == NODE_CollidableShape){
1738 veccopy3f(translation,x3dbody->position.c);
1739 veccopy4f(rotation,x3dbody->orientation.c);
1745 static int loopcount = 0;
1747 printf(
"pos %lf %lf %lf\n",dpos[0],dpos[1],dpos[2]);
1748 printf(
"rot %f %f %f %f\n",rotation[0],rotation[1],rotation[2],rotation[3]);
1749 printf(
"trn %f %f %f\n",translation[0],translation[1],translation[2]);
1757 x3doffset->_change++;
1761 for(i=0;i<x3dworld->joints.n;i++){
1765 switch(joint->_nodeType){
1766 case NODE_BallJoint:
1771 if(jnt->_forceout & FORCEOUT_body1AnchorPoint){
1773 MARK_EVENT(X3D_NODE(jnt),offsetof(
struct X3D_BallJoint,body1AnchorPoint));
1775 if(jnt->_forceout & FORCEOUT_body2AnchorPoint){
1777 MARK_EVENT(X3D_NODE(jnt),offsetof(
struct X3D_BallJoint,body2AnchorPoint));
1783 case NODE_SingleAxisHingeJoint:
1789 if(jnt->_forceout & FORCEOUT_angle){
1793 if(jnt->_forceout & FORCEOUT_angleRate){
1798 if(jnt->_forceout & FORCEOUT_body1AnchorPoint){
1802 if(jnt->_forceout & FORCEOUT_body2AnchorPoint){
1809 case NODE_DoubleAxisHingeJoint:
1814 if(jnt->_forceout & FORCEOUT_body1AnchorPoint){
1818 if(jnt->_forceout & FORCEOUT_body1Axis){
1822 if(jnt->_forceout & FORCEOUT_body2AnchorPoint){
1826 if(jnt->_forceout & FORCEOUT_body2Axis){
1830 if(jnt->_forceout & FORCEOUT_hinge1Angle){
1834 if(jnt->_forceout & FORCEOUT_hinge1AngleRate){
1838 if(jnt->_forceout & FORCEOUT_hinge2Angle){
1842 if(jnt->_forceout & FORCEOUT_hinge2AngleRate){
1850 case NODE_SliderJoint:
1855 if(jnt->_forceout & FORCEOUT_separation){
1857 MARK_EVENT(X3D_NODE(jnt),offsetof(
struct X3D_SliderJoint,separation));
1859 if(jnt->_forceout & FORCEOUT_separationRate){
1861 MARK_EVENT(X3D_NODE(jnt),offsetof(
struct X3D_SliderJoint,separationRate));
1866 case NODE_UniversalJoint:
1871 if(jnt->_forceout & FORCEOUT_body1AnchorPoint){
1875 if(jnt->_forceout & FORCEOUT_body1Axis){
1879 if(jnt->_forceout & FORCEOUT_body2AnchorPoint){
1883 if(jnt->_forceout & FORCEOUT_body2Axis){
1890 case NODE_MotorJoint:
1895 if(jnt->_forceout & FORCEOUT_motor1Angle){
1896 jnt->motor1Angle = (float) dJointGetAMotorAngle( jnt->_joint, 0 );
1897 MARK_EVENT(X3D_NODE(jnt),offsetof(
struct X3D_MotorJoint,motor1Angle));
1899 if(jnt->_forceout & FORCEOUT_motor1AngleRate){
1900 jnt->motor1AngleRate = (float) dJointGetAMotorAngleRate( jnt->_joint, 0 );
1901 MARK_EVENT(X3D_NODE(jnt),offsetof(
struct X3D_MotorJoint,motor1AngleRate));
1903 if(jnt->_forceout & FORCEOUT_motor2Angle){
1904 jnt->motor2Angle = (float) dJointGetAMotorAngle( jnt->_joint, 1 );
1905 MARK_EVENT(X3D_NODE(jnt),offsetof(
struct X3D_MotorJoint,motor2Angle));
1907 if(jnt->_forceout & FORCEOUT_motor2AngleRate){
1908 jnt->motor2AngleRate = (float) dJointGetAMotorAngleRate( jnt->_joint, 1 );
1909 MARK_EVENT(X3D_NODE(jnt),offsetof(
struct X3D_MotorJoint,motor2AngleRate));
1911 if(jnt->_forceout & FORCEOUT_motor3Angle){
1912 jnt->motor3Angle = (float) dJointGetAMotorAngle( jnt->_joint, 2 );
1913 MARK_EVENT(X3D_NODE(jnt),offsetof(
struct X3D_MotorJoint,motor3Angle));
1915 if(jnt->_forceout & FORCEOUT_motor3AngleRate){
1916 jnt->motor3AngleRate = (float) dJointGetAMotorAngleRate( jnt->_joint, 2 );
1917 MARK_EVENT(X3D_NODE(jnt),offsetof(
struct X3D_MotorJoint,motor3AngleRate));
1928 dJointGroupEmpty (contactgroup);
1934 void register_CollisionCollection(
struct X3D_Node * _node){
1935 if(_node->_nodeType == NODE_CollisionCollection){
1939 if(!x3dcollisioncollections) x3dcollisioncollections = newVector(
struct X3D_Node*,5);
1940 if(!space) dHashSpaceCreate(0);
1941 vector_pushBack(
struct X3D_Node*,x3dcollisioncollections,_node);
1945 void register_CollisionSensor(
struct X3D_Node *_node){
1946 if(_node->_nodeType == NODE_CollisionSensor){
1950 if(!x3dcollisionsensors) x3dcollisionsensors = newVector(
struct X3D_Node*,5);
1951 vector_pushBack(
struct X3D_Node*,x3dcollisionsensors,_node);
1956 void register_RigidBodyCollection(
struct X3D_Node *_node){
1957 if(_node->_nodeType == NODE_RigidBodyCollection){
1959 dJointGroupID groupID;
1964 space = dHashSpaceCreate (0);
1966 world = dWorldCreate();
1967 dWorldSetGravity (world,node->gravity.c[0],node->gravity.c[1],node->gravity.c[2]);
1968 dWorldSetCFM (world,1e-5);
1969 dWorldSetAutoDisableFlag (world,1);
1974 contactgroup = dJointGroupCreate (0);
1978 dWorldSetAutoDisableAverageSamplesCount( world, 10 );
1982 dWorldSetLinearDamping(world, 0.00001);
1983 dWorldSetAngularDamping(world, 0.005);
1984 dWorldSetMaxAngularSpeed(world, 200);
1986 dWorldSetContactMaxCorrectingVel (world,0.1);
1987 dWorldSetContactSurfaceLayer (world,0.001);
1991 groupID = dJointGroupCreate (0);
1992 node->_group = groupID;
1993 if(!x3dworlds) x3dworlds = newVector(
struct X3D_Node*,5);
1994 vector_pushBack(
struct X3D_Node*,x3dworlds,_node);
2015 void prep_CollidableShape(
struct X3D_Node *_node){
2022 if(!renderstate()->render_vp) {
2033 if(!renderstate()->render_vp) {
2036 FW_GL_PUSH_MATRIX();
2039 if (node->__do_trans)
2040 FW_GL_TRANSLATE_F(node->translation.c[0],node->translation.c[1],node->translation.c[2]);
2043 if (node->__do_rotation) {
2044 FW_GL_ROTATE_RADIANS(node->rotation.c[3], node->rotation.c[0],node->rotation.c[1],node->rotation.c[2]);
2051 void compile_CollidableShape(
struct X3D_Node *_node){
2052 if(_node->_nodeType == NODE_CollidableShape || _node->_nodeType == NODE_CollidableOffset){
2058 node->__do_trans = verify_translate ((GLfloat *)node->translation.c);
2059 node->__do_rotation = verify_rotate ((GLfloat *)node->rotation.c);
2064 void fin_CollidableShape(
struct X3D_Node *_node){
2066 if(!renderstate()->render_vp) {
2070 if((_node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) {
2073 FW_GL_ROTATE_RADIANS(-(((node->rotation).c[3])),((node->rotation).c[0]),((node->rotation).c[1]),((node->rotation).c[2])
2075 FW_GL_TRANSLATE_F(-(((node->translation).c[0])),-(((node->translation).c[1])),-(((node->translation).c[2]))
2081 void compile_CollidableOffset(
struct X3D_Node *node){
2082 compile_CollidableShape(node);
2084 void child_CollidableShape(
struct X3D_Node *_node){
2085 if(_node->_nodeType == NODE_CollidableShape){
2089 if(node->shape) render_node(node->shape);
2092 void prep_CollidableOffset(
struct X3D_Node *node){
2093 prep_CollidableShape(node);
2095 void fin_CollidableOffset(
struct X3D_Node *node){
2096 fin_CollidableShape(node);
2098 void child_CollidableOffset(
struct X3D_Node *_node){
2099 if(_node->_nodeType == NODE_CollidableOffset){
2107 if(node->collidable) {
2108 switch(node->collidable->_nodeType){
2109 case NODE_CollidableOffset:
2110 prep_CollidableOffset(node->collidable);
2111 child_CollidableOffset(node->collidable);
2112 fin_CollidableOffset(node->collidable);
2114 case NODE_CollidableShape:
2115 prep_CollidableShape(node->collidable);
2116 child_CollidableShape(node->collidable);
2117 fin_CollidableShape(node->collidable);
2131 if(!static_did_physics_since_last_Tick)
return;
2132 static_did_physics_since_last_Tick = 0;
2133 if(!node->enabled)
return;
2135 if(node->contacts.n){
2136 if(node->isActive == FALSE){
2137 node->isActive = TRUE;
2144 if(node->isActive == TRUE){
2145 node->isActive = FALSE;
2153 if(node->intersections.n){
2163 void do_CollisionSensorTick(
void * ptr){
2168 void add_physics(
struct X3D_Node *node){
2169 switch(node->_nodeType){
2170 case NODE_CollisionSensor:
2175 register_CollisionSensor(node);
2177 case NODE_CollisionCollection:
2181 register_CollisionCollection(node);
2183 case NODE_RigidBodyCollection:
2185 register_RigidBodyCollection(node);
2195 #else //else no ode phyiscs engine, just stubs
2197 void compile_CollidableShape(
struct X3D_Node *node){
2199 void prep_CollidableShape(
struct X3D_Node *node){
2201 void fin_CollidableShape(
struct X3D_Node *node){
2203 void child_CollidableShape(
struct X3D_Node *node){
2205 void compile_CollidableOffset(
struct X3D_Node *node){
2207 void prep_CollidableOffset(
struct X3D_Node *node){
2209 void fin_CollidableOffset(
struct X3D_Node *node){
2211 void child_CollidableOffset(
struct X3D_Node *node){
2213 void rbp_run_physics(){
2215 void add_physics(
struct X3D_Node *node){
2217 void do_CollisionSensorTick(
void * ptr){