Index: ode.c
===================================================================
--- ode.c	(revision 716)
+++ ode.c	(revision 717)
@@ -9,7 +9,7 @@
 #include "index.h"
 #else
 #include "headers/ode.h"
-#endif 
+#endif
 
 // TODO:
 // load object from file
@@ -90,7 +90,7 @@
 raydium_ode_joint[i].id=i;
 raydium_ode_joint[i].name[0]=0;
 raydium_ode_joint[i].state=0;
-raydium_ode_joint[i].mesh=-1;       
+raydium_ode_joint[i].mesh=-1;
 raydium_ode_joint[i].joint=NULL;
 //raydium_ode_joint[i].hinge2correct=0;
 raydium_ode_joint[i].breakableforce=0;
@@ -310,7 +310,7 @@
         {
         max_index=i;
         max_val=tmp;
-        }    
+        }
     }
 
 //printf("%i %s %i %i\n",TriCount,e->name,TriIndices[0],TriIndices[1]);
@@ -619,10 +619,19 @@
     raydium_log("ODE: Error: cannot add force to a static element");
     return;
     }
-                
+
 dBodyAddForce(raydium_ode_element[e].body,vect[0],vect[1],vect[2]);
 }
 
+void raydium_ode_element_addforce_3f(int e, dReal vx, dReal vy, dReal vz)
+{
+dReal vect[3];
+vect[0]=vx;
+vect[1]=vy;
+vect[2]=vz;
+raydium_ode_element_addforce(e,vect);
+}
+
 void raydium_ode_element_addforce_name(char *e, dReal *vect)
 {
 raydium_ode_element_addforce(raydium_ode_element_find(e),vect);
@@ -649,7 +658,7 @@
     raydium_log("ODE: Error: cannot add torque to a static element");
     return;
     }
-                
+
 dBodyAddTorque(raydium_ode_element[e].body,vect[0],vect[1],vect[2]);
 }
 
@@ -831,7 +840,7 @@
     body=dBodyCreate(raydium_ode_world); // fake temporary body
     dBodySetPosition(body,pos[0],pos[1],pos[2]);
     dBodySetQuaternion(body,rot);
-    
+
     dBodyGetRelPointPos(body,rel[0],rel[1],rel[2],world);
 
     dBodyDestroy(body);
@@ -866,7 +875,7 @@
     body=dBodyCreate(raydium_ode_world); // fake temporary body
     dBodySetPosition(body,pos[0],pos[1],pos[2]);
     dBodySetQuaternion(body,rot);
-    
+
     dBodyGetPosRelPoint(body,world[0],world[1],world[2],rel);
 
     dBodyDestroy(body);
@@ -900,7 +909,7 @@
     body=dBodyCreate(raydium_ode_world); // fake temporary body
     dBodySetPosition(body,pos[0],pos[1],pos[2]);
     dBodySetQuaternion(body,rot);
-    
+
     dBodyVectorToWorld(body,vect[0],vect[1],vect[2],world);
 
     dBodyDestroy(body);
@@ -1070,7 +1079,7 @@
         dBodySetMass(raydium_ode_element[i].body,&m);
         dBodySetData(raydium_ode_element[i].body,&raydium_ode_element[i]);
 //      dBodySetAutoDisableSF1(raydium_ode_element[i].body,1);
-     }  
+     }
      else raydium_ode_element[i].body=0;
 
      raydium_ode_element[i].geom=dCreateSphere(0,radius);
@@ -1145,7 +1154,7 @@
         dBodySetMass(raydium_ode_element[i].body,&m);
         dBodySetData(raydium_ode_element[i].body,&raydium_ode_element[i]);
 //      dBodySetAutoDisableSF1(raydium_ode_element[i].body,1);
-     } 
+     }
      else raydium_ode_element[i].body=0;
 
      raydium_ode_element[i].geom=dCreateBox(0,tx,ty,tz);
@@ -1209,7 +1218,7 @@
 
 raydium_log("ODE: Error: No more free ray slots for this element");
 return -1;
-}    
+}
 
 signed char raydium_ode_element_ray_attach_name(char *element, dReal length, dReal dirx, dReal diry, dReal dirz)
 {
@@ -1225,7 +1234,7 @@
     raydium_log("ODE: Error: Cannot change ray length: element is not valid");
     return 0;
     }
-        
+
 e=&raydium_ode_element[element];
 if(!e->ray[ray_id].state)
     {
@@ -1251,7 +1260,7 @@
     raydium_log("ODE: Error: Cannot move ray: element is not valid");
     return 0;
     }
