00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00074
00075
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
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
00089
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