From a42dfe96f15c235941775d60eb8924cd8106565a Mon Sep 17 00:00:00 2001 From: Robin Engman Date: Fri, 14 Feb 2014 11:52:44 +0100 Subject: [PATCH] Jump implemented --- Code/Game/GameLogic/Game_PlayerData.cpp | 2 +- Code/Game/GameLogic/Player.cpp | 44 +++++++++++--- Code/Game/GameLogic/Player.h | 1 + .../Implementation/PhysicsAPI_Impl.cpp | 6 +- .../Implementation/SimpleRigidBody.cpp | 57 +++++++++++++++++++ .../Implementation/SimpleRigidBody.h | 12 +++- Code/GamePhysics/PhysicsAPI.h | 2 + Code/GamePhysics/PhysicsStructs-Impl.h | 4 +- Code/GamePhysics/PhysicsStructs.h | 1 + 9 files changed, 116 insertions(+), 13 deletions(-) diff --git a/Code/Game/GameLogic/Game_PlayerData.cpp b/Code/Game/GameLogic/Game_PlayerData.cpp index 56df13c4..1719da4a 100644 --- a/Code/Game/GameLogic/Game_PlayerData.cpp +++ b/Code/Game/GameLogic/Game_PlayerData.cpp @@ -15,7 +15,7 @@ Game::PlayerData::PlayerData() //sbDesc.quaternion = Oyster::Math::Float3(0, Oyster::Math::pi, 0); //create rigid body - Oyster::Physics::ICustomBody* rigidBody = Oyster::Physics::API::Instance().AddCollisionBox(size, Oyster::Math::Float4(0, 0, 0, 1), centerPosition, mass, 0.5f, 0.8f, 0.6f ); + Oyster::Physics::ICustomBody* rigidBody = Oyster::Physics::API::Instance().AddCharacter(1.5f, 0.5f, Oyster::Math::Float4(0, 0, 0, 1), centerPosition, mass, 0.5f, 0.8f, 0.6f ); rigidBody->SetAngularFactor(0.0f); //create player with this rigid body this->player = new Player(rigidBody, Player::PlayerCollision, OBJECT_TYPE::OBJECT_TYPE_PLAYER); diff --git a/Code/Game/GameLogic/Player.cpp b/Code/Game/GameLogic/Player.cpp index 19a0bb9c..9a780d76 100644 --- a/Code/Game/GameLogic/Player.cpp +++ b/Code/Game/GameLogic/Player.cpp @@ -52,6 +52,7 @@ void Player::InitPlayer() key_strafeRight = 0; key_strafeLeft = 0; + this->previousPosition = Oyster::Math::Float3(0,0,0); this->moveDir = Oyster::Math::Float3(0,0,0); this->moveSpeed = 100; this->previousMoveSpeed = Oyster::Math::Float3(0,0,0); @@ -72,12 +73,34 @@ void Player::BeginFrame() //weapon->Update(0.002f); Object::BeginFrame(); - if(this->moveDir != Oyster::Math::Float3::null) + //Oyster::Math::Float3 previousFall = this->previousMoveSpeed*-this->rigidBody->GetState().centerPos.GetNormalized(); + //Oyster::Math::Float3 currentFall = this->rigidBody->GetLinearVelocity()*-this->rigidBody->GetState().centerPos.GetNormalized(); + + if(this->moveDir != Oyster::Math::Float3::null && this->playerState != PLAYER_STATE_JUMPING) { 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 ); } + else + { + + if(this->rigidBody->GetLamda() == 1.0f) + { + this->playerState = PLAYER_STATE_WALKING; + } + + if(this->moveDir != Oyster::Math::Float3::null) + { + Oyster::Math::Float3 velocity = this->rigidBody->GetLinearVelocity(); + this->rigidBody->SetLinearVelocity(velocity - this->moveDir*this->moveSpeed ); + } + } + + if(this->rigidBody->GetLamda() == 1.0f) + { + this->playerState = PLAYER_STATE_WALKING; + } this->moveDir = Oyster::Math::Float3::null; @@ -109,10 +132,12 @@ void Player::BeginFrame() 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->rigidBody->SetLinearVelocity(this->moveDir*this->moveSpeed + this->rigidBody->GetLinearVelocity()); } + this->previousMoveSpeed = this->rigidBody->GetLinearVelocity(); + this->previousPosition = this->rigidBody->GetState().centerPos; + this->weapon->Update(0.01f); } @@ -190,15 +215,18 @@ void Player::Rotate(const Oyster::Math3D::Float3 lookDir, const Oyster::Math3D:: // this is the camera right vector this->lookDir = lookDir; - Oyster::Math::Float3 up = this->rigidBody->GetState().GetOrientation().v[1]; - this->rigidBody->SetUpAndRight(up, right); + //Oyster::Math::Float3 up = this->rigidBody->GetState().GetOrientation().v[1]; + //this->rigidBody->SetUpAndRight(up, right); } void Player::Jump() { - Oyster::Math::Float3 up = this->rigidBody->GetState().GetOrientation().v[1].GetNormalized(); - this->rigidBody->ApplyImpulse(up *1500); - this->playerState == PLAYER_STATE::PLAYER_STATE_JUMPING; + if(this->rigidBody->GetLamda() < 1.0f) + { + Oyster::Math::Float3 up = this->rigidBody->GetState().GetOrientation().v[1].GetNormalized(); + this->rigidBody->ApplyImpulse(up *1500); + this->playerState = PLAYER_STATE::PLAYER_STATE_JUMPING; + } } bool Player::IsWalking() diff --git a/Code/Game/GameLogic/Player.h b/Code/Game/GameLogic/Player.h index bdd83f41..b9ba7c05 100644 --- a/Code/Game/GameLogic/Player.h +++ b/Code/Game/GameLogic/Player.h @@ -91,6 +91,7 @@ namespace GameLogic float key_jump; + Oyster::Math::Float3 previousPosition; Oyster::Math::Float3 moveDir; Oyster::Math::Float moveSpeed; Oyster::Math::Float3 previousMoveSpeed; diff --git a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp index b3ad6777..9cd87d1d 100644 --- a/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp +++ b/Code/GamePhysics/Implementation/PhysicsAPI_Impl.cpp @@ -210,7 +210,7 @@ ICustomBody* API_Impl::AddCharacter(::Oyster::Math::Float height, ::Oyster::Math this->customBodies.push_back(body); state.centerPos = position; - state.reach = Float3(radius, height*0.5f, radius); + state.reach = Float3(radius, height, radius); state.dynamicFrictionCoeff = 0.5f; state.staticFrictionCoeff = 0.5f; state.quaternion = Quaternion(Float3(rotation.xyz), rotation.w); @@ -230,7 +230,9 @@ void API_Impl::UpdateWorld() { for(unsigned int i = 0; i < this->customBodies.size(); i++ ) { - this->customBodies[i]->SetGravity(-(this->customBodies[i]->GetState().centerPos - this->gravityPoint).GetNormalized()*this->gravity); + SimpleRigidBody* simpleBody = dynamic_cast(this->customBodies[i]); + this->customBodies[i]->SetGravity(-(this->customBodies[i]->GetState().centerPos - this->gravityPoint).GetNormalized()*this->gravity); + simpleBody->PreStep(this->dynamicsWorld); } this->dynamicsWorld->stepSimulation(this->timeStep, 1, this->timeStep); diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp index 3d9fbc4f..cd0c1962 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.cpp +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.cpp @@ -344,4 +344,61 @@ void * SimpleRigidBody::GetCustomTag() const void SimpleRigidBody::SetCustomTag( void *ref ) { this->customTag = ref; +} + + +void SimpleRigidBody::PreStep (const btCollisionWorld* collisionWorld) +{ + btTransform xform; + this->rigidBody->getMotionState()->getWorldTransform (xform); + btVector3 down = -xform.getBasis()[1]; + btVector3 forward = xform.getBasis()[2]; + down.normalize (); + forward.normalize(); + + this->raySource[0] = xform.getOrigin(); + this->raySource[1] = xform.getOrigin(); + + this->rayTarget[0] = this->raySource[0] + down * this->state.reach.y * btScalar(1.1); + this->rayTarget[1] = this->raySource[1] + forward * this->state.reach.y * btScalar(1.1); + + class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback + { + public: + ClosestNotMe (btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) + { + m_me = me; + } + + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) + { + if (rayResult.m_collisionObject == m_me) + return 1.0; + + return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace); + } + protected: + btRigidBody* m_me; + }; + + ClosestNotMe rayCallback(this->rigidBody); + + int i = 0; + for (i = 0; i < 2; i++) + { + rayCallback.m_closestHitFraction = 1.0; + if((this->raySource[i] - this->rayTarget[i]).length() != 0) + collisionWorld->rayTest (this->raySource[i], this->rayTarget[i], rayCallback); + if (rayCallback.hasHit()) + { + this->rayLambda[i] = rayCallback.m_closestHitFraction; + } else { + this->rayLambda[i] = 1.0; + } + } +} + +float SimpleRigidBody::GetLamda() const +{ + return this->rayLambda[0]; } \ No newline at end of file diff --git a/Code/GamePhysics/Implementation/SimpleRigidBody.h b/Code/GamePhysics/Implementation/SimpleRigidBody.h index d08fd886..d67393d1 100644 --- a/Code/GamePhysics/Implementation/SimpleRigidBody.h +++ b/Code/GamePhysics/Implementation/SimpleRigidBody.h @@ -58,11 +58,17 @@ namespace Oyster void SetCustomTag( void *ref ); void* GetCustomTag() const; + + // Class specific void SetCollisionShape(btCollisionShape* shape); void SetMotionState(btDefaultMotionState* motionState); void SetRigidBody(btRigidBody* rigidBody); + void PreStep(const btCollisionWorld* collisionWorld); + + float GetLamda() const; + private: btCollisionShape* collisionShape; @@ -76,7 +82,11 @@ namespace Oyster void *customTag; - ::Oyster::Math::Float3 gravity; + Math::Float3 gravity; + + btVector3 raySource[2]; + btVector3 rayTarget[2]; + btScalar rayLambda[2]; }; } } diff --git a/Code/GamePhysics/PhysicsAPI.h b/Code/GamePhysics/PhysicsAPI.h index 1c220d3e..e83f1d99 100644 --- a/Code/GamePhysics/PhysicsAPI.h +++ b/Code/GamePhysics/PhysicsAPI.h @@ -179,6 +179,8 @@ namespace Oyster * @param ref: Anything castable to a void pointer, the engine won't care. ********************************************************/ virtual void SetCustomTag( void *ref ) = 0; + + virtual float GetLamda() const = 0; }; } } diff --git a/Code/GamePhysics/PhysicsStructs-Impl.h b/Code/GamePhysics/PhysicsStructs-Impl.h index 07ba0bb2..87cfcb17 100644 --- a/Code/GamePhysics/PhysicsStructs-Impl.h +++ b/Code/GamePhysics/PhysicsStructs-Impl.h @@ -10,9 +10,10 @@ namespace Oyster { namespace Struct { - inline CustomBodyState::CustomBodyState( ::Oyster::Math::Float mass, ::Oyster::Math::Float restitutionCoeff, ::Oyster::Math::Float staticFrictionCoeff, ::Oyster::Math::Float dynamicFrictionCoeff, const ::Oyster::Math::Float3 ¢erPos, const ::Oyster::Math::Quaternion& quaternion) + inline CustomBodyState::CustomBodyState( ::Oyster::Math::Float mass, ::Oyster::Math::Float3 reach, ::Oyster::Math::Float restitutionCoeff, ::Oyster::Math::Float staticFrictionCoeff, ::Oyster::Math::Float dynamicFrictionCoeff, const ::Oyster::Math::Float3 ¢erPos, const ::Oyster::Math::Quaternion& quaternion) { this->mass = mass; + this->reach = reach; this->restitutionCoeff = restitutionCoeff; this->staticFrictionCoeff = staticFrictionCoeff; this->dynamicFrictionCoeff = dynamicFrictionCoeff; @@ -24,6 +25,7 @@ namespace Oyster { this->mass = state.mass; this->restitutionCoeff = state.restitutionCoeff; + this->reach = state.reach; this->staticFrictionCoeff = state.staticFrictionCoeff; this->dynamicFrictionCoeff = state.dynamicFrictionCoeff; this->centerPos = state.centerPos; diff --git a/Code/GamePhysics/PhysicsStructs.h b/Code/GamePhysics/PhysicsStructs.h index fa6c023c..2f369b90 100644 --- a/Code/GamePhysics/PhysicsStructs.h +++ b/Code/GamePhysics/PhysicsStructs.h @@ -16,6 +16,7 @@ namespace Oyster public: // Default constructor CustomBodyState( ::Oyster::Math::Float mass = 1.0f, + ::Oyster::Math::Float3 reach = ::Oyster::Math::Float3(0,0,0), ::Oyster::Math::Float restitutionCoeff = 0.5f, ::Oyster::Math::Float staticFrictionCoeff = 1.0f, ::Oyster::Math::Float dynamicFrictionCoeff = 1.0f,