00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <physics/ODECollisionResponseHandler>
00026
00027 #include <physics/CollisionState>
00028 #include <physics/ODEMotor>
00029 #include <physics/ODEConstraintGroup>
00030 #include <physics/ODECollidableBody>
00031
00032 using physics::ODECollisionResponseHandler;
00033
00034 using physics::CollidableBody;
00035 using physics::ODECollidableBody;
00036 using physics::ConstraintGroup;
00037 using physics::ODEConstraintGroup;
00038
00039
00040
00041 ODECollisionResponseHandler::ODECollisionResponseHandler(dWorldID worldID)
00042 : worldID(worldID)
00043 {
00044 contactJointGroupID = dJointGroupCreate(0);
00045 }
00046
00047
00048 ODECollisionResponseHandler::~ODECollisionResponseHandler()
00049 {
00050 dJointGroupDestroy(contactJointGroupID);
00051 }
00052
00053
00054 void ODECollisionResponseHandler::preCollisionTesting()
00055 {
00056 dJointGroupEmpty(contactJointGroupID);
00057 }
00058
00059
00060 void ODECollisionResponseHandler::handleCollision(ref<CollisionState> collisionState)
00061 {
00062 ref<const Solid> solid1(collisionState->solid1);
00063 ref<const Solid> solid2(collisionState->solid2);
00064
00065 CollisionState::Contacts::const_iterator c(collisionState->contacts.begin());
00066 CollisionState::Contacts::const_iterator end(collisionState->contacts.end());
00067 while (c != end) {
00068 const CollisionState::Contact& contact(*c);
00069
00070
00071 dContact oc;
00072 oc.surface.mode = dContactApprox1 | dContactSoftERP | dContactSoftCFM | dContactBounce;
00073
00074
00075 oc.surface.mu = 8;
00076
00077
00078 oc.surface.soft_erp = 0.5;
00079 oc.surface.soft_cfm = 1e-5;
00080 oc.surface.bounce = 0.3;
00081
00082
00083
00084 Point3 gpos(solid1->getOrientation().rotate(contact.p1) + solid1->getPosition() );
00085 oc.geom.pos[0] = gpos.x;
00086 oc.geom.pos[1] = gpos.y;
00087 oc.geom.pos[2] = gpos.z;
00088
00089 Vector3 gnormal(solid1->getOrientation().rotate(contact.n1));
00090 oc.geom.normal[0] = gnormal.x;
00091 oc.geom.normal[1] = gnormal.y;
00092 oc.geom.normal[2] = gnormal.z;
00093
00094 oc.geom.depth = contact.depth;
00095
00096
00097 dJointID cj = dJointCreateContact(worldID, contactJointGroupID, &oc);
00098
00099 ref<const ODESolid> solid1(narrow_ref<const ODESolid>(collisionState->solid1));
00100 ref<const ODESolid> solid2(narrow_ref<const ODESolid>(collisionState->solid2));
00101 dJointAttach(cj, solid1->bodyID, solid2->bodyID);
00102
00103 ++c;
00104 }
00105 }
00106