Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

physics/ODECollisionResponseHandler.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2002 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017   
00018   $Id: ODECollisionResponseHandler.cpp 1031 2004-02-11 20:46:36Z jungd $
00019   $Revision: 1.4 $
00020   $Date: 2004-02-11 15:46:36 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
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); // clear contact constraints from previous collisions
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     // setup ODE contact structure
00071     dContact oc;
00072     oc.surface.mode = dContactApprox1 | dContactSoftERP | dContactSoftCFM | dContactBounce;
00073     //dContactSlip1 | dContactSlip2 ;
00074     //| dContactSoftERP | dContactSoftCFM; | dContactBounce;
00075     oc.surface.mu = 8; //!!! arbitrary - should be calc'd from the two materials
00076     //oc.surface.slip1 = 0.1;
00077     //oc.surface.slip2 = 0.1;
00078     oc.surface.soft_erp = 0.5;
00079     oc.surface.soft_cfm = 1e-5;
00080     oc.surface.bounce = 0.3;
00081     //oc.surface.bounce_vel = 0.1;
00082 
00083     // transform contact point and normal to global coordinates
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     // create the contact 'joint' & attach it to the Solids
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 

Generated on Thu Jul 29 15:56:25 2004 for OpenSim by doxygen 1.3.6