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

physics/ODECollidableBody.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)2003 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: ODECollidableBody.cpp 1066 2004-02-27 19:55:32Z jungd $
00019  
00020 ****************************************************************************/
00021 
00022 #include <physics/ODECollidableBody>
00023 
00024 #include <physics/Box>
00025 #include <physics/Sphere>
00026 #include <physics/Cylinder>
00027 #include <physics/Capsule>
00028 #include <physics/Polyhedron>
00029 
00030 
00031 using base::Dimension3;
00032 using base::Point3;
00033 using base::Orient;
00034 
00035 using physics::ODECollidableBody;
00036 using physics::Shape;
00037 using physics::Box;
00038 using physics::Sphere;
00039 using physics::Cylinder;
00040 using physics::Capsule;
00041 
00042 
00043 
00044 ODECollidableBody::ODECollidableBody(ref<const Shape> shape)
00045   : CollidableBody(shape)
00046 {
00047   init(true);
00048 }
00049 
00050 ODECollidableBody::~ODECollidableBody()
00051 {
00052   dGeomDestroy(geomID);
00053 }
00054 
00055 
00056 void ODECollidableBody::createGeom() 
00057 {
00058   ref<const Shape> shape(getShape());
00059   Assert(shape);
00060   geomID = 0;
00061   if (instanceof(*shape, const Box)) {
00062     ref<const Box> box = narrow_ref<const Box>(shape);
00063     Dimension3 dim = box->dimensions();
00064     geomID = dCreateBox(0, dim.x, dim.y, dim.z);
00065   }
00066   else if (instanceof(*shape, const Sphere)) {
00067     ref<const Sphere> sphere = narrow_ref<const Sphere>(shape);
00068     geomID = dCreateSphere(0, sphere->radius());
00069   }
00070   else if (instanceof(*shape, const Cylinder)) {
00071     ref<const Cylinder> cylinder = narrow_ref<const Cylinder>(shape);
00072     geomID = dCreateCCylinder(0, cylinder->radius(), cylinder->height());
00073     // !!! switch this to use a real cynilder, not a capped cylinder (capsule)
00074     // (may need a geom transform, as currently ODE's cylinder is oriented fifferently, unless
00075     //  that changes)
00076   }
00077   else if (instanceof(*shape, const Capsule)) {
00078     ref<const Capsule> capsule = narrow_ref<const Capsule>(shape);
00079     geomID = dCreateCCylinder(0, capsule->radius(), capsule->height());
00080     //!!! is ODE CCylinder axis aligned with Capsule axis?? suspect so (didn't I change the orient of mine to match?)
00081   }
00082   else {
00083     Logln("Unsupported Shape: " << shape->className() << ", using bounding sphere for collision region");
00084     Real radius = (shape->getBoundingSphere()).radius();
00085     geomID = dCreateSphere(0, radius);
00086   }
00087   
00088   // now put this into the geom data so that the ODECollisionCuller can fetch it
00089   //  (to get the ODECollidableBody form the geomID)
00090   dGeomSetData(geomID, this);
00091 }
00092 
00093 
00094 void ODECollidableBody::setPosition(const Point3& x)
00095 {
00096   dGeomSetPosition(geomID, x.x, x.y, x.z);
00097 }
00098 
00099 void ODECollidableBody::setOrientation(const Orient& orient)
00100 {
00101   dQuaternion quat;
00102   Quat4 q( orient );
00103   quat[0] = q.w; quat[1] = q.v.x; quat[2] = q.v.y; quat[3] = q.v.z;
00104   dGeomSetQuaternion(geomID, quat);  
00105 }
00106 
00107 Point3 ODECollidableBody::getPosition() const
00108 {
00109   const dReal* pos = dGeomGetPosition(geomID);
00110   return Point3(pos[0],pos[1],pos[2]);
00111 }
00112 
00113 Orient ODECollidableBody::getOrientation() const
00114 {
00115   dQuaternion orient;
00116   dGeomGetQuaternion(geomID, orient);
00117   return Orient(Quat4(orient[1], orient[2], orient[3], orient[0]));
00118 }
00119 
00120 
00121 void ODECollidableBody::saveState()
00122 {
00123   state->savedPos = getPosition();
00124   state->savedOrient = getOrientation();
00125   state->savedVel = state->vel;
00126   state->savedAngVel = state->angVel;
00127 }
00128 
00129 void ODECollidableBody::restoreState()
00130 {
00131   setPosition(state->savedPos);
00132   setOrientation(state->savedOrient);
00133   state->vel = state->savedVel;
00134   state->angVel = state->savedAngVel;
00135 }
00136 

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