-        
+
 e=&raydium_ode_element[element];
 if(!e->ray[ray_id].state)
     {
@@ -1360,7 +1369,7 @@
 if(nelems<1)
     {
     raydium_log("ODE: Error: Must fix at least one element");
-    return -1;    
+    return -1;
     }
 
 for(i=0;i<nelems;i++)
@@ -1388,7 +1397,7 @@
 
 // 2 - create new element (using AABB from elements)
 dGeomGetAABB(raydium_ode_element[elem[0]].geom,aabbR);
-    
+
 for(i=1;i<nelems;i++)
     {
     dGeomGetAABB(raydium_ode_element[elem[i]].geom,aabb);
@@ -1514,7 +1523,7 @@
     }
 
 if(dGeomGetClass(raydium_ode_element[elem].geom)==dSphereClass)
-    {    
+    {
     dMassSetSphere(&m,1,dGeomSphereGetRadius(raydium_ode_element[elem].geom));
     }
 else
@@ -1739,7 +1748,7 @@
     pos[0]=x;
     pos[1]=y;
     pos[2]=z;
-    raydium_ode_object_move(obj,pos);  
+    raydium_ode_object_move(obj,pos);
 }
 
 void raydium_ode_object_move_name(char *name, dReal *pos)
@@ -1904,7 +1913,7 @@
     raydium_ode_element[elem2].state==RAYDIUM_ODE_STATIC )
     {
     raydium_log("ODE: Error: Cannot attach a static element");
-    return -1;    
+    return -1;
     }
 
 for(i=0;i<RAYDIUM_ODE_MAX_JOINTS;i++)
@@ -1964,7 +1973,7 @@
     raydium_ode_element[elem2].state==RAYDIUM_ODE_STATIC )
     {
     raydium_log("ODE: Error: Cannot attach a static element");
-    return -1;    
+    return -1;
     }
 
 for(i=0;i<RAYDIUM_ODE_MAX_JOINTS;i++)
@@ -2021,7 +2030,7 @@
     raydium_ode_element[elem2].state==RAYDIUM_ODE_STATIC )
     {
     raydium_log("ODE: Error: Cannot attach a static element");
-    return -1;    
+    return -1;
     }
 
 for(i=0;i<RAYDIUM_ODE_MAX_JOINTS;i++)
@@ -2076,7 +2085,7 @@
     raydium_ode_element[elem2].state==RAYDIUM_ODE_STATIC )
     {
     raydium_log("ODE: Error: Cannot attach a static element");
-    return -1;    
+    return -1;
     }
 
 //raydium_log("ODE: Warning: fixed joint slows down physics !");
@@ -2132,7 +2141,7 @@
     dJointSetUniversalParam(raydium_ode_joint[j].joint,dParamLoStop2,lo2);
     dJointSetUniversalParam(raydium_ode_joint[j].joint,dParamHiStop2,hi2);
     dJointSetUniversalParam(raydium_ode_joint[j].joint,dParamLoStop2,lo2);
-    
+
     return;
     }
 raydium_log("ODE: Error: cannot set joint limits: invalid index or name");
@@ -2181,7 +2190,7 @@
         dJointSetHinge2Param(raydium_ode_joint[j].joint,dParamLoStop,lo); // ODE "feature" :)
         return;
         }
-    raydium_log("ODE: Error: cannot set joint limits: invalid index or name");    
+    raydium_log("ODE: Error: cannot set joint limits: invalid index or name");
 }
 
 
@@ -2235,7 +2244,7 @@
 // may crash if joint is disconnected at one of his ends !
 elem1=dBodyGetData(dJointGetBody(raydium_ode_joint[j].joint,0));
 elem2=dBodyGetData(dJointGetBody(raydium_ode_joint[j].joint,1));
-    
+
 *e1=elem1->id;
 *e2=elem2->id;
 }
@@ -2257,7 +2266,7 @@
     // test if element is attached:
     if(raydium_ode_motor[j].rocket_element<0)
         return;
-        
+
     speed=raydium_ode_motor[j].speed;
     if(raydium_ode_motor[j].rocket_playermovement &&
        !raydium_ode_element[raydium_ode_motor[j].rocket_element]._touched )
@@ -2272,7 +2281,7 @@
                              raydium_ode_motor[j].rocket_position[1],
                              raydium_ode_motor[j].rocket_position[2]);
     return;
-    }        
+    }
     // if motor is anything else than a rocket:
     for(i=0;i<RAYDIUM_ODE_MOTOR_MAX_JOINTS;i++)
         if(raydium_ode_motor[j].joints[i]>=0)
@@ -2283,7 +2292,7 @@
         int fmax;
         int type;
         char cancel=0;
-        
+
         switch(raydium_ode_motor[j].joints_axe[i])
             {
             case 0:
@@ -2302,9 +2311,9 @@
                 cancel=1;
                 raydium_log("ODE: Motor: Invalid axe for this joint (%s, motor is %s)",raydium_ode_joint[raydium_ode_motor[j].joints[i]].name,raydium_ode_motor[j].name);
             }
-        
+
         type=dJointGetType(raydium_ode_joint[raydium_ode_motor[j].joints[i]].joint);
-            
+
         switch(type)
             {
             case dJointTypeHinge2:
@@ -2331,35 +2340,35 @@
                 cancel=1;
                 raydium_log("ODE: Motor: Invalid joint type (%s, motor is %s)",raydium_ode_joint[raydium_ode_motor[j].joints[i]].name,raydium_ode_motor[j].name);
             }
-            
-        
+
+
         if(cancel) continue; // previous tests failed
