diff --git a/rwengine/include/engine/GameObject.hpp b/rwengine/include/engine/GameObject.hpp index 08ca4237..46c418b0 100644 --- a/rwengine/include/engine/GameObject.hpp +++ b/rwengine/include/engine/GameObject.hpp @@ -45,7 +45,7 @@ public: */ float mHealth; - bool _inWater; + bool inWater; /** * @brief stores the height of water at the last tick @@ -60,7 +60,7 @@ public: GameObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, ModelRef model) : _lastPosition(pos), _lastRotation(rot), position(pos), rotation(rot), model(model), engine(engine), animator(nullptr), skeleton(nullptr), mHealth(0.f), - _inWater(false), _lastHeight(std::numeric_limits::max()), visible(true), + inWater(false), _lastHeight(std::numeric_limits::max()), visible(true), lifetime(GameObject::UnknownLifetime) {} @@ -139,7 +139,7 @@ public: virtual bool isAnimationFixed() const { return true; } - virtual bool isInWater() const { return _inWater; } + virtual bool isInWater() const { return inWater; } virtual void tick(float dt) = 0; diff --git a/rwengine/src/objects/CharacterObject.cpp b/rwengine/src/objects/CharacterObject.cpp index 3e9c4ef7..1ec0d05b 100644 --- a/rwengine/src/objects/CharacterObject.cpp +++ b/rwengine/src/objects/CharacterObject.cpp @@ -230,7 +230,15 @@ void CharacterObject::updateCharacter(float dt) float wh = engine->gameData.waterHeights[wi]; auto ws = getPosition(); wh += engine->gameData.getWaveHeightAt(ws); - if( ws.z < wh ) { + + // If Not in water before + // If last position was above water + // Now Underwater + // Else Not Underwater + // Else + // Underwater + + if( ! inWater && ws.z < wh && _lastHeight > wh ) { ws.z = wh; btVector3 bpos(ws.x, ws.y, ws.z); @@ -240,13 +248,14 @@ void CharacterObject::updateCharacter(float dt) physObject->setWorldTransform(wt); physCharacter->setGravity(0.f); - _inWater = true; + inWater = true; } else { physCharacter->setGravity(9.81f); - _inWater = false; + inWater = false; } } + _lastHeight = getPosition().z; } } diff --git a/rwengine/src/objects/InstanceObject.cpp b/rwengine/src/objects/InstanceObject.cpp index 13e2ba4f..794455fe 100644 --- a/rwengine/src/objects/InstanceObject.cpp +++ b/rwengine/src/objects/InstanceObject.cpp @@ -65,19 +65,19 @@ void InstanceObject::tick(float dt) wH = engine->gameData.waterHeights[hI]; wH += engine->gameData.getWaveHeightAt(ws); if( vH <= wH ) { - _inWater = true; + inWater = true; } else { - _inWater = false; + inWater = false; } } else { - _inWater = false; + inWater = false; } } _lastHeight = ws.z; - if( _inWater ) { + if( inWater ) { float oZ = -(body->collisionHeight * (dynamics->bouancy/100.f)); body->body->activate(true); // Damper motion diff --git a/rwengine/src/objects/VehicleObject.cpp b/rwengine/src/objects/VehicleObject.cpp index d49ce251..b8d1e0dd 100644 --- a/rwengine/src/objects/VehicleObject.cpp +++ b/rwengine/src/objects/VehicleObject.cpp @@ -245,24 +245,24 @@ void VehicleObject::tickPhysics(float dt) // and was not underwater here in the last tick if( _lastHeight >= wH ) { // we are for real, underwater - _inWater = true; + inWater = true; } - else if( _inWater == false ) { + else if( inWater == false ) { // It's just a tunnel or something, we good. - _inWater = false; + inWater = false; } } else { // The water is beneath us - _inWater = false; + inWater = false; } } else { - _inWater = false; + inWater = false; } } - if( _inWater ) { + if( inWater ) { // Ensure that vehicles don't fall asleep at the top of a wave. if(! physBody->isActive() ) { diff --git a/rwgame/RWGame.cpp b/rwgame/RWGame.cpp index 477b68cf..d977e91d 100644 --- a/rwgame/RWGame.cpp +++ b/rwgame/RWGame.cpp @@ -108,6 +108,8 @@ RWGame::RWGame(const std::string& gamepath, int argc, char* argv[]) std::string name = "radar" + num + std::to_string(m); engine->gameData.loadTXD(name + ".txd"); } + + getRenderer()->water.setWaterTable(engine->gameData.waterHeights, 48, engine->gameData.realWater, 128*128); auto loading = new LoadingState(this); if( newgame ) diff --git a/rwgame/ingamestate.cpp b/rwgame/ingamestate.cpp index 2f3b00ff..8122eb81 100644 --- a/rwgame/ingamestate.cpp +++ b/rwgame/ingamestate.cpp @@ -117,6 +117,15 @@ void IngameState::tick(float dt) _lookAngles.x += deltaMouse.x / 100.0; _lookAngles.y += deltaMouse.y / 100.0; + + while(_lookAngles.x > glm::pi()) + { + _lookAngles.x -= 2.f * glm::pi(); + } + while(_lookAngles.x < -glm::pi()) + { + _lookAngles.x += 2.f * glm::pi(); + } if (_lookAngles.y > qpi) _lookAngles.y = qpi; @@ -153,9 +162,38 @@ void IngameState::tick(float dt) float speed = vehicle->physVehicle->getCurrentSpeedKmHour(); if( autolookTimer <= 0.f && std::abs(speed) > 1.f ) { - float d = glm::sign(speed) > 0.f ? 0.f : glm::radians(180.f); - auto atrophy = std::min(1.f * glm::sign(_lookAngles.x - d) * dt, _lookAngles.x - d); - _lookAngles.x -= atrophy; + float b = glm::roll(vehicle->getRotation()) + glm::half_pi(); + while( b > glm::pi() ) + { + b -= 2.f * glm::pi(); + } + while( b < -glm::pi() ) + { + b += 2.f * glm::pi(); + } + if( speed < 0.f ) + { + if( _lookAngles.x < 0.f ) + { + b -= glm::pi(); + } + else + { + b += glm::pi(); + } + } + + float aD = b - _lookAngles.x; + const float rotateSpeed = 1.f; + if( std::abs(aD) <= rotateSpeed * dt ) + { + _lookAngles.x = b; + } + else + { + _lookAngles.x += glm::sign(aD) * rotateSpeed * dt; + } + angle = glm::angleAxis(_lookAngles.x, glm::vec3(0.f, 0.f, 1.f)); } } diff --git a/rwgame/ingamestate.hpp b/rwgame/ingamestate.hpp index 947dffc7..5692f3cd 100644 --- a/rwgame/ingamestate.hpp +++ b/rwgame/ingamestate.hpp @@ -10,8 +10,10 @@ class IngameState : public State bool started; bool test; ViewCamera _look; + /** Player input */ glm::vec2 _lookAngles; glm::vec3 _movement; + /** Timer to reset _lookAngles to forward in vehicles */ float autolookTimer; public: IngameState(RWGame* game, bool test = false);