diff --git a/Code/Game/GameLogic/AttatchmentMassDriver.cpp b/Code/Game/GameLogic/AttatchmentMassDriver.cpp index a2002566..9a90a524 100644 --- a/Code/Game/GameLogic/AttatchmentMassDriver.cpp +++ b/Code/Game/GameLogic/AttatchmentMassDriver.cpp @@ -104,10 +104,13 @@ void AttatchmentMassDriver::ForcePush(const GameLogic::WEAPON_FIRE &usage, float Oyster::Math::Float4x4 hitSpace = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/8,1,1,50); Oyster::Collision3D::Frustrum hitFrustum = Oyster::Collision3D::Frustrum(Oyster::Math3D::ViewProjectionMatrix(aim,hitSpace)); + + + Oyster::Collision3D::Cone *hitCone; forcePushData args; args.pushForce = pushForce; - Oyster::Physics::API::Instance().ApplyEffect(hitFrustum,&args,ForcePushAction); + //Oyster::Physics::API::Instance().ApplyEffect(hitFrustum,&args,ForcePushAction); } /******************************************************** @@ -126,7 +129,7 @@ void AttatchmentMassDriver::ForceZip(const WEAPON_FIRE &usage, float dt) void AttatchmentMassDriver::ForcePull(const WEAPON_FIRE &usage, float dt) { - if(hasObject) return; //this test checks if the weapon already has something picked up, if so then it cant use this function + //if(hasObject) return; //this test checks if the weapon already has something picked up, if so then it cant use this function PickUpObject(usage,dt); //first test if there is a nearby object to pickup @@ -142,19 +145,15 @@ void AttatchmentMassDriver::ForcePull(const WEAPON_FIRE &usage, float dt) forcePushData args; args.pushForce = -pushForce; - Oyster::Physics::API::Instance().ApplyEffect(hitFrustum,&args,ForcePushAction); + //Oyster::Physics::API::Instance().ApplyEffect(hitFrustum,&args,ForcePushAction); } void AttatchmentMassDriver::PickUpObject(const WEAPON_FIRE &usage, float dt) { Oyster::Math::Float3 pos = owner->GetPosition() + owner->GetLookDir().GetNormalized()*5; - Oyster::Collision3D::Sphere hitSphere = Oyster::Collision3D::Sphere(pos,20); - /*Oyster::Math::Float4x4 aim = Oyster::Math3D::ViewMatrix_LookAtDirection(owner->GetLookDir(), owner->GetRigidBody()->GetGravityNormal(), owner->GetPosition()); - - Oyster::Math::Float4x4 hitSpace = Oyster::Math3D::ProjectionMatrix_Perspective(Oyster::Math::pi/4,1,1,20); - Oyster::Collision3D::Frustrum hitFrustum = Oyster::Collision3D::Frustrum(Oyster::Math3D::ViewProjectionMatrix(aim,hitSpace)); -*/ - + Oyster::Collision3D::Sphere *hitSphere = new Oyster::Collision3D::Sphere(pos,20); Oyster::Physics::API::Instance().ApplyEffect(hitSphere,this,AttemptPickUp); + + delete hitSphere; } 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..c2e3d5ea 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*)(colObj1->getCollisionObject()->getUserPointer()), this->args); + } + else + { + assert(colObj1->m_collisionObject == &body && "Body does not match either collision object"); + pt = cp.m_localPointB; + this->func((ICustomBody*)(colObj0->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/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index 58f598ed..7cd2f2b6 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -67,6 +67,11 @@ void SimpleRigidBody::SetState( const SimpleRigidBody::State &state ) this->state = state; } +void SimpleRigidBody::ApplyImpulse(Float3 impulse) +{ + this->rigidBody->applyImpulse(btVector3(impulse.x, impulse.y, impulse.z), btVector3(0.0f, 0.0f, 0.0f)); +} + void SimpleRigidBody::SetCollisionShape(btCollisionShape* shape) { this->collisionShape = shape; diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.h b/Code/GamePhysics/Implementation/SimpleRigidBody.h index 039345eb..3663c45c 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.h +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.h @@ -18,6 +18,8 @@ namespace Oyster State& GetState( State &targetMem ) const; void SetState( const State &state ); + void ApplyImpulse(Math::Float3 impulse); + void SetCollisionShape(btCollisionShape* shape); void SetMotionState(btDefaultMotionState* motionState); void SetRigidBody(btRigidBody* rigidBody); diff --git a/Code/GamePhysics/PhysicsAPI.h b/Code/GamePhysics/PhysicsAPI.h index 46f663d7..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() {} @@ -134,6 +135,8 @@ namespace Oyster virtual void SetSubscription(EventAction_AfterCollisionResponse function) = 0; virtual void SetSubscription(EventAction_Move function) = 0; + virtual void ApplyImpulse(::Oyster::Math::Float3 impulse) = 0; + virtual void SetLinearVelocity(::Oyster::Math::Float3 velocity) = 0; virtual void SetPosition(::Oyster::Math::Float3 position) = 0; virtual void SetRotation(::Oyster::Math::Float4 quaternion) = 0; 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