From d3b2ae30d59d81b8481f1c98b887900217243205 Mon Sep 17 00:00:00 2001 From: Sergey Lapin Date: Thu, 21 Aug 2025 10:47:57 +0300 Subject: [PATCH] Making this work --- Editor.cpp | 7 ++-- Game.cpp | 34 +++++++++++++++- src/characters/character.cpp | 11 ++++-- src/characters/character.h | 15 ++++++- src/characters/controller.cpp | 13 +++--- src/characters/controller.h | 15 +++++++ src/terrain/terrain.cpp | 3 +- water/water.cpp | 74 +++++++++++++++++++++++++---------- water/water.h | 21 +++++----- 9 files changed, 147 insertions(+), 46 deletions(-) diff --git a/Editor.cpp b/Editor.cpp index 93ca68b..7038c43 100644 --- a/Editor.cpp +++ b/Editor.cpp @@ -457,9 +457,11 @@ public: std::cout << "Init camera" << "\n"; initCamera(); std::cout << "Set up water" << "\n"; - m_water.createWater(getRenderWindow(), mCamera); + m_water.createWater(getRenderWindow(), mCamera, + mDynWorld.get()); std::cout << "Set up cursor" << "\n"; - Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups(); + Ogre::ResourceGroupManager::getSingleton() + .initialiseAllResourceGroups(); // OgreBites::ApplicationContext::loadResources(); setupCursor(); std::cout << "Create content" << "\n"; @@ -470,7 +472,6 @@ public: } void setupCursor() { - // mKeyDirection = Ogre::Vector3::ZERO; // mVerticalVelocity = 0; Ogre::ManualObject *mobj = diff --git a/Game.cpp b/Game.cpp index 398f26f..8941250 100644 --- a/Game.cpp +++ b/Game.cpp @@ -244,6 +244,7 @@ public: float panel_width; void initGui(); }; +#define WATER class App : public OgreBites::ApplicationContext { std::unique_ptr mDynWorld; std::unique_ptr mDbgDraw; @@ -258,7 +259,9 @@ class App : public OgreBites::ApplicationContext { TerrainSetup m_terrain; Ogre::Light *mSun; SkyBoxRenderer *sky; +#ifdef WATER Water m_water; +#endif class KeyboardListener : public OgreBites::InputListener, public Ogre::FrameListener { App *mApp; @@ -361,6 +364,10 @@ 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->getCharacterController()->enableUpdates(); if (!gui_active) { mApp->updateSun(evt.timeSinceLastFrame); mApp->updateTerrain(evt.timeSinceLastFrame); @@ -407,7 +414,11 @@ public: } void dump_water() { +#if 0 +#ifdef WATER m_water.dump_textures(); +#endif +#endif } void initCamera() @@ -457,7 +468,10 @@ public: std::cout << "Init camera" << "\n"; initCamera(); std::cout << "Set up water" << "\n"; - m_water.createWater(getRenderWindow(), mCamera); +#ifdef WATER + m_water.createWater(getRenderWindow(), mCamera, + mDynWorld.get()); +#endif std::cout << "Set up cursor" << "\n"; Ogre::ResourceGroupManager::getSingleton() .initialiseAllResourceGroups(); @@ -467,7 +481,9 @@ public: createContent(); std::cout << "Setup terrain" << "\n"; setupTerrain(); +#ifdef WATER m_water.init(); +#endif setupPlayer(); setupInput(); } @@ -535,13 +551,23 @@ public: void updateTerrain(float delta) { } + // TODO: implement rough water level calculation + float getWaterLevel(const Ogre::Vector3 &position) + { + Ogre::Vector3::UNIT_Y; + float etime = + Ogre::ControllerManager::getSingleton().getElapsedTime(); + return 0.0f; + } void updateWorld(float delta) { - mDynWorld->getBtWorld()->stepSimulation(delta, 10); + mDynWorld->getBtWorld()->stepSimulation(delta, 60); } void updateWater(float delta) { +#ifdef WATER m_water.updateWater(delta); +#endif } void setupInput() { @@ -608,6 +634,10 @@ public: m_terrain.setupTerrain(mCamera, mSun, mDynWorld.get(), mDbgDraw.get()); } + CharacterController *getCharacterController() + { + return mCharacterController; + } }; void EditUI::buildings_editor() diff --git a/src/characters/character.cpp b/src/characters/character.cpp index bcfc0ab..9338f63 100644 --- a/src/characters/character.cpp +++ b/src/characters/character.cpp @@ -22,6 +22,7 @@ Character::Character(Ogre::SceneManager *scnMgr, const Ogre::String &model, , mGhostObject(nullptr) , mWorld(world) , mGoalDirection(0, 0, 0) + , mUpdate(false) { setupBody(); setupAnimations(); @@ -38,10 +39,12 @@ bool Character::frameStarted(const Ogre::FrameEvent &evt) bool Character::frameRenderingQueued(const Ogre::FrameEvent &evt) { - updateBody(evt.timeSinceLastFrame); - updateAnimations(evt.timeSinceLastFrame); - if (evt.timeSinceLastFrame > 0) - updateRootMotion(evt.timeSinceLastFrame); + if (mUpdate) { + updateBody(evt.timeSinceLastFrame); + updateAnimations(evt.timeSinceLastFrame); + if (evt.timeSinceLastFrame > 0) + updateRootMotion(evt.timeSinceLastFrame); + } return true; } diff --git a/src/characters/character.h b/src/characters/character.h index 8c7cb01..fe56c3b 100644 --- a/src/characters/character.h +++ b/src/characters/character.h @@ -38,6 +38,7 @@ class Character : public Ogre::FrameListener { btCompoundShape *mCollisionShape; btPairCachingGhostObject *mGhostObject; Ogre::Bullet::DynamicsWorld *mWorld; + bool mUpdate; public: Character(Ogre::SceneManager *scnMgr, const Ogre::String &modelName, @@ -112,4 +113,16 @@ public: return mGoalDirection; } Ogre::Vector3 getPosition(); -}; \ No newline at end of file + void enableUpdates() + { + mUpdate = true; + } + void disableUpdates() + { + mUpdate = false; + } + bool getUpdates() + { + return mUpdate; + } +}; diff --git a/src/characters/controller.cpp b/src/characters/controller.cpp index dfd762b..0ea4d45 100644 --- a/src/characters/controller.cpp +++ b/src/characters/controller.cpp @@ -183,6 +183,7 @@ CharacterController::CharacterController(Ogre::SceneNode *camNode, , mWorld(world) , mCollisionShape(nullptr) , mGhostObject(nullptr) + , mUpdate(false) { setupBody(); setupCamera(); @@ -445,11 +446,13 @@ bool CharacterController::mousePressed(const OgreBites::MouseButtonEvent &evt) } void CharacterController::frameRendered(const Ogre::FrameEvent &evt) { - updateBody(evt.timeSinceLastFrame); - updateAnimations(evt.timeSinceLastFrame); - updateCamera(evt.timeSinceLastFrame); - if (evt.timeSinceLastFrame > 0) - updateRootMotion(evt.timeSinceLastFrame); + if (mUpdate) { + updateBody(evt.timeSinceLastFrame); + updateAnimations(evt.timeSinceLastFrame); + updateCamera(evt.timeSinceLastFrame); + if (evt.timeSinceLastFrame > 0) + updateRootMotion(evt.timeSinceLastFrame); + } } bool CharacterController::frameStarted(const Ogre::FrameEvent &evt) { diff --git a/src/characters/controller.h b/src/characters/controller.h index fceb4a0..0a1a0bc 100644 --- a/src/characters/controller.h +++ b/src/characters/controller.h @@ -81,6 +81,8 @@ class CharacterController : public OgreBites::InputListener, btCompoundShape *mCollisionShape; btPairCachingGhostObject *mGhostObject; + bool mUpdate; + public: CharacterController(Ogre::SceneNode *camNode, Ogre::Camera *cam, Ogre::SceneManager *scnMgr, @@ -159,4 +161,17 @@ private: q = convert(from.getRotation()); v = convert(from.getOrigin()); } +public: + void enableUpdates() + { + mUpdate = true; + } + void disableUpdates() + { + mUpdate = false; + } + bool getUpdates() + { + return mUpdate; + } }; diff --git a/src/terrain/terrain.cpp b/src/terrain/terrain.cpp index 978d99b..633b2a2 100644 --- a/src/terrain/terrain.cpp +++ b/src/terrain/terrain.cpp @@ -21,7 +21,8 @@ #define ENDLESS_TERRAIN_FILE_PREFIX Ogre::String("EndlessWorldTerrain") #define ENDLESS_TERRAIN_FILE_SUFFIX Ogre::String("dat") #define TERRAIN_WORLD_SIZE 4000.0f -#define TERRAIN_SIZE 513 +// #define TERRAIN_SIZE 513 +#define TERRAIN_SIZE 129 // #define HOLD_LOD_DISTANCE 3000.0 #define USE_PERLIN_DEFINER 0 template T CLAMP(T value, T low, T high) diff --git a/water/water.cpp b/water/water.cpp index 9f79c63..e21eaf7 100644 --- a/water/water.cpp +++ b/water/water.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "water.h" /* TODO: use blender glb model for water shape. @@ -20,12 +21,19 @@ Water::Water() , mWindow(nullptr) , mCameraNode(nullptr) , mWaterPlane(Ogre::Vector3::UNIT_Y, 0) - , mReflectionPlane(Ogre::Vector3(0.0, 1.0, 0.0), 0.0f /* water height */) - , mReflectionClipPlaneAbove(Ogre::Vector3(0.0, 1.0, 0.0), 0.0f /* water height */ - 2.0f) - , mReflectionClipPlaneBelow(Ogre::Vector3(0.0, -1.0, 0.0), -(0.0f /* water height */ + 2.0)) - , mRefractionClipPlaneAbove(Ogre::Vector3(0.0, -1.0, 0.0), -(0.0f /* water height */ + 2.0)) - , mRefractionClipPlaneBelow(Ogre::Vector3(0.0, 1.0, 0.0), 0.0f /* water height */ - 2.0) + , mReflectionPlane(Ogre::Vector3(0.0, 1.0, 0.0), + 0.0f /* water height */) + , mReflectionClipPlaneAbove(Ogre::Vector3(0.0, 1.0, 0.0), + 0.0f /* water height */ - 2.0f) + , mReflectionClipPlaneBelow(Ogre::Vector3(0.0, -1.0, 0.0), + -(0.0f /* water height */ + 2.0)) + , mRefractionClipPlaneAbove(Ogre::Vector3(0.0, -1.0, 0.0), + -(0.0f /* water height */ + 2.0)) + , mRefractionClipPlaneBelow(Ogre::Vector3(0.0, 1.0, 0.0), + 0.0f /* water height */ - 2.0) , mAbove(true) + , mWaterBody(nullptr) + , mDynWorld(nullptr) { } @@ -33,8 +41,16 @@ Water::~Water() { if (mWaterNode) mScnMgr->destroySceneNode(mWaterNode); - if(mReflectionTexture) + if (mReflectionTexture) mReflectionTexture->removeAllListeners(); + if (mWaterBody) { + if (mWaterBody->getWorldArrayIndex() >= 0) + if (mDynWorld) + mDynWorld->getBtWorld()->removeCollisionObject( + mWaterBody); + delete mWaterBody; + mWaterBody = nullptr; + } } void Water::create_cameras() @@ -48,9 +64,11 @@ void Water::create_cameras() mReflectionCamera->enableCustomNearClipPlane(mReflectionClipPlaneAbove); mReflectionCamera->enableReflection(mReflectionPlane); - Ogre::Viewport * reflectionViewport = mReflectionTexture->addViewport(mReflectionCamera, 0, 0, 0, 0.5f, 1.0f); + Ogre::Viewport *reflectionViewport = mReflectionTexture->addViewport( + mReflectionCamera, 0, 0, 0, 0.5f, 1.0f); reflectionViewport->setClearEveryFrame(true); - reflectionViewport->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 1.0, 1.0)); + reflectionViewport->setBackgroundColour( + Ogre::ColourValue(0.0, 0.0, 1.0, 1.0)); reflectionViewport->setOverlaysEnabled(false); reflectionViewport->setSkiesEnabled(true); reflectionViewport->setAutoUpdated(false); @@ -63,9 +81,11 @@ void Water::create_cameras() mRefractionCamera->setFarClipDistance(mCamera->getFarClipDistance()); mRefractionCamera->enableCustomNearClipPlane(mRefractionClipPlaneAbove); - Ogre::Viewport * refractionViewport = mReflectionTexture->addViewport(mRefractionCamera, 1, 0.5, 0, 0.5f, 1.0f); + Ogre::Viewport *refractionViewport = mReflectionTexture->addViewport( + mRefractionCamera, 1, 0.5, 0, 0.5f, 1.0f); refractionViewport->setClearEveryFrame(true); - refractionViewport->setBackgroundColour(Ogre::ColourValue(0.0, 0.5, 1.0, 1.0)); + refractionViewport->setBackgroundColour( + Ogre::ColourValue(0.0, 0.5, 1.0, 1.0)); refractionViewport->setOverlaysEnabled(false); refractionViewport->setSkiesEnabled(false); refractionViewport->setAutoUpdated(false); @@ -74,13 +94,12 @@ void Water::create_cameras() void Water::create_textures() { - Ogre::TexturePtr reflectionTexture = Ogre::TextureManager::getSingleton().createManual( - "ReflectionRefractionTexture", - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Ogre::TEX_TYPE_2D, 512, 512, - 0, - Ogre::PF_R8G8B8A8, - Ogre::TU_RENDERTARGET); + Ogre::TexturePtr reflectionTexture = + Ogre::TextureManager::getSingleton().createManual( + "ReflectionRefractionTexture", + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Ogre::TEX_TYPE_2D, 512, 512, 0, Ogre::PF_R8G8B8A8, + Ogre::TU_RENDERTARGET); mReflectionTexture = reflectionTexture->getBuffer()->getRenderTarget(); mReflectionTexture->setAutoUpdated(false); @@ -115,10 +134,12 @@ void Water::init() { -1, 0, 1 }, { 1, 0, -1 }, { 1, 0, 1 } }; mWaterNode = mScnMgr->getRootSceneNode()->createChildSceneNode("Water"); - auto mat = Ogre::MaterialManager::getSingleton().getByName("Water/Above"); + auto mat = + Ogre::MaterialManager::getSingleton().getByName("Water/Above"); mat->load(); mat->setReceiveShadows(false); - auto mat2 = Ogre::MaterialManager::getSingleton().getByName("Water/Below"); + auto mat2 = + Ogre::MaterialManager::getSingleton().getByName("Water/Below"); mat2->load(); mat2->setReceiveShadows(false); #if 0 @@ -146,9 +167,11 @@ void Water::init() water_ent->setMaterial(mat); mWaterNode->attachObject(water_ent); mWaterMeshes.push_back(water_ent); + mDynWorld->attachCollisionObject(mWaterBody, water_ent, 1, 0x7FFFFFFF); } -void Water::createWater(Ogre::RenderWindow * window, Ogre::Camera *camera) +void Water::createWater(Ogre::RenderWindow *window, Ogre::Camera *camera, + Ogre::Bullet::DynamicsWorld *world) { int i; mCamera = camera; @@ -158,6 +181,17 @@ void Water::createWater(Ogre::RenderWindow * window, Ogre::Camera *camera) mWindow = window; mCameraPosition = mCameraNode->getPosition(); create_textures(); + mDynWorld = world; + mWaterBody = new btGhostObject; + btBoxShape *boxShape = new btBoxShape(btVector3(1000, 1000, 1000)); + btCompoundShape *shape = new btCompoundShape; + shape->addChildShape( + btTransform(btQuaternion(), btVector3(0, -1000, 0)), boxShape); + mWaterBody->setCollisionShape(shape); + mWaterBody->setCollisionFlags( + mWaterBody->getCollisionFlags() | + btCollisionObject::CF_NO_CONTACT_RESPONSE | + btCollisionObject::CF_STATIC_OBJECT); } void Water::updateWater(float delta) diff --git a/water/water.h b/water/water.h index 175b5ff..0d4a5ec 100644 --- a/water/water.h +++ b/water/water.h @@ -2,37 +2,38 @@ #define MAT_WATER_H #include class App; +class btGhostObject; class Water : public /* Ogre::FrameListener, */ Ogre::RenderTargetListener { Ogre::SceneManager *mScnMgr; - Ogre::RenderWindow * mWindow; + Ogre::RenderWindow *mWindow; Ogre::SceneNode *mWaterNode, *mCameraNode; Ogre::Vector3 mCameraPosition; Ogre::Camera *mCamera; - Ogre::Plane mWaterPlane, - mReflectionPlane, - mReflectionClipPlaneAbove, - mReflectionClipPlaneBelow, - mRefractionClipPlaneAbove, + Ogre::Plane mWaterPlane, mReflectionPlane, mReflectionClipPlaneAbove, + mReflectionClipPlaneBelow, mRefractionClipPlaneAbove, mRefractionClipPlaneBelow; bool mAbove; std::vector mWaterMeshes; std::vector mViewports; // Reflection - Ogre::RenderTexture * mReflectionTexture; - Ogre::Camera * mReflectionCamera; + Ogre::RenderTexture *mReflectionTexture; + Ogre::Camera *mReflectionCamera; // Refraction // Ogre::RenderTexture * mRefractionTexture; - Ogre::Camera * mRefractionCamera; + Ogre::Camera *mRefractionCamera; bool mInRefTexUpdate; Ogre::Timer mtexture_dump; void create_cameras(); + btGhostObject *mWaterBody; + Ogre::Bullet::DynamicsWorld *mDynWorld; public: Water(); virtual ~Water(); void create_textures(); void dump_textures(); - void createWater(Ogre::RenderWindow * window, Ogre::Camera *camera); + void createWater(Ogre::RenderWindow *window, Ogre::Camera *camera, + Ogre::Bullet::DynamicsWorld *world); void init(); void updateWater(float delta); /* bool frameEnded(const Ogre::FrameEvent &evt) override; */