00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "space.h"
00023 #include "world.h"
00024 #include "collider.h"
00025 #include <oxygen/sceneserver/scene.h>
00026 #include <zeitgeist/logserver/logserver.h>
00027
00028 using namespace boost;
00029 using namespace oxygen;
00030
00031 static void collisionNearCallback (void *data, dGeomID obj1, dGeomID obj2)
00032 {
00033 Space *space = (Space*)data;
00034 space->HandleCollide(obj1, obj2);
00035 }
00036
00037 Space::Space() : mODESpace(0), mODEContactGroup(0)
00038 {
00039 }
00040
00041 Space::~Space()
00042 {
00043 if (mODEContactGroup)
00044 {
00045 dJointGroupDestroy(mODEContactGroup);
00046 mODEContactGroup = 0;
00047 }
00048
00049
00050 if (mODESpace)
00051 {
00052 dSpaceDestroy(mODESpace);
00053 mODESpace = 0;
00054 }
00055 }
00056
00057 dSpaceID Space::GetODESpace() const
00058 {
00059 return mODESpace;
00060 }
00061
00062 dJointGroupID Space::GetODEJointGroup() const
00063 {
00064 return mODEContactGroup;
00065 }
00066
00067 void Space::Collide()
00068 {
00069
00070 dSpaceCollide(mODESpace, this, collisionNearCallback);
00071 }
00072
00073 void Space::HandleCollide(dGeomID obj1, dGeomID obj2)
00074 {
00075
00076 const dBodyID b1 = dGeomGetBody(obj1);
00077 const dBodyID b2 = dGeomGetBody(obj2);
00078
00079 if ((b1) && (b2) && (dAreConnected(b1,b2)))
00080 {
00081 return;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090 static const int nContacts = 6;
00091 static dContact contacts[nContacts];
00092
00093 int n = dCollide (obj1, obj2, nContacts,
00094 &contacts[0].geom, sizeof(dContact));
00095
00096 if (n == 0)
00097 {
00098 return;
00099 }
00100
00101
00102 shared_ptr<Collider> collider = Collider::GetCollider(obj1);
00103 shared_ptr<Collider> collidee = Collider::GetCollider(obj2);
00104
00105 if (
00106 (collider.get() == 0) ||
00107 (collidee.get() == 0)
00108 )
00109 {
00110 return;
00111 }
00112
00113 for (int i=0;i<n;++i)
00114 {
00115
00116 collider->OnCollision(collidee,contacts[i],Collider::CT_DIRECT);
00117 collidee->OnCollision(collider,contacts[i],Collider::CT_SYMMETRIC);
00118 }
00119 }
00120
00121 bool Space::ConstructInternal()
00122 {
00123
00124
00125
00126 mODESpace = dHashSpaceCreate(0);
00127
00128
00129 mODEContactGroup = dJointGroupCreate(0);
00130
00131 return (
00132 (mODESpace != 0) &&
00133 (mODEContactGroup != 0)
00134 );
00135 }
00136
00137 void Space::PostPhysicsUpdateInternal()
00138 {
00139
00140 dJointGroupEmpty (mODEContactGroup);
00141 }
00142