2013-11-20 11:09:27 +01:00
|
|
|
#include "PhysicsAPI_Impl.h"
|
2013-11-22 11:52:45 +01:00
|
|
|
#include "OysterPhysics3D.h"
|
2013-11-28 11:58:46 +01:00
|
|
|
#include "SimpleRigidBody.h"
|
|
|
|
#include "SphericalRigidBody.h"
|
2013-11-20 11:09:27 +01:00
|
|
|
|
2014-01-15 10:44:31 +01:00
|
|
|
using namespace ::Oyster;
|
2013-11-21 17:22:13 +01:00
|
|
|
using namespace ::Oyster::Physics;
|
|
|
|
using namespace ::Oyster::Math;
|
|
|
|
using namespace ::Oyster::Collision3D;
|
|
|
|
using namespace ::Utility::DynamicMemory;
|
2013-12-19 10:15:32 +01:00
|
|
|
using namespace ::Utility::Value;
|
2013-11-20 11:09:27 +01:00
|
|
|
|
2013-11-25 16:35:56 +01:00
|
|
|
API_Impl API_instance;
|
2013-11-20 11:09:27 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
API & API::Instance()
|
2013-11-29 09:21:44 +01:00
|
|
|
{
|
2014-02-09 21:24:09 +01:00
|
|
|
return API_instance;
|
|
|
|
}
|
2014-02-06 21:15:28 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
API_Impl::API_Impl()
|
|
|
|
{
|
|
|
|
this->broadphase = NULL;
|
|
|
|
this->collisionConfiguration = NULL;
|
|
|
|
this->dispatcher = NULL;
|
|
|
|
this->solver = NULL;
|
|
|
|
this->dynamicsWorld = NULL;
|
2014-02-11 09:15:21 +01:00
|
|
|
|
|
|
|
this->timeStep = 1.0f/120.0f;
|
2014-02-09 21:24:09 +01:00
|
|
|
}
|
2014-02-06 21:15:28 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
API_Impl::~API_Impl()
|
|
|
|
{
|
|
|
|
delete this->dynamicsWorld;
|
|
|
|
this->dynamicsWorld = NULL;
|
|
|
|
delete this->solver;
|
|
|
|
this->solver = NULL;
|
|
|
|
delete this->dispatcher;
|
|
|
|
this->dispatcher = NULL;
|
|
|
|
delete this->collisionConfiguration;
|
|
|
|
this->collisionConfiguration = NULL;
|
|
|
|
delete this->broadphase;
|
|
|
|
this->broadphase = NULL;
|
2014-02-06 21:15:28 +01:00
|
|
|
|
2014-02-11 09:15:21 +01:00
|
|
|
for(unsigned int i = 0; i < this->customBodies.size(); i++)
|
2014-02-06 21:15:28 +01:00
|
|
|
{
|
2014-02-09 21:24:09 +01:00
|
|
|
delete this->customBodies[i];
|
|
|
|
this->customBodies[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
2014-02-03 10:45:25 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
// Bullet physics
|
2014-02-10 14:18:45 +01:00
|
|
|
ICustomBody* API_Impl::AddCollisionSphere(float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction)
|
2014-02-09 21:24:09 +01:00
|
|
|
{
|
|
|
|
SimpleRigidBody* body = new SimpleRigidBody;
|
2014-02-10 15:46:55 +01:00
|
|
|
SimpleRigidBody::State state;
|
2014-01-22 13:50:54 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
// Add collision shape
|
|
|
|
btCollisionShape* collisionShape = new btSphereShape(radius);
|
|
|
|
body->SetCollisionShape(collisionShape);
|
2014-02-07 15:38:53 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
// Add motion state
|
|
|
|
btDefaultMotionState* motionState = new btDefaultMotionState(btTransform(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w),btVector3(position.x, position.y, position.z)));
|
|
|
|
body->SetMotionState(motionState);
|
2014-01-22 15:29:50 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
// Add rigid body
|
|
|
|
btVector3 fallInertia(0, 0, 0);
|
|
|
|
collisionShape->calculateLocalInertia(mass, fallInertia);
|
|
|
|
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, motionState, collisionShape, fallInertia);
|
|
|
|
btRigidBody* rigidBody = new btRigidBody(rigidBodyCI);
|
2014-02-10 14:22:10 +01:00
|
|
|
rigidBody->setFriction(staticFriction);
|
|
|
|
rigidBody->setRestitution(restitution);
|
2014-02-09 21:24:09 +01:00
|
|
|
rigidBody->setUserPointer(body);
|
|
|
|
body->SetRigidBody(rigidBody);
|
2014-01-29 11:22:04 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
// Add rigid body to world
|
|
|
|
this->dynamicsWorld->addRigidBody(rigidBody);
|
|
|
|
this->customBodies.push_back(body);
|
2013-11-29 09:21:44 +01:00
|
|
|
|
2014-02-10 15:46:55 +01:00
|
|
|
state.centerPos = position;
|
|
|
|
state.reach = Float3(radius, radius, radius);
|
|
|
|
state.dynamicFrictionCoeff = 0.5f;
|
|
|
|
state.staticFrictionCoeff = 0.5f;
|
|
|
|
state.quaternion = Quaternion(Float3(rotation.xyz), rotation.w);
|
|
|
|
state.mass = mass;
|
|
|
|
|
|
|
|
body->SetState(state);
|
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
return body;
|
2013-11-20 11:09:27 +01:00
|
|
|
}
|
2014-02-10 14:18:45 +01:00
|
|
|
|
|
|
|
ICustomBody* API_Impl::AddCollisionBox(Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction)
|
2013-11-28 17:59:12 +01:00
|
|
|
{
|
2014-02-09 21:24:09 +01:00
|
|
|
SimpleRigidBody* body = new SimpleRigidBody;
|
2014-02-10 15:46:55 +01:00
|
|
|
SimpleRigidBody::State state;
|
2013-11-20 11:09:27 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
// Add collision shape
|
|
|
|
btCollisionShape* collisionShape = new btBoxShape(btVector3(halfSize.x, halfSize.y, halfSize.z));
|
|
|
|
body->SetCollisionShape(collisionShape);
|
2013-11-20 11:09:27 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
// Add motion state
|
|
|
|
btDefaultMotionState* motionState = new btDefaultMotionState(btTransform(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w),btVector3(position.x, position.y, position.z)));
|
|
|
|
body->SetMotionState(motionState);
|
2013-11-28 10:26:29 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
// Add rigid body
|
2014-02-10 14:18:45 +01:00
|
|
|
btVector3 fallInertia(0, 0, 0);
|
|
|
|
collisionShape->calculateLocalInertia(mass, fallInertia);
|
|
|
|
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, motionState, collisionShape, fallInertia);
|
|
|
|
btRigidBody* rigidBody = new btRigidBody(rigidBodyCI);
|
2014-02-10 14:22:10 +01:00
|
|
|
rigidBody->setFriction(staticFriction);
|
|
|
|
rigidBody->setRestitution(restitution);
|
2014-02-10 14:18:45 +01:00
|
|
|
rigidBody->setUserPointer(body);
|
|
|
|
body->SetRigidBody(rigidBody);
|
|
|
|
|
|
|
|
// Add rigid body to world
|
|
|
|
this->dynamicsWorld->addRigidBody(rigidBody);
|
|
|
|
this->customBodies.push_back(body);
|
|
|
|
|
2014-02-10 15:46:55 +01:00
|
|
|
state.centerPos = position;
|
|
|
|
state.reach = halfSize;
|
|
|
|
state.dynamicFrictionCoeff = 0.5f;
|
|
|
|
state.staticFrictionCoeff = 0.5f;
|
|
|
|
state.quaternion = Quaternion(Float3(rotation.xyz), rotation.w);
|
|
|
|
state.mass = mass;
|
|
|
|
|
|
|
|
body->SetState(state);
|
|
|
|
|
2014-02-10 14:18:45 +01:00
|
|
|
return body;
|
|
|
|
}
|
|
|
|
|
|
|
|
ICustomBody* API_Impl::AddCollisionCylinder(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction)
|
|
|
|
{
|
|
|
|
SimpleRigidBody* body = new SimpleRigidBody;
|
2014-02-10 15:46:55 +01:00
|
|
|
SimpleRigidBody::State state;
|
2014-02-10 14:18:45 +01:00
|
|
|
|
|
|
|
// Add collision shape
|
|
|
|
btCollisionShape* collisionShape = new btCylinderShape(btVector3(halfSize.x, halfSize.y, halfSize.z));
|
|
|
|
body->SetCollisionShape(collisionShape);
|
|
|
|
|
|
|
|
// Add motion state
|
|
|
|
btDefaultMotionState* motionState = new btDefaultMotionState(btTransform(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w),btVector3(position.x, position.y, position.z)));
|
|
|
|
body->SetMotionState(motionState);
|
|
|
|
|
|
|
|
// Add rigid body
|
2014-02-09 21:24:09 +01:00
|
|
|
btVector3 fallInertia(0, 0, 0);
|
|
|
|
collisionShape->calculateLocalInertia(mass, fallInertia);
|
|
|
|
btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, motionState, collisionShape, fallInertia);
|
|
|
|
btRigidBody* rigidBody = new btRigidBody(rigidBodyCI);
|
2014-02-10 14:22:10 +01:00
|
|
|
rigidBody->setFriction(staticFriction);
|
|
|
|
rigidBody->setRestitution(restitution);
|
2014-02-09 21:24:09 +01:00
|
|
|
rigidBody->setUserPointer(body);
|
|
|
|
body->SetRigidBody(rigidBody);
|
2013-11-28 10:26:29 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
// Add rigid body to world
|
|
|
|
this->dynamicsWorld->addRigidBody(rigidBody);
|
|
|
|
this->customBodies.push_back(body);
|
2014-01-29 12:22:18 +01:00
|
|
|
|
2014-02-10 15:46:55 +01:00
|
|
|
state.centerPos = position;
|
|
|
|
state.reach = halfSize;
|
|
|
|
state.dynamicFrictionCoeff = 0.5f;
|
|
|
|
state.staticFrictionCoeff = 0.5f;
|
|
|
|
state.quaternion = Quaternion(Float3(rotation.xyz), rotation.w);
|
|
|
|
state.mass = mass;
|
|
|
|
|
|
|
|
body->SetState(state);
|
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
return body;
|
2013-11-20 11:09:27 +01:00
|
|
|
}
|
|
|
|
|
2014-02-11 09:15:21 +01:00
|
|
|
void API_Impl::SetTimeStep(float timeStep)
|
|
|
|
{
|
|
|
|
this->timeStep = timeStep;
|
|
|
|
}
|
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
void API_Impl::UpdateWorld()
|
2013-12-20 11:43:12 +01:00
|
|
|
{
|
2014-02-11 09:15:21 +01:00
|
|
|
this->dynamicsWorld->stepSimulation(this->timeStep, 1, this->timeStep);
|
2013-12-20 11:43:12 +01:00
|
|
|
|
2014-02-07 15:38:53 +01:00
|
|
|
ICustomBody::State state;
|
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
for(unsigned int i = 0; i < this->customBodies.size(); i++ )
|
2013-11-29 09:21:44 +01:00
|
|
|
{
|
2014-02-11 09:15:21 +01:00
|
|
|
SimpleRigidBody* simpleBody = dynamic_cast<SimpleRigidBody*>(this->customBodies[i]);
|
2014-02-09 21:24:09 +01:00
|
|
|
btTransform trans;
|
2014-02-11 09:15:21 +01:00
|
|
|
simpleBody->GetMotionState()->getWorldTransform(trans);
|
2014-02-10 14:39:45 +01:00
|
|
|
this->customBodies[i]->SetPosition(Float3(trans.getOrigin().x(), trans.getOrigin().y(), trans.getOrigin().z()));
|
|
|
|
this->customBodies[i]->SetRotation(Quaternion(Float3(trans.getRotation().x(), trans.getRotation().y(), trans.getRotation().z()), trans.getRotation().w()));
|
2014-02-11 10:49:37 +01:00
|
|
|
//simpleBody->SetUpAndRight(Float3(0,1,0), Float3(-1,0,0));
|
2014-02-11 09:15:21 +01:00
|
|
|
if(simpleBody->GetRigidBody()->getActivationState() == ACTIVE_TAG)
|
2014-02-10 13:55:01 +01:00
|
|
|
{
|
2014-02-11 09:15:21 +01:00
|
|
|
simpleBody->CallSubscription_Move();
|
2014-02-10 13:55:01 +01:00
|
|
|
}
|
2013-11-29 09:21:44 +01:00
|
|
|
}
|
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
int numManifolds = this->dynamicsWorld->getDispatcher()->getNumManifolds();
|
2014-02-11 09:15:21 +01:00
|
|
|
for (int i = 0; i < numManifolds; i++)
|
2013-11-29 09:21:44 +01:00
|
|
|
{
|
2014-02-09 21:24:09 +01:00
|
|
|
btPersistentManifold* contactManifold = this->dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);
|
|
|
|
const btCollisionObject* obA = contactManifold->getBody0();
|
|
|
|
const btCollisionObject* obB = contactManifold->getBody1();
|
|
|
|
|
|
|
|
ICustomBody* bodyA = (ICustomBody*)obA->getUserPointer();
|
|
|
|
ICustomBody* bodyB = (ICustomBody*)obB->getUserPointer();
|
|
|
|
|
2014-02-10 13:55:01 +01:00
|
|
|
dynamic_cast<SimpleRigidBody*>(bodyA)->CallSubscription_AfterCollisionResponse(bodyA, bodyB, 0.0f);
|
|
|
|
dynamic_cast<SimpleRigidBody*>(bodyB)->CallSubscription_AfterCollisionResponse(bodyB, bodyA, 0.0f);
|
2013-11-29 09:21:44 +01:00
|
|
|
}
|
2013-11-20 11:09:27 +01:00
|
|
|
|
2013-11-21 17:22:13 +01:00
|
|
|
}
|
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
void API_Impl::Init()
|
2013-11-20 11:09:27 +01:00
|
|
|
{
|
2014-02-09 21:24:09 +01:00
|
|
|
this->broadphase = new btDbvtBroadphase();
|
|
|
|
this->collisionConfiguration = new btDefaultCollisionConfiguration();
|
|
|
|
this->dispatcher = new btCollisionDispatcher(this->collisionConfiguration);
|
|
|
|
this->solver = new btSequentialImpulseConstraintSolver;
|
|
|
|
this->dynamicsWorld = new btDiscreteDynamicsWorld(this->dispatcher,this->broadphase,this->solver,this->collisionConfiguration);
|
|
|
|
this->dynamicsWorld->setGravity(btVector3(0,-10,0));
|
2013-11-20 11:09:27 +01:00
|
|
|
}
|
|
|
|
|
2013-11-21 17:22:13 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
bool API_Impl::IsInLimbo( const ICustomBody* objRef )
|
2013-11-21 17:22:13 +01:00
|
|
|
{
|
2014-02-09 21:24:09 +01:00
|
|
|
return true;
|
2013-11-21 17:22:13 +01:00
|
|
|
}
|
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
void API_Impl::MoveToLimbo( const ICustomBody* objRef )
|
2014-01-15 10:44:31 +01:00
|
|
|
{
|
2014-02-09 21:24:09 +01:00
|
|
|
|
2014-01-15 10:44:31 +01:00
|
|
|
}
|
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
void API_Impl::ReleaseFromLimbo( const ICustomBody* objRef )
|
2014-01-15 10:44:31 +01:00
|
|
|
{
|
2014-02-09 21:24:09 +01:00
|
|
|
|
2014-01-15 10:44:31 +01:00
|
|
|
}
|
|
|
|
|
2014-01-28 10:18:26 +01:00
|
|
|
void API_Impl::ApplyEffect( const Oyster::Collision3D::ICollideable& collideable, void* args, void(hitAction)(ICustomBody*, void*) )
|
2014-01-21 14:10:31 +01:00
|
|
|
{
|
2014-02-09 21:24:09 +01:00
|
|
|
|
2014-01-21 14:10:31 +01:00
|
|
|
}
|
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
namespace Oyster
|
|
|
|
{
|
|
|
|
namespace Physics
|
2013-11-28 17:59:12 +01:00
|
|
|
{
|
2014-02-09 21:24:09 +01:00
|
|
|
namespace Default
|
|
|
|
{
|
|
|
|
void EventAction_Destruction( ::Utility::DynamicMemory::UniquePointer<::Oyster::Physics::ICustomBody> proto )
|
|
|
|
{ /* Do nothing except allowing the proto uniquePointer destroy itself. */ }
|
2013-11-28 10:26:29 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
::Oyster::Physics::ICustomBody::SubscriptMessage EventAction_BeforeCollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter )
|
|
|
|
{ /* Do nothing except returning business as usual. */
|
|
|
|
return ::Oyster::Physics::ICustomBody::SubscriptMessage_none;
|
|
|
|
}
|
2014-01-17 16:07:25 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
void EventAction_AfterCollisionResponse( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter, ::Oyster::Math::Float kineticEnergyLoss )
|
2014-02-11 09:15:21 +01:00
|
|
|
{ /* Do nothing except returning business as usual. */ }
|
2014-01-22 13:50:54 +01:00
|
|
|
|
2014-02-09 21:24:09 +01:00
|
|
|
void EventAction_Move( const ::Oyster::Physics::ICustomBody *object )
|
|
|
|
{ /* Do nothing. */ }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|