-        
+
         if(raydium_ode_motor[j].state==RAYDIUM_ODE_MOTOR_ENGINE)
                 {
                 dReal speed;
                 dReal force;
                 speed=raydium_ode_motor[j].speed*raydium_ode_motor[j].gears[raydium_ode_motor[j].gear];
-                
+
                 if(raydium_ode_motor[j].gears[raydium_ode_motor[j].gear]==0.0)
                     force=0;
                 else
                     force=raydium_ode_motor[j].force*(1/raydium_ode_motor[j].gears[raydium_ode_motor[j].gear]);
-                
+
 //              force=raydium_ode_motor[j].force;
 //              raydium_log("speed=%f force=%f",speed,force);
                 SetParam(raydium_ode_joint[raydium_ode_motor[j].joints[i]].joint,vel,speed);
                 SetParam(raydium_ode_joint[raydium_ode_motor[j].joints[i]].joint,fmax,force);
                 }
-                
+
         if(raydium_ode_motor[j].state==RAYDIUM_ODE_MOTOR_ANGULAR)
             {
                 dReal v;
                 SetParam(raydium_ode_joint[raydium_ode_motor[j].joints[i]].joint,fmax,raydium_ode_motor[j].force);
-                v = raydium_ode_motor[j].angle - 
+                v = raydium_ode_motor[j].angle -
                     GetAngle(raydium_ode_joint[raydium_ode_motor[j].joints[i]].joint);
                 SetParam(raydium_ode_joint[raydium_ode_motor[j].joints[i]].joint,vel,v*10);
-            }           
+            }
         }
     return;
     }
@@ -2503,17 +2512,17 @@
 if(raydium_ode_element_isvalid(e))
     {
     matrix=(dReal *)dGeomGetRotation(raydium_ode_element[e].geom);
-    
+
     if(matrix[2] < 1-epsilon && matrix[2] > -1+epsilon)
     {
         *ry=-asin(matrix[2]);
         c=cos(*ry);
         *rx= atan2(matrix[6]/c,matrix[10]/c);
         *rz= atan2(matrix[1]/c,matrix[0]/c);
-    } 
-    else 
-    {       
-        *rz=0;   
+    }
+    else
+    {
+        *rz=0;
         *ry=-atan2(matrix[2],0);
         *rx= atan2(-matrix[9],matrix[5]);
     }
@@ -2540,20 +2549,20 @@
 if(raydium_ode_element_isvalid(e))
     {
     matrix=(dReal *)dGeomGetRotation(raydium_ode_element[e].geom);
-    
+
     if(matrix[8] < 1-epsilon && matrix[8] > -1+epsilon)
     {
         *ry=-asin(matrix[8]);
         c=cos(*ry);
         *rx= atan2(matrix[9]/c,matrix[10]/c);
         *rz= atan2(matrix[4]/c,matrix[0]/c);
-    }       
-    else    
-    {       
-        *rz=0;   
+    }
+    else
+    {
+        *rz=0;
         *ry=-atan2(matrix[8],0);
         *rx= atan2(-matrix[6],matrix[5]);
-    }       
+    }
 
     // rad to deg
     //(*rx)*=180/PI;
@@ -2594,7 +2603,7 @@
 if(!raydium_ode_element_isvalid(e))
     {
     raydium_log("ODE: Error: cannot get RelPointPos: invalid index or name");
-    return;    
+    return;
     }
 
 if(raydium_ode_element[e].state==RAYDIUM_ODE_STATIC)
@@ -2625,7 +2634,7 @@
 if(!raydium_ode_object_isvalid(obj))
     {
     raydium_log("ODE: Cannot add motor \"%s\": parent object is invalid",name);
-    return -1;    
+    return -1;
     }
 
 for(i=0;i<RAYDIUM_ODE_MAX_MOTORS;i++)
@@ -2633,7 +2642,7 @@
      {
      strcpy(raydium_ode_motor[i].name,name);
      raydium_ode_motor[i].state=type;
-     raydium_ode_motor[i].object=obj;     
+     raydium_ode_motor[i].object=obj;
      return i;
      }
 raydium_log("ODE: No more motor slots ! aborting \"%s\" creation",name);
@@ -2653,17 +2662,17 @@
     // may crash if joint is disconnected at one of its ends !
     elem1=dBodyGetData(dJointGetBody(raydium_ode_joint[joint].joint,0));
     elem2=dBodyGetData(dJointGetBody(raydium_ode_joint[joint].joint,1));
-    
+
     e1=elem1->id;
     e2=elem2->id;
-    
+
     if(raydium_ode_motor[motor].object!=raydium_ode_element[e1].object &&
        raydium_ode_motor[motor].object!=raydium_ode_element[e2].object )
         {
         raydium_log("ODE: Cannot attach motor: joint must be attached to at least one element from motor's object");
         return;
-        }       
-    
+        }
+
     for(i=0;i<RAYDIUM_ODE_MOTOR_MAX_JOINTS;i++)
         if(raydium_ode_motor[motor].joints[i]<0)
             {
@@ -2706,7 +2715,7 @@
         velf+=sqrt(vel[0]*vel[0] + vel[1]*vel[1] + vel[2]*vel[2]);
         n++;
         }
