Project

General

Profile

SO3Engine
SO3Physics.cpp
Go to the documentation of this file.
1
8#include "SCOLPack/SO3SCOL.h"
17#include "SO3Renderer/SO3Root.h"
18
20//extern int SO3_BODY_LEAVE_WORLD_MSG;
21extern int getMaterialOverlapStartedCallback(mmachine m, SCOL_PTR_TYPE id, SCOL_PTR_TYPE param);
22extern int getMaterialContactCallback(mmachine m, SCOL_PTR_TYPE id, SCOL_PTR_TYPE param);
23extern int getMaterialOverlapEndedCallback(mmachine m, SCOL_PTR_TYPE id, SCOL_PTR_TYPE param);
24extern SMaterialPair* getMaterialPairByWorld(SPhysicWorld* world, int ID1, int ID2);
25
26
27namespace SO3
28{
29
30 //forbidden
31 SPhysicWorld::SPhysicWorld()
32 {
33 }
34
35 SPhysicWorld::SPhysicWorld(SScene* scene): mscene(scene)
36 {
37 maxBodyPair = 100;
38 initNewtonWorld();
39 }
40
42 {
43 if(worldDebugger)
44 {
45 if(worldDebuggerIsInit)
46 {
47 worldDebugger->hideDebugInformation();
48 worldDebugger->stopRaycastRecording();
49 worldDebugger->deInit();
50 worldDebuggerIsInit = false;
51 }
52 worldDebugger = 0;
53 }
54
59 listOfMaterialID.clear();
61
62 SO3_SAFE_DELETE(worldDebugger);
63 SO3_SAFE_DELETE(world);
64 }
65
66 void SPhysicWorld::initNewtonWorld()
67 {
68 world = NULL;
69 showPhysicsLine = false;
70 mResetPhysicWorld = false;
71 mGravity = Ogre::Vector3(0.0f, -9.81f, 0.0f);
72 worldIsEnabled = false;
73 worldDebugger = 0;
74 solverModel = 0;
75 frictionModel = 0;
76
77 world = new OgreNewt::World();
78 world->setThreadCount(2);
79
80 SetPhysicFPS(120);
81
82 worldDebugger = &world->getDebugger();
83 worldDebuggerIsInit = false;
84
85 //scol callback with body who leaves
86 //deprecated
87 //world->setLeaveWorldCallback(std::bind(&SPhysicWorld::LeaveWorldCallBack, this, std::placeholders::_1, std::placeholders::_2));
88
89 world->setPreListener(mscene->GetName(), this, PreUpdate);
90 world->setpostListener(mscene->GetName(), this, PreUpdate);
91 }
92
94 {
95 return world;
96 }
97
99 {
100 return mscene;
101 }
102
103 void SPhysicWorld::PreUpdate(const NewtonWorld* const world, void* const listenerUserData, dFloat timestep)
104 {
105 /*SPhysicWorld* const me = static_cast<SPhysicWorld*>(listenerUserData);
106 if(me)
107 {
108 //OBJpostEvent(SCENE_PRE_RENDER_PHYSIC_EVENT, (int)me->GetScene(), SCOL_PTR (timestep * 1000.0));
109 };*/
110 }
111
112 void SPhysicWorld::PostUpdate(const NewtonWorld* const world, void* const listenerUserData, dFloat timestep)
113 {
114 /*SPhysicWorld* const me = static_cast<SPhysicWorld*>(listenerUserData);
115 if(me)
116 {
117 //OBJpostEvent(SCENE_POST_RENDER_PHYSIC_EVENT, (int)me->GetScene(), SCOL_PTR (timestep * 1000.0));
118 };*/
119 }
120
121
123 {
124 return worldIsEnabled;
125 }
126
127 void SPhysicWorld::SetPhysicWorldEnable(const bool& enable)
128 {
129 worldIsEnabled = enable;
130
131 if (world && worldDebugger)
132 {
133 if (!worldIsEnabled && showPhysicsLine && worldDebuggerIsInit)
134 {
135 worldDebugger->hideDebugInformation();
136 worldDebugger->stopRaycastRecording();
137 // remove debug bodies
138 worldDebugger->deInit();
139 worldDebuggerIsInit = false;
140 }
141 else if (worldIsEnabled && showPhysicsLine)
142 {
144 }
145 }
146 }
147
152
153 void SPhysicWorld::SetPhysicDebugEnable(const bool& enable)
154 {
155 //OgreNewt debugger is crappy :/
156 //we deinit debugger to remove unused bodies frame listener
157 //and to be sure that the bodies list is up to date
158 if (worldDebugger)
159 {
160 if (worldDebuggerIsInit)
161 {
162 worldDebugger->hideDebugInformation();
163 worldDebugger->stopRaycastRecording();
164 // remove debug bodies
165 worldDebugger->deInit();
166 worldDebuggerIsInit = false;
167 }
168
169 showPhysicsLine = enable;
170
171 // create debug bodies
172 if (showPhysicsLine)
173 {
174 worldDebugger->init(const_cast<SScene*>(mscene)->GetOgreScenePointer());
175 worldDebugger->startRaycastRecording(false);
176 worldDebuggerIsInit = true;
177 }
178 }
179 }
180
182 {
183 return worldDebugger;
184 }
185
186 void SPhysicWorld::UpdatePhysic(const float& frameTime)
187 {
188 //$BB apply physics after render callback
189 if (GetPhysicWorld() != 0)
190 {
191 //invalidateCache must not be done in world update
193 {
195 SetResetPhysicWorld(false);
196 }
197
198 std::vector<MCOLL*> lOverlapStartCp;
199 std::vector<MCOLL*> lOverlapStopCp;
200 std::vector<MCOLL*> lContactCp;
201
203 {
204 try
205 {
206 GetPhysicWorld()->update(frameTime);
207 }
208 catch (std::exception &)
209 {
210 // update failed
211 return;
212 }
213
216
217 //mutex
218 std::unique_lock<std::mutex> l(mutexUpdate);
219
220 //$BB send callbacks here to be sure that no scol or other code will be executed while the physic update loop
221 //send overlap start callbacks
222 const PhysicContactMap lOverlapStart = physicContactOverlapStartMap;
223 PhysicContactMap::const_iterator iOverlapStartMap = lOverlapStart.begin();
224 while (iOverlapStartMap != lOverlapStart.end())
225 {
226 MCOLL* mCollResult = iOverlapStartMap->second;
227 lOverlapStartCp.push_back(mCollResult);
228 iOverlapStartMap++;
229 }
230 physicContactOverlapStartMap.clear();
231
232 //send contact callbacks
233 const PhysicContactMap lContacts = physicContactMap;
234 PhysicContactMap::const_iterator iContactMap = lContacts.begin();
235 while (iContactMap != lContacts.end())
236 {
237 MCOLL* mCollResult = iContactMap->second;
238 lContactCp.push_back(mCollResult);
239 iContactMap++;
240 }
241 physicContactMap.clear();
242
243 const BodyPairMap bodyPairList = bodyPairMap;
244 // Parsing all bodies that were detected in contact
245 BodyPairMap::const_iterator iBodyPairMap = bodyPairList.begin();
246 while (iBodyPairMap != bodyPairList.end())
247 {
248 // Checking if bodies are still in contact. Note that NewtonBodyGetFirstContactJoint() is not binded in OgreNewt for the moment.
249 bool bodiesInContact = false;
250 SBody** bpair = iBodyPairMap->second;
251 SBody* fbody0 = bpair[0];
252 SBody* fbody1 = bpair[1];
253 if ((fbody0 != NULL) && (fbody1 != NULL))
254 {
255 OgreNewt::Body* nbody0 = fbody0->getOgreNewtBodyPointer();
256 OgreNewt::Body* nbody1 = fbody1->getOgreNewtBodyPointer();
257
258 if ((nbody0 != NULL) && (nbody1 != NULL))
259 {
260 NewtonBody* b0 = nbody0->getNewtonBody();
261 NewtonBody* b1 = nbody1->getNewtonBody();
262 NewtonJoint* contactJoint = NewtonBodyGetFirstContactJoint(b0);
263
264 while((contactJoint) && (!bodiesInContact))
265 {
266 // Get infos about the bodies of contact from Newton
267 NewtonBody* b0Bis = NewtonJointGetBody0(contactJoint);
268 NewtonBody* b1Bis = NewtonJointGetBody1(contactJoint);
269 int colstate = NewtonJointIsActive(contactJoint);
270 //void* contact = NewtonContactJointGetFirstContact(contactJoint);
271
272 // Is the body still in contact with the second body of the pair value?
273 if(colstate && ((b0Bis == b0)&&(b1Bis == b1)) || ((b0Bis == b1)&&(b1Bis == b0)))
274 bodiesInContact = true;
275 else
276 contactJoint = NewtonBodyGetNextContactJoint(b0, contactJoint);
277 }
278
279 // If not, remove the bodies pair from the map.
280 if(!bodiesInContact)
281 {
282 // Getting the material pair. TODO: cleaner way to parse MaterialPair list
283 SMaterialPair* matPair = 0;
284 const SMaterialPairMap materialPairList = listOfPhysicsMaterialPair;
285 SMaterialPairMap::const_iterator iMaterialPairList = materialPairList.begin();
286 while((iMaterialPairList != materialPairList.end()) && (!matPair))
287 {
288 if(((*iMaterialPairList)->getID1() == fbody0->GetMaterialID()->getID() && (*iMaterialPairList)->getID2() == fbody1->GetMaterialID()->getID())
289 ||((*iMaterialPairList)->getID2() == fbody0->GetMaterialID()->getID() && (*iMaterialPairList)->getID1() == fbody1->GetMaterialID()->getID()))
290 matPair = *iMaterialPairList;
291
292 iMaterialPairList++;
293 }
294
295 if(matPair != 0)
296 {
297 // Construct CollResult
298 MCOLL* mCollResult = new MCOLL();
299 mCollResult->node0 = fbody0->GetParentNode()->GetName();
300 mCollResult->node1 = fbody1->GetParentNode()->GetName();
301 mCollResult->curScene = mscene;
302 mCollResult->matPair = matPair;
303
304 lOverlapStopCp.push_back(mCollResult);
305 }
306
307 // erase the entry from the map.
308 free(bpair);
309 bodyPairMap.erase(iBodyPairMap->first);
310 }
311 }
312 }
313 // Next couple.
314 iBodyPairMap++;
315 }
316 }
317
318 // send callbacks without mutex
320 {
321 unsigned int i = 0;
322 for (i = 0; i < lOverlapStartCp.size(); i++)
323 {
324 MCOLL* mCollResult = lOverlapStartCp[i];
326 getMaterialOverlapStartedCallback(mm, SCOL_PTR mCollResult->matPair, SCOL_PTR mCollResult);
327
328 // Release memory.
329 delete(mCollResult);
330 }
331
332 for (i = 0; i < lContactCp.size(); i++)
333 {
334 MCOLL* mCollResult = lContactCp[i];
335 if (mCollResult->matPair->GetContactCallbackActivated())
336 getMaterialContactCallback(mm, SCOL_PTR mCollResult->matPair, SCOL_PTR mCollResult);
337
338 // Release memory.
339 delete(mCollResult);
340 }
341
342 for (i = 0; i < lOverlapStopCp.size(); i++)
343 {
344 MCOLL* mCollResult = lOverlapStopCp[i];
345 // Send contact end callback to scol virtual machine.
346 if (mCollResult->matPair->GetOverlapEndedCallbackActivated())
347 getMaterialOverlapEndedCallback(mm, SCOL_PTR mCollResult->matPair, SCOL_PTR mCollResult);
348
349 // Release memory.
350 delete(mCollResult);
351 }
352 }
353 }
354 }
355
357 {
358 bool bLastState = GetPhysicWorldEnable();
359 if (bLastState)
360 {
363 }
364
365 //clear physic material pair callback
367
368 //not realy needed since these maps are cleared each world update
371
372 // reset world params before next update
374
375 if (bLastState)
376 {
378 UpdatePhysic(0.0f);
379 }
380
381 SNodeMap::const_iterator iNodeList = mscene->GetNodeList().begin();
382 while (iNodeList != mscene->GetNodeList().end())
383 {
384 SNode* curNode = iNodeList->second;
385 SBody* curBody = curNode->GetSceneNodeBody();
386
387 if (curBody != 0)
388 curBody->Reset();
389
390 iNodeList++;
391 }
392 }
393
395 {
396 SNodeMap::const_iterator iNodeList = mscene->GetNodeList().begin();
397 while(iNodeList != mscene->GetNodeList().end())
398 {
399 SNode* curNode = iNodeList->second;
400 SBody* curBody = curNode->GetSceneNodeBody();
401
402 if(curBody!=NULL)
403 {
404 curNode->StoreInitialPRS();
405 }
406 iNodeList++;
407 }
408 }
409
411 {
412 world->setSolverModel(mod);
413 solverModel = mod;
414 }
415
417 {
418 return solverModel;
419 }
420
422 {
423 //world->setPlatformArchitecture(mod);
424 }
425
427 {
428 Ogre::String aname;
429 return world->getPlatformArchitecture(aname);
430 }
431
432 void SPhysicWorld::SetPhysicGravity(const Ogre::Vector3& gravity)
433 {
434 mGravity = gravity;
435 }
436
438 {
439 return mGravity;
440 }
441
442 void SPhysicWorld::SetPhysicFPS(const int& fps)
443 {
444 if (fps < 120)
445 worldFPS = 120;
446 else
447 worldFPS = fps;
448
449 // high frame skipping make the leap or other synch physic with prerender to be very slow
450 if (world != 0)
451 world->setUpdateFPS(Ogre::Real(worldFPS), 6);
452 }
453
455 {
456 return worldFPS;
457 }
458
460 {
461 return mResetPhysicWorld;
462 }
463
464 void SPhysicWorld::SetResetPhysicWorld(const bool& state)
465 {
466 mResetPhysicWorld = state;
467 }
468
469 SBody* SPhysicWorld::PhysicsRayCast(const Ogre::Vector3& src, const Ogre::Vector3& dir, const Ogre::Real& maxdist, Ogre::Real& hitdistance, Ogre::Vector3& hitnormal)
470 {
471 OgreNewt::BasicRaycast* ray = new OgreNewt::BasicRaycast(world, src, (src + (dir.normalisedCopy() * maxdist)), true);
473 OgreNewt::Body* body = info.getBody();
474
475 SBody* sbody = 0;
476 if (info.getBody())
477 {
478 SNode* node = Ogre::any_cast<SNode*>(body->getUserData());
479 sbody = node->GetSceneNodeBody();
480
481 hitdistance = maxdist * info.getDistance();
482 hitnormal = info.getNormal();
483 }
484 delete ray;
485
486 return sbody;
487 }
488
489 std::vector<MRAYINFO> SPhysicWorld::PhysicsRayCast(const Ogre::Vector3& src, const Ogre::Vector3& dir, const Ogre::Real& maxdist)
490 {
491 OgreNewt::BasicRaycast* ray = new OgreNewt::BasicRaycast(world, src, (src + (dir.normalisedCopy() * maxdist)), true);
492 std::vector<MRAYINFO> lray;
493 int nbHits = ray->getHitCount();
494
495 for (int i = 0; i < nbHits; i++)
496 {
498 OgreNewt::Body* body = info.getBody();
499
500 if (info.getBody())
501 {
502 MRAYINFO mray;
503 SNode* node = Ogre::any_cast<SNode*>(body->getUserData());
504 mray.body = node->GetSceneNodeBody();
505
506 mray.distance = maxdist * info.getDistance();
507 mray.normal = info.getNormal();
508 lray.push_back(mray);
509 }
510 }
511 delete ray;
512
513 return lray;
514 }
515
516 //deprecated
517 void SPhysicWorld::SetPhysicWorldSize(const Ogre::Vector3& minsize, const Ogre::Vector3& maxsize)
518 {
519 //world->setWorldSize(minsize, maxsize);
520 }
521
522 //deprecated
523 void SPhysicWorld::GetPhysicWorldSize(Ogre::Vector3& minsize, Ogre::Vector3& maxsize)
524 {
525 //Ogre::AxisAlignedBox box = world->getWorldSize();
526 //minsize = box.getMinimum();
527 //maxsize = box.getMaximum();
528 }
529
530 SMaterialID* SPhysicWorld::CreatePhysicMaterialID(const std::string& materialIdName)
531 {
532 std::unique_lock<std::mutex> l(mutexUpdate);
533 SMaterialID* matid = new SMaterialID(const_cast<SScene*>(mscene), materialIdName);
534 listOfMaterialID.insert(SMaterialIDMap::value_type(materialIdName, matid));
535
536 return matid;
537 }
538
540 {
541 // Destroy Materials Pair Associated with IT
542 SMaterialIDMap::iterator iMaterialIDList = listOfMaterialID.begin();
543 while (iMaterialIDList != listOfMaterialID.end())
544 {
545 // Getting Material Pair Associated in the Scene
546 SMaterialPair* matPair;
547 matPair = NULL;
548 matPair = getMaterialPairByWorld(this, matID->getID(), iMaterialIDList->second->getID());
549 OBJdelTH(mm, SO3PHYSICSMATERIALPAIR, SCOL_PTR matPair);
550
551 iMaterialIDList++;
552 }
553
554 // Replace all Material ID of bodies using it by default
555 OgreNewt::Body* curBody = world->getFirstBody();
556 while(curBody!=NULL)
557 {
558 if(curBody->getMaterialGroupID()->getID() == matID->getID())
559 curBody->setMaterialGroupID(world->getDefaultMaterialID());
560
561 curBody = curBody->getNext();
562 }
563
564 // Destruction of pointer C
565 std::unique_lock<std::mutex> l(mutexUpdate);
566
567 SMaterialIDMap::iterator iMaterialIDSearched = listOfMaterialID.find(matID->GetName());
568 if(iMaterialIDSearched != listOfMaterialID.end())
569 listOfMaterialID.erase(iMaterialIDSearched);
570
571 delete matID;
572 }
573
575 {
576 std::unique_lock<std::mutex> l(mutexUpdate);
577 SMaterialPair* matpair = new SMaterialPair(const_cast<SScene*>(mscene), mat1, mat2);
578 listOfPhysicsMaterialPair.insert(matpair);
579
580 return matpair;
581 }
582
584 {
585 std::unique_lock<std::mutex> l(mutexUpdate);
586 listOfPhysicsMaterialPair.erase(matpair);
587 delete matpair;
588 }
589
591 {
592 /*if(body)
593 {
594 std::unique_lock<std::mutex> l(mutexUpdate);
595 SNode* nodeScol = Ogre::any_cast<SNode*>(body->getUserData());
596
597 if(nodeScol != NULL)
598 {
599 SBody* b0 = nodeScol->GetSceneNodeBody();
600 if (b0 != 0)
601 OBJpostEvent(SO3_BODY_LEAVE_WORLD_MSG, SCOL_PTR b0, 0);
602 }
603 }*/
604 }
605
607 {
608 return maxBodyPair;
609 }
610
612 {
613 std::unique_lock<std::mutex> l(mutexUpdate);
614 BodyPairMap::iterator iBodyPairSearched = bodyPairMap.find(b0->GetParentNode()->GetName() + "|" + b1->GetParentNode()->GetName());
615 if(iBodyPairSearched == bodyPairMap.end())
616 {
617 iBodyPairSearched = bodyPairMap.find(b1->GetParentNode()->GetName() + "|" + b0->GetParentNode()->GetName());
618 if(iBodyPairSearched == bodyPairMap.end())
619 return false;
620 }
621 return true;
622 }
623
624 void SPhysicWorld::AddBodyPair(std::string name, SBody** pair)
625 {
626 std::unique_lock<std::mutex> l(mutexUpdate);
627 bodyPairMap.insert(BodyPairMap::value_type(name, pair));
628 }
629
631 {
632 return bodyPairMap.size();
633 }
634
636 {
637 if(world)
638 {
639 std::unique_lock<std::mutex> l(mutexUpdate);
640 // Checking in the body pair list if this body is referenced
641 const BodyPairMap bodyMapList = bodyPairMap;
642 BodyPairMap::const_iterator iBodyPairSearched = bodyMapList.begin();
643 while (iBodyPairSearched != bodyMapList.end())
644 {
645 SBody** bpair = iBodyPairSearched->second;
646 if ((bpair[0] == body) || (bpair[1] == body))
647 {
648 free(bpair);
649 bodyPairMap.erase(iBodyPairSearched->first);
650 }
651
652 iBodyPairSearched++;
653 }
654 }
655 }
656
658 {
659 std::unique_lock<std::mutex> l(mutexUpdate);
660 const BodyPairMap bodyListCopy = bodyPairMap;
661 BodyPairMap::const_iterator iBodyMap = bodyListCopy.begin();
662 while (iBodyMap != bodyListCopy.end())
663 {
664 free(iBodyMap->second);
665 bodyPairMap.erase(iBodyMap->first);
666 iBodyMap++;
667 };
668 }
669
671 {
672 physicContraintList.insert(contraint);
673 }
674
676 {
677 physicContraintList.erase(contraint);
678 delete(contraint);
679 }
680
682 {
683 return physicContraintList;
684 }
685
687 {
688 const PhysicContraintList list = physicContraintList;
689 PhysicContraintList::const_iterator it;
690 for (it = list.begin(); it != list.end(); ++it)
691 {
692 delete((*it));
693 physicContraintList.erase(it);
694 }
695 }
696
698 {
699 const PhysicContraintList list = physicContraintList;
700 PhysicContraintList::const_iterator it;
701 for (it = list.begin(); it != list.end(); ++it)
702 {
703 if (((*it)->GetParentBody() == body) || ((*it)->GetSonBody() == body))
704 {
705 if ((*it)->GetParentBody() == body)
706 {
707 (*it)->SetParentBody(0);
708 }
709 else
710 {
711 (*it)->SetSonBody(0);
712 }
713 }
714 }
715 }
716
718 {
719 std::unique_lock<std::mutex> l(mutexUpdate);
720 const PhysicContactMap lOverlapStart = physicContactOverlapStartMap;
721 PhysicContactMap::const_iterator iOverlapStartMap = lOverlapStart.begin();
722 while (iOverlapStartMap != lOverlapStart.end())
723 {
724 MCOLL* mCollResult = iOverlapStartMap->second;
725 // Release memory.
726 delete(mCollResult);
727
728 iOverlapStartMap++;
729 }
730 physicContactOverlapStartMap.clear();
731 }
732
733 void SPhysicWorld::AddContactOverlapStart(std::string name, MCOLL* coll)
734 {
735 std::unique_lock<std::mutex> l(mutexUpdate);
736 physicContactOverlapStartMap.insert(PhysicContactMap::value_type(name, coll));
737 }
738
740 {
741 std::unique_lock<std::mutex> l(mutexUpdate);
742 const PhysicContactMap lContact = physicContactMap;
743 PhysicContactMap::const_iterator iContact = lContact.begin();
744 while (iContact != lContact.end())
745 {
746 MCOLL* mCollResult = iContact->second;
747 // Release memory.
748 delete(mCollResult);
749
750 iContact++;
751 }
752 physicContactMap.clear();
753 }
754
756 {
757 std::unique_lock<std::mutex> l(mutexUpdate);
758 PhysicContactMap::iterator iBodyContactSearched = physicContactMap.find(b0->GetParentNode()->GetName() + "|" + b1->GetParentNode()->GetName());
759 if(iBodyContactSearched == physicContactMap.end())
760 iBodyContactSearched = physicContactMap.find(b1->GetParentNode()->GetName() + "|" + b0->GetParentNode()->GetName());
761
762 if (iBodyContactSearched != physicContactMap.end())
763 {
764 delete (iBodyContactSearched->second);
765 iBodyContactSearched->second = coll;
766 }
767 else
768 {
769 physicContactMap.insert(PhysicContactMap::value_type(b0->GetParentNode()->GetName() + "|" + b1->GetParentNode()->GetName(), coll));
770 }
771 }
772
773 int SPhysicWorld::ImpulsePointCallback(const NewtonBody* const body, void* const userData)
774 {
775 const OgreNewt::Body* obody = (const OgreNewt::Body*) NewtonBodyGetUserData(body);
776 const NewtonWorld* newtonWorld = NewtonBodyGetWorld(body);
777 const OgreNewt::World* world = (const OgreNewt::World*) NewtonWorldGetUserData(newtonWorld);
778 const NewtonCollision* collision = NewtonBodyGetCollision(body);
779
780 MIMPULSEDATA* data = (MIMPULSEDATA*)userData;
781 dFloat Ixx;
782 dFloat Iyy;
783 dFloat Izz;
784 dFloat mass;
785 NewtonBodyGetMassMatrix(body, &mass, &Ixx, &Iyy, &Izz);
786 mass = std::max(0.9f, mass);
787
788 dMatrix matrix;
789 NewtonBodyGetMatrix(body, &matrix[0][0]);
790 Ogre::Vector3 contact;
791 Ogre::Vector3 normal;
792
793 if (NewtonCollisionPointDistance(newtonWorld, &data->position.x, collision, &matrix[0][0], &contact.x, &normal.x, 0))
794 {
795 float distance = (contact - data->position).squaredLength();
796 if (distance <= data->radius)
797 {
798 Ogre::Vector3 impulse = (normal * (-data->strenght * (1.0f - distance / data->radius))) / mass;
799 NewtonBodyAddImpulse(body, &impulse[0], &contact[0]);
800 }
801 }
802 return 1;
803 }
804
805 void SPhysicWorld::ApplyImpulsePoint(Ogre::Vector3 pos, Ogre::Real radius, Ogre::Real strength)
806 {
807 // an axis-aligned bounding box of the sphere around position with radius
808 Ogre::Vector3 vmin = pos - radius;
809 Ogre::Vector3 vmax = pos + radius;
810
811 MIMPULSEDATA data;
812 data.radius = radius * radius;
813 data.strenght = strength;
814 data.position = pos;
815
816 NewtonWorldForEachBodyInAABBDo(world->getNewtonWorld(), &vmin.x, &vmax.x, SPhysicWorld::ImpulsePointCallback, &data);
817 }
818}
int getMaterialOverlapEndedCallback(mmachine m, SCOL_PTR_TYPE id, SCOL_PTR_TYPE param)
C function that prepares the VM for the execution of the Physic Material Overlap callback.
SMaterialPair * getMaterialPairByWorld(SPhysicWorld *world, int ID1, int ID2)
function to check if a material ID exists
int getMaterialOverlapStartedCallback(mmachine m, SCOL_PTR_TYPE id, SCOL_PTR_TYPE param)
C function that prepares the VM for the execution of the Physic Material Overlap callback.
int getMaterialContactCallback(mmachine m, SCOL_PTR_TYPE id, SCOL_PTR_TYPE param)
C function that prepares the VM for the execution of the callback a body leave the physic world.
float mod(float _a, float _b)
int getMaterialOverlapEndedCallback(mmachine m, SCOL_PTR_TYPE id, SCOL_PTR_TYPE param)
C function that prepares the VM for the execution of the Physic Material Overlap callback.
SMaterialPair * getMaterialPairByWorld(SPhysicWorld *world, int ID1, int ID2)
function to check if a material ID exists
int getMaterialOverlapStartedCallback(mmachine m, SCOL_PTR_TYPE id, SCOL_PTR_TYPE param)
C function that prepares the VM for the execution of the Physic Material Overlap callback.
int SCENE_PRE_RENDER_PHYSIC_EVENT
Definition SO3SCOL.cpp:192
int getMaterialContactCallback(mmachine m, SCOL_PTR_TYPE id, SCOL_PTR_TYPE param)
C function that prepares the VM for the execution of the callback a body leave the physic world.
SCOL_EXPORT void SCOL_PTR_TYPE param
Definition SO3SCOL.cpp:5089
int SO3PHYSICSMATERIALPAIR
Definition SO3SCOL.cpp:96
mmachine mm
Definition SO3SCOL.cpp:109
simple class that represents a single raycast rigid body intersection.
Basic implementation of the raycast.
BasicRaycastInfo getInfoAt(unsigned int hitnum) const
retrieve the raycast info for a specific hit.
int getHitCount() const
how many bodies did we hit?
BasicRaycastInfo getFirstHit() const
get the closest body hit by the ray.
main class for all Rigid Bodies in the system.
const Ogre::Any & getUserData() const
retrieve pointer to previously set user data.
void setMaterialGroupID(const MaterialID *ID)
set the material for the body
const OgreNewt::MaterialID * getMaterialGroupID() const
get a pointer to the Material assigned to this body.
Body * getNext() const
use this function to iterate through all bodies
NewtonBody * getNewtonBody() const
get a pointer to the NewtonBody object
For viewing the Newton rigid bodies visually.
void showDebugInformation()
show the newton world
void init(Ogre::SceneManager *smgr)
init the debugger.
void hideDebugInformation()
remove lines and text drawn
void deInit()
de-init the debugger (cleantup)
void stopRaycastRecording()
disables raycast-debugging
void startRaycastRecording(bool markhitbodies=false)
enable additional raycast-debugging (this also enables displaying of recorded raycasts!...
int getID() const
get Newton-assigned material ID.
represents a physics world.
void setPreListener(std::string name, void *const listenerUserData, NewtonWorldUpdateListenerCallback update)
const MaterialID * getDefaultMaterialID() const
get the default materialID object.
void setpostListener(std::string name, void *const listenerUserData, NewtonWorldUpdateListenerCallback update)
int update(Ogre::Real t_step)
update the world by the specified time_step.
void setThreadCount(int threads)
set the number of threads for the physics simulation to use, don't do this while world update
void setSolverModel(int model)
set the physics solver model
Debugger & getDebugger() const
get the debugger for this world
NewtonWorld * getNewtonWorld() const
retrieves a pointer to the NewtonWorld
void setUpdateFPS(Ogre::Real desiredFps, int maxUpdatesPerFrames)
set simulation frames per and max updated per updates
Body * getFirstBody() const
to iterate through all bodies call this function and then use body->getNext()
void waitForUpdateToFinish() const
int getPlatformArchitecture(Ogre::String &description)
get the architecture used for physics calculations.
void invalidateCache()
invalidate internal cache
OgreNewt::Body * getOgreNewtBodyPointer()
Definition SO3Body.cpp:340
void Reset()
Definition SO3Body.cpp:116
const OgreNewt::MaterialID * GetMaterialID()
Definition SO3Body.cpp:500
SNode * GetParentNode()
Definition SO3Body.cpp:649
std::string GetName() const
bool GetOverlapStartedCallbackActivated()
bool GetOverlapEndedCallbackActivated()
SBody * GetSceneNodeBody()
virtual void StoreInitialPRS()
const SScene * GetScene()
SMaterialPair * CreatePhysicMaterialPair(SMaterialID *mat1, SMaterialID *mat2)
static void PostUpdate(const NewtonWorld *const world, void *const listenerUserData, dFloat timestep)
bool GetPhysicDebugEnable()
SMaterialPairMap listOfPhysicsMaterialPair
Definition SO3Physics.h:103
static int ImpulsePointCallback(const NewtonBody *const body, void *const userData)
void SetPhysicWorldSize(const Ogre::Vector3 &minsize, const Ogre::Vector3 &maxsize)
void ClearContactActivated()
void LeaveWorldCallBack(OgreNewt::Body *, int threadIndex)
static void PreUpdate(const NewtonWorld *const world, void *const listenerUserData, dFloat timestep)
void RemoveBodyPair(SBody *body)
void AddBodyPair(std::string name, SBody **pair)
void SetPhysicDebugEnable(const bool &enable)
void UpdatePhysic(const float &frameTime)
void AddPhysicContraint(SPhysicContraint *contraint)
SMaterialID * CreatePhysicMaterialID(const std::string &materialIdName)
void ClearContactOverlapStart()
void SetPhysicPlatformArchitecture(const int &mod)
void SetPhysicSolverModel(const int &mod)
void GetPhysicWorldSize(Ogre::Vector3 &minsize, Ogre::Vector3 &maxsize)
bool GetPhysicWorldEnable()
void SetContactActivated(SBody *b0, SBody *b1, MCOLL *coll)
unsigned int GetBodyPairSize()
std::mutex mutexUpdate
Definition SO3Physics.h:106
bool GetBodyPairExist(SBody *b0, SBody *b1)
void SetPhysicWorldEnable(const bool &enable)
void SetPhysicFPS(const int &fps)
void SetResetPhysicWorld(const bool &state)
void ApplyImpulsePoint(Ogre::Vector3 pos, Ogre::Real radius, Ogre::Real strength)
SMaterialIDMap listOfMaterialID
Definition SO3Physics.h:104
void RemovePhysicContraint(SPhysicContraint *contraint)
OgreNewt::Debugger * GetPhysicDebugger()
PhysicContraintList GetPhysicContraintList()
int GetPhysicPlatformArchitecture()
OgreNewt::World * GetPhysicWorld()
void SetPhysicBodiesInitialState()
SBody * PhysicsRayCast(const Ogre::Vector3 &src, const Ogre::Vector3 &dir, const Ogre::Real &maxdist, Ogre::Real &hitdistance, Ogre::Vector3 &hitnormal)
void RemoveBodyContraint(SBody *body)
void ClearPhysicContraint()
Ogre::Vector3 GetPhysicGravity()
void SetPhysicGravity(const Ogre::Vector3 &gravity)
void AddContactOverlapStart(std::string name, MCOLL *coll)
void DeletePhysicMaterialID(SMaterialID *matID)
void DeletePhysicMaterialPair(SMaterialPair *matpair)
unsigned int GetMaxBodyPair()
const SNodeMap & GetNodeList() const
Definition SO3Scene.cpp:588
std::unordered_set< SMaterialPair * > SMaterialPairMap
std::set< SPhysicContraint * > PhysicContraintList
Definition SO3Physics.h:98
std::unordered_map< std::string, MCOLL * > PhysicContactMap
Definition SO3Physics.h:97
std::unordered_map< std::string, SBody ** > BodyPairMap
Definition SO3Physics.h:96
SMaterialPair * matPair
Definition SO3Physics.h:48
std::string node1
Definition SO3Physics.h:50
const SScene * curScene
Definition SO3Physics.h:47
std::string node0
Definition SO3Physics.h:49
Ogre::Real radius
Definition SO3Physics.h:85
Ogre::Real strenght
Definition SO3Physics.h:86
Ogre::Vector3 position
Definition SO3Physics.h:87
Ogre::Vector3 normal
Definition SO3Physics.h:73
Ogre::Real distance
Definition SO3Physics.h:72
SBody * body
Definition SO3Physics.h:71