From b434e516f0d7e4db44a24f2cdffdb572a222ad1c Mon Sep 17 00:00:00 2001 From: Sergey Lapin Date: Mon, 1 Sep 2025 12:32:34 +0300 Subject: [PATCH] Removed separate controller class --- Game.cpp | 93 +++++++++++++++++++--- src/characters/controller.cpp | 112 -------------------------- src/characters/controller.h | 146 ---------------------------------- src/gamedata/GameData.cpp | 44 +++++++++- src/gamedata/GameData.h | 2 + 5 files changed, 128 insertions(+), 269 deletions(-) delete mode 100644 src/characters/controller.cpp delete mode 100644 src/characters/controller.h diff --git a/Game.cpp b/Game.cpp index 8d3fd02..8d1664a 100644 --- a/Game.cpp +++ b/Game.cpp @@ -269,6 +269,11 @@ class App : public OgreBites::ApplicationContext { public Ogre::FrameListener { App *mApp; + uint32_t control; + ECS::Vector2 mouse{ 0, 0 }; + float wheel_y; + bool mouse_moved = false, wheel_moved = false; + public: bool gui_active; Ogre::Timer fps_timer; @@ -293,26 +298,71 @@ class App : public OgreBites::ApplicationContext { mApp->setWindowGrab(false); return true; } + OgreBites::Keycode key = evt.keysym.sym; + if (key == 'w') + control |= 1; + else if (key == 'a') + control |= 2; + else if (key == 's') + control |= 4; + else if (key == 'd') + control |= 8; + else if (key == OgreBites::SDLK_LSHIFT) + control |= 16; + if (key == 'w' || key == 'a' || key == 's' || + key == 'd' || key == OgreBites::SDLK_LSHIFT) + return true; return false; } bool keyReleased(const OgreBites::KeyboardEvent &evt) override { + OgreBites::Keycode key = evt.keysym.sym; if (gui_active) return false; + if (key == 'w') + control &= ~1; + else if (key == 'a') + control &= ~2; + else if (key == 's') + control &= ~4; + else if (key == 'd') + control &= ~8; + else if (key == OgreBites::SDLK_LSHIFT) + control &= ~16; + if (key == 'w' || key == 'a' || key == 's' || + key == 'd' || key == OgreBites::SDLK_LSHIFT) + return true; return false; } - bool mouseMoved(const OgreBites::MouseMotionEvent &evt) + bool mouseMoved(const OgreBites::MouseMotionEvent &evt) override { if (gui_active) return false; + mouse.x = evt.xrel; + mouse.y = evt.yrel; + mouse_moved = true; /* no special mouse handling */ - return false; + return true; } - bool mouseWheelRolled(const OgreBites::MouseWheelEvent &evt) + bool + mouseWheelRolled(const OgreBites::MouseWheelEvent &evt) override { if (gui_active) return false; /* no special mouse wheel handling */ + wheel_y = evt.y; + wheel_moved = true; + return true; + } + bool + mousePressed(const OgreBites::MouseButtonEvent &evt) override + { + std::cout << "Mouse press " << (int)evt.button << " " + << (int)evt.clicks << "\n"; + if ((int)evt.button == 1) + control |= 256; + else + control &= ~256; return false; } void update(float delta) @@ -341,19 +391,26 @@ class App : public OgreBites::ApplicationContext { fps_timer.reset(); } update(evt.timeSinceLastFrame); - if (mApp->getCharacterController() && gui_active) - mApp->getCharacterController()->disableUpdates(); - else if (mApp->getCharacterController() && - !gui_active && mApp->isTerrainReady()) { + if (mApp->getCharacterController() && !gui_active && + mApp->isTerrainReady()) { OgreAssert(mApp->isTerrainReady(), "terrain is not ready"); - mApp->getCharacterController()->enableUpdates(); } if (!gui_active) { mApp->updateSun(evt.timeSinceLastFrame); mApp->updateTerrain(evt.timeSinceLastFrame); mApp->updateWater(evt.timeSinceLastFrame); mApp->updateWorld(evt.timeSinceLastFrame); + ECS::Input &input = + ECS::get().get_mut(); + input.control = control; + input.mouse = mouse; + mouse.x = 0; + mouse.y = 0; + input.wheel_y = wheel_y; + wheel_y = 0; + input.mouse_moved = mouse_moved; + input.wheel_moved = wheel_moved; } } }; @@ -533,9 +590,19 @@ public: void updateTerrain(float delta) { // Ogre::Vector3 pos = mCharacterController->getPosition(); - Ogre::Vector3 pos(0, 0, 0); + const ECS::CharacterBase &ch = + getPlayer().get(); + ECS::CharacterBody &body = + getPlayer().get_mut(); + if (!body.checkGround) { + body.checkGround = true; + getPlayer().modified(); + } + if (!ch.mBodyNode) + return; + Ogre::Vector3 pos = ch.mBodyNode->getPosition(); if (!mTerrainReady && m_terrain.isLoadedAt(pos) && - mCharacterController->checkGround()) { + body.checkGroundResult) { std::cout << "terrain ready\n"; mTerrainReady = true; } @@ -635,6 +702,12 @@ public: { return mCharacterController; } + flecs::entity getPlayer() const + { + flecs::entity player = + ECS::get().lookup("ECS::CharacterModule::player"); + return player; + } }; void EditUI::buildings_editor() diff --git a/src/characters/controller.cpp b/src/characters/controller.cpp deleted file mode 100644 index 828b8de..0000000 --- a/src/characters/controller.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include -#include -#include "GameData.h" -#include "character.h" -#include "controller.h" -#define CAM_HEIGHT 1.6f // height of camera above character's center of mass -#define RUN_SPEED 17 // character running speed in units per second -#define TURN_SPEED 500.0f // character turning in degrees per second -#define ANIM_FADE_SPEED \ - 7.5f // animation crossfade speed in % of full weight per second -CharacterController::CharacterController(Ogre::SceneNode *camNode, - Ogre::Camera *cam, - Ogre::SceneManager *scnMgr, - Ogre::Bullet::DynamicsWorld *world) - : mCameraNode(camNode) - , mCamera(cam) - , mScnMgr(scnMgr) - , mPivotPitch(0) - , mWorld(world) - , mUpdate(false) -{ - setupCamera(); - Ogre::Root::getSingleton().addFrameListener(this); -} -CharacterController::~CharacterController() -{ -} -void CharacterController::setupCamera() -{ -} -static uint32_t control; -static ECS::Vector2 mouse{ 0, 0 }; -static float wheel_y; -static bool mouse_moved = false, wheel_moved = false; -bool CharacterController::keyPressed(const OgreBites::KeyboardEvent &evt) -{ - OgreBites::Keycode key = evt.keysym.sym; - if (key == 'w') - control |= 1; - else if (key == 'a') - control |= 2; - else if (key == 's') - control |= 4; - else if (key == 'd') - control |= 8; - else if (key == OgreBites::SDLK_LSHIFT) - control |= 16; - return true; -} -bool CharacterController::keyReleased(const OgreBites::KeyboardEvent &evt) -{ - OgreBites::Keycode key = evt.keysym.sym; - if (key == 'w') - control &= ~1; - else if (key == 'a') - control &= ~2; - else if (key == 's') - control &= ~4; - else if (key == 'd') - control &= ~8; - else if (key == OgreBites::SDLK_LSHIFT) - control &= ~16; - return true; -} -bool CharacterController::mouseMoved(const OgreBites::MouseMotionEvent &evt) -{ - mouse.x = evt.xrel; - mouse.y = evt.yrel; - mouse_moved = true; - return true; -} -bool CharacterController::mouseWheelRolled(const OgreBites::MouseWheelEvent &evt) -{ - wheel_y = evt.y; - wheel_moved = true; - return true; -} -bool CharacterController::mousePressed(const OgreBites::MouseButtonEvent &evt) -{ - std::cout << "Mouse press\n"; - return false; -} -void CharacterController::frameRendered(const Ogre::FrameEvent &evt) -{ - if (mUpdate) { - updateBody(evt.timeSinceLastFrame); - updateCamera(evt.timeSinceLastFrame); - } -} -bool CharacterController::frameStarted(const Ogre::FrameEvent &evt) -{ - return true; -} -void CharacterController::updateBody(Ogre::Real delta) -{ - ECS::Input &input = ECS::get().get_mut(); - input.control = control; - input.mouse = mouse; - mouse.x = 0; - mouse.y = 0; - input.wheel_y = wheel_y; - wheel_y = 0; - input.mouse_moved = mouse_moved; - input.wheel_moved = wheel_moved; -} -struct EntityCollisionListener { - const Ogre::MovableObject *entity; - Ogre::Bullet::CollisionListener *listener; -}; -void CharacterController::updateCamera(Ogre::Real delta) -{ -} \ No newline at end of file diff --git a/src/characters/controller.h b/src/characters/controller.h deleted file mode 100644 index 4ccad2a..0000000 --- a/src/characters/controller.h +++ /dev/null @@ -1,146 +0,0 @@ -#include -#include -#include -#include -#include "GameData.h" -class CharacterController : public OgreBites::InputListener, - Ogre::FrameListener { - Ogre::SceneNode *mCameraNode; - Ogre::Camera *mCamera; - Ogre::SceneManager *mScnMgr; - - Ogre::SceneNode *mCameraPivot; - Ogre::SceneNode *mCameraGoal; - Ogre::Real mPivotPitch; - Ogre::Real - mTimer; // general timer to see how long animations have been playing - Ogre::Bullet::DynamicsWorld *mWorld; - Ogre::Vector3 rootMotion; - Ogre::Quaternion rootRotation; - // btRigidBody *mRigidBody; -#if 0 - Ogre::Vector3 gvelocity; -#endif - - bool mUpdate; - -public: - CharacterController(Ogre::SceneNode *camNode, Ogre::Camera *cam, - Ogre::SceneManager *scnMgr, - Ogre::Bullet::DynamicsWorld *world); - ~CharacterController(); - -private: - void setupCamera(); - -public: - bool keyPressed(const OgreBites::KeyboardEvent &evt) override; - bool keyReleased(const OgreBites::KeyboardEvent &evt) override; - bool mouseMoved(const OgreBites::MouseMotionEvent &evt) override; - bool mouseWheelRolled(const OgreBites::MouseWheelEvent &evt) override; - bool mousePressed(const OgreBites::MouseButtonEvent &evt) override; - bool frameStarted(const Ogre::FrameEvent &evt) override; - void frameRendered(const Ogre::FrameEvent &evt) override; - -private: - void updateBody(Ogre::Real deltaTime); - void updateCamera(Ogre::Real deltaTime); - inline btQuaternion convert(const Ogre::Quaternion &q) - { - return btQuaternion(q.x, q.y, q.z, q.w); - } - inline btVector3 convert(const Ogre::Vector3 &v) - { - return btVector3(v.x, v.y, v.z); - } - inline btTransform convert(const Ogre::Quaternion &q, - const Ogre::Vector3 &v) - { - btQuaternion mq = convert(q); - btVector3 mv = convert(v); - return btTransform(mq, mv); - } - inline Ogre::Quaternion convert(const btQuaternion &q) - { - return Ogre::Quaternion(q.w(), q.x(), q.y(), q.z()); - } - inline Ogre::Vector3 convert(const btVector3 &v) - { - return Ogre::Vector3(v.x(), v.y(), v.z()); - } - inline void convert(const btTransform &from, Ogre::Quaternion &q, - Ogre::Vector3 &v) - { - q = convert(from.getRotation()); - v = convert(from.getOrigin()); - } - -public: - void enableUpdates() - { - mUpdate = true; - } - void disableUpdates() - { - mUpdate = false; - } - bool getUpdates() - { - return mUpdate; - } - Ogre::Vector3 getPosition() const - { - flecs::entity player = - ECS::get().lookup("ECS::CharacterModule::player"); - return player.get().mBodyNode->getPosition(); - } - Ogre::Quaternion getRotation() const - { - flecs::entity player = - ECS::get().lookup("ECS::CharacterModule::player"); - return player.get() - .mBodyNode->getOrientation(); - } - class ClosestNotMeRayResultCallback - : public btCollisionWorld::ClosestRayResultCallback { - btCollisionObject *mMe; - - public: - ClosestNotMeRayResultCallback(btCollisionObject *me, - const btVector3 &from, - const btVector3 &to) - : btCollisionWorld::ClosestRayResultCallback(from, to) - { - mMe = me; - } - virtual btScalar - addSingleResult(btCollisionWorld::LocalRayResult &rayResult, - bool normalInWorldSpace) - { - if (rayResult.m_collisionObject == mMe) - return 1.0f; - return ClosestRayResultCallback::addSingleResult( - rayResult, normalInWorldSpace); - } - }; - bool checkGround() - { - flecs::entity player = - ECS::get().lookup("ECS::CharacterModule::player"); - btVector3 from = player.get() - .mGhostObject->getWorldTransform() - .getOrigin() + - btVector3(0, 0.2f, 0); - btVector3 to = from + btVector3(0, -3000.0f, 0); - ClosestNotMeRayResultCallback resultCallback( - player.get().mGhostObject, from, - to); - player.get().mGhostObject->rayTest( - from, to, resultCallback); - // std::cout << (resultCallback.hasHit() ? "hit" : "no hit"); - // if (resultCallback.hasHit()) - // std::cout << " " << Ogre::Bullet::convert(resultCallback.m_hitPointWorld); - // std::cout << "\n"; - return resultCallback.hasHit(); - } -}; diff --git a/src/gamedata/GameData.cpp b/src/gamedata/GameData.cpp index e2e511d..940ef96 100644 --- a/src/gamedata/GameData.cpp +++ b/src/gamedata/GameData.cpp @@ -14,7 +14,8 @@ CharacterModule::CharacterModule(flecs::world &ecs) false }); player.set( { "normal-male.glb", nullptr, nullptr, nullptr }); - player.set({}); + player.set( + { nullptr, nullptr, nullptr, { 0, 0, 0 }, false, false }); player.add(); player.add(); ecs.system("HandleInput") @@ -418,6 +419,47 @@ CharacterModule::CharacterModule(flecs::world &ecs) ch.mBodyNode->yaw(Ogre::Degree(yawToGoal)); } }); + class ClosestNotMeRayResultCallback + : public btCollisionWorld::ClosestRayResultCallback { + btCollisionObject *mMe; + + public: + ClosestNotMeRayResultCallback(btCollisionObject *me, + const btVector3 &from, + const btVector3 &to) + : btCollisionWorld::ClosestRayResultCallback(from, to) + { + mMe = me; + } + virtual btScalar + addSingleResult(btCollisionWorld::LocalRayResult &rayResult, + bool normalInWorldSpace) + { + if (rayResult.m_collisionObject == mMe) + return 1.0f; + return ClosestRayResultCallback::addSingleResult( + rayResult, normalInWorldSpace); + } + }; + ecs.system("CheckGround") + .kind(flecs::OnUpdate) + .with() + .each([](const EngineData &eng, CharacterBody &body) { + if (body.checkGround) { + btVector3 from = + body.mGhostObject->getWorldTransform() + .getOrigin() + + btVector3(0, 0.2f, 0); + btVector3 to = from + btVector3(0, -3000.0f, 0); + ClosestNotMeRayResultCallback resultCallback( + body.mGhostObject, from, to); + body.mGhostObject->rayTest(from, to, + resultCallback); + body.checkGroundResult = + resultCallback.hasHit(); + body.checkGround = false; + } + }); } void CharacterModule::setAnimation(AnimationControl &anim) diff --git a/src/gamedata/GameData.h b/src/gamedata/GameData.h index b422b5a..e4ff24a 100644 --- a/src/gamedata/GameData.h +++ b/src/gamedata/GameData.h @@ -54,6 +54,8 @@ struct CharacterBody { btCompoundShape *mCollisionShape; Ogre::Bullet::KinematicMotionSimple *mController; Ogre::Vector3 gvelocity; + bool checkGround; + bool checkGroundResult; }; struct Camera { Ogre::SceneNode *mCameraNode;