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/ODECollisionCuller>
00026
00027 #include <physics/ODECollidableGroup>
00028
00029 #include <physics/ODECollidableBody>
00030
00031 #include <physics/VisualDebugUtil>
00032
00033 using physics::ODECollisionCuller;
00034
00035 using physics::Collider;
00036 using physics::Collidable;
00037 using physics::CollidableBody;
00038 using physics::ODECollidableBody;
00039 using physics::CollidableGroup;
00040 using physics::ODECollidableGroup;
00041
00042
00043 ref<CollidableGroup> ODECollisionCuller::createCollidableGroup() const
00044 {
00045 return ref<ODECollidableGroup>(NewObj ODECollidableGroup());
00046 }
00047
00048
00049 void ODECollisionCuller::nearCallback(void *data, dGeomID o1, dGeomID o2)
00050 {
00051 (static_cast<ODECollisionCuller*>(data))->callback(o1,o2);
00052 }
00053
00054
00055 void ODECollisionCuller::callback(dGeomID o1, dGeomID o2)
00056 {
00057 if (dGeomIsSpace(o1)) {
00058
00059 ref<const ODECollidableGroup> group1( (const ODECollidableGroup*)dGeomGetData(o1) );
00060
00061 if (dGeomIsSpace(o2)) {
00062 ref<const ODECollidableGroup> group2( (const ODECollidableGroup*)dGeomGetData(o2) );
00063 collide(group1, group2);
00064 }
00065 else {
00066 ref<const ODECollidableBody> body2( (const ODECollidableBody*)dGeomGetData(o2) );
00067 collide(group1, body2);
00068 }
00069
00070 }
00071 else {
00072
00073 ref<const ODECollidableBody> body1( (const ODECollidableBody*)dGeomGetData(o1) );
00074
00075 if (dGeomIsSpace(o2)) {
00076 ref<const ODECollidableGroup> group2( (const ODECollidableGroup*)dGeomGetData(o2) );
00077 collide(body1, group2);
00078 }
00079 else {
00080 ref<const ODECollidableBody> body2( (const ODECollidableBody*)dGeomGetData(o2) );
00081 collide(body1,body2);
00082 }
00083
00084 }
00085
00086 }
00087
00088
00089
00090 void ODECollisionCuller::collide(ref<const Collidable> collidable)
00091 {
00092 if (!isCollisionEnabled()) return;
00093
00094 if (!instanceof(*collidable, const CollidableGroup))
00095 return;
00096
00097 Assert(instanceof(*collidable, const ODECollidableGroup));
00098 ref<const ODECollidableGroup> group(narrow_ref<const ODECollidableGroup>(collidable));
00099 if (!group->isChildIntercollisionEnabled()) return;
00100 Collider::collide(collidable);
00101
00102 }
00103
00104
00105
00106 void ODECollisionCuller::collide(ref<const Collidable> collidable1, ref<const Collidable> collidable2)
00107 {
00108 if (!isCollisionEnabled()) return;
00109
00110 if (collidable1->getUserClass() != 0)
00111 if (collidable1->getUserClass() == collidable2->getUserClass())
00112 return;
00113
00114
00115
00116 if (instanceof(*collidable1, const ODECollidableBody)) {
00117 VisualDebugUtil::setConfiguration( collidable1->getName()+" Sensor", narrow_ref<const ODECollidableBody>(collidable1)->getConfiguration());
00118
00119 }
00120 if (instanceof(*collidable2, const ODECollidableBody)) {
00121 VisualDebugUtil::setConfiguration( collidable2->getName()+" Sensor", narrow_ref<const ODECollidableBody>(collidable2)->getConfiguration());
00122
00123 }
00124
00125
00126
00127 if (instanceof(*collidable1, const ODECollidableBody) && instanceof(*collidable2, const ODECollidableBody)) {
00128 if (!isCollisionEnabled(collidable1, collidable2)) return;
00129 notifyListeners(collidable1, collidable2);
00130 return;
00131 }
00132
00133 if (instanceof(*collidable1, const ODECollidableGroup) && instanceof(*collidable2, const ODECollidableGroup)) {
00134
00135
00136 ref<const ODECollidableGroup> group1(narrow_ref<const ODECollidableGroup>(collidable1));
00137 ref<const ODECollidableGroup> group2(narrow_ref<const ODECollidableGroup>(collidable2));
00138
00139 if (isCollisionEnabled(collidable1, collidable2))
00140 dSpaceCollide2((dGeomID)group1->getSpaceID(), (dGeomID)group2->getSpaceID(), this, nearCallback);
00141
00142
00143 if (group1->isChildIntercollisionEnabled())
00144 dSpaceCollide(group1->getSpaceID(), this, nearCallback);
00145
00146 if (group2->isChildIntercollisionEnabled())
00147 dSpaceCollide(group2->getSpaceID(), this, nearCallback);
00148
00149 }
00150 else {
00151
00152
00153 if (instanceof(*collidable1, const ODECollidableBody))
00154 base::swap(collidable1, collidable2);
00155
00156
00157
00158 Assert(instanceof(*collidable1, const ODECollidableGroup));
00159 Assert(instanceof(*collidable2, const ODECollidableBody));
00160
00161 ref<const ODECollidableGroup> group(narrow_ref<const ODECollidableGroup>(collidable1));
00162 ref<const ODECollidableBody> body(narrow_ref<const ODECollidableBody>(collidable2));
00163
00164
00165 if (isCollisionEnabled(collidable1, collidable2))
00166 dSpaceCollide2((dGeomID)group->getSpaceID(), body->getGeomID(), this, nearCallback);
00167
00168
00169 if (group->isChildIntercollisionEnabled())
00170 dSpaceCollide(group->getSpaceID(), this, nearCallback);
00171
00172 }
00173
00174 }