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/ODECollidableGroup>
00026
00027 #include <physics/ODECollidableBody>
00028
00029 using base::Dimension3;
00030 using base::Point3;
00031 using base::Orient;
00032
00033 using physics::ODECollidableGroup;
00034 using physics::ODECollidableBody;
00035
00036
00037
00038 ODECollidableGroup::ODECollidableGroup()
00039 {
00040 create(ODESimpleSpace);
00041 }
00042
00043 ODECollidableGroup::~ODECollidableGroup()
00044 {
00045 clear();
00046 dSpaceDestroy(spaceID);
00047 }
00048
00049
00050 void ODECollidableGroup::create(ODECollidableGroup::ODESpaceType type)
00051 {
00052 switch (type) {
00053 case ODESimpleSpace:
00054 spaceID = dSimpleSpaceCreate(0);
00055 break;
00056
00057 case ODEHashSpace: {
00058 spaceID = dHashSpaceCreate(0);
00059 } break;
00060
00061 case ODEQuadTreeSpace: {
00062
00063 dVector3 center = {0,0,0};
00064 dVector3 extent = {1025.0,1025.0,1025.0};
00065 spaceID = dQuadTreeSpaceCreate(0,center,extent,6);
00066 } break;
00067
00068 default:
00069 spaceID = dSimpleSpaceCreate(0);
00070 }
00071
00072
00073 dGeomSetData((dGeomID)spaceID, this);
00074
00075 dSpaceSetCleanup(spaceID, 0);
00076 }
00077
00078
00079 void ODECollidableGroup::addCollidable(ref<Collidable> c)
00080 {
00081 Assert(c);
00082 if (instanceof(*c, ODECollidableBody)) {
00083 dSpaceAdd(spaceID, (narrow_ref<ODECollidableBody>(c))->getGeomID() );
00084 }
00085 else if (instanceof(*c, ODECollidableGroup)) {
00086 dSpaceAdd(spaceID, (dGeomID)(narrow_ref<ODECollidableGroup>(c))->getSpaceID() );
00087 }
00088 else
00089 throw std::invalid_argument(Exception("only ODE type Collidables can be added to an ODECollidableGroup (not a "+c->className()+")"));
00090
00091 CollidableGroup::addCollidable(c);
00092 }
00093
00094
00095 void ODECollidableGroup::removeCollidable(ref<Collidable> c)
00096 {
00097 dGeomID geomID = 0;
00098 if (instanceof(*c, ODECollidableBody)) {
00099 geomID = (narrow_ref<ODECollidableBody>(c))->getGeomID();
00100 }
00101 else if (instanceof(*c, ODECollidableGroup)) {
00102 geomID = (dGeomID)(narrow_ref<ODECollidableGroup>(c))->getSpaceID();
00103 }
00104
00105 if (geomID != 0)
00106 if (dSpaceQuery(spaceID, geomID) == 0)
00107 geomID = 0;
00108
00109 if (geomID == 0)
00110 throw std::invalid_argument(Exception("the specified Collidable is not in this CollidableGroup"));
00111
00112 dSpaceRemove(spaceID, geomID);
00113 CollidableGroup::removeCollidable(c);
00114 }
00115
00116
00117 void ODECollidableGroup::clear()
00118 {
00119 while(dSpaceGetNumGeoms(spaceID) > 0)
00120 dSpaceRemove(spaceID, dSpaceGetGeom(spaceID, dSpaceGetNumGeoms(spaceID)-1) );
00121
00122 CollidableGroup::clear();
00123 }
00124