-if(n) 
+if(n)
     {
     velf/=n;
     if(gears) velf*=(1/raydium_trigo_abs(raydium_ode_motor[m].gears[raydium_ode_motor[m].gear]));
@@ -2743,7 +2752,7 @@
         body=dJointGetBody(raydium_ode_joint[raydium_ode_motor[m].joints[axe]].joint,raydium_ode_motor[m].joints_axe[axe]);
         dJointGetAMotorAngle (raydium_ode_joint[raydium_ode_motor[m].joints[axe]].joint,);
 */
-  
+
         switch(dJointGetType(raydium_ode_joint[raydium_ode_motor[m].joints[axe]].joint))
             {
             case dJointTypeHinge2:
@@ -2782,7 +2791,7 @@
     raydium_log("ODE: Error: Cannot set rocket element: motor is not a rocket");
     return;
     }
-    
+
 raydium_ode_motor[m].rocket_element=element;
 raydium_ode_motor[m].rocket_position[0]=x;
 raydium_ode_motor[m].rocket_position[1]=y;
@@ -2931,7 +2940,7 @@
 // verify element state after user callback (element may be already deleted ! :)
 // note : this test is bad.. an new element may have taken the free slot ...
 // in facts, a user must not delete an element during his own OnDelete callback
-if(!raydium_ode_element_isvalid(e)) 
+if(!raydium_ode_element_isvalid(e))
     return 1; // delete is successfull thru user callback
 
 
@@ -2953,10 +2962,10 @@
             {
             j=dJointGetData(dBodyGetJoint(raydium_ode_element[e].body,i));
             if(j)
-                to_delete[i]=j->id; 
-            else 
+                to_delete[i]=j->id;
+            else
                 to_delete[i]=-1;
-            }    
+            }
         // ... and delete joints
         for(i=0;i<n_joints;i++)
           if(to_delete[i]>=0)
@@ -3022,8 +3031,8 @@
 for(i=0;i<RAYDIUM_ODE_MAX_MOTORS;i++)
     if(raydium_ode_motor[i].state &&
        raydium_ode_motor[i].object==obj)
-        raydium_ode_motor_delete(i);    
-    
+        raydium_ode_motor_delete(i);
+
 // Wow... group indices are unstable while deleting group's bodies !
 //for(i=0;i<dGeomGroupGetNumGeoms(raydium_ode_object[obj].group);i++)
 //    {
@@ -3083,7 +3092,7 @@
         e2=dJointGetBody(j->joint,1);
         if(e1==raydium_ode_element[element].body) e1=0;
         if(e2==raydium_ode_element[element].body) e2=0;
-        dJointAttach(j->joint,e1,e2);   
+        dJointAttach(j->joint,e1,e2);
         }
     }
 // Well well well.. donno if dGeomGroupAdd removes body from previous
@@ -3253,23 +3262,23 @@
         dReal len;
         dReal force;
         elp=(dReal *)dGeomGetPosition(raydium_ode_element[i].geom);
-        
+
         //raydium_log("Blow: %s",raydium_ode_element[i].name);
-        
+
         // explosion to element vector
         vect[0]=elp[0]-pos[0];
         vect[1]=elp[1]-pos[1];
         vect[2]=elp[2]-pos[2];
         // distance from explosion
         len=sqrt(vect[0]*vect[0] + vect[1]*vect[1] + vect[2]*vect[2]);
-        
+
         if(len==0.f) continue;
 //      raydium_log("dist from core: %f (radius=%f)",len,radius);
         // normalize vector
         vect[0]/=len;
         vect[1]/=len;
         vect[2]/=len;
-        
+
         if(len>radius) continue;
         force = ((radius*radius) - (len*len)) / (radius * radius) * max_force;
 //      raydium_log("resulting force: %f (max force at core=%f)",force,max_force);
@@ -3357,7 +3366,7 @@
      raydium_ode_explosion[i].config_propag=propag;
      raydium_ode_explosion[i].radius=0;
      memcpy(raydium_ode_explosion[i].position,pos,sizeof(dReal)*3);
-     
+
      f=raydium_ode_ExplosionCallback;
      if(f)
         f(RAYDIUM_ODE_NETWORK_EXPLOSION_EXPL,final_radius,propag,pos);
@@ -3506,19 +3515,19 @@
       raydium_osd_printf_3D(res1[0],res1[1],res1[2],12,0.6,"font2.tga","<%s>",raydium_ode_joint[i].name);
      }
     }
-     
 
