From 0838f88dbea0ce645045e1fcf120fe9bec6e0b3d Mon Sep 17 00:00:00 2001 From: Lendemor Date: Wed, 23 Aug 2017 19:39:58 +0200 Subject: [PATCH] improved player control --- src/scene/playercharacternode.cpp | 60 +++++++++++++++++++++++++------ 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/src/scene/playercharacternode.cpp b/src/scene/playercharacternode.cpp index b868a3e..4b2721d 100644 --- a/src/scene/playercharacternode.cpp +++ b/src/scene/playercharacternode.cpp @@ -155,9 +155,10 @@ void PlayerCharacterNode::update() const glm::vec3 &glmDir = m_fpsCamera.getDirection(); const btVector3 &velocity = m_rigidBody->getLinearVelocity(); btVector3 targetVelocity(0.f, velocity.getY(), 0.f); + glm::vec3 moveDir; if(walk != 0 || strafe != 0) { - glm::vec3 moveDir = glm::normalize(glmDir*walk + glm::cross(glmDir, glm::vec3(0, 1, 0))*strafe); + moveDir = glm::normalize(glmDir*walk + glm::cross(glmDir, glm::vec3(0, 1, 0))*strafe); if (m_noclipMode) { btVector3 dir(moveDir.x, moveDir.y, moveDir.z); @@ -182,14 +183,53 @@ void PlayerCharacterNode::update() else { bool onGround = false; - btVector3 start(pos); - start.setY(start.y() - TORSO_HEIGHT/2.f); - btVector3 end(start); - end.setY(end.y() - (LEGS_HEIGHT*2.f)); - btCollisionWorld::ClosestRayResultCallback RayCallback(start, end); - getEngine().getPhysics()->rayTest(start, end, RayCallback); + btVector3 dir(moveDir.x/4,0,moveDir.z/4); + btVector3 start_front(pos+dir); + start_front.setY(pos.y() - TORSO_HEIGHT/2.f); + btVector3 end_front(start_front); + end_front.setY(end_front.y() - (LEGS_HEIGHT*2.f)); + btCollisionWorld::ClosestRayResultCallback RayCallback_front(start_front, end_front); + + btVector3 start_back(pos-dir); + start_back.setY(pos.y() - TORSO_HEIGHT/2.f); + btVector3 end_back(start_back); + end_back.setY(end_back.y() - (LEGS_HEIGHT)); + btCollisionWorld::ClosestRayResultCallback RayCallback_back(start_back, end_back); + + getEngine().getPhysics()->rayTest(start_front, end_front, RayCallback_front); + getEngine().getPhysics()->rayTest(start_back, end_back, RayCallback_back); + float controlRatio = 0.f; // 1 = total control, 0 = no control, can be seen as a slipperiness factor - if(RayCallback.hasHit() ) // if ground is nearby + + if(RayCallback_back.hasHit()){ + onGround = true; + + //btVector3 normal_front = RayCallback_front.m_hitNormalWorld; + btVector3 normal_back = RayCallback_back.m_hitNormalWorld; + + float slope = normal_back.dot(btVector3(0,1,0)); + controlRatio = slope > 0.4f ? 0.2f * slope : 0.f; + + if (RayCallback_front.hasHit()){ + float displacement = RayCallback_front.m_hitPointWorld.y() - (end_front.y() + start_front.y())/2.f; + if(abs(displacement) > 0.1f) + pos.setY(pos.y() + deltaTime*0.01f*(displacement > 0 ? 1 : -1)); + else + pos.setY(pos.y() + displacement/4); + + btTransform transform = btTransform::getIdentity(); + transform.setOrigin(pos); + m_rigidBody->setWorldTransform(transform); + } + + if(jump) + m_jumping = true; + else + m_jumping = false; + + } + + /* if(RayCallback.hasHit() ) // if ground is nearby { onGround = true; btVector3 normal = RayCallback.m_hitNormalWorld; @@ -205,7 +245,7 @@ void PlayerCharacterNode::update() else pos.setY(pos.y() + displacement/4); //} - m_last_displacement = displacement; + //m_last_displacement = displacement; btTransform transform = btTransform::getIdentity(); transform.setOrigin(pos); m_rigidBody->setWorldTransform(transform); @@ -215,7 +255,7 @@ void PlayerCharacterNode::update() else m_jumping = false; } - +*/ btVector3 newVelocity = velocity*(1.f-controlRatio) + targetVelocity*controlRatio; if(onGround) {