NLS Engine  v0.1
The Next Logical Step in game engine design.
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines
PhysicsModuleCollisions.cpp
Go to the documentation of this file.
00001 
00011 #pragma once
00012 
00013 #include "PhysicsModule.h"
00014 
00015 // System Library Includes
00016 
00017 // Application Library Includes
00018 #include <boost/foreach.hpp>
00019 
00020 // Local Includes
00021 #include "../sharedbase/MessageRouter.h"
00022 #include "../sharedbase/EntityList.h"
00023 #include "../sharedbase/Envelope.h"
00024 #include "component/InterfaceCollider.h"
00025 #include "Messages.h"
00026 
00027 // Classes
00028 namespace Physics {
00029   /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
00030   void PhysicsModule::ReportCollisions() const {
00031     InterfaceCollider* collider_left;
00032     InterfaceCollider* collider_right;
00033     BoundingSphere object_left;
00034     BoundingSphere object_right;
00035     Vector3D penetration;
00036     float seperation_sq;
00037     float penetration_sq;
00038     
00039     Threading::ReadLock r_lock(this->collidableObjectsMutex);
00040     
00041     // Broadphase collision detection
00042     for (CollidableListType::iterator collider_iterator_left = this->collidableObjects.begin(); collider_iterator_left != this->collidableObjects.end(); ++collider_iterator_left) {
00043       CollidableListType::iterator collider_iterator_right = collider_iterator_left;
00044       for (++collider_iterator_right; collider_iterator_right != this->collidableObjects.end(); ++collider_iterator_right) {
00045         collider_left = *collider_iterator_left;
00046         collider_right = *collider_iterator_right;
00047         
00048         // It should be impossible to collide an object with itself, but just to make sure...
00049         if (collider_left != collider_right) {
00050           
00051           // Using the sphere test as we currently only have spherical colliders.
00052           object_left = collider_left->GetBoundingSphere();
00053           object_right = collider_right->GetBoundingSphere();
00054           
00055           penetration = object_right.center - object_left.center;
00056           
00057           seperation_sq = D3DXVec3LengthSq(&penetration);
00058           
00059           penetration_sq = seperation_sq - (object_right.radius * object_right.radius + object_left.radius * object_left.radius);
00060           
00061           if (penetration_sq < 0.0f) {
00062             // *TODO: do a fine-phase collision, maybe only storing the possible collisions in a set or list of some kind so that the fine phase can be done in later code.
00063             
00064             // *HACK: Treating broadphase as fine phase and jumping the gun.
00065             D3DXVec3Normalize(&penetration, &penetration);
00066             penetration *= sqrt(-penetration_sq);
00067             
00068             EntitySPTR left_ent(collider_left->GetOwnerEntity());
00069             EntitySPTR right_ent(collider_right->GetOwnerEntity());
00070             
00071             std::string left_name = this->elist->FindName(left_ent);
00072             std::string right_name = this->elist->FindName(right_ent);
00073             
00074             EnvelopeSPTR envelope(new Envelope);
00075             envelope->msgid = MSG_ENTITY_COLLISION;
00076             envelope->AddData(left_name);
00077             envelope->AddData(right_name);
00078             envelope->AddData(penetration);
00079             this->msgrouter->SendSP(envelope);
00080           }
00081         }
00082       }
00083     }
00084     
00085   }
00086 }