Water works!

This commit is contained in:
2025-09-15 01:51:38 +03:00
parent 4d0fb8f60f
commit 5c03f0cd2c
18 changed files with 2435 additions and 1501 deletions

View File

@@ -4,28 +4,31 @@
#include "GameData.h"
#include "CharacterModule.h"
#include "WaterModule.h"
#include "TerrainModule.h"
#include "Components.h"
namespace ECS
{
CharacterModule::CharacterModule(flecs::world &ecs)
{
ecs.module<CharacterModule>();
player = ecs.entity("player");
player.set<AnimationControl>({ AnimationControl::ANIM_NONE,
AnimationControl::ANIM_NONE, false,
false });
player.set<CharacterBase>(
{ "normal-male.glb", 0.0f, nullptr, nullptr, nullptr });
player.set<CharacterBody>(
{ nullptr, nullptr, nullptr, { 0, 0, 0 }, false, false });
player.add<Character>();
player.add<Player>();
ecs.component<Character>();
ecs.component<Player>();
ecs.component<CharacterBase>();
ecs.component<CharacterVelocity>();
ecs.component<CharacterBody>().on_add(
[](flecs::entity e, CharacterBody &body) {
e.set<CharacterVelocity>(
{ { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } });
body.checkGround = false;
body.checkGroundResult = false;
body.mCollisionShape = nullptr;
body.mGhostObject = nullptr;
body.mController = nullptr;
});
ecs.system<EngineData, CharacterBase>("UpdateTimer")
.kind(flecs::OnUpdate)
.each([this](EngineData &eng, CharacterBase &ch) {
ch.mTimer += eng.delta;
if (eng.startupDelay >= 0.0f)
eng.startupDelay -= eng.delta;
});
ecs.system<Input, Camera>("HandleInput")
.kind(flecs::OnUpdate)
@@ -38,6 +41,8 @@ CharacterModule::CharacterModule(flecs::world &ecs)
uint32_t active = input.control;
float zaxis = input.motion.z;
zaxis *= 0.9f;
if (!camera.mCameraPivot || !camera.mCameraGoal)
return;
if (pressed & 1)
std::cout << "W pressed\n";
if (released & 1)
@@ -181,25 +186,15 @@ CharacterModule::CharacterModule(flecs::world &ecs)
return;
ch.mBoneMotion = ch.mRootBone->getPosition();
});
ecs.system<const EngineData, CharacterBase, CharacterBody,
AnimationControl>("HandleRootMotion")
ecs.system<const EngineData, const CharacterBase, CharacterVelocity>(
"HandleGravity")
.kind(flecs::OnUpdate)
.with<TerrainReady>()
.with<WaterReady>()
.each([this](flecs::entity e, const EngineData &eng,
CharacterBase &ch, CharacterBody &body,
AnimationControl &anim) {
float delta = e.world().delta_time();
if (!ch.mBodyNode)
return;
Ogre::Quaternion rot = ch.mBodyNode->getOrientation();
Ogre::Vector3 pos = ch.mBodyNode->getPosition();
Ogre::Vector3 boneMotion = ch.mBoneMotion;
Ogre::Vector3 velocity = rot * boneMotion / delta;
OgreAssert(delta > 0.0f, "Zero delta");
int maxPen = 0;
Ogre::Vector3 colNormal;
bool is_on_floor = false;
bool penetration = false;
const CharacterBase &ch, CharacterVelocity &gr) {
Ogre::Vector3 gravity(0, -9.8f, 0);
Ogre::Vector3 pos = ch.mBodyNode->getPosition();
if (e.has<InWater>()) {
float volume = 2.0f * 0.5f * 0.5f;
float density = 900.0f;
@@ -216,33 +211,80 @@ CharacterModule::CharacterModule(flecs::world &ecs)
Ogre::Vector3 b = -gravity * density * volume *
multiplier * current_subm /
full_subm / mass;
body.gvelocity += (gravity + b) * delta;
body.gvelocity.y = Ogre::Math::Clamp(
body.gvelocity.y, -2.5f, 2.5f);
} else
body.gvelocity += gravity * delta;
gr.gvelocity += (gravity + b) * eng.delta;
gr.gvelocity.y = Ogre::Math::Clamp(
gr.gvelocity.y, -2.5f, 2.5f);
} else {
gr.gvelocity += gravity * eng.delta;
if (pos.y < -1.2) {
gr.gvelocity.y = 0.0f;
}
}
gr.gvelocity *= 0.99;
});
ecs.system<const EngineData, const CharacterBase, CharacterVelocity>(
"HandleRootMotionVelocity")
.kind(flecs::OnUpdate)
.with<TerrainReady>()
.with<WaterReady>()
.each([this](flecs::entity e, const EngineData &eng,
const CharacterBase &ch, CharacterVelocity &v) {
if (eng.delta < 0.0000001f)
return;
if (!ch.mBodyNode)
return;
Ogre::Quaternion rot = ch.mBodyNode->getOrientation();
Ogre::Vector3 pos = ch.mBodyNode->getPosition();
Ogre::Vector3 boneMotion = ch.mBoneMotion;
v.velocity = rot * boneMotion / eng.delta;
if (eng.startupDelay < 0.0f)
v.velocity += v.gvelocity;
v.velocity.y = Ogre::Math::Clamp(v.velocity.y, -10.5f,
1000000.0f);
});
ecs.system<const EngineData, CharacterBase, CharacterBody,
AnimationControl, CharacterVelocity>("HandleRootMotion")
.kind(flecs::OnUpdate)
.each([this](flecs::entity e, const EngineData &eng,
CharacterBase &ch, CharacterBody &body,
AnimationControl &anim, CharacterVelocity &v) {
if (!ch.mBodyNode)
return;
if (eng.delta < 0.0000001f)
return;
OgreAssert(eng.delta > 0.0f, "Zero delta");
int maxPen = 0;
Ogre::Vector3 colNormal;
bool is_on_floor = false;
bool penetration = false;
if (eng.startupDelay < 0.0f) {
body.gvelocity *= 0.99;
velocity += body.gvelocity;
Ogre::Vector3 rotMotion = velocity * delta;
btVector3 currentPosition =
body.mGhostObject->getWorldTransform()
.getOrigin();
is_on_floor = body.mController->isOnFloor();
penetration = body.mController->isPenetrating();
if (is_on_floor)
body.gvelocity =
Ogre::Vector3(0.0f, 0.0f, 0.0f);
if (body.mController) {
Ogre::Vector3 rotMotion =
v.velocity * eng.delta;
btVector3 currentPosition =
body.mGhostObject
->getWorldTransform()
.getOrigin();
is_on_floor =
body.mController->isOnFloor();
penetration = body.mController
->isPenetrating();
if (is_on_floor)
v.gvelocity = Ogre::Vector3(
0.0f, 0.0f, 0.0f);
btTransform from(
Ogre::Bullet::convert(
ch.mBodyNode->getOrientation()),
Ogre::Bullet::convert(
ch.mBodyNode->getPosition()));
ch.mBodyNode->setPosition(
ch.mBodyNode->getPosition() +
rotMotion);
ch.mBoneMotion = Ogre::Vector3(0, 0, 0);
btTransform from(
Ogre::Bullet::convert(
ch.mBodyNode
->getOrientation()),
Ogre::Bullet::convert(
ch.mBodyNode
->getPosition()));
ch.mBodyNode->setPosition(
ch.mBodyNode->getPosition() +
rotMotion);
ch.mBoneMotion = Ogre::Vector3(0, 0, 0);
}
}
});
ecs.system<const Input, AnimationControl>("HandlePlayerAnimations")
@@ -289,6 +331,7 @@ CharacterModule::CharacterModule(flecs::world &ecs)
.each([](const EngineData &eng, CharacterBase &ch,
CharacterBody &body) {
if (!ch.mBodyNode) {
body.mController = nullptr;
ch.mBodyEnt = eng.mScnMgr->createEntity(
"normal-male.glb");
ch.mBodyNode = eng.mScnMgr->getRootSceneNode()
@@ -297,7 +340,8 @@ CharacterModule::CharacterModule(flecs::world &ecs)
ch.mSkeleton = ch.mBodyEnt->getSkeleton();
body.mGhostObject =
new btPairCachingGhostObject();
body.mCollisionShape = new btCompoundShape;
body.mCollisionShape =
new btCompoundShape(false);
body.mGhostObject->setCollisionShape(
body.mCollisionShape);
{
@@ -333,16 +377,8 @@ CharacterModule::CharacterModule(flecs::world &ecs)
eng.mWorld->attachCollisionObject(
body.mGhostObject, ch.mBodyEnt, 1,
0x7FFFFFFF);
body.mController =
new Ogre::Bullet::KinematicMotionSimple(
body.mGhostObject,
ch.mBodyNode);
OgreAssert(body.mGhostObject,
"Need GhostObject");
OgreAssert(body.mController, "Need controller");
eng.mWorld->getBtWorld()->addAction(
body.mController);
OgreAssert(body.mCollisionShape,
"No collision shape");
OgreAssert(ch.mSkeleton->hasBone("Root"),
@@ -351,11 +387,31 @@ CharacterModule::CharacterModule(flecs::world &ecs)
OgreAssert(ch.mRootBone, "No root bone");
}
});
ecs.system<const EngineData, CharacterBase, CharacterBody>(
"UpdateCharacterPhysics")
.kind(flecs::OnUpdate)
.with<Character>()
.with<TerrainReady>()
.with<WaterReady>()
.each([](const EngineData &eng, CharacterBase &ch,
CharacterBody &body) {
if (ch.mBodyNode && !body.mController &&
eng.startupDelay < 0.0f) {
body.mController =
new Ogre::Bullet::KinematicMotionSimple(
body.mGhostObject,
ch.mBodyNode);
eng.mWorld->getBtWorld()->addAction(
body.mController);
OgreAssert(body.mController, "Need controller");
}
});
#define CAM_HEIGHT 1.6f // height of camera above character's center of mass
ecs.system<const EngineData, Camera, const CharacterBase>(
"UpdateCamera")
.kind(flecs::OnUpdate)
.with<Player>()
.with<GroundCheckReady>()
.each([](const EngineData &eng, Camera &camera,
const CharacterBase &ch) {
float delta = eng.delta;
@@ -475,8 +531,10 @@ CharacterModule::CharacterModule(flecs::world &ecs)
ecs.system<const EngineData, CharacterBody>("CheckGround")
.kind(flecs::OnUpdate)
.with<Character>()
.with<Player>()
.without<GroundCheckReady>()
.each([](const EngineData &eng, CharacterBody &body) {
if (body.checkGround) {
if (body.mGhostObject) {
btVector3 from =
body.mGhostObject->getWorldTransform()
.getOrigin() +
@@ -488,7 +546,8 @@ CharacterModule::CharacterModule(flecs::world &ecs)
resultCallback);
body.checkGroundResult =
resultCallback.hasHit();
body.checkGround = false;
if (resultCallback.hasHit())
ECS::get().add<GroundCheckReady>();
}
});
ecs.system<const WaterBody, const CharacterBase, CharacterBody>(
@@ -498,8 +557,7 @@ CharacterModule::CharacterModule(flecs::world &ecs)
.without<InWater>()
.each([](flecs::entity e, const WaterBody &waterb,
const CharacterBase &ch, CharacterBody &body) {
if (waterb.mInWater.find(body.mGhostObject) !=
waterb.mInWater.end() &&
if (waterb.isInWater(body.mGhostObject) &&
ch.mBodyNode->_getDerivedPosition().y < -0.05f) {
e.add<InWater>();
std::cout << "Big Splash\n";
@@ -518,8 +576,7 @@ CharacterModule::CharacterModule(flecs::world &ecs)
.with<InWater>()
.each([](flecs::entity e, const WaterBody &waterb,
const CharacterBase &ch, CharacterBody &body) {
if (waterb.mInWater.find(body.mGhostObject) ==
waterb.mInWater.end() &&
if (waterb.isInWater(body.mGhostObject) &&
ch.mBodyNode->_getDerivedPosition().y > 0.05f)
e.remove<InWater>();
});
@@ -535,6 +592,16 @@ CharacterModule::CharacterModule(flecs::world &ecs)
<< "\n";
});
#endif
/* Create player */
player = ecs.entity("player");
player.set<AnimationControl>({ AnimationControl::ANIM_NONE,
AnimationControl::ANIM_NONE, false,
false });
player.set<CharacterBase>(
{ "normal-male.glb", 0.0f, nullptr, nullptr, nullptr });
player.set<CharacterBody>({ nullptr, nullptr, nullptr, false, false });
player.add<Character>();
player.add<Player>();
}
void CharacterModule::setAnimation(AnimationControl &anim)

View File

@@ -21,10 +21,13 @@ struct CharacterBody {
btPairCachingGhostObject *mGhostObject;
btCompoundShape *mCollisionShape;
Ogre::Bullet::KinematicMotionSimple *mController;
Ogre::Vector3 gvelocity;
bool checkGround;
bool checkGroundResult;
};
struct CharacterVelocity {
Ogre::Vector3 gvelocity;
Ogre::Vector3 velocity;
};
struct AnimationControl {
enum AnimID {
ANIM_IDLE = 0,

View File

@@ -2,6 +2,10 @@
#define COMPONENTS_H_
#include <Ogre.h>
#include <OgreBullet.h>
namespace Ogre
{
class ImGuiOverlay;
}
namespace OgreBites
{
class ApplicationContextSDL;
@@ -18,6 +22,8 @@ struct EngineData {
Ogre::Bullet::DynamicsWorld *mWorld;
float delta;
float startupDelay;
int width;
int height;
};
struct Vector3 {
float x;
@@ -58,10 +64,13 @@ struct RenderWindow {
float dpi;
};
struct App {
OgreBites::ApplicationContextSDL *app;
Ogre::ImGuiOverlay *mGuiOverlay;
OgreBites::InputListenerChain *mInput;
std::vector<OgreBites::InputListener *> listeners;
};
struct InWater {};
struct TerrainReady {};
struct WaterReady {};
struct GroundCheckReady {};
}
#endif

View File

@@ -144,6 +144,27 @@ struct GUIListener : public Ogre::RenderTargetListener {
{
int i;
Ogre::ImGuiOverlay::NewFrame();
if (ECS::get().get<EngineData>().startupDelay > 0.0f) {
ImVec2 size = ImGui::GetMainViewport()->Size;
ImGui::SetNextWindowPos(ImVec2(0, 0), ImGuiCond_Always);
ImGui::SetNextWindowSize(ImVec2(size.x, size.y),
ImGuiCond_Always);
ImGui::Begin(
"StartupScreen", nullptr,
ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoDecoration |
ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoCollapse |
ImGuiWindowFlags_NoFocusOnAppearing |
ImGuiWindowFlags_NoInputs);
// if (ECS::get().get<GUI>().enabled)
// ECS::get().get<App>().app->setWindowGrab(true);
ImGui::Text(
"This game does not autosave. Please use save function to keep your state");
ImGui::End();
}
if (ECS::get().get<GUI>().enabled) {
buttons_panel();
buildings_editor();
@@ -258,9 +279,21 @@ struct GUIListener : public Ogre::RenderTargetListener {
GUIModule::GUIModule(flecs::world &ecs)
{
ecs.component<GUI>().add(flecs::Singleton);
ecs.component<GUIData>().add(flecs::Singleton);
ecs.set<GUI>({ false, true, false, nullptr });
ecs.component<GUI>()
.on_add([](GUI &gui) {
gui.enabled = false;
gui.grab = false;
gui.grabChanged = false;
})
.add(flecs::Singleton);
ecs.component<GUIData>()
.on_add([](GUIData &priv) {
priv.glb_names.clear();
priv.mGUIListener = nullptr;
priv.mGuiOverlay = nullptr;
})
.add(flecs::Singleton);
ecs.set<GUI>({ false, true, false });
ecs.set<GUIData>({ nullptr, {}, nullptr });
ui_wait =
ecs.system<const RenderWindow, App, GUIData>("SetupGUI")
@@ -275,8 +308,9 @@ GUIModule::GUIModule(flecs::world &ecs)
Ogre::OverlayManager::getSingleton()
.setPixelRatio(vpScale);
std::cout << "GUI configure\n";
gui.mGuiOverlay =
app.app->initialiseImGui();
OgreAssert(app.mGuiOverlay,
"No ImGUI overlay");
gui.mGuiOverlay = app.mGuiOverlay;
gui.mGuiOverlay->setZOrder(300);
gui.mGuiOverlay->show();
gui.mGUIListener = new GUIListener();
@@ -299,10 +333,6 @@ GUIModule::GUIModule(flecs::world &ecs)
names.begin(),
names.end());
}
ECS::get_mut<ECS::GUI>()
.mGuiInpitListener =
new OgreBites::
ImGuiInputListener();
ECS::modified<ECS::GUI>();
std::cout << "GUI configure finished\n";
}

View File

@@ -3,7 +3,6 @@
#include <flecs.h>
namespace OgreBites
{
class InputListener;
}
namespace ECS
{
@@ -11,7 +10,6 @@ struct GUI {
bool enabled;
bool grab;
bool grabChanged;
OgreBites::InputListener *mGuiInpitListener;
static void setWindowGrab(bool g = true)
{
ECS::GUI &gui = ECS::get().get_mut<ECS::GUI>();

View File

@@ -12,7 +12,8 @@ namespace ECS
{
static flecs::world ecs;
void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world,
Ogre::SceneNode *cameraNode, Ogre::Camera *camera)
Ogre::SceneNode *cameraNode, Ogre::Camera *camera,
Ogre::RenderWindow *window)
{
std::cout << "Setup GameData\n";
ecs.component<EngineData>().add(flecs::Singleton);
@@ -20,23 +21,60 @@ void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world,
ecs.component<Input>().add(flecs::Singleton);
ecs.component<Camera>().add(flecs::Singleton);
ecs.component<InWater>();
ecs.component<App>().add(flecs::Singleton);
ecs.component<WaterReady>().add(flecs::Singleton);
ecs.component<GroundCheckReady>().add(flecs::Singleton);
ecs.component<App>()
.on_add([](App &app) {
app.mInput = nullptr;
app.mGuiOverlay = nullptr;
app.listeners.clear();
})
.add(flecs::Singleton);
/* lots of things depend on it */
ecs.component<TerrainReady>().add(flecs::Singleton);
ecs.import <WaterModule>();
ecs.import <CharacterModule>();
ecs.import <SunModule>();
ecs.import <TerrainModule>();
ecs.import <SunModule>();
ecs.import <GUIModule>();
ecs.system<EngineData>("UpdateDelta")
.kind(flecs::OnUpdate)
.each([](EngineData &eng) {
eng.delta = ECS::get().delta_time();
});
ecs.set<EngineData>({ scnMgr, world, 0.0f, 0.0f });
ecs.system<EngineData>("UpdateDelay")
.kind(flecs::OnUpdate)
.with<TerrainReady>()
.with<WaterReady>()
.with<GroundCheckReady>()
.each([](EngineData &eng) {
if (eng.startupDelay >= 0.0f)
eng.startupDelay -= eng.delta;
#ifdef VDEBUG
if (ECS::get().has<GroundCheckReady>())
std::cout << "ground check ready\n";
#endif
});
ecs.system<EngineData>("CheckStatus")
.kind(flecs::OnUpdate)
.run([](flecs::iter &it) {
#ifdef VDEBUG
if (ECS::get().has<WaterReady>())
std::cout << "water ready\n";
if (ECS::get().has<TerrainReady>())
std::cout << "terrain ready\n";
if (ECS::get().has<GroundCheckReady>())
std::cout << "ground check ready\n";
#endif
});
ecs.set<EngineData>({ scnMgr, world, 0.0f, 5.0f,
(int)window->getWidth(),
(int)window->getHeight() });
ecs.set<Camera>({ cameraNode, camera, false });
ecs.add<GameData>();
ecs.add<Input>();
ecs.set<WaterSurface>({ nullptr, nullptr, nullptr, nullptr, nullptr });
ecs.set<WaterBody>({ nullptr });
ecs.add<WaterSurface>();
ecs.set<Sun>({ nullptr, nullptr, nullptr, nullptr });
ecs.set<Terrain>({ nullptr,
nullptr,
nullptr,

View File

@@ -5,7 +5,8 @@
namespace ECS
{
void setup(Ogre::SceneManager *scnMgr, Ogre::Bullet::DynamicsWorld *world,
Ogre::SceneNode *cameraNode, Ogre::Camera *camera);
Ogre::SceneNode *cameraNode, Ogre::Camera *camera,
Ogre::RenderWindow *window);
void update(float delta);
flecs::world get();
template <class T> const T &get()

View File

@@ -7,7 +7,6 @@ namespace ECS
SunModule::SunModule(flecs::world &ecs)
{
ecs.component<Sun>().add(flecs::Singleton);
ecs.set<Sun>({ nullptr, nullptr, nullptr, nullptr });
ecs.system<const EngineData, Sun>("UpdateSetupSun")
.kind(flecs::OnUpdate)
.each([](const EngineData &eng, Sun &sun) {

View File

@@ -237,11 +237,14 @@ public:
float maxH = terrain->getMaxHeight();
int size = terrain->getSize();
float worldSize = terrain->getWorldSize();
if (!created || true) {
if (true) {
btRigidBody *body =
mWorld->addTerrainRigidBody(
group, x, y, 2,
0x7ffffffd & (~16));
OgreAssert(
body,
"Could not create RigidBody");
Ogre::LogManager::getSingleton().logError(
"created rigid body " +
Ogre::StringConverter::toString(
@@ -278,6 +281,11 @@ public:
output.push_back(collider_queue.front());
collider_queue.pop_front();
}
if (collider_queue.empty() &&
!ECS::get<Terrain>().mTerrainReady) {
ECS::get_mut<Terrain>().mTerrainReady = true;
ECS::modified<Terrain>();
}
}
collider_queue = output;
}
@@ -328,7 +336,7 @@ TerrainModule::TerrainModule(flecs::world &ecs)
.each([](const EngineData &eng, const Camera &camera,
const Sun &sun, Terrain &terrain,
TerrainPrivate &priv) {
if (!terrain.mTerrainGroup) {
if (!terrain.mTerrainGroup && sun.mSun && eng.mScnMgr) {
std::cout << "Terrain setup\n";
if (!priv.mDummyPageProvider)
priv.mDummyPageProvider =
@@ -338,6 +346,9 @@ TerrainModule::TerrainModule(flecs::world &ecs)
terrain.mTerrainGlobals =
OGRE_NEW Ogre::TerrainGlobalOptions();
OgreAssert(terrain.mTerrainGlobals,
"Failed to allocate global options");
Ogre::LogManager::getSingleton().setMinLogLevel(
Ogre::LML_TRIVIAL);
@@ -423,47 +434,14 @@ TerrainModule::TerrainModule(flecs::world &ecs)
terrain.mTerrainGroup->freeTemporaryResources();
std::cout << "Terrain setup done\n";
}
bool playerCheck = false;
ECS::get()
.query_builder<CharacterBase, CharacterBody>()
.with<Character>()
.with<Player>()
.each([&playerCheck,
terrain](flecs::entity e,
CharacterBase &ch,
CharacterBody &body) {
if (!body.checkGround)
body.checkGround = true;
if (ch.mBodyNode &&
body.checkGroundResult) {
long x, y;
Ogre::Vector3 pos =
ch.mBodyNode
->getPosition();
terrain.mTerrainGroup
->convertWorldPositionToTerrainSlot(
pos, &x, &y);
if (terrain.mTerrainGroup
->getTerrain(x,
y) &&
terrain.mTerrainGroup
->getTerrain(x, y)
->isLoaded())
playerCheck = true;
}
});
if (playerCheck)
terrain.mTerrainReady = true;
if (priv.mSunUpdate.getMilliseconds() > 1000) {
Ogre::TerrainGlobalOptions::getSingleton()
.setCompositeMapAmbient(
eng.mScnMgr->getAmbientLight());
Ogre::TerrainGlobalOptions::getSingleton()
.setCompositeMapDiffuse(
sun.mSun->getDiffuseColour());
Ogre::TerrainGlobalOptions::getSingleton()
.setLightMapDirection(
sun.mSun->getDerivedDirection());
if (sun.mSun &&
priv.mSunUpdate.getMilliseconds() > 1000) {
terrain.mTerrainGlobals->setCompositeMapAmbient(
eng.mScnMgr->getAmbientLight());
terrain.mTerrainGlobals->setCompositeMapDiffuse(
sun.mSun->getDiffuseColour());
terrain.mTerrainGlobals->setLightMapDirection(
sun.mSun->getDerivedDirection());
std::cout << "sun pitch: "
<< sun.mSunNode->getOrientation()
.getPitch()
@@ -471,5 +449,24 @@ TerrainModule::TerrainModule(flecs::world &ecs)
priv.mSunUpdate.reset();
}
});
ecs.system<const CharacterBase, const Terrain>("UpdateTerrainStatus")
.kind(flecs::OnUpdate)
.without<TerrainReady>()
.each([](const CharacterBase &ch, const Terrain &terrain) {
std::cout << "mTerrainReady: " << terrain.mTerrainReady
<< "\n";
std::cout << "mBodyNode: " << ch.mBodyNode << "\n";
if (ch.mBodyNode && terrain.mTerrainReady) {
long x, y;
Ogre::Vector3 pos = ch.mBodyNode->getPosition();
terrain.mTerrainGroup
->convertWorldPositionToTerrainSlot(
pos, &x, &y);
if (terrain.mTerrainGroup->getTerrain(x, y) &&
terrain.mTerrainGroup->getTerrain(x, y)
->isLoaded())
ECS::get().add<TerrainReady>();
}
});
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -38,14 +38,19 @@ struct WaterSurface {
Ogre::Viewport *mViewports[4];
};
struct WaterBody {
std::vector<btCollisionShape *> mChildShapes;
btCollisionShape *mWaterShape;
btPairCachingGhostObject *mWaterBody;
std::set<btCollisionObject *> mInWater;
std::unordered_map<btCollisionObject *, float> mSurface;
btManifoldArray mManifoldArray;
btVector3 mShapeAabbMin, mShapeAabbMax;
int count;
btActionInterface *action;
bool isInWater(const btCollisionObject *body) const;
};
struct WaterModule {
btPairCachingGhostObject *mGhostObject;
WaterModule(flecs::world &ecs);
void createWaterShape(WaterBody *water);
};
}
#endif