From ff951d21834e938978b8e8aff13da45314b71890 Mon Sep 17 00:00:00 2001 From: Robin Engman Date: Thu, 13 Feb 2014 19:49:33 +0100 Subject: [PATCH] Moving fixed Jumping and waiting for camera is next --- Code/Game/GameLogic/Level.cpp | 2 +- Code/Game/GameLogic/Player.cpp | 62 +++-- Code/Game/GameLogic/Player.h | 9 +- Code/GamePhysics/GamePhysics.vcxproj | 6 - Code/GamePhysics/GamePhysics.vcxproj.filters | 18 -- Code/GamePhysics/Implementation/Octree.cpp | 226 ------------------ Code/GamePhysics/Implementation/Octree.h | 85 ------- .../Implementation/PhysicsAPI_Impl.cpp | 52 +++- .../Implementation/PhysicsAPI_Impl.h | 3 +- .../Implementation/SimpleRigidBody.cpp | 77 +++++- .../Implementation/SimpleRigidBody.h | 15 +- .../Implementation/SphericalRigidBody.cpp | 0 .../Implementation/SphericalRigidBody.h | 0 Code/GamePhysics/PhysicsAPI.h | 12 +- Code/GamePhysics/PhysicsFormula-Impl.h | 82 ------- Code/GamePhysics/PhysicsFormula.h | 35 --- 16 files changed, 188 insertions(+), 496 deletions(-) delete mode 100644 Code/GamePhysics/Implementation/Octree.cpp delete mode 100644 Code/GamePhysics/Implementation/Octree.h delete mode 100644 Code/GamePhysics/Implementation/SphericalRigidBody.cpp delete mode 100644 Code/GamePhysics/Implementation/SphericalRigidBody.h delete mode 100644 Code/GamePhysics/PhysicsFormula-Impl.h delete mode 100644 Code/GamePhysics/PhysicsFormula.h diff --git a/Code/Game/GameLogic/Level.cpp b/Code/Game/GameLogic/Level.cpp index 15d855c3..2289b85b 100644 --- a/Code/Game/GameLogic/Level.cpp +++ b/Code/Game/GameLogic/Level.cpp @@ -181,7 +181,7 @@ void Level::InitiateLevel(float radius) this->staticObjects[0]->objectID = idCount++; // add jumppad - ICustomBody* rigidBody_Jumppad = API::Instance().AddCollisionBox(Oyster::Math::Float3(1, 1, 1), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(4, 600.3, 0), 5, 0.5f, 0.8f, 0.6f); + ICustomBody* rigidBody_Jumppad = API::Instance().AddCollisionBox(Oyster::Math::Float3(1, 1, 1), Oyster::Math::Float4(0, 0, 0, 1), Oyster::Math::Float3(4, 600.3, 0), 0, 0.5f, 0.8f, 0.6f); this->staticObjects.Push(new JumpPad(rigidBody_Jumppad, JumpPad::JumpPadActivated, OBJECT_TYPE::OBJECT_TYPE_JUMPPAD, Oyster::Math::Float3(0,2000,0))); rigidBody_Jumppad->SetCustomTag(this->staticObjects[1]); diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 90f2c66b..19a0bb9c 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -47,11 +47,15 @@ void Player::InitPlayer() this->teamID = -1; this->playerState = PLAYER_STATE_IDLE; this->lookDir = Oyster::Math::Float3(0,0,-1); - this->moveDir = Oyster::Math::Float3(0,0,0); key_forward = 0; key_backward = 0; key_strafeRight = 0; key_strafeLeft = 0; + + this->moveDir = Oyster::Math::Float3(0,0,0); + this->moveSpeed = 100; + this->previousMoveSpeed = Oyster::Math::Float3(0,0,0); + } Player::~Player(void) @@ -67,48 +71,60 @@ void Player::BeginFrame() { //weapon->Update(0.002f); Object::BeginFrame(); - Oyster::Math::Float3 forward(0,0,0); - Oyster::Math::Float3 back(0,0,0); - Oyster::Math::Float3 right(0,0,0); - Oyster::Math::Float3 left(0,0,0); - Oyster::Math::Float3 moveDirection(0,0,0); + + if(this->moveDir != Oyster::Math::Float3::null) + { + Oyster::Math::Float3 velocity = this->rigidBody->GetLinearVelocity(); + Oyster::Math::Float3 lostVelocity = (this->previousMoveSpeed - velocity).GetMagnitude()*this->moveDir; + this->rigidBody->SetLinearVelocity(velocity + lostVelocity - this->moveDir*this->moveSpeed ); + } + + this->moveDir = Oyster::Math::Float3::null; + if (key_forward > 0.001) { key_forward -= gameInstance->GetFrameTime(); // fixed timer - forward = this->rigidBody->GetState().GetOrientation().v[2].GetNormalized(); + this->moveDir += this->rigidBody->GetState().GetOrientation().v[2].GetNormalized().xyz; } if (key_backward > 0.001) { key_backward -= gameInstance->GetFrameTime(); - back = -this->rigidBody->GetState().GetOrientation().v[2].GetNormalized(); + this->moveDir -= this->rigidBody->GetState().GetOrientation().v[2].GetNormalized().xyz; } if (key_strafeRight > 0.001) { - key_strafeRight -= gameInstance->GetFrameTime(); - Oyster::Math::Float3 forward = this->rigidBody->GetState().GetOrientation().v[2].GetNormalized(); - Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos.Normalize(); - right = -((up).Cross(forward).Normalize()); - right.Normalize(); + Oyster::Math::Float3 forward = this->rigidBody->GetState().GetOrientation().v[2]; + Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos; + this->moveDir -= (up).Cross(forward).GetNormalized(); } if (key_strafeLeft > 0.001) { key_strafeLeft -= gameInstance->GetFrameTime(); - Oyster::Math::Float3 forward = this->rigidBody->GetState().GetOrientation().v[2].GetNormalized(); - Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos.Normalize(); - left = (up).Cross(forward).Normalize(); - left.Normalize(); + Oyster::Math::Float3 forward = this->rigidBody->GetState().GetOrientation().v[2]; + Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos; + this->moveDir += (up).Cross(forward).GetNormalized(); } - moveDirection = forward + back + left + right; - //moveDirection.Normalize(); - rigidBody->SetLinearVelocity( MOVE_FORCE * moveDirection ); - weapon->Update(0.01f); + if(this->moveDir != Oyster::Math::Float3::null) + { + this->moveDir.Normalize(); + this->rigidBody->SetLinearVelocity(this->moveDir*this->moveSpeed + this->rigidBody->GetLinearVelocity()); + this->previousMoveSpeed = this->rigidBody->GetLinearVelocity(); + } + + + this->weapon->Update(0.01f); } void Player::EndFrame() { // snap to axis + Oyster::Math::Float4 rotation; + + this->rigidBody->SetUp(this->rigidBody->GetState().centerPos.GetNormalized()); + + Object::EndFrame(); } @@ -176,7 +192,6 @@ void Player::Rotate(const Oyster::Math3D::Float3 lookDir, const Oyster::Math3D:: Oyster::Math::Float3 up = this->rigidBody->GetState().GetOrientation().v[1]; this->rigidBody->SetUpAndRight(up, right); - this->rigidBody->SetUpAndRight(this->rigidBody->GetState().centerPos.GetNormalized(), this->rigidBody->GetState().GetOrientation().v[0].xyz.GetNormalized()); } void Player::Jump() @@ -231,5 +246,4 @@ void Player::DamageLife(int damage) playerState = PLAYER_STATE_DEAD; this->gameInstance->onDisableFnc(this, 0.0f); } -} - +} \ No newline at end of file diff --git a/Code/Game/GameLogic/Player.h b/Code/Game/GameLogic/Player.h index d2adb4be..bdd83f41 100644 --- a/Code/Game/GameLogic/Player.h +++ b/Code/Game/GameLogic/Player.h @@ -75,7 +75,6 @@ namespace GameLogic void EndFrame(); static Oyster::Physics::ICustomBody::SubscriptMessage PlayerCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss); - private: void Jump(); @@ -84,7 +83,6 @@ namespace GameLogic int teamID; Weapon *weapon; PLAYER_STATE playerState; - Oyster::Math::Float3 moveDir; Oyster::Math::Float3 lookDir; float key_forward; float key_backward; @@ -92,9 +90,14 @@ namespace GameLogic float key_strafeLeft; float key_jump; + + Oyster::Math::Float3 moveDir; + Oyster::Math::Float moveSpeed; + Oyster::Math::Float3 previousMoveSpeed; + + bool hasTakenDamage; float invincibleCooldown; - }; } #endif \ No newline at end of file diff --git a/Code/GamePhysics/GamePhysics.vcxproj b/Code/GamePhysics/GamePhysics.vcxproj index 9b883bb3..475a05f9 100644 --- a/Code/GamePhysics/GamePhysics.vcxproj +++ b/Code/GamePhysics/GamePhysics.vcxproj @@ -165,22 +165,16 @@ - - - - - - diff --git a/Code/GamePhysics/GamePhysics.vcxproj.filters b/Code/GamePhysics/GamePhysics.vcxproj.filters index aa3cbd73..5a3c6fb2 100644 --- a/Code/GamePhysics/GamePhysics.vcxproj.filters +++ b/Code/GamePhysics/GamePhysics.vcxproj.filters @@ -30,24 +30,12 @@ Header Files\Implementation - - Header Files\Implementation - - - Header Files\Implementation - Header Files\Include Header Files\Include - - Header Files\Include - - - Header Files\Include - @@ -59,11 +47,5 @@ Source Files - - Source Files - - - Source Files - \ No newline at end of file diff --git a/Code/GamePhysics/Implementation/Octree.cpp b/Code/GamePhysics/Implementation/Octree.cpp deleted file mode 100644 index 4778e5f1..00000000 --- a/Code/GamePhysics/Implementation/Octree.cpp +++ /dev/null @@ -1,226 +0,0 @@ -#include "Octree.h" - -using namespace Oyster; -using namespace Physics; -using namespace ::Utility::DynamicMemory; - -const unsigned int Octree::invalid_ref = ::Utility::Value::numeric_limits::max(); - -Octree::Octree(unsigned int bufferSize, unsigned char numLayers, Math::Float3 worldSize) -{ - this->worldNode.dataPtr = NULL; - - this->worldNode.container.maxVertex = worldSize*0.5f; - this->worldNode.container.minVertex = -worldSize*0.5f; -} - -Octree::~Octree() -{ - -} - -Octree& Octree::operator=(const Octree& orig) -{ - this->leafData = orig.leafData; - this->updateQueue = orig.updateQueue; - this->worldNode = orig.worldNode; - this->mapReferences = orig.mapReferences; - - return *this; -} - -void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef) -{ - //customBodyRef->SetScene( this ); - Data data; - //Data* tempPtr = this->worldNode.dataPtr; - - //data.container = customBodyRef->GetBoundingSphere(); - data.queueRef = -1; - data.next = NULL; - data.prev = NULL; - data.customBodyRef = customBodyRef; - data.limbo = false; - this->mapReferences.insert(std::pair (data.customBodyRef, this->leafData.size())); - this->leafData.push_back(data); - - /*if(tempPtr != NULL) - { - tempPtr->prev->next = &this->leafData[this->leafData.size() - 1]; - this->leafData[this->leafData.size() - 1].prev = tempPtr->prev; - tempPtr->prev = &this->leafData[this->leafData.size() - 1]; - this->leafData[this->leafData.size() - 1].next = tempPtr; - } - else - { - this->worldNode.dataPtr = &this->leafData[this->leafData.size() - 1]; - this->worldNode.dataPtr->next = this->worldNode.dataPtr; - this->worldNode.dataPtr->prev = this->worldNode.dataPtr; - }*/ -} - -void Octree::MoveToUpdateQueue(UniquePointer< ICustomBody > customBodyRef) -{ - /*this->leafData[this->mapReferences[customBodyRef]].queueRef = this->updateQueue.size(); - this->updateQueue.push_back(&this->leafData[this->mapReferences[customBodyRef]]);*/ -} - -void Octree::MoveToLimbo(const ICustomBody* customBodyRef) -{ - auto object = this->mapReferences.find(customBodyRef); - - unsigned int tempRef = object->second; - - this->leafData[tempRef].limbo = true; -} - -bool Octree::IsInLimbo(const ICustomBody* customBodyRef) -{ - auto object = this->mapReferences.find(customBodyRef); - - unsigned int tempRef = object->second; - - return this->leafData[tempRef].limbo; -} - -void Octree::ReleaseFromLimbo(const ICustomBody* customBodyRef) -{ - auto object = this->mapReferences.find(customBodyRef); - - unsigned int tempRef = object->second; - - this->leafData[tempRef].limbo = false; -} - -void Octree::DestroyObject(UniquePointer< ICustomBody > customBodyRef) -{ - std::map::iterator it = this->mapReferences.find(customBodyRef); - - this->mapReferences.erase(it); - - this->leafData.erase(this->leafData.begin() + this->leafData[this->mapReferences[customBodyRef]].queueRef); -} - -std::vector& Octree::Sample(ICustomBody* customBodyRef, std::vector& updateList) -{ - auto object = this->mapReferences.find(customBodyRef); - - if(object == this->mapReferences.end()) - { - return updateList; - } - - unsigned int tempRef = object->second; - - for(unsigned int i = 0; ileafData.size(); i++) - { - if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container)) - { - updateList.push_back(this->leafData[i].customBodyRef); - } - } - - return updateList; -} - -std::vector& Octree::Sample(const Oyster::Collision3D::ICollideable& collideable, std::vector& updateList) -{ - for(unsigned int i = 0; ileafData.size(); i++) - { - if(!this->leafData[i].limbo && this->leafData[i].container.Intersects(collideable)) - { - updateList.push_back(this->leafData[i].customBodyRef); - } - } - - return updateList; -} - -void Octree::Visit(ICustomBody* customBodyRef, VisitorAction hitAction ) -{ - auto object = this->mapReferences.find(customBodyRef); - - // If rigid body is not found - if(object == this->mapReferences.end()) - { - return; - } - - unsigned int tempRef = object->second; - - // Go through all object and test for intersection - for(unsigned int i = 0; ileafData.size(); i++) - { - // If objects intersect call collision response function - if(tempRef != i && !this->leafData[i].limbo) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container)) - { - hitAction(*this, tempRef, i); - } - } -} - -void Octree::Visit(const Oyster::Collision3D::ICollideable& collideable, void* args, VisitorActionCollideable hitAction) -{ - for(unsigned int i = 0; ileafData.size(); i++) - { - if(!this->leafData[i].limbo && collideable.Intersects(this->leafData[i].container)) - { - hitAction( this->GetCustomBody(i), args ); - } - } -} - -ICustomBody* Octree::GetCustomBody(const unsigned int tempRef) -{ - return this->leafData[tempRef].customBodyRef; -} - -UniquePointer Octree::Extract( const ICustomBody* objRef ) -{ // Dan Andersson - auto iter = this->mapReferences.find( objRef ); - if( iter != this->mapReferences.end() ) - { - return this->Extract( iter->second ); - } - else - { - return NULL; - } -} - -UniquePointer Octree::Extract( unsigned int tempRef ) -{ - if( tempRef != Octree::invalid_ref ) - { - //! @todo TODO: implement stub - return NULL; - } - else - { - return NULL; - } -} - -unsigned int Octree::GetTemporaryReferenceOf( const ICustomBody* objRef ) const -{ // Dan Andersson - auto iter = this->mapReferences.find( objRef ); - if( iter != this->mapReferences.end() ) - { - return iter->second; - } - else - { - return Octree::invalid_ref; - } -} - -void Octree::SetAsAltered( unsigned int tempRef ) -{ - //this->leafData[tempRef].container = this->leafData[tempRef].customBodyRef->GetBoundingSphere(); - //! @todo TODO: implement stub -} - -void Octree::EvaluatePosition( unsigned int tempRef ) -{ - //! @todo TODO: implement stub -} \ No newline at end of file diff --git a/Code/GamePhysics/Implementation/Octree.h b/Code/GamePhysics/Implementation/Octree.h deleted file mode 100644 index 573738f2..00000000 --- a/Code/GamePhysics/Implementation/Octree.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef OCTREE_H -#define OCTREE_H - -#include -#include -#include "Sphere.h" -#include "BoxAxisAligned.h" -#include "Utilities.h" -#include "../PhysicsAPI.h" - -namespace Oyster -{ - namespace Physics - { - class Octree - { - public: - static const unsigned int invalid_ref; - - typedef void(*VisitorAction)(Octree&, unsigned int, unsigned int); - typedef void(*VisitorActionCollideable)(ICustomBody*, void*); - - struct Data - { - Data* prev; - Data* next; - - Collision3D::Sphere container; - - ::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef; - - bool limbo; - - unsigned int queueRef; - }; - - struct OctreeNode - { - OctreeNode* children[8]; - Data* dataPtr; - Collision3D::BoxAxisAligned container; - }; - - Octree(unsigned int bufferSize = 0, unsigned char numLayers = 0, Math::Float3 worldSize = Math::Float3::null); - virtual ~Octree(); - - Octree& operator=(const Octree& orig); - - void AddObject(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef); - - void MoveToUpdateQueue(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef); - - void MoveToLimbo(const ICustomBody* customBodyRef); - bool IsInLimbo(const ICustomBody* customBodyRef); - void ReleaseFromLimbo(const ICustomBody* customBodyRef); - - void DestroyObject(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef); - - std::vector& Sample(ICustomBody* customBodyRef, std::vector& updateList); - std::vector& Sample(const Oyster::Collision3D::ICollideable& collideable, std::vector& updateList); - void Visit(ICustomBody* customBodyRef, VisitorAction hitAction ); - void Visit(const Oyster::Collision3D::ICollideable& collideable, void* args, VisitorActionCollideable hitAction ); - - ICustomBody* GetCustomBody(const unsigned int tempRef); - - ::Utility::DynamicMemory::UniquePointer Extract( const ICustomBody* objRef ); - ::Utility::DynamicMemory::UniquePointer Extract( unsigned int tempRef ); // Dan vill ha - unsigned int GetTemporaryReferenceOf( const ICustomBody* objRef ) const; // Dan vill ha - void SetAsAltered( unsigned int tempRef ); // Dan vill ha - void EvaluatePosition( unsigned int tempRef ); // Dan vill ha - - private: - std::vector < Data > leafData; - std::vector < Data* > updateQueue; - std::vector < Data* > limbo; - - std::map< const ICustomBody*, unsigned int > mapReferences; - - OctreeNode worldNode; - }; - } - -} - -#endif \ No newline at end of file diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index 26da0998..b3ad6777 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -1,7 +1,6 @@ #include "PhysicsAPI_Impl.h" #include "OysterPhysics3D.h" #include "SimpleRigidBody.h" -#include "SphericalRigidBody.h" using namespace ::Oyster; using namespace ::Oyster::Physics; @@ -181,6 +180,47 @@ ICustomBody* API_Impl::AddCollisionCylinder(::Oyster::Math::Float3 halfSize, ::O return body; } +ICustomBody* API_Impl::AddCharacter(::Oyster::Math::Float height, ::Oyster::Math::Float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) +{ + SimpleRigidBody* body = new SimpleRigidBody; + SimpleRigidBody::State state; + + // Add collision shape + btCapsuleShape* collisionShape = new btCapsuleShape(radius, height); + 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 + btVector3 fallInertia(0, 0, 0); + collisionShape->calculateLocalInertia(mass, fallInertia); + btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(mass, motionState, collisionShape, fallInertia); + btRigidBody* rigidBody = new btRigidBody(rigidBodyCI); + rigidBody->setFriction(staticFriction); + rigidBody->setRestitution(restitution); + rigidBody->setUserPointer(body); + rigidBody->setAngularFactor(0); + rigidBody->setSleepingThresholds(0, 0); + body->SetRigidBody(rigidBody); + + // Add rigid body to world + this->dynamicsWorld->addRigidBody(rigidBody); + this->customBodies.push_back(body); + + state.centerPos = position; + state.reach = Float3(radius, height*0.5f, radius); + state.dynamicFrictionCoeff = 0.5f; + state.staticFrictionCoeff = 0.5f; + state.quaternion = Quaternion(Float3(rotation.xyz), rotation.w); + state.mass = mass; + + body->SetState(state); + + return body; +} + void API_Impl::SetTimeStep(float timeStep) { this->timeStep = timeStep; @@ -204,11 +244,11 @@ void API_Impl::UpdateWorld() trans = simpleBody->GetRigidBody()->getWorldTransform(); 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())); - + if(simpleBody->GetRigidBody()->getActivationState() == ACTIVE_TAG) { - simpleBody->CallSubscription_Move(); - } + this->customBodies[i]->CallSubscription_Move(); + } } int numManifolds = this->dynamicsWorld->getDispatcher()->getNumManifolds(); @@ -221,8 +261,8 @@ void API_Impl::UpdateWorld() ICustomBody* bodyA = (ICustomBody*)obA->getUserPointer(); ICustomBody* bodyB = (ICustomBody*)obB->getUserPointer(); - dynamic_cast(bodyA)->CallSubscription_AfterCollisionResponse(bodyA, bodyB, 0.0f); - dynamic_cast(bodyB)->CallSubscription_AfterCollisionResponse(bodyB, bodyA, 0.0f); + bodyA->CallSubscription_AfterCollisionResponse(bodyA, bodyB, 0.0f); + bodyB->CallSubscription_AfterCollisionResponse(bodyB, bodyA, 0.0f); } } diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h index 422e82ef..002cb039 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.h @@ -2,7 +2,6 @@ #define PHYSICS_API_IMPL_H #include "../PhysicsAPI.h" -#include "Octree.h" #include namespace Oyster @@ -65,6 +64,8 @@ namespace Oyster ICustomBody* AddCollisionBox(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction); ICustomBody* AddCollisionCylinder(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction); + ICustomBody* AddCharacter(::Oyster::Math::Float height, ::Oyster::Math::Float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction); + void SetTimeStep(float timeStep); void UpdateWorld(); diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index 5670d32b..81d58f5b 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -139,6 +139,46 @@ void SimpleRigidBody::SetRotation(Float3 eulerAngles) this->state.quaternion = Quaternion(Float3(trans.getRotation().x(), trans.getRotation().y(), trans.getRotation().z()), trans.getRotation().w()); } +void SimpleRigidBody::SetRotation(::Oyster::Math::Float4x4 rotation) +{ + btTransform trans; + btMatrix3x3 newRotation; + btVector3 rightVector(rotation.v[0].x, rotation.v[0].y, rotation.v[0].z); + btVector3 upVector(rotation.v[1].x, rotation.v[1].y, rotation.v[1].z); + btVector3 forwardVector(rotation.v[2].x, rotation.v[2].y, rotation.v[2].z); + + + newRotation[0] = rightVector; + newRotation[1] = upVector; + newRotation[2] = forwardVector; + + trans = this->rigidBody->getWorldTransform(); + trans.setBasis(newRotation); + this->rigidBody->setWorldTransform(trans); + + btQuaternion quaternion; + quaternion = trans.getRotation(); + this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w()); +} + +void SimpleRigidBody::SetRotationAsAngularAxis(::Oyster::Math::Float4 angularAxis) +{ + if(angularAxis.xyz.GetMagnitude() == 0) + { + return; + } + + btTransform trans; + btVector3 vector(angularAxis.x, angularAxis.y, angularAxis.z); + btQuaternion quaternion(vector, angularAxis.w); + + trans = this->rigidBody->getWorldTransform(); + trans.setRotation(quaternion); + this->rigidBody->setWorldTransform(trans); + + this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w()); +} + void SimpleRigidBody::SetAngularFactor(Float factor) { this->rigidBody->setAngularFactor(factor); @@ -177,7 +217,7 @@ void SimpleRigidBody::SetUpAndForward(::Oyster::Math::Float3 up, ::Oyster::Math: btVector3 forwardVector(forward.x, forward.y, forward.z); rotation[1] = upVector.normalized(); rotation[2] = forwardVector.normalized(); - rotation[0] = forwardVector.cross(upVector).normalized(); + rotation[0] = upVector.cross(forwardVector).normalized(); trans = this->rigidBody->getWorldTransform(); trans.setBasis(rotation); this->rigidBody->setWorldTransform(trans); @@ -187,6 +227,27 @@ void SimpleRigidBody::SetUpAndForward(::Oyster::Math::Float3 up, ::Oyster::Math: this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w()); } +void SimpleRigidBody::SetUp(::Oyster::Math::Float3 up) +{ + Float3 vector = Float3(0, 1, 0).Cross(up); + + if(vector == Float3::null) + { + return; + } + + Float sine = vector.GetLength(); + Float cosine = acos(Float3(0, 1, 0).Dot(up)); + + btQuaternion quaternion(btVector3(vector.x, vector.y, vector.z),cosine); + + btTransform trans; + trans = this->rigidBody->getWorldTransform(); + trans.setRotation(quaternion); + this->rigidBody->setWorldTransform(trans); + this->state.quaternion = Quaternion(Float3(quaternion.x(), quaternion.y(), quaternion.z()), quaternion.w()); +} + Float4x4 SimpleRigidBody::GetRotation() const { return this->state.GetRotation(); @@ -229,6 +290,16 @@ Float4x4 SimpleRigidBody::GetView( const ::Oyster::Math::Float3 &offset ) const return this->state.GetView(offset); } +Float3 SimpleRigidBody::GetGravity() const +{ + return this->rigidBody->getGravity(); +} +Float3 SimpleRigidBody::GetLinearVelocity() const +{ + return this->rigidBody->getLinearVelocity(); +} + + void SimpleRigidBody::CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Oyster::Math::Float kineticEnergyLoss) { if(this->afterCollision) @@ -265,6 +336,4 @@ void * SimpleRigidBody::GetCustomTag() const void SimpleRigidBody::SetCustomTag( void *ref ) { this->customTag = ref; -} - - +} \ No newline at end of file diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.h b/Code/GamePhysics/Implementation/SimpleRigidBody.h index 3663c45c..ec162860 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.h +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.h @@ -19,10 +19,6 @@ namespace Oyster void SetState( const State &state ); void ApplyImpulse(Math::Float3 impulse); - - void SetCollisionShape(btCollisionShape* shape); - void SetMotionState(btDefaultMotionState* motionState); - void SetRigidBody(btRigidBody* rigidBody); void SetSubscription(EventAction_AfterCollisionResponse function); void SetSubscription(EventAction_Move function); @@ -32,12 +28,15 @@ namespace Oyster void SetRotation(Math::Float4 quaternion); void SetRotation(Math::Quaternion quaternion); void SetRotation(Math::Float3 eulerAngles); + void SetRotation(::Oyster::Math::Float4x4 rotation); + void SetRotationAsAngularAxis(::Oyster::Math::Float4 angularAxis); void SetAngularFactor(Math::Float factor); void SetGravity(Math::Float3 gravity); void SetUpAndRight(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 right); void SetUpAndForward(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 forward); + void SetUp(::Oyster::Math::Float3 up); Math::Float4x4 GetRotation() const; Math::Float4 GetRotationAsAngularAxis(); @@ -45,6 +44,9 @@ namespace Oyster Math::Float4x4 GetView() const; Math::Float4x4 GetView( const ::Oyster::Math::Float3 &offset ) const; + Math::Float3 GetGravity() const; + ::Oyster::Math::Float3 GetLinearVelocity() const; + void CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Math::Float kineticEnergyLoss); void CallSubscription_Move(); @@ -55,6 +57,11 @@ namespace Oyster void SetCustomTag( void *ref ); void* GetCustomTag() const; + // Class specific + void SetCollisionShape(btCollisionShape* shape); + void SetMotionState(btDefaultMotionState* motionState); + void SetRigidBody(btRigidBody* rigidBody); + private: btCollisionShape* collisionShape; diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.cpp b/Code/GamePhysics/Implementation/SphericalRigidBody.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/Code/GamePhysics/Implementation/SphericalRigidBody.h b/Code/GamePhysics/Implementation/SphericalRigidBody.h deleted file mode 100644 index e69de29b..00000000 diff --git a/Code/GamePhysics/PhysicsAPI.h b/Code/GamePhysics/PhysicsAPI.h index 9fd3722e..25cb7610 100644 --- a/Code/GamePhysics/PhysicsAPI.h +++ b/Code/GamePhysics/PhysicsAPI.h @@ -87,6 +87,8 @@ namespace Oyster virtual ICustomBody* AddCollisionBox(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0; virtual ICustomBody* AddCollisionCylinder(::Oyster::Math::Float3 halfSize, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0; + virtual ICustomBody* AddCharacter(::Oyster::Math::Float height, ::Oyster::Math::Float radius, ::Oyster::Math::Float4 rotation, ::Oyster::Math::Float3 position, float mass, float restitution, float staticFriction, float dynamicFriction) = 0; + virtual void SetTimeStep(float timeStep) = 0; virtual void UpdateWorld() = 0; @@ -142,12 +144,15 @@ namespace Oyster virtual void SetRotation(::Oyster::Math::Float4 quaternion) = 0; virtual void SetRotation(::Oyster::Math::Quaternion quaternion) = 0; virtual void SetRotation(::Oyster::Math::Float3 eulerAngles) = 0; + virtual void SetRotation(::Oyster::Math::Float4x4 rotation) = 0; + virtual void SetRotationAsAngularAxis(::Oyster::Math::Float4 angularAxis) = 0; virtual void SetAngularFactor(::Oyster::Math::Float factor) = 0; virtual void SetGravity(::Oyster::Math::Float3 gravity) = 0; virtual void SetUpAndRight(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 right) = 0; virtual void SetUpAndForward(::Oyster::Math::Float3 up, ::Oyster::Math::Float3 forward) = 0; + virtual void SetUp(::Oyster::Math::Float3 up) = 0; virtual ::Oyster::Math::Float4x4 GetRotation() const = 0; virtual ::Oyster::Math::Float4 GetRotationAsAngularAxis() = 0; @@ -155,6 +160,12 @@ namespace Oyster virtual ::Oyster::Math::Float4x4 GetView() const = 0; virtual ::Oyster::Math::Float4x4 GetView(const ::Oyster::Math::Float3 &offset) const = 0; + virtual ::Oyster::Math::Float3 GetGravity() const = 0; + virtual ::Oyster::Math::Float3 GetLinearVelocity() const = 0; + + virtual void CallSubscription_AfterCollisionResponse(ICustomBody* bodyA, ICustomBody* bodyB, Math::Float kineticEnergyLoss) = 0; + virtual void CallSubscription_Move() = 0; + /******************************************************** * @return the void pointer set by SetCustomTag. * nullptr if none is set. @@ -172,6 +183,5 @@ namespace Oyster } #include "PhysicsStructs.h" -#include "PhysicsFormula.h" #endif \ No newline at end of file diff --git a/Code/GamePhysics/PhysicsFormula-Impl.h b/Code/GamePhysics/PhysicsFormula-Impl.h deleted file mode 100644 index 189691f6..00000000 --- a/Code/GamePhysics/PhysicsFormula-Impl.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef PHYSICS_FORMULA_IMPL_H -#define PHYSICS_FORMULA_IMPL_H - -#include "PhysicsFormula.h" -#include "OysterPhysics3D.h" - -namespace Oyster { namespace Physics { namespace Formula -{ - namespace MomentOfInertia - { - inline ::Oyster::Math::Float4x4 CreateSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ) - { - return ::Oyster::Physics3D::Formula::MomentOfInertia::Sphere(mass, radius); - } - - inline ::Oyster::Math::Float4x4 CreateHollowSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ) - { - return ::Oyster::Physics3D::Formula::MomentOfInertia::HollowSphere(mass, radius); - } - - inline ::Oyster::Math::Float4x4 CreateCuboidMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float width, const ::Oyster::Math::Float depth ) - { - return ::Oyster::Physics3D::Formula::MomentOfInertia::Cuboid(mass, height, width, depth); - } - - inline ::Oyster::Math::Float4x4 CreateCylinderMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius ) - { - return ::Oyster::Physics3D::Formula::MomentOfInertia::Cylinder(mass, height, radius); - } - - inline ::Oyster::Math::Float4x4 CreateRodMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length ) - { - return ::Oyster::Physics3D::Formula::MomentOfInertia::RodCenter(mass, length); - } - } - - namespace CollisionResponse - { - inline ::Oyster::Math::Float Bounce( ::Oyster::Math::Float e, ::Oyster::Math::Float mA, ::Oyster::Math::Float gA, ::Oyster::Math::Float mB, ::Oyster::Math::Float gB ) - { - //return (e + 1) * (mB*gA - mA*gB) / (mA + mB); - return (e + 1) * (mA*gB - mB*gA) / (mA + mB); - } - - inline ::Oyster::Math::Float4 Friction( ::Oyster::Math::Float i, ::Oyster::Math::Float4 iN, ::Oyster::Math::Float4 momA, ::Oyster::Math::Float sFA, ::Oyster::Math::Float dFA, ::Oyster::Math::Float mA, ::Oyster::Math::Float4 momB, ::Oyster::Math::Float sFB, ::Oyster::Math::Float dFB, ::Oyster::Math::Float mB ) - { - // FRICTION - // Relative momentum after normal impulse - ::Oyster::Math::Float4 relativeMomentum = momB - momA; - - ::Oyster::Math::Float4 tanFriction = relativeMomentum - relativeMomentum.Dot( iN ) * iN; - - if( tanFriction.Dot(tanFriction) > 0.0f ) - { // no friction if moving directly into surface, or not at all. - tanFriction.Normalize(); - - ::Oyster::Math::Float magnitudeFriction = -relativeMomentum.Dot( tanFriction ); - magnitudeFriction = magnitudeFriction * mA * mB / ( mA + mB ); - - ::Oyster::Math::Float mu = 0.5f * ( sFA + sFB ); - - ::Oyster::Math::Float4 frictionImpulse; - if( abs(magnitudeFriction) < i * mu ) - { - frictionImpulse = magnitudeFriction * tanFriction; - } - else - { - ::Oyster::Math::Float dynamicFriction = 0.5f * ( dFA + dFB ); - frictionImpulse = ( -i * dynamicFriction ) * tanFriction; - } - - return ( 1 / mA ) * frictionImpulse; - } - else - return ::Oyster::Math::Float4::null; - } - } - -} } } - -#endif \ No newline at end of file diff --git a/Code/GamePhysics/PhysicsFormula.h b/Code/GamePhysics/PhysicsFormula.h deleted file mode 100644 index fe91ae3a..00000000 --- a/Code/GamePhysics/PhysicsFormula.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef PHYSICS_FORMULA_H -#define PHYSICS_FORMULA_H - -#include "OysterMath.h" -#include "OysterPhysics3D.h" - -namespace Oyster { namespace Physics { namespace Formula -{ - namespace MomentOfInertia - { - ::Oyster::Math::Float4x4 CreateSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ); - ::Oyster::Math::Float4x4 CreateHollowSphereMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float radius ); - ::Oyster::Math::Float4x4 CreateCuboidMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float width, const ::Oyster::Math::Float depth ); - ::Oyster::Math::Float4x4 CreateCylinderMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float height, const ::Oyster::Math::Float radius ); - ::Oyster::Math::Float4x4 CreateRodMatrix( const ::Oyster::Math::Float mass, const ::Oyster::Math::Float length ); - } - - namespace CollisionResponse - { - ::Oyster::Math::Float Bounce( ::Oyster::Math::Float coeffOfRestitution, - ::Oyster::Math::Float massA, ::Oyster::Math::Float momentumA, - ::Oyster::Math::Float massB, ::Oyster::Math::Float momentumB ); - - ::Oyster::Math::Float4 Friction( ::Oyster::Math::Float impulse, ::Oyster::Math::Float4 impulseNormal, - ::Oyster::Math::Float4 momentumA, ::Oyster::Math::Float staticFrictionA, - ::Oyster::Math::Float dynamicFrictionA, ::Oyster::Math::Float massA, - ::Oyster::Math::Float4 momentumB, ::Oyster::Math::Float staticFrictionB, - ::Oyster::Math::Float dynamicFrictionB, ::Oyster::Math::Float massB ); - - } -} } } - -#include "PhysicsFormula-Impl.h" - -#endif \ No newline at end of file