diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 43e86a30..820688a5 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -12,6 +12,8 @@ using namespace ::Utility::Value; API_Impl API_instance; + + API & API::Instance() { return API_instance; @@ -251,9 +253,73 @@ void API_Impl::ReleaseFromLimbo( const ICustomBody* objRef ) } -void API_Impl::ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void* args, void(hitAction)(ICustomBody*, void*) ) +void API_Impl::ApplyEffect(Oyster::Collision3D::ICollideable* collideable, void* args, EventAction_ApplyEffect effect) { - + btRigidBody* body; + btCollisionShape* shape; + btMotionState* state; + btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(0, NULL, NULL); + + Sphere* sphere; + Box* box; + Cone* cone; + + switch(collideable->type) + { + case ICollideable::Type::Type_sphere: + sphere = dynamic_cast(collideable); + // Add collision shape + shape = new btSphereShape(sphere->radius); + + // Add motion state + state = new btDefaultMotionState(btTransform(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f),btVector3(sphere->center.x, sphere->center.y, sphere->center.z))); + + // Add rigid body + rigidBodyCI = btRigidBody::btRigidBodyConstructionInfo(0, state, shape); + body = new btRigidBody(rigidBodyCI); + + break; + + case ICollideable::Type::Type_box: + box = dynamic_cast(collideable); + // Add collision shape + shape = new btBoxShape(btVector3(box->boundingOffset.x, box->boundingOffset.y, box->boundingOffset.z)); + + // Add motion state + state = new btDefaultMotionState(btTransform(btQuaternion(0.0f, 0.0f, 0.0f, 1.0f),btVector3(box->center.x, box->center.y, box->center.z))); + + // Add rigid body + rigidBodyCI = btRigidBody::btRigidBodyConstructionInfo(0, state, shape); + body = new btRigidBody(rigidBodyCI); + + break; + + case ICollideable::Type::Type_cone: + cone = dynamic_cast(collideable); + // Add collision shape + shape = new btConeShape(cone->radius, cone->height.GetLength()); + + // Add motion state + state = new btDefaultMotionState(btTransform(btQuaternion(btVector3(cone->height.x, cone->height.y, cone->height.z).normalized(), 0.0f),btVector3(cone->position.x, cone->position.y, cone->position.z))); + + // Add rigid body + rigidBodyCI = btRigidBody::btRigidBodyConstructionInfo (0, state, shape); + body = new btRigidBody(rigidBodyCI); + + break; + default: + return; + } + ContactSensorCallback callback(*body, effect, args); + + this->dynamicsWorld->contactTest(body, callback); + + delete state; + state = NULL; + delete shape; + shape = NULL; + delete body; + body = NULL; } namespace Oyster diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h index 3cef6373..c54ebe37 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h @@ -12,6 +12,42 @@ namespace Oyster class API_Impl : public API { public: + struct ContactSensorCallback : public btCollisionWorld::ContactResultCallback + { + ContactSensorCallback(btRigidBody& contactBody, EventAction_ApplyEffect effect, void* args) + : btCollisionWorld::ContactResultCallback(), body(contactBody), func(effect), args(args) {} + + btRigidBody& body; + EventAction_ApplyEffect func; + void* args; + + virtual bool needsCollision(btBroadphaseProxy* proxy) const + { + if(!btCollisionWorld::ContactResultCallback::needsCollision(proxy)) + return false; + + return body.checkCollideWithOverride(static_cast(proxy->m_clientObject)); + } + + virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0, int partId0, int index0, const btCollisionObjectWrapper* colObj1, int partId1, int index1) + { + btVector3 pt; + if(colObj0->m_collisionObject == &body) + { + pt = cp.m_localPointA; + this->func((ICustomBody*)(colObj0->getCollisionObject()->getUserPointer()), this->args); + } + else + { + assert(colObj1->m_collisionObject == &body && "Body does not match either collision object"); + pt = cp.m_localPointB; + this->func((ICustomBody*)(colObj1->getCollisionObject()->getUserPointer()), this->args); + } + + return 0; + } + }; + API_Impl(); virtual ~API_Impl(); @@ -33,7 +69,7 @@ namespace Oyster void UpdateWorld(); - void ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void* args, void(hitAction)(ICustomBody*, void*) ); + void ApplyEffect(Oyster::Collision3D::ICollideable* collideable, void* args, EventAction_ApplyEffect effect); private: btBroadphaseInterface* broadphase; diff --git a/Code/GamePhysics/PhysicsAPI.h b/Code/GamePhysics/PhysicsAPI.h index d971fe79..9fd3722e 100644 --- a/Code/GamePhysics/PhysicsAPI.h +++ b/Code/GamePhysics/PhysicsAPI.h @@ -45,6 +45,7 @@ namespace Oyster typedef Struct::Gravity Gravity; typedef void (*EventAction_Destruction)( ::Utility::DynamicMemory::UniquePointer proto ); + typedef void (*EventAction_ApplyEffect)(ICustomBody* collidedBody, void* args); /** Gets the Physics instance. */ static API & Instance(); @@ -99,7 +100,7 @@ namespace Oyster * @param hitAction: A function that contains the effect. Parameterlist contains the custom body the collideable hits, and the arguments sent to the function. ********************************************************/ - virtual void ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void* args, void(hitAction)(ICustomBody*, void*) ) = 0; + virtual void ApplyEffect(Oyster::Collision3D::ICollideable* collideable, void* args, EventAction_ApplyEffect effect) = 0; protected: virtual ~API() {} diff --git a/Code/OysterPhysics3D/Cone.cpp b/Code/OysterPhysics3D/Cone.cpp new file mode 100644 index 00000000..a336f820 --- /dev/null +++ b/Code/OysterPhysics3D/Cone.cpp @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////// +// Created by Erik Persson 2014 +///////////////////////////////////////////////////////////////////// + +#include "Cone.h" +#include "OysterCollision3D.h" + +using namespace ::Oyster::Collision3D; +using namespace ::Oyster::Math3D; + + +Cone::Cone( ) : ICollideable(Type_cone) +{ + this->radius = 1; + this->height = Oyster::Math::Float3(0,0,0); +} + +Cone::Cone( const ::Oyster::Math::Float3 &height, const Oyster::Math::Float3 &position, const ::Oyster::Math::Float &radius ) +{ + this->radius = radius; + this->height = height; + this->position = position; +} + +Cone::Cone( const ::Oyster::Math::Float4 &height, const Oyster::Math::Float4 &position, const ::Oyster::Math::Float &radius ) +{ + this->radius = radius; + this->height = (Oyster::Math::Float3)height; + this->position = (Oyster::Math::Float3)position; +} + +Cone::~Cone( ) +{ + +} + +Cone & Cone::operator = ( const Cone &cone ) +{ + this->radius = cone.radius; + this->height = cone.height; + this->position = cone.position; + return *this; +} + diff --git a/Code/OysterPhysics3D/Cone.h b/Code/OysterPhysics3D/Cone.h new file mode 100644 index 00000000..0c12201a --- /dev/null +++ b/Code/OysterPhysics3D/Cone.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////// +// Created by Erik Persson 2014 +///////////////////////////////////////////////////////////////////// + +#pragma once +#ifndef OYSTER_COLLISION_3D_CONE_H +#define OYSTER_COLLISION_3D_CONE_H + + +#include "OysterMath.h" +#include "ICollideable.h" + +namespace Oyster +{ + namespace Collision3D + { + class Cone : public ICollideable + { + public: + + Cone(); + Cone( const ::Oyster::Math::Float3 &height, const Oyster::Math::Float3 &position, const ::Oyster::Math::Float &radius ); + Cone( const ::Oyster::Math::Float4 &height, const Oyster::Math::Float4 &position, const ::Oyster::Math::Float &radius ); + virtual ~Cone( ); + + Cone & operator = ( const Cone &Cone ); + + Oyster::Math::Float3 height; + Oyster::Math::Float3 position; + Oyster::Math::Float radius; + }; + } + +} + + + + +#endif \ No newline at end of file diff --git a/Code/OysterPhysics3D/ICollideable.h b/Code/OysterPhysics3D/ICollideable.h index 3e63200e..1caf23cf 100644 --- a/Code/OysterPhysics3D/ICollideable.h +++ b/Code/OysterPhysics3D/ICollideable.h @@ -26,7 +26,8 @@ namespace Oyster { namespace Collision3D //! Contains a collection of 3D shapes Type_box_axis_aligned, Type_box, Type_frustrum, - Type_line + Type_line, + Type_cone, }; const Type type; diff --git a/Code/OysterPhysics3D/OysterCollision3D.h b/Code/OysterPhysics3D/OysterCollision3D.h index 83a6239e..3b1e589f 100644 --- a/Code/OysterPhysics3D/OysterCollision3D.h +++ b/Code/OysterPhysics3D/OysterCollision3D.h @@ -17,6 +17,7 @@ #include "Box.h" #include "Frustrum.h" #include "Line.h" +#include "Cone.h" namespace Oyster { namespace Collision3D { namespace Utility { diff --git a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj index dffeca4f..2998c1bb 100644 --- a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj +++ b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj @@ -154,6 +154,7 @@ + @@ -172,6 +173,7 @@ + diff --git a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters index f6b6d934..4947a4d7 100644 --- a/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters +++ b/Code/OysterPhysics3D/OysterPhysics3D.vcxproj.filters @@ -81,6 +81,9 @@ Header Files\Collision + + Header Files\Collision + @@ -131,5 +134,8 @@ Source Files\Physics + + Source Files\Collision + \ No newline at end of file