00001
00007 #include "SO3MaterialPair.h"
00008 #include "SO3MaterialID.h"
00009 #include "SO3Body.h"
00010 #include "..\SO3SceneGraph\SO3NodeScol.h"
00011 #include "..\SO3SceneGraph\SO3Scene.h"
00012
00013 #include "../SCOLPack/SO3SCOL.h"
00014
00015 extern WindowHandle hwndScol;
00016 extern mmachine mm;
00017
00018 namespace SO3
00019 {
00020
00021 SMaterialPair::SMaterialPair(SScene* scene, SMaterialID* mat1, SMaterialID* mat2)
00022 {
00023 O3MaterialPair = new OgreNewt::MaterialPair(scene->GetPhysicsWorld()->GetPhysicWorld(), mat1->getOgreNewtMaterialID(), mat2->getOgreNewtMaterialID());
00024 mScene = scene;
00025 mMat1 = mat1;
00026 mMat2 = mat2;
00027 contactCallbackActivated = false;
00028 overlapStartedCallbackActivated = false;
00029 overlapEndedCallbackActivated = false;
00030
00031 O3MaterialPair->setContactCallback(this);
00032 }
00033
00034 SMaterialPair::~SMaterialPair()
00035 {
00036 delete O3MaterialPair;
00037 }
00038
00039 int SMaterialPair::getID1()
00040 {
00041 return mMat1->getID();
00042 }
00043
00044 int SMaterialPair::getID2()
00045 {
00046 return mMat2->getID();
00047 }
00048
00049 bool SMaterialPair::GetContactCallbackActivated()
00050 {
00051 return contactCallbackActivated;
00052 }
00053
00054 void SMaterialPair::SetContactCallbackActivated(bool state)
00055 {
00056 contactCallbackActivated = state;
00057 }
00058
00059 bool SMaterialPair::GetOverlapStartedCallbackActivated()
00060 {
00061 return overlapStartedCallbackActivated;
00062 }
00063
00064 void SMaterialPair::SetOverlapStartedCallbackActivated(bool state)
00065 {
00066 overlapStartedCallbackActivated = state;
00067 }
00068
00069 bool SMaterialPair::GetOverlapEndedCallbackActivated()
00070 {
00071 return overlapEndedCallbackActivated;
00072 }
00073
00074 void SMaterialPair::SetOverlapEndedCallbackActivated(bool state)
00075 {
00076 overlapEndedCallbackActivated = state;
00077 }
00078
00079 void SMaterialPair::SetDefaultSurfaceThickness(Ogre::Real value)
00080 {
00081 O3MaterialPair->setDefaultSurfaceThickness(value);
00082 }
00083
00084 void SMaterialPair::SetDefaultElasticity(Ogre::Real value)
00085 {
00086 O3MaterialPair->setDefaultElasticity(value);
00087 }
00088
00089 void SMaterialPair::SetDefaultFriction(Ogre::Real stat, Ogre::Real kin)
00090 {
00091
00092 O3MaterialPair->setDefaultFriction(stat == 0.0f ? 0.01f : stat, kin == 0.0f ? 0.01f : kin);
00093 }
00094
00095 void SMaterialPair::SetDefaultSoftness(Ogre::Real value)
00096 {
00097 O3MaterialPair->setDefaultSoftness(value);
00098 }
00099
00100 void SMaterialPair::SetDefaultCollidable(bool enable)
00101 {
00102 O3MaterialPair->setDefaultCollidable(enable ? 1 : 0);
00103 }
00104
00105 void SMaterialPair::SetContinuousCollisionMode(bool enable)
00106 {
00107 O3MaterialPair->setContinuousCollisionMode(enable ? 1 : 0);
00108 }
00109
00110 SScene* SMaterialPair::GetParentScene()
00111 {
00112 return mScene;
00113 }
00114
00115 int SMaterialPair::onAABBOverlap(OgreNewt::Body* body0, OgreNewt::Body* body1, int threadIndex )
00116 {
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 return 1;
00152 }
00153
00154 void SMaterialPair::contactsProcess(OgreNewt::ContactJoint &contactJoint, Ogre::Real timeStep, int threadIndex)
00155 {
00156 SNode* nodeScol0 = Ogre::any_cast<SNode*>(contactJoint.getBody0()->getUserData());
00157 SNode* nodeScol1 = Ogre::any_cast<SNode*>(contactJoint.getBody1()->getUserData());
00158
00159 if((nodeScol0 != NULL) && (nodeScol1 != NULL))
00160 {
00161 SBody* b0 = nodeScol0->getSceneNodeBody();
00162 SBody* b1 = nodeScol1->getSceneNodeBody();
00163
00164 if(b0 != NULL && b1 != NULL)
00165 {
00166 SScene* mScene = nodeScol0->GetParentScene();
00167 SPhysicWorld* world = mScene->GetPhysicsWorld();
00168
00169
00170 if (GetOverlapStartedCallbackActivated())
00171 {
00172
00173 BodyPairMap::iterator iBodyPairSearched = world->bodyPairMap.find(b0->GetParentNode()->GetName() + "|" + b1->GetParentNode()->GetName());
00174 if(iBodyPairSearched == world->bodyPairMap.end())
00175 {
00176 iBodyPairSearched = world->bodyPairMap.find(b1->GetParentNode()->GetName() + "|" + b0->GetParentNode()->GetName());
00177
00178 if(iBodyPairSearched == world->bodyPairMap.end())
00179 {
00180
00181 MCOLL* mCollResult = new MCOLL();
00182 mCollResult->matPair = this;
00183 mCollResult->node0 = b0->GetParentNode()->GetName();
00184 mCollResult->node1 = b1->GetParentNode()->GetName();
00185 mCollResult->curScene = mScene;
00186
00187 SBody** bpair = (SBody**)malloc(sizeof(SBody*)*2);
00188 if (bpair == 0)
00189 return;
00190
00191 bpair[0] = b0;
00192 bpair[1] = b1;
00193
00194
00195 world->bodyPairMap.insert(BodyPairMap::value_type(b0->GetParentNode()->GetName() + "|" + b1->GetParentNode()->GetName(), bpair));
00196 world->physicContactOverlapStartMap.insert(PhysicContactMap::value_type(b0->GetParentNode()->GetName() + "|" + b1->GetParentNode()->GetName(), mCollResult));
00197 }
00198 }
00199 }
00200
00201
00202 if (GetContactCallbackActivated())
00203 {
00204 for (OgreNewt::Contact contact = contactJoint.getFirstContact(); contact; contact = contact.getNext())
00205 {
00206 PhysicContactMap::iterator iBodyContactSearched = world->physicContactMap.find(b0->GetParentNode()->GetName() + "|" + b1->GetParentNode()->GetName());
00207 if(iBodyContactSearched == world->physicContactMap.end())
00208 iBodyContactSearched = world->physicContactMap.find(b1->GetParentNode()->GetName() + "|" + b0->GetParentNode()->GetName());
00209
00210 Ogre::Vector3 pos;
00211 Ogre::Vector3 normal;
00212 contact.getPositionAndNormal(pos, normal);
00213
00214 MCOLL* mCollResult = new MCOLL();
00215 mCollResult->matPair = this;
00216 mCollResult->node0 = b0->GetParentNode()->GetName();
00217 mCollResult->node1 = b1->GetParentNode()->GetName();
00218 mCollResult->position = pos;
00219 mCollResult->normal = normal;
00220 mCollResult->normalspeed = contact.getNormalSpeed();
00221 mCollResult->force = contact.getForce();
00222 mCollResult->curScene = mScene;
00223
00224 if (iBodyContactSearched != world->physicContactMap.end())
00225 {
00226 delete (iBodyContactSearched->second);
00227 iBodyContactSearched->second = mCollResult;
00228
00229 }
00230 else
00231 {
00232 world->physicContactMap.insert(PhysicContactMap::value_type(b0->GetParentNode()->GetName() + "|" + b1->GetParentNode()->GetName(), mCollResult));
00233 }
00234 }
00235 }
00236 }
00237 }
00238 }
00239
00240 }