Posted 03 December 2012 - 09:10 AM
UPDATE:
Ok, so I have implemented something based on what I was thinking. Both the tractor and the trailer are rigid bodies. I calculate forces generated by the wheels in both objects, then integrate the forces. Then I calculate the speed difference between the attachment points on both objects and multiply by mass to get the force vector. Then I add that force vector to one object and an opposite response force vector to the other. Then integrate the forces again.
Does this make sense?
The result is something that looks almost right. They stay (almost) together, and pivot around the hinge point. However, sometimes weird problems occur. The trailer drifts off the hinge point (very slowly) after substantial use, and sometimes the trailer pulls the tractor into unexpected high speed turns, not sure why.
I'll post the relevant code:
[source lang="cpp"]struct image{const char *fname;void *texture; //SDL_Textureint w,h;double angle;};struct rigidBody{VEC2 coord;VEC2 speed;VEC2 force;double mass;double angle;double angleV;double torque;double inertia;};struct wheel{VEC2 coord, forward, side;double angle, speed, radius;double inertia, torque;double steer,throttle,brake;};struct vehicle{struct rigidBody chassis;struct wheel wheel[4];struct vehicle *trailer;VEC2 hinge,pin;struct image img;};void updateHinge(struct vehicle *obj){ //Don't apply forces from trailer if there is no trailer if (obj->trailer==NULL) return; VEC2 hoffset,poffset,hspeed,pspeed,wspeed,force; relativeToWorld(obj,&obj->hinge,&hoffset); relativeToWorld(obj->trailer,&obj->trailer->pin,&poffset); pointVel(obj,&hoffset,&hspeed); pointVel(obj->trailer,&poffset,&pspeed); subtractVEC(&hspeed,&pspeed,&wspeed); reverseVEC(&wspeed,&wspeed); multiplyVEC(&wspeed,obj->chassis.mass,&force); addForce(&obj->chassis,&force,&hoffset); reverseVEC(&wspeed,&wspeed); multiplyVEC(&wspeed,obj->trailer->chassis.mass,&force); addForce(&obj->trailer->chassis,&force,&poffset); return;}int main(){struct vehicle user,trail;initVehicle(&user,20.0);user.chassis.coord.x=100.0;user.chassis.coord.y=200.0;user.chassis.angle=0.0;initWheel(&user,0,30.0,15.0,2.0);//FLinitWheel(&user,1,30.0,-15.0,2.0);//FRinitWheel(&user,2,-30.0,15.0,2.0);//RLinitWheel(&user,3,-30.0,-15.0,2.0);//RRuser.wheel[0].throttle=0;user.wheel[1].throttle=0;//Initialize test trailerinitVehicle(&trail,40.0);trail.chassis.coord.x=100.0-32;trail.chassis.coord.y=200.0;trail.chassis.angle=0.0;initWheel(&trail,0,-25.0,15.0,5.0);//FLinitWheel(&trail,1,-25.0,-15.0,5.0);//FRinitWheel(&trail,2,-30.0,15.0,5.0);//RLinitWheel(&trail,3,-30.0,-15.0,5.0);//RRtrail.wheel[0].throttle=0;trail.wheel[1].throttle=0;trail.wheel[2].throttle=0;trail.wheel[3].throttle=0;//Attach tractor and traileruser.trailer=&trail;user.hinge.x=-32+14;user.hinge.y=0;trail.pin.x=14;trail.pin.y=0;//Set more stuff up... while (1){//......Other stuff updateWheels(&user); updateWheels(&trail); updateRigidBody(&user.chassis); updateRigidBody(&trail.chassis); updateHinge(&user); updateHinge(&trail); updateRigidBody(&user.chassis); updateRigidBody(&trail.chassis);//....Draw the stuff here}}[/source]
Now, obviously, there is a lot of code left out, but this should be the relevant parts. If there is something else that you need to see then let me know and I will provide. I intend to release my project open source, so I won't be hiding anything.