+
 for(i=0;i<RAYDIUM_ODE_MAX_ELEMENTS;i++)
     if(raydium_ode_element[i].state)
      {
-        
-     if(names==RAYDIUM_ODE_DRAW_NORMAL || 
+
+     if(names==RAYDIUM_ODE_DRAW_NORMAL ||
         names==RAYDIUM_ODE_DRAW_SHADOWERS ||
         names==RAYDIUM_ODE_DRAW_NORMAL_NO_POST)
         {
-        
+
         if(names==RAYDIUM_ODE_DRAW_SHADOWERS && raydium_ode_element[i].mesh==raydium_shadow_ground_mesh)
-            continue;   
+            continue;
         if(names!=RAYDIUM_ODE_DRAW_SHADOWERS && bef && !bef(i))
             continue;
 
@@ -3551,7 +3560,7 @@
              dBodyGetRelPointPos(body,
                                 raydium_ode_element[i].particle_offset[0],
                                 raydium_ode_element[i].particle_offset[1],
-                                raydium_ode_element[i].particle_offset[2],          
+                                raydium_ode_element[i].particle_offset[2],
                                 res);
              dBodyDestroy(body);
             }
@@ -3561,14 +3570,14 @@
              dBodyGetRelPointPos(raydium_ode_element[i].body,
                                 raydium_ode_element[i].particle_offset[0],
                                 raydium_ode_element[i].particle_offset[1],
-                                raydium_ode_element[i].particle_offset[2],          
-                                res);       
+                                raydium_ode_element[i].particle_offset[2],
+                                res);
             }
-            
+
             raydium_particle_generator_move(
                 raydium_ode_element[i].particle,res);
             }
-           
+
         for(j=0;j<RAYDIUM_ODE_ELEMENT_MAX_FIXING;j++)
           if(raydium_ode_element[i].fixed_elements[j])
             {
@@ -3606,7 +3615,7 @@
         {
         const dReal *p;
 
-        
+
         if(names==RAYDIUM_ODE_DRAW_DEBUG) // draw shape
             {
             raydium_rendering_internal_prepare_texture_render(0); // !!!
@@ -3642,7 +3651,7 @@
                 glVertex3f (-lx,-ly,-lz);
                 glVertex3f (-lx,-ly,lz);
                 glEnd();
-            
+
                 // top face
                 glBegin (GL_TRIANGLE_FAN);
                 glNormal3f (0,0,1);
@@ -3660,7 +3669,7 @@
                 glVertex3f (lx,ly,-lz);
                 glVertex3f (lx,-ly,-lz);
                 glEnd();
-                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);          
+                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
                 }
             else
                 if(dGeomGetClass(raydium_ode_element[i].geom)==dSphereClass)
@@ -3668,24 +3677,24 @@
                 glutWireSphere(dGeomSphereGetRadius(raydium_ode_element[i].geom),10,10);
                 }
             // else TriMesh ...
-                
-        
+
+
             p=dGeomGetPosition(raydium_ode_element[i].geom);
             if(raydium_ode_element[i]._touched)
                 raydium_osd_color_ega('c');
             else
                 raydium_osd_color_ega('f');
-                
+
             if(raydium_ode_element[i]._avoidedcol)
                 raydium_osd_color_ega('d');
-        
+
             if(!dGeomIsEnabled(raydium_ode_element[i].geom))
                 raydium_osd_color_ega('a');
 
             if( raydium_ode_element[i].state==RAYDIUM_ODE_STANDARD &&
                 !dBodyIsEnabled(raydium_ode_element[i].body) )
                     raydium_osd_color_ega('0');
-        
+
             raydium_osd_printf_3D(p[0],p[1],p[2],12,0.6,"font2.tga","%i %s (%s) @ %i",i,raydium_ode_element[i].name,raydium_ode_object[raydium_ode_element[i].object].name,raydium_ode_element[i].distant_owner);
             }
 
@@ -3719,7 +3728,7 @@
             glVertex3f (aabb[0],aabb[2],aabb[4]);
             glVertex3f (aabb[0],aabb[2],aabb[5]);
             glEnd();
-            
+
             // top face
             glBegin (GL_TRIANGLE_FAN);
             glNormal3f (0,0,1);
@@ -3739,7 +3748,7 @@
             glEnd();
             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
             }
-            
+
             if(names==RAYDIUM_ODE_DRAW_RAY)
             {
               for(j=0;j<RAYDIUM_ODE_MAX_RAYS;j++)
@@ -3751,9 +3760,9 @@
                 raydium_rendering_internal_prepare_texture_render(0); // !!!
                 raydium_texture_current_set_name("rgb(1,0,0)");
                 raydium_rendering_internal_prepare_texture_render(raydium_texture_current_main);
-                
+
                 dGeomRayGet(raydium_ode_element[i].ray[j].geom,start,dir);
-                
+
         if ((len=raydium_ode_element[i].ray[j].min_dist)==0)  // Draw ray to first contact point if exist
             len=dGeomRayGetLength(raydium_ode_element[i].ray[j].geom);
 
@@ -3811,7 +3820,7 @@
 r=raydium_ode_RayCallback;
 
 
-if(dGeomIsSpace (o1) || dGeomIsSpace (o2)) 
+if(dGeomIsSpace (o1) || dGeomIsSpace (o2))
     {
     raydium_ode_Object *oo1, *oo2;
     signed char (*g)(int,int);
@@ -3848,14 +3857,14 @@
   n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
   if(n>=N-1)
     raydium_log("ODE: WARNING ! Not enought contact points available ! (%i max)",N);
-  if (n > 0) 
+  if (n > 0)
   {
-  
-    for (i=0; i<n; i++) 
-        {       
+
+    for (i=0; i<n; i++)
+        {
         e1=dGeomGetData(contact[i].geom.g1);
         e2=dGeomGetData(contact[i].geom.g2);
-        
+
         if(e1==NULL || e2==NULL)
             continue; // Deleted, or not one of our elements
 
@@ -3880,7 +3889,7 @@
                 e2->_avoidedcol=1;
                 continue; // avoid collision ! (where are moving from this object)
                 }
-        
+
         erp=cfm=slip=0;
 
         if(e1)
@@ -3890,7 +3899,7 @@
             slip=e1->slip;
             count=1;
             }
-            
+
         if(e2)
             {
             erp+=e2->erp;
@@ -3898,27 +3907,27 @@
             slip+=e2->slip;
             count++;
             }
-            
+
         if(count)
             {
             erp/=count;
             cfm/=count;
             slip/=count;
             }
-            
+
         contact[i].surface.mode = dContactSlip1 | dContactSlip2 |
         dContactSoftERP | dContactSoftCFM | dContactApprox1;
         contact[i].surface.mu = dInfinity;
 
         contact[i].surface.slip1 = slip;
         contact[i].surface.slip2 = slip;
-        
+
         contact[i].surface.soft_erp = erp;
         contact[i].surface.soft_cfm = cfm;
 
 
         gencontact=0;
-        
+
         if(dGeomGetClass(contact[i].geom.g1)==dRayClass)
             {
             // raydium_ode_RayCallback (1)
@@ -3928,7 +3937,7 @@
                 contact[i].geom.g1=e1->geom;
                 e1->_last_touched_ray=ray_id;
                 }
-            
+
             if(r)
                 {
                 int id1,id2;
@@ -3939,7 +3948,7 @@
                 if(gencontact==RAYDIUM_ODE_RAY_CONTACT_IGNORE) continue;
                 }
 
-            if(e1 && e2 && 
+            if(e1 && e2 &&
             (e1->ray[ray_id].min_dist > contact[i].geom.depth || e1->ray[ray_id].min_dist==0) )
                 {
                 e1->ray[ray_id].min_dist=contact[i].geom.depth;
@@ -3977,7 +3986,7 @@
                 if(gencontact==RAYDIUM_ODE_RAY_CONTACT_IGNORE) continue;
                 }
 
-            if(e1 && e2 && 
+            if(e1 && e2 &&
             (e2->ray[ray_id].min_dist > contact[i].geom.depth || e2->ray[ray_id].min_dist==0) )
                 {
                 e2->ray[ray_id].min_dist=contact[i].geom.depth;
@@ -3994,7 +4003,7 @@
             if(gencontact!=RAYDIUM_ODE_RAY_CONTACT_CREATE) // "report"
                 continue;
             }
-                
+
         // raydium_ode_CollideCallback
         if(f)
             {
@@ -4061,7 +4070,7 @@
             torqueinv[2]=torque[2]*-raydium_ode_element[i].rotfriction;
             dBodyAddTorque(raydium_ode_element[i].body,torqueinv[0],torqueinv[1],torqueinv[2]);
             }
-        
+
         for(j=0;j<RAYDIUM_ODE_MAX_RAYS;j++)
           if(raydium_ode_element[i].ray[j].state)
             {
@@ -4097,10 +4106,10 @@
                     dReal * dir;
                     dReal ndir[3],npos[3];
                 raydium_ode_Ray *r;
-                
+
                 r=&raydium_ode_element[i].ray[j];
                 // Get pos vector and rot matrix of element.
-                pos = (dReal *) dGeomGetPosition(raydium_ode_element[i].geom);                
+                pos = (dReal *) dGeomGetPosition(raydium_ode_element[i].geom);
                 dir = (dReal *) dGeomGetRotation(raydium_ode_element[i].geom);
                 // Compute relative dir to element orientation
                 ndir[0]=dir[0]*r->rel_dir[0] + dir[1]*r->rel_dir[1] + dir[2]*r->rel_dir[2];
@@ -4130,7 +4139,7 @@
          {
          // 2 - increment radius
          raydium_ode_explosion[i].radius+=raydium_ode_explosion[i].config_propag;
-         
+
          // 3 - delete previous element if exists
          if(raydium_ode_explosion[i].element>=0)
             raydium_ode_element_delete(raydium_ode_explosion[i].element,0);
@@ -4176,20 +4185,20 @@
 dJointGroupEmpty (raydium_ode_contactgroup);
 
 for(i=0;i<RAYDIUM_ODE_MAX_ELEMENTS;i++)
-    if(raydium_ode_element[i].state  && 
+    if(raydium_ode_element[i].state  &&
        raydium_ode_element[i].marked_as_deleted)
             raydium_ode_element_delete(i,1);
-            
 
 
+
 for(i=0;i<RAYDIUM_ODE_MAX_ELEMENTS;i++)
-    if(raydium_ode_element[i].state         && 
+    if(raydium_ode_element[i].state         &&
        raydium_ode_element[i]._movesfrom>=0 &&
        !raydium_ode_element[i]._avoidedcol  )
             raydium_ode_element[i]._movesfrom=-1;
 
 for(i=0;i<RAYDIUM_ODE_MAX_ELEMENTS;i++)
-    if(raydium_ode_element[i].state   && 
+    if(raydium_ode_element[i].state   &&
        raydium_ode_element[i].isplayer )
         {
         dMatrix3 R;
@@ -4205,7 +4214,7 @@
         if(raydium_ode_element[i].ttl==0)
             raydium_ode_element_delete(i,1);
         else
-            raydium_ode_element[i].ttl--;       
+            raydium_ode_element[i].ttl--;
         }
 
 
@@ -4233,7 +4242,7 @@
 
     // It may be an good idea to find a quicker way to do this ... :)
     for(i=0;i<RAYDIUM_ODE_MAX_ELEMENTS;i++)
-        if(raydium_ode_element[i].state && 
+        if(raydium_ode_element[i].state &&
            raydium_ode_element[i].id!=ground_elem_id &&
            raydium_ode_element[i].recorded)
             count++;
@@ -4241,7 +4250,7 @@
     fwrite(&count,sizeof(count),1,raydium_ode_record_fp);
 
     for(i=0;i<RAYDIUM_ODE_MAX_ELEMENTS;i++)
-        if(raydium_ode_element[i].state && 
+        if(raydium_ode_element[i].state &&
            raydium_ode_element[i].id!=ground_elem_id &&
            raydium_ode_element[i].recorded)
             {
@@ -4249,10 +4258,10 @@
             dReal *p;
             dReal pos[3];
             dReal q[4];
-            
+
             id=raydium_ode_element[i].id;
             fwrite(&id,sizeof(id),1,raydium_ode_record_fp);
-            
+
             // no idea why I must make a local copy ... :/
             p=raydium_ode_element_pos_get(i);
             pos[0]=p[0];
@@ -4261,7 +4270,7 @@
             fwrite(&pos,sizeof(dReal),3,raydium_ode_record_fp);
 
             raydium_ode_element_rotq_get(i,q);
-            fwrite(&q,sizeof(dReal),4,raydium_ode_record_fp);       
+            fwrite(&q,sizeof(dReal),4,raydium_ode_record_fp);
             }
     }
   else
@@ -4410,7 +4419,7 @@
 
 
 // This function is provided "for fun" only. Not all effects are dumped:
-// Missing : shadows, forced colors, before/after callbacks, 
+// Missing : shadows, forced colors, before/after callbacks,
 // fixed elements, ...
 // Some code is pasted from file.c (and this is BAD ! :)
 
@@ -4435,7 +4444,7 @@
     if(raydium_ode_element[i].state && raydium_ode_element[i].mesh>=0)
      {
         int end;
-        
+
         dBodyID body;
         dReal *pos;
         dQuaternion rot;
@@ -4445,13 +4454,13 @@
         dBodySetPosition(body,pos[0],pos[1],pos[2]);
         dBodySetQuaternion(body,rot);
         k=raydium_ode_element[i].mesh;
-        
+
         // should prepare "ode" instance here, too ...
         if(raydium_object_anims[k]>0)
             end=raydium_object_start[k]+raydium_object_anim_len[k];
         else
             end=raydium_object_end[k];
-        
+
         for(j=raydium_object_start[k];j<end;j++)
         {
           if(raydium_vertex_texture_multi[j])
@@ -4463,19 +4472,19 @@
             }
         else
             strcpy(text,raydium_texture_name[raydium_vertex_texture[j]]);
-                                                                                                               
+
         dBodyGetRelPointPos(body,
                                 raydium_vertex_x[j],
                                 raydium_vertex_y[j],
                                 raydium_vertex_z[j],
                                 res);
-                                
+
         dBodyVectorToWorld(body,
                                 raydium_vertex_normal_visu_x[j],
                                 raydium_vertex_normal_visu_y[j],
                                 raydium_vertex_normal_visu_z[j],
                                 norm);
-        
+
         fprintf(fp,"%f %f %f %f %f %f %f %f %s\n",
                                         res[0],
                                         res[1],
@@ -4518,7 +4527,7 @@
             if(raydium_ode_element[k].state)
                 if(raydium_ode_element[k].geom==g)
                     break;
-        
+
         if(k==RAYDIUM_ODE_MAX_ELEMENTS)
             {
             cpt++;
@@ -4534,22 +4543,22 @@
 {
     GLdouble dX, dY, dZ;
     int id;
-    dReal min_dist;     
+    dReal min_dist;
     dGeomID ray;
     dContact pt;
     signed char (*f)(int,int, dContact *);
-        
+
     f=raydium_ode_CollideCallback;
-        
+
     // Get mouse pointed coordinate
     gluUnProject( (float)raydium_mouse_x, (float)(raydium_window_ty - raydium_mouse_y), (float) -1.0, raydium_camera_gl_modelview, raydium_camera_gl_projection, raydium_camera_gl_viewport, &dX, &dY, &dZ);
 
-    //Create Ray        
+    //Create Ray
     ray =  dCreateRay (raydium_ode_object[raydium_ode_object_find("GLOBAL")].group,dist);
     // Set ray origin and dist
     dGeomRaySet (ray, raydium_camera_x, raydium_camera_y,raydium_camera_z,dX-raydium_camera_x, dY-raydium_camera_y, dZ-raydium_camera_z);
     //dGeomRaySetClosestHit(ray, true);
-        
+
     id=-1;
     min_dist=dist;
 
@@ -4560,9 +4569,9 @@
             #define N 400
             static  dContact contact[N];
             int i,n;
-            
+
             // Recurse into space
-            if(dGeomIsSpace (o1) || dGeomIsSpace (o2)) 
+            if(dGeomIsSpace (o1) || dGeomIsSpace (o2))
             {
                 raydium_ode_Object *oo1, *oo2;
                 signed char (*g)(int,int);
@@ -4573,23 +4582,23 @@
                 dSpaceCollide2 (o1,o2,data,&dNearPickback);
                 return;
             }
-            
-            
+
+
             if (o1==ray || o2==ray) {
                 raydium_ode_Element *e1,*e2;
-                
+
                 //Should never exist, but in case of swap o2 ray, o1 object
                 if (o2!=ray){
                     o1=o2;
                     o2=ray;
                 }
-            
+
                 e1=dGeomGetData(o1);
-                
+
                 n = dCollide (o1,o2,N,&contact[0].geom,sizeof(dContact));
-                
+
                 for (i=0; i<n; i++) {
-                    
+
                     if(f)
                     {
                         int id1;
@@ -4605,7 +4614,7 @@
                                 memcpy(&pt,&contact[i],sizeof(dContact));
                             id = e2->id;
                         }
-                    
+
                     if (contact[i].geom.g2==ray)
                         if (contact[i].geom.depth<min_dist){
                             min_dist=contact[i].geom.depth;
@@ -4615,19 +4624,19 @@
                 }
             }
         }
-        
+
         dSpaceCollide2((dGeomID) raydium_ode_space,ray,(void *) NULL,&dNearPickback);
     }
-        
+
     dGeomDestroy(ray);
-        
+
     pos[0]=pt.geom.pos[0];
     pos[1]=pt.geom.pos[1];
     pos[2]=pt.geom.pos[2];
     *depth = pt.geom.depth;
 
     return id;
-    
+
 }
 
 void raydium_ode_set_physics_freq(GLfloat freq)
@@ -4700,15 +4709,15 @@
             sizes[0]=dGeomSphereGetRadius(raydium_ode_element[i].geom);
             ctype=RAYDIUM_ODE_RECORD_NEWSPHERE;
             }
-        if(type==dBoxClass)     
+        if(type==dBoxClass)
             {
             dGeomBoxGetLengths(raydium_ode_element[i].geom,sizes);
             ctype=RAYDIUM_ODE_RECORD_NEWBOX;
             }
-        
+
         if(ctype!=-1)
             raydium_ode_capture_internal_create(ctype,i,sizes,raydium_object_name[raydium_ode_element[i].mesh]);
-        }                      
+        }
 }
 
 
@@ -4731,7 +4740,7 @@
     event=RAYDIUM_ODE_RECORD_DELSPHERE;
     sizes[0]=dGeomSphereGetRadius(raydium_ode_element[id].geom);
     }
-if(type==dBoxClass)     
+if(type==dBoxClass)
     {
     event=RAYDIUM_ODE_RECORD_DELBOX;
     dGeomBoxGetLengths(raydium_ode_element[id].geom,sizes);
@@ -4830,15 +4839,15 @@
         last_event_wrote=0;
         }
 
-    if(raydium_ode_record_index_size>0 && 
+    if(raydium_ode_record_index_size>0 &&
        raydium_ode_record_index_forward[raydium_ode_record_index_size-1].fpos==0)
         {
         raydium_ode_record_index_forward[raydium_ode_record_index_size-1].fpos=pos;
         raydium_ode_record_index_forward[raydium_ode_record_index_size-1].index=raydium_ode_record_index_size;
         }
-    
+
     n_events++;
-    
+
     switch(event)
         {
         case RAYDIUM_ODE_RECORD_DELSPHERE:
@@ -4859,7 +4868,7 @@
             raydium_file_binary_fgets(name,RAYDIUM_MAX_NAME_LEN-1,raydium_ode_record_play_fp);
             break;
 
-        case RAYDIUM_ODE_RECORD_NEWSPHERE:          
+        case RAYDIUM_ODE_RECORD_NEWSPHERE:
             // newbox event : dReal + short + string
             fseek(raydium_ode_record_play_fp,sizeof(dReal)+sizeof(short),SEEK_CUR);
             raydium_file_binary_fgets(name,RAYDIUM_MAX_NAME_LEN-1,raydium_ode_record_play_fp);
@@ -4928,7 +4937,7 @@
 fclose(fp);
 }*/
 
-// let's be kind: replace the cursor where we found it (almost useless for 
+// let's be kind: replace the cursor where we found it (almost useless for
 // replay reading itself, but it helps debuging somehow)
 fseek(raydium_ode_record_play_fp,old_pos,SEEK_SET);