Refactoring: split items
This commit is contained in:
@@ -296,15 +296,71 @@ public:
|
||||
void frameRendered(const Ogre::FrameEvent &evt) override;
|
||||
};
|
||||
|
||||
class App : public OgreBites::ApplicationContext {
|
||||
Ogre::SceneNode *mCameraNode, *mCameraPivot, *mCameraGoal;
|
||||
Ogre::Camera *mCamera;
|
||||
Ogre::Real mPivotPitch;
|
||||
struct SceneData {
|
||||
Ogre::SceneManager *mScnMgr;
|
||||
Ogre::Camera *mCamera;
|
||||
Ogre::SceneNode *mCameraNode, *mCameraPivot, *mCameraGoal;
|
||||
Ogre::Real mPivotPitch;
|
||||
SceneData()
|
||||
: mScnMgr(nullptr)
|
||||
, mCamera(nullptr)
|
||||
, mCameraNode(nullptr)
|
||||
, mCameraPivot(nullptr)
|
||||
, mCameraGoal(nullptr)
|
||||
{
|
||||
}
|
||||
void setup(Ogre::Root *root, Ogre::OverlaySystem *overlaySystem)
|
||||
{
|
||||
Ogre::SceneManager *scnMgr = root->createSceneManager();
|
||||
mScnMgr = scnMgr;
|
||||
mScnMgr->addRenderQueueListener(overlaySystem);
|
||||
}
|
||||
void initCamera(const Ogre::String &cameraName)
|
||||
{
|
||||
mCameraNode = mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
cameraName + "CameraNode");
|
||||
mCameraNode->setPosition(0, 2, 3);
|
||||
mCameraNode->lookAt(Ogre::Vector3(0, 1, -1),
|
||||
Ogre::Node::TS_PARENT);
|
||||
|
||||
// create the camera
|
||||
mCamera = mScnMgr->createCamera(cameraName);
|
||||
mCamera->setNearClipDistance(0.05f);
|
||||
mCamera->setAutoAspectRatio(true);
|
||||
mCameraNode->attachObject(mCamera);
|
||||
mCameraPivot =
|
||||
mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
cameraName + "FPSCameraPivot");
|
||||
mCameraGoal = mCameraPivot->createChildSceneNode(
|
||||
cameraName + "FPSCameraGoal", Ogre::Vector3(0, 2, 3));
|
||||
mCameraNode->setPosition(mCameraPivot->getPosition() +
|
||||
mCameraGoal->getPosition());
|
||||
mCameraPivot->setFixedYawAxis(true);
|
||||
mCameraGoal->setFixedYawAxis(true);
|
||||
mCameraNode->setFixedYawAxis(true);
|
||||
// our model is quite small, so reduce the clipping planes
|
||||
mCamera->setNearClipDistance(0.1f);
|
||||
mCamera->setFarClipDistance(800);
|
||||
mPivotPitch = 0;
|
||||
}
|
||||
void setupRTSS()
|
||||
{
|
||||
Ogre::RTShader::ShaderGenerator *shadergen =
|
||||
Ogre::RTShader::ShaderGenerator::getSingletonPtr();
|
||||
shadergen->addSceneManager(mScnMgr);
|
||||
}
|
||||
Ogre::SceneManager *getSceneManager()
|
||||
{
|
||||
return mScnMgr;
|
||||
}
|
||||
};
|
||||
|
||||
class App : public OgreBites::ApplicationContext {
|
||||
Ogre::Viewport *mViewport;
|
||||
SkyBoxRenderer *sky;
|
||||
bool mGrab;
|
||||
KeyboardListener mKbd;
|
||||
SceneData mEditorNormalScene, mEditorAltScene;
|
||||
|
||||
public:
|
||||
App()
|
||||
@@ -316,16 +372,12 @@ public:
|
||||
virtual ~App()
|
||||
{
|
||||
}
|
||||
void setup()
|
||||
void setup() override
|
||||
{
|
||||
OgreBites::ApplicationContext::setup();
|
||||
Ogre::Root *root = getRoot();
|
||||
Ogre::SceneManager *scnMgr = root->createSceneManager();
|
||||
mScnMgr = scnMgr;
|
||||
Ogre::OverlaySystem *pOverlaySystem = getOverlaySystem();
|
||||
mScnMgr->addRenderQueueListener(pOverlaySystem);
|
||||
// mTrayMgr = new OgreBites::TrayManager("AppTrays",
|
||||
// getRenderWindow());
|
||||
mEditorNormalScene.setup(root, getOverlaySystem());
|
||||
mEditorAltScene.setup(root, getOverlaySystem());
|
||||
}
|
||||
bool isWindowGrab()
|
||||
{
|
||||
@@ -353,85 +405,41 @@ public:
|
||||
|
||||
void initCamera()
|
||||
{
|
||||
mCameraNode = mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
"CameraNode");
|
||||
mCameraNode->setPosition(0, 2, 3);
|
||||
mCameraNode->lookAt(Ogre::Vector3(0, 1, -1),
|
||||
Ogre::Node::TS_PARENT);
|
||||
|
||||
// create the camera
|
||||
mCamera = mScnMgr->createCamera("fps_camera");
|
||||
mCamera->setNearClipDistance(0.05f);
|
||||
mCamera->setAutoAspectRatio(true);
|
||||
mCameraNode->attachObject(mCamera);
|
||||
|
||||
// and tell it to render into the main window
|
||||
mViewport = getRenderWindow()->addViewport(mCamera);
|
||||
mCameraPivot =
|
||||
mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
"FPSCameraPivot");
|
||||
mCameraGoal = mCameraPivot->createChildSceneNode(
|
||||
"FPSCameraGoal", Ogre::Vector3(0, 2, 3));
|
||||
mCameraNode->setPosition(mCameraPivot->getPosition() +
|
||||
mCameraGoal->getPosition());
|
||||
mCameraPivot->setFixedYawAxis(true);
|
||||
mCameraGoal->setFixedYawAxis(true);
|
||||
mCameraNode->setFixedYawAxis(true);
|
||||
// our model is quite small, so reduce the clipping planes
|
||||
mCamera->setNearClipDistance(0.1f);
|
||||
mCamera->setFarClipDistance(800);
|
||||
mPivotPitch = 0;
|
||||
mEditorNormalScene.initCamera("fps_camera");
|
||||
mEditorNormalScene.initCamera("alt_camera");
|
||||
mViewport = getRenderWindow()->addViewport(
|
||||
mEditorNormalScene.mCamera);
|
||||
}
|
||||
void configure()
|
||||
{
|
||||
std::cout << "Startup"
|
||||
<< "\n";
|
||||
std::cout << "Startup"
|
||||
<< "\n";
|
||||
initApp();
|
||||
std::cout << "Set up RTSS"
|
||||
<< "\n";
|
||||
std::cout << "Set up RTSS"
|
||||
<< "\n";
|
||||
Ogre::Root *root = getRoot();
|
||||
Ogre::SceneManager *scnMgr = getSceneManager();
|
||||
|
||||
// register our scene with the RTSS
|
||||
Ogre::RTShader::ShaderGenerator *shadergen =
|
||||
Ogre::RTShader::ShaderGenerator::getSingletonPtr();
|
||||
shadergen->addSceneManager(scnMgr);
|
||||
mEditorNormalScene.setupRTSS();
|
||||
mEditorAltScene.setupRTSS();
|
||||
setWindowGrab(false);
|
||||
std::cout << "Init camera"
|
||||
<< "\n";
|
||||
std::cout << "Init camera"
|
||||
<< "\n";
|
||||
initCamera();
|
||||
std::cout << "Set up water"
|
||||
<< "\n";
|
||||
std::cout << "Set up cursor"
|
||||
<< "\n";
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.initialiseAllResourceGroups();
|
||||
// OgreBites::ApplicationContext::loadResources();
|
||||
// setupCursor();
|
||||
std::cout << "Setup input"
|
||||
<< "\n";
|
||||
std::cout << "Setup input"
|
||||
<< "\n";
|
||||
setupInput();
|
||||
std::cout << "Create content"
|
||||
<< "\n";
|
||||
std::cout << "Create content"
|
||||
<< "\n";
|
||||
createContent();
|
||||
std::cout << "Setup done"
|
||||
<< "\n";
|
||||
#if 0
|
||||
mDbgDraw->setDebugMode(mDbgDraw->getDebugMode() |
|
||||
btIDebugDraw::DBG_DrawContactPoints);
|
||||
#endif
|
||||
}
|
||||
Ogre::SceneManager *getSceneManager()
|
||||
{
|
||||
return mScnMgr;
|
||||
std::cout << "Setup done"
|
||||
<< "\n";
|
||||
}
|
||||
Ogre::Timer mTerrainUpd;
|
||||
// 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)
|
||||
@@ -447,6 +455,26 @@ public:
|
||||
ECS::get().modified<ECS::GUI>();
|
||||
}
|
||||
ECS::update(delta);
|
||||
#if 0
|
||||
if (switchWindow) {
|
||||
int scene = ECS::get<ECS::EditorSceneSwitch>().scene;
|
||||
mEditorNormalScene.mScnMgr->removeRenderQueueListener(
|
||||
getOverlaySystem());
|
||||
mEditorAltScene.mScnMgr->removeRenderQueueListener(
|
||||
getOverlaySystem());
|
||||
mViewport->setOverlaysEnabled(false);
|
||||
if (scene == 0)
|
||||
mViewport->setCamera(
|
||||
mEditorNormalScene.mCamera);
|
||||
else if (scene == 1)
|
||||
mViewport->setCamera(mEditorAltScene.mCamera);
|
||||
mViewport->setOverlaysEnabled(true);
|
||||
mEditorNormalScene.mScnMgr->addRenderQueueListener(
|
||||
getOverlaySystem());
|
||||
mEditorAltScene.mScnMgr->addRenderQueueListener(
|
||||
getOverlaySystem());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
class InputListenerChainFlexible : public OgreBites::InputListener {
|
||||
protected:
|
||||
@@ -580,10 +608,11 @@ public:
|
||||
void setupInput()
|
||||
{
|
||||
}
|
||||
bool switchWindow = false;
|
||||
void createContent()
|
||||
{
|
||||
int i;
|
||||
sky = new SkyBoxRenderer(getSceneManager());
|
||||
sky = new SkyBoxRenderer(mEditorNormalScene.getSceneManager());
|
||||
bool drawFirst = true;
|
||||
uint8_t renderQueue = drawFirst ?
|
||||
Ogre::RENDER_QUEUE_SKIES_EARLY :
|
||||
@@ -599,8 +628,14 @@ public:
|
||||
"Skybox/Dynamic", "General");
|
||||
OgreAssert(m, "Sky box material not found.");
|
||||
m->load();
|
||||
ECS::setupEditor(mScnMgr, /*mDynWorld.get(), */ mCameraNode,
|
||||
mCamera, getRenderWindow());
|
||||
ECS::setupEditor(
|
||||
mEditorNormalScene.mScnMgr,
|
||||
/*mDynWorld.get(), */ mEditorNormalScene.mCameraNode,
|
||||
mEditorNormalScene.mCamera, getRenderWindow());
|
||||
ECS::setupEditorAlt(
|
||||
mEditorAltScene.mScnMgr,
|
||||
/*mDynWorld.get(), */ mEditorAltScene.mCameraNode,
|
||||
mEditorAltScene.mCamera, getRenderWindow());
|
||||
ECS::get().import <ECS::EditorGizmoModule>();
|
||||
ECS::get().import <ECS::EditorInputModule>();
|
||||
ECS::get().set<ECS::RenderWindow>(
|
||||
@@ -632,11 +667,20 @@ public:
|
||||
nullptr,
|
||||
{ getImGuiInputListener(), &mKbd } });
|
||||
ECS::get().add<ECS::EditorDebugMaterial>();
|
||||
#if 0
|
||||
ECS::get()
|
||||
.observer<ECS::EditorSceneSwitch>("UpdateEditorScene")
|
||||
.event(flecs::OnSet)
|
||||
.each([&](ECS::EditorSceneSwitch &sw) {
|
||||
switchWindow = true;
|
||||
});
|
||||
#endif
|
||||
std::shared_ptr<Ogre::ManualObject> manualObj(
|
||||
mScnMgr->createManualObject("EditorGizmo"));
|
||||
mEditorNormalScene.mScnMgr->createManualObject(
|
||||
"EditorGizmo"));
|
||||
Ogre::SceneNode *gizmoNode =
|
||||
mScnMgr->getRootSceneNode()->createChildSceneNode(
|
||||
"EditorGizmoNode");
|
||||
mEditorNormalScene.mScnMgr->getRootSceneNode()
|
||||
->createChildSceneNode("EditorGizmoNode");
|
||||
gizmoNode->attachObject(manualObj.get());
|
||||
manualObj->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY);
|
||||
ECS::get().set<ECS::EditorGizmo>({ manualObj, gizmoNode });
|
||||
@@ -723,13 +767,9 @@ public:
|
||||
ECS::get().get_mut<ECS::GUI>().enabled = active;
|
||||
ECS::get().modified<ECS::GUI>();
|
||||
}
|
||||
Ogre::Camera *getCamera()
|
||||
{
|
||||
return mCamera;
|
||||
}
|
||||
flecs::entity getPlayer() const
|
||||
{
|
||||
return ECS::player;
|
||||
return ECS::player;
|
||||
}
|
||||
void enableDbgDraw(bool enable)
|
||||
{
|
||||
@@ -795,7 +835,7 @@ int main()
|
||||
{
|
||||
App ctx;
|
||||
ctx.configure();
|
||||
// ctx.enableDbgDraw(false);
|
||||
// ctx.enableDbgDraw(false);
|
||||
ctx.getRoot()->startRendering();
|
||||
ctx.setWindowGrab(false);
|
||||
ctx.closeApp();
|
||||
|
||||
@@ -4,6 +4,7 @@ find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging Terrain Overlay CONFIG
|
||||
find_package(Bullet REQUIRED)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
find_package(OgreProcedural REQUIRED CONFIG)
|
||||
add_subdirectory(items)
|
||||
add_library(GameData STATIC GameData.cpp CharacterModule.cpp WaterModule.cpp SunModule.cpp TerrainModule.cpp
|
||||
GUIModule.cpp LuaData.cpp WorldMapModule.cpp BoatModule.cpp EventTriggerModule.cpp
|
||||
CharacterAnimationModule.cpp PhysicsModule.cpp EventModule.cpp CharacterManagerModule.cpp
|
||||
@@ -14,7 +15,7 @@ target_link_libraries(GameData PUBLIC
|
||||
nlohmann_json::nlohmann_json
|
||||
OgreMain
|
||||
OgreBites
|
||||
OgrePaging OgreTerrain OgreOverlay OgreProcedural::OgreProcedural
|
||||
OgrePaging OgreTerrain OgreOverlay OgreProcedural::OgreProcedural items
|
||||
PRIVATE sceneloader world-build physics editor)
|
||||
target_include_directories(GameData PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${BULLET_INCLUDE_DIR} ../luaaa)
|
||||
target_compile_definitions(GameData PRIVATE FLECS_CPP_NO_AUTO_REGISTRATION)
|
||||
|
||||
@@ -75,5 +75,8 @@ struct GroundCheckReady {};
|
||||
struct Body2Entity {
|
||||
/* std::unordered_map<btCollisionObject *, flecs::entity> entities; */
|
||||
};
|
||||
struct EditorSceneSwitch {
|
||||
int scene;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,7 +42,7 @@ void setup_minimal()
|
||||
ecs.component<Body2Entity>().add(flecs::Singleton);
|
||||
}
|
||||
void setupExteriorScene(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
{
|
||||
std::cout << "Setup GameData\n";
|
||||
setup_minimal();
|
||||
@@ -112,58 +112,58 @@ void setupExteriorScene(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
|
||||
// ecs.set<Body2Entity>({});
|
||||
std::cout << "Setup GameData done\n";
|
||||
ecs.system("SpawnPlayer").kind(flecs::OnUpdate).interval(0.5f).run([&](flecs::iter &it) {
|
||||
flecs::entity player =
|
||||
ECS::get<CharacterManagerModule>().getPlayer();
|
||||
if (!player.is_valid()) {
|
||||
/* Create player */
|
||||
Ogre::Vector3 position;
|
||||
JPH::BodyID id;
|
||||
long x, y;
|
||||
Ogre::TerrainGroup *tg =
|
||||
ECS::get<ECS::Terrain>().mTerrainGroup;
|
||||
if (tg->isDerivedDataUpdateInProgress())
|
||||
return;
|
||||
tg->convertWorldPositionToTerrainSlot(
|
||||
Ogre::Vector3(0, 0, 4), &x, &y);
|
||||
Ogre::Terrain *terrain = tg->getTerrain(x, y);
|
||||
if (terrain && terrain->isLoaded()) {
|
||||
if (PhysicsModule::raycastQuery(
|
||||
Ogre::Vector3(0, 500, 4),
|
||||
Ogre::Vector3(0, -500, 4), position,
|
||||
id)) {
|
||||
if (position.y < -10.0f &&
|
||||
position.y > -50.0f) {
|
||||
player =
|
||||
ecs.get_mut<
|
||||
CharacterManagerModule>()
|
||||
.createPlayer(
|
||||
{ position.x,
|
||||
position.y,
|
||||
position.z },
|
||||
Ogre::Quaternion(
|
||||
Ogre::Radian(
|
||||
Ogre::Math::
|
||||
PI),
|
||||
Ogre::Vector3::
|
||||
UNIT_Y));
|
||||
std::cout << position
|
||||
<< std::endl;
|
||||
// OgreAssert(false, "spawn");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
ecs.system("SpawnPlayer").kind(flecs::OnUpdate).interval(0.5f).run([&](flecs::iter &it) {
|
||||
flecs::entity player =
|
||||
ECS::get<CharacterManagerModule>().getPlayer();
|
||||
if (!player.is_valid()) {
|
||||
/* Create player */
|
||||
Ogre::Vector3 position;
|
||||
JPH::BodyID id;
|
||||
long x, y;
|
||||
Ogre::TerrainGroup *tg =
|
||||
ECS::get<ECS::Terrain>().mTerrainGroup;
|
||||
if (tg->isDerivedDataUpdateInProgress())
|
||||
return;
|
||||
tg->convertWorldPositionToTerrainSlot(
|
||||
Ogre::Vector3(0, 0, 4), &x, &y);
|
||||
Ogre::Terrain *terrain = tg->getTerrain(x, y);
|
||||
if (terrain && terrain->isLoaded()) {
|
||||
if (PhysicsModule::raycastQuery(
|
||||
Ogre::Vector3(0, 500, 4),
|
||||
Ogre::Vector3(0, -500, 4), position,
|
||||
id)) {
|
||||
if (position.y < -10.0f &&
|
||||
position.y > -50.0f) {
|
||||
player =
|
||||
ecs.get_mut<
|
||||
CharacterManagerModule>()
|
||||
.createPlayer(
|
||||
{ position.x,
|
||||
position.y,
|
||||
position.z },
|
||||
Ogre::Quaternion(
|
||||
Ogre::Radian(
|
||||
Ogre::Math::
|
||||
PI),
|
||||
Ogre::Vector3::
|
||||
UNIT_Y));
|
||||
std::cout << position
|
||||
<< std::endl;
|
||||
// OgreAssert(false, "spawn");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
void setupInteriorScene(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
{
|
||||
}
|
||||
|
||||
void setupInventoryScene(Ogre::SceneManager *scnMgr,
|
||||
Ogre::SceneNode *cameraNode, Ogre::Camera *camera,
|
||||
Ogre::RenderWindow *window)
|
||||
Ogre::SceneNode *cameraNode, Ogre::Camera *camera,
|
||||
Ogre::RenderWindow *window)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -173,6 +173,7 @@ void setupEditor(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
std::cout << "Setup Editor\n";
|
||||
setup_minimal();
|
||||
ecs.component<RenderWindow>().add(flecs::Singleton);
|
||||
ecs.component<EditorSceneSwitch>().add(flecs::Singleton);
|
||||
ecs.import <CharacterModule>();
|
||||
ecs.import <BoatModule>();
|
||||
ecs.import <PhysicsModule>();
|
||||
@@ -218,6 +219,9 @@ void setupEditor(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
ecs.set<EngineData>({ scnMgr, 0.0f, 5.0f, (int)window->getWidth(),
|
||||
(int)window->getHeight(), false });
|
||||
ecs.set<Camera>({ cameraNode, camera, false });
|
||||
#if 0
|
||||
ecs.set<EditorSceneSwitch>({ 0 });
|
||||
#endif
|
||||
ecs.add<GameData>();
|
||||
ecs.add<Input>();
|
||||
ecs.add<WaterSurface>();
|
||||
@@ -252,11 +256,11 @@ flecs::world get()
|
||||
bool Vector3::zeroLength() const
|
||||
{
|
||||
float l = x * x + y * y + z * z;
|
||||
return (l < 1e-06 * 1e-06);
|
||||
return (l < 1e-06 * 1e-06);
|
||||
}
|
||||
|
||||
void setupEditorAlt(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
Ogre::Camera *camera, Ogre::RenderWindow *window)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,7 +19,11 @@ struct TerrainItem {
|
||||
};
|
||||
struct TerrainItemNode {
|
||||
Ogre::SceneNode *itemNode;
|
||||
Ogre::StaticGeometry *geo;
|
||||
Ogre::StaticGeometry *geo;
|
||||
};
|
||||
struct TerrainItemMeshNode {
|
||||
Ogre::SceneNode *itemNode;
|
||||
Ogre::StaticGeometry *geo;
|
||||
};
|
||||
|
||||
struct StaticGeometryModule {
|
||||
@@ -43,16 +47,7 @@ struct StaticGeometryModule {
|
||||
static void getItemsProperties(
|
||||
std::list<std::pair<flecs::entity, Ogre::String> > *items);
|
||||
static void createItemGeometry(flecs::entity e);
|
||||
static void destroyItemGeometry(flecs::entity e);
|
||||
static void setupLods(Ogre::LodConfig &config);
|
||||
static void createPlazza(flecs::entity e, const nlohmann::json &district, Ogre::SceneNode *sceneNode, Ogre::StaticGeometry *geo);
|
||||
static void createBridge(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
static void createPier(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
static void createHarbour(flecs::entity e, Ogre::SceneNode *sceneNode, Ogre::StaticGeometry *geo);
|
||||
static void createBuildings(flecs::entity e, const nlohmann::json &district, Ogre::SceneNode *sceneNode, Ogre::StaticGeometry *geo);
|
||||
static void createTemple(flecs::entity e, Ogre::SceneNode *sceneNode, Ogre::StaticGeometry *geo);
|
||||
static void destroyItemGeometry(flecs::entity e);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -278,7 +278,7 @@ public:
|
||||
float worldSize = terrain->getWorldSize();
|
||||
float scaled = worldSize / (size - 1);
|
||||
Ogre::Vector3 bodyPosition = terrain->getPosition();
|
||||
// bodyPosition.y += (maxH + minH) / 2.0f;
|
||||
// bodyPosition.y += (maxH + minH) / 2.0f;
|
||||
bodyPosition.x += worldSize / 2.0f;
|
||||
bodyPosition.z += worldSize / 2.0f;
|
||||
Ogre::Vector3 offset =
|
||||
@@ -338,21 +338,22 @@ public:
|
||||
}
|
||||
void update()
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mtx);
|
||||
static bool created = false;
|
||||
std::lock_guard<std::mutex> guard(mtx);
|
||||
static bool created = false;
|
||||
while (!collider_queue.empty()) {
|
||||
Ogre::TerrainGroup *group =
|
||||
Ogre::TerrainGroup *group =
|
||||
collider_queue.front().group;
|
||||
if (group->isDerivedDataUpdateInProgress())
|
||||
break;
|
||||
long x = collider_queue.front().x;
|
||||
if (group->isDerivedDataUpdateInProgress())
|
||||
break;
|
||||
long x = collider_queue.front().x;
|
||||
long y = collider_queue.front().y;
|
||||
std::cout << x << " " << y << " "
|
||||
<< collider_queue.size() << std::endl;
|
||||
std::cout << x << " " << y << " "
|
||||
<< collider_queue.size() << std::endl;
|
||||
Ogre::Terrain *terrain = group->getTerrain(x, y);
|
||||
Ogre::Vector3 worldPos;
|
||||
group->convertTerrainSlotToWorldPosition(x, y,
|
||||
&worldPos);
|
||||
#if 0
|
||||
std::cout << "terrain: " << terrain;
|
||||
if (terrain)
|
||||
std::cout
|
||||
@@ -360,7 +361,8 @@ public:
|
||||
<< terrain->isLoaded() << " "
|
||||
<< terrain->isDerivedDataUpdateInProgress()
|
||||
<< std::endl;
|
||||
if (terrain && terrain->getHeightData() &&
|
||||
#endif
|
||||
if (terrain && terrain->getHeightData() &&
|
||||
terrain->isLoaded() &&
|
||||
!terrain->isDerivedDataUpdateInProgress()) {
|
||||
Ogre::LogManager::getSingleton().logError(
|
||||
@@ -368,8 +370,8 @@ public:
|
||||
Ogre::StringConverter::toString(x) +
|
||||
" " +
|
||||
Ogre::StringConverter::toString(y));
|
||||
// float minH = terrain->getMinHeight();
|
||||
// float maxH = terrain->getMaxHeight();
|
||||
// float minH = terrain->getMinHeight();
|
||||
// float maxH = terrain->getMaxHeight();
|
||||
int size = terrain->getSize();
|
||||
float worldSize = terrain->getWorldSize();
|
||||
{
|
||||
@@ -440,22 +442,22 @@ public:
|
||||
#endif
|
||||
/* Spawn items */
|
||||
StaticGeometryModule::addGeometryForSlot(x, y);
|
||||
collider_queue.pop_front();
|
||||
collider_queue.pop_front();
|
||||
|
||||
} else {
|
||||
/* Terrain data not ready maybe move to next terrain */
|
||||
gen_collider m = collider_queue.front();
|
||||
/* Terrain data not ready maybe move to next terrain */
|
||||
gen_collider m = collider_queue.front();
|
||||
collider_queue.pop_front();
|
||||
collider_queue.push_back(m);
|
||||
break; // allow system to move on
|
||||
collider_queue.push_back(m);
|
||||
break; // allow system to move on
|
||||
}
|
||||
}
|
||||
if (collider_queue.empty() &&
|
||||
!ECS::get<Terrain>().mTerrainReady) {
|
||||
ECS::get_mut<Terrain>().mTerrainReady = true;
|
||||
ECS::modified<Terrain>();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (collider_queue.empty() &&
|
||||
!ECS::get<Terrain>().mTerrainReady) {
|
||||
ECS::get_mut<Terrain>().mTerrainReady = true;
|
||||
ECS::modified<Terrain>();
|
||||
}
|
||||
}
|
||||
};
|
||||
class DummyPageProvider : public Ogre::PageProvider {
|
||||
public:
|
||||
|
||||
@@ -468,6 +468,31 @@ WaterModule::WaterModule(flecs::world &ecs)
|
||||
std::cout << "Water setup done\n";
|
||||
ECS::get().add<WaterAlmostReady>();
|
||||
})
|
||||
.on_remove([](flecs::entity e, WaterSurface &water) {
|
||||
const Ogre::String renderTargetName =
|
||||
"ReflectionRefractionTexture";
|
||||
ECS::get<EngineData>()
|
||||
.mScnMgr->getRenderQueue()
|
||||
->setRenderableListener(nullptr);
|
||||
water.mReflectionTexture->removeAllViewports();
|
||||
ECS::get<EngineData>().mScnMgr->destroyCamera(
|
||||
water.mRefractionCamera);
|
||||
ECS::get<EngineData>().mScnMgr->destroyCamera(
|
||||
water.mRefractionDepthCamera);
|
||||
ECS::get<EngineData>().mScnMgr->destroyCamera(
|
||||
water.mReflectionCamera);
|
||||
ECS::get<EngineData>().mScnMgr->destroyCamera(
|
||||
water.mReflectionDepthCamera);
|
||||
Ogre::TextureManager::getSingleton().remove(
|
||||
renderTargetName);
|
||||
water.mWaterNode->destroyAllChildrenAndObjects();
|
||||
ECS::get<EngineData>().mScnMgr->destroySceneNode(
|
||||
water.mWaterNode);
|
||||
Ogre::MaterialManager::getSingleton().remove(
|
||||
"Water/Depth");
|
||||
Ogre::MaterialManager::getSingleton().remove(
|
||||
"Water/Above");
|
||||
})
|
||||
.add(flecs::Singleton);
|
||||
#if 0
|
||||
ecs.component<WaterBody>().add(flecs::Singleton);
|
||||
|
||||
16
src/gamedata/items/CMakeLists.txt
Normal file
16
src/gamedata/items/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
project(items)
|
||||
find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging Terrain Overlay CONFIG)
|
||||
find_package(Bullet REQUIRED)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
find_package(OgreProcedural REQUIRED CONFIG)
|
||||
add_library(items STATIC items.cpp harbour.cpp temple.cpp town.cpp)
|
||||
target_include_directories(items PUBLIC .)
|
||||
target_link_libraries(items PRIVATE
|
||||
flecs::flecs_static
|
||||
nlohmann_json::nlohmann_json
|
||||
GameData
|
||||
OgreMain
|
||||
OgreBites
|
||||
editor
|
||||
physics
|
||||
)
|
||||
983
src/gamedata/items/harbour.cpp
Normal file
983
src/gamedata/items/harbour.cpp
Normal file
@@ -0,0 +1,983 @@
|
||||
#include <iostream>
|
||||
#include <Ogre.h>
|
||||
#include <OgreTerrainGroup.h>
|
||||
#include <OgreImGuiOverlay.h>
|
||||
#include <OgreRTShaderSystem.h>
|
||||
#include <Procedural.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
#include "EditorGizmoModule.h"
|
||||
#include "TerrainModule.h"
|
||||
#include "StaticGeometryModule.h"
|
||||
#include "items.h"
|
||||
#include "harbour.h"
|
||||
namespace ECS
|
||||
{
|
||||
namespace Items
|
||||
{
|
||||
/* This is editor function */
|
||||
static bool findPierOffset(float &offset)
|
||||
{
|
||||
Ogre::Vector3 basePos =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion baseRot =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedOrientation();
|
||||
Ogre::Vector3 direction = baseRot * Ogre::Vector3(0, 0, 1);
|
||||
float length = 0.0f;
|
||||
while (length < 250.0f) {
|
||||
Ogre::Vector3 currentPosition = basePos + direction * length;
|
||||
float height = ECS::get<Terrain>()
|
||||
.mTerrainGroup->getHeightAtWorldPosition(
|
||||
currentPosition);
|
||||
if (height < -4.0f) {
|
||||
offset = length;
|
||||
break;
|
||||
}
|
||||
length += 2.0f;
|
||||
}
|
||||
return length < 250.0f;
|
||||
}
|
||||
static bool findPierOffsetAndLengthAndDepth(float &offset, float &length,
|
||||
float &depth)
|
||||
{
|
||||
if (!findPierOffset(offset))
|
||||
return false;
|
||||
Ogre::Vector3 basePos =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion baseRot =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedOrientation();
|
||||
Ogre::Vector3 direction = baseRot * Ogre::Vector3(0, 0, 1);
|
||||
length = 0.0f;
|
||||
depth = 4.0f;
|
||||
while (length < 60.0f) {
|
||||
Ogre::Vector3 currentPosition =
|
||||
basePos + direction * (offset + length);
|
||||
float height = ECS::get<Terrain>()
|
||||
.mTerrainGroup->getHeightAtWorldPosition(
|
||||
currentPosition);
|
||||
if (depth < -height)
|
||||
depth = -height;
|
||||
if (height > -4.0f)
|
||||
break;
|
||||
length += 6.0f;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static void findPierHeight(float maxLength, float &height)
|
||||
{
|
||||
Ogre::Vector3 basePos =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion baseRot =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedOrientation();
|
||||
Ogre::Vector3 direction = baseRot * Ogre::Vector3(0, 0, 1);
|
||||
float length = 0.0f;
|
||||
height = 0.0f;
|
||||
while (length < 60.0f) {
|
||||
Ogre::Vector3 currentPosition = basePos + direction * (length);
|
||||
float dheight =
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainGroup->getHeightAtWorldPosition(
|
||||
currentPosition);
|
||||
if (height < dheight)
|
||||
height = dheight;
|
||||
length += 1.0f;
|
||||
}
|
||||
}
|
||||
static void findPierPath(float pathLength, std::vector<Ogre::Vector3> &path)
|
||||
{
|
||||
float minHeight = 0.2f;
|
||||
int i;
|
||||
Ogre::Vector3 basePos =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion baseRot =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedOrientation();
|
||||
Ogre::Vector3 direction = baseRot * Ogre::Vector3(0, 0, 1);
|
||||
float length = 0.0f;
|
||||
while (length < pathLength) {
|
||||
Ogre::Vector3 currentPosition = basePos + direction * (length);
|
||||
float dheight =
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainGroup->getHeightAtWorldPosition(
|
||||
currentPosition);
|
||||
if (dheight < minHeight)
|
||||
dheight = minHeight;
|
||||
Ogre::Vector3 localOffset = Ogre::Vector3(0, 0, 1) * length;
|
||||
Ogre::Vector3 localFromWorld =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode->convertWorldToLocalPosition(
|
||||
{ currentPosition.x, dheight,
|
||||
currentPosition.z });
|
||||
path.push_back(
|
||||
{ localOffset.x, localFromWorld.y, localOffset.z });
|
||||
length += 2.0f;
|
||||
}
|
||||
if (path.size() == 0) {
|
||||
path.push_back(Ogre::Vector3(0, 0, 0));
|
||||
path.push_back(Ogre::Vector3(0, 0, pathLength));
|
||||
}
|
||||
std::vector<Ogre::Vector3> tmppath = path;
|
||||
path.clear();
|
||||
for (auto &pt : tmppath) {
|
||||
if (path.size() == 0)
|
||||
path.push_back(pt);
|
||||
else {
|
||||
if (path.back().z + 0.5f >= pt.z)
|
||||
continue;
|
||||
else
|
||||
path.push_back(pt);
|
||||
}
|
||||
}
|
||||
Ogre::Vector3 lastp = path.back();
|
||||
for (i = 1; i < path.size(); i++) {
|
||||
Ogre::Vector3 &prev = path[i - 1];
|
||||
if (path[i].y > prev.y)
|
||||
continue;
|
||||
else if (path[i].y < prev.y) {
|
||||
float d = prev.y - path[i].y;
|
||||
if (d > 0.15f)
|
||||
path[i].y = prev.y - 0.15f;
|
||||
}
|
||||
}
|
||||
float dy = path.back().y - lastp.y;
|
||||
if (dy > 0)
|
||||
path.push_back({ lastp.x, lastp.y, path.back().z + dy * 3.0f });
|
||||
path.push_back({ path.back().x, path.back().y, path.back().z + 2.0f });
|
||||
}
|
||||
bool editHarbourDistrict(nlohmann::json &jitem)
|
||||
{
|
||||
float plazzaRadius = 5.0f;
|
||||
float plazzaHeight = 0.2f;
|
||||
float plazzaElevation = 0.0f;
|
||||
float centerOffset = 0.0f;
|
||||
bool plazza = false;
|
||||
bool changed = false;
|
||||
struct LotData {
|
||||
float distance;
|
||||
float angle;
|
||||
float width;
|
||||
float depth;
|
||||
float elevation;
|
||||
bool valid;
|
||||
Ogre::String type;
|
||||
Ogre::String properties;
|
||||
};
|
||||
std::vector<LotData> centerBuildings;
|
||||
nlohmann::json &j = jitem;
|
||||
if (j.find("centerOffset") != j.end())
|
||||
centerOffset = j["centerOffset"].get<float>();
|
||||
if (j.find("plazza") != j.end())
|
||||
plazza = j["plazza"].get<bool>();
|
||||
if (j.find("plazzaRadius") != j.end())
|
||||
plazzaRadius = j["plazzaRadius"].get<float>();
|
||||
if (j.find("plazzaHeight") != j.end())
|
||||
plazzaHeight = j["plazzaHeight"].get<float>();
|
||||
if (j.find("plazzaElevation") != j.end())
|
||||
plazzaElevation = j["plazzaElevation"].get<float>();
|
||||
if (j.find("centerBuildings") != j.end()) {
|
||||
for (auto &jb : j["centerBuildings"]) {
|
||||
LotData data;
|
||||
data.distance = 100.0f;
|
||||
data.angle = 0;
|
||||
data.width = 50.0f;
|
||||
data.depth = 50.0f;
|
||||
data.elevation = 0.0f;
|
||||
data.type = "base";
|
||||
data.properties = "{}";
|
||||
data.valid = true;
|
||||
if (jb.find("distance") != jb.end())
|
||||
data.distance = jb["distance"].get<float>();
|
||||
if (jb.find("angle") != jb.end())
|
||||
data.angle = jb["angle"].get<float>();
|
||||
if (jb.find("width") != jb.end())
|
||||
data.width = jb["width"].get<float>();
|
||||
if (jb.find("depth") != jb.end())
|
||||
data.depth = jb["depth"].get<float>();
|
||||
if (jb.find("elevation") != jb.end())
|
||||
data.elevation = jb["elevation"].get<float>();
|
||||
if (jb.find("type") != jb.end())
|
||||
data.type = jb["type"].get<Ogre::String>();
|
||||
if (jb.find("properties") != jb.end())
|
||||
data.properties =
|
||||
jb["properties"].get<Ogre::String>();
|
||||
centerBuildings.push_back(data);
|
||||
}
|
||||
}
|
||||
if (ImGui::SliderFloat("Center Offset", ¢erOffset, 0.0f, 100.0f))
|
||||
changed = true;
|
||||
if (ImGui::Checkbox("Plazza", &plazza))
|
||||
changed = true;
|
||||
if (plazza) {
|
||||
if (ImGui::SliderFloat("Plazza Radius", &plazzaRadius, 5.0f,
|
||||
100.0f))
|
||||
changed = true;
|
||||
if (ImGui::SliderFloat("Plazza Height", &plazzaHeight, 0.2f,
|
||||
1.0f))
|
||||
changed = true;
|
||||
if (ImGui::SliderFloat("Plazza Elevation", &plazzaElevation,
|
||||
-5.0f, 5.0f))
|
||||
changed = true;
|
||||
}
|
||||
int count = 0;
|
||||
for (auto &b : centerBuildings) {
|
||||
ImGui::Text("Lot %d", count);
|
||||
Ogre::String ms = "##" + Ogre::StringConverter::toString(count);
|
||||
if (ImGui::SliderFloat(("Lot distance" + ms).c_str(),
|
||||
&b.distance, 0.0f, 100.0f))
|
||||
changed = true;
|
||||
if (ImGui::SliderFloat(("Lot angle" + ms).c_str(), &b.angle,
|
||||
0.0f, 360.0f))
|
||||
changed = true;
|
||||
if (ImGui::SliderFloat(("Width" + ms).c_str(), &b.width, 10.0f,
|
||||
200.0f))
|
||||
changed = true;
|
||||
if (ImGui::SliderFloat(("Depth" + ms).c_str(), &b.depth, 10.0f,
|
||||
200.0f))
|
||||
changed = true;
|
||||
if (ImGui::SliderFloat(("Elevation" + ms).c_str(), &b.elevation,
|
||||
-10.0f, 10.0f))
|
||||
changed = true;
|
||||
if (ImGui::SmallButton(("Delete" + ms).c_str()))
|
||||
b.valid = false;
|
||||
count++;
|
||||
}
|
||||
if (ImGui::SmallButton("Add building")) {
|
||||
changed = true;
|
||||
LotData data;
|
||||
data.distance = 100.0f;
|
||||
data.angle = 0;
|
||||
data.width = 50.0f;
|
||||
data.depth = 50.0f;
|
||||
data.elevation = 0.0f;
|
||||
data.type = "base";
|
||||
data.properties = "{}";
|
||||
data.valid = true;
|
||||
centerBuildings.push_back(data);
|
||||
}
|
||||
if (changed) {
|
||||
j["centerOffset"] = centerOffset;
|
||||
j["plazza"] = plazza;
|
||||
j["plazzaRadius"] = plazzaRadius;
|
||||
j["plazzaHeight"] = plazzaHeight;
|
||||
j["plazzaElevation"] = plazzaElevation;
|
||||
nlohmann::json lots = nlohmann::json::array();
|
||||
for (const auto &d : centerBuildings) {
|
||||
nlohmann::json jdata;
|
||||
if (!d.valid)
|
||||
continue;
|
||||
jdata["distance"] = d.distance;
|
||||
jdata["angle"] = d.angle;
|
||||
jdata["width"] = d.width;
|
||||
jdata["depth"] = d.depth;
|
||||
jdata["elevation"] = d.elevation;
|
||||
jdata["type"] = d.type;
|
||||
jdata["properties"] = d.properties;
|
||||
lots.push_back(jdata);
|
||||
}
|
||||
j["centerBuildings"] = lots;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
void createHarbourPopup(const std::pair<flecs::entity, Ogre::String> item)
|
||||
{
|
||||
bool lighthouse = false;
|
||||
float lighthouseDistance = 0.0f;
|
||||
float lighthouseAngle = 0.0f;
|
||||
float centerOffset = 0.0f;
|
||||
bool changed = false;
|
||||
|
||||
Ogre::String prop = StaticGeometryModule::getItemProperties(item.first);
|
||||
nlohmann::json j = nlohmann::json::parse(prop);
|
||||
nlohmann::json jcenter = nlohmann::json::object();
|
||||
if (j.find("lighthouse") != j.end())
|
||||
lighthouse = j["lighthouse"].get<bool>();
|
||||
if (j.find("lighthouseDistance") != j.end())
|
||||
lighthouseDistance = j["lighthouseDistance"].get<float>();
|
||||
if (j.find("lighthouseAngle") != j.end())
|
||||
lighthouseAngle = j["lighthouseAngle"].get<float>();
|
||||
if (j.find("centerOffset") != j.end())
|
||||
centerOffset = j["centerOffset"].get<float>();
|
||||
if (j.find("center") != j.end())
|
||||
jcenter = j["center"];
|
||||
if (ImGui::Checkbox("Lighthouse", &lighthouse))
|
||||
changed = true;
|
||||
if (lighthouse) {
|
||||
if (ImGui::SliderFloat("Lighthouse Distance",
|
||||
&lighthouseDistance, 0.0f, 100.0f))
|
||||
changed = true;
|
||||
if (ImGui::SliderFloat("Lighthouse Angle", &lighthouseAngle,
|
||||
-90.0f, 90.0f))
|
||||
changed = true;
|
||||
}
|
||||
if (ImGui::SliderFloat("Center Offset Global", ¢erOffset, 0.0f,
|
||||
100.0f))
|
||||
changed = true;
|
||||
changed = changed || editHarbourDistrict(jcenter);
|
||||
if (changed) {
|
||||
j["lighthouse"] = lighthouse;
|
||||
j["lighthouseDistance"] = lighthouseDistance;
|
||||
j["lighthouseAngle"] = lighthouseAngle;
|
||||
j["center"] = jcenter;
|
||||
j["centerOffset"] = centerOffset;
|
||||
StaticGeometryModule::setItemProperties(item.first, j.dump());
|
||||
StaticGeometryModule::saveItems();
|
||||
StaticGeometryModule::destroyItemGeometry(item.first);
|
||||
StaticGeometryModule::createItemGeometry(item.first);
|
||||
}
|
||||
ImGui::Text("%s", j.dump(4).c_str());
|
||||
}
|
||||
void createHarbourItem()
|
||||
{
|
||||
Ogre::Vector3 itemPosition =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion itemOrientation =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedOrientation();
|
||||
float pierLength, pierDepth;
|
||||
float pierOffset;
|
||||
float pierHeight;
|
||||
if (!findPierOffsetAndLengthAndDepth(pierOffset, pierLength, pierDepth))
|
||||
return;
|
||||
findPierHeight(pierOffset + pierLength, pierHeight);
|
||||
std::vector<Ogre::Vector3> pierPath;
|
||||
findPierPath(pierOffset + 2.0f, pierPath);
|
||||
flecs::entity e = StaticGeometryModule::createItem(
|
||||
itemPosition, itemOrientation, "harbour");
|
||||
Ogre::String prop = StaticGeometryModule::getItemProperties(e);
|
||||
nlohmann::json j = nlohmann::json::parse(prop);
|
||||
j["pierOffset"] = pierOffset;
|
||||
j["pierLength"] = pierLength;
|
||||
j["pierDepth"] = pierDepth;
|
||||
j["pierHeight"] = pierHeight;
|
||||
nlohmann::json p = nlohmann::json::array();
|
||||
for (const auto &pt : pierPath) {
|
||||
nlohmann::json pj;
|
||||
to_json(pj, pt);
|
||||
p.push_back(pj);
|
||||
}
|
||||
j["pierPath"] = p;
|
||||
StaticGeometryModule::setItemProperties(e, j.dump());
|
||||
// setHarbourSurface();
|
||||
StaticGeometryModule::saveItems();
|
||||
// updateWorldTexture();
|
||||
// updateHeightmap();
|
||||
// TerrainModule::save_heightmap();
|
||||
}
|
||||
void createHarbourMenu()
|
||||
{
|
||||
if (ImGui::MenuItem("Create"))
|
||||
createHarbourItem();
|
||||
}
|
||||
}
|
||||
namespace Geometry
|
||||
{
|
||||
void createBridge(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo)
|
||||
{
|
||||
int i;
|
||||
Procedural::TriangleBuffer tb;
|
||||
Ogre::MaterialPtr harbourMaterial;
|
||||
harbourMaterial = Ogre::MaterialManager::getSingleton().getByName(
|
||||
"proceduralMaterialHarbour" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
float stepWidth = 12.0f;
|
||||
float stepHeight = 0.15f;
|
||||
float stepDepth = 0.25f;
|
||||
float stairsHeight = 0.0f;
|
||||
float stairsOffset = 0.0f;
|
||||
std::vector<Ogre::Vector3> pierPath;
|
||||
Ogre::String props = e.get<TerrainItem>().properties;
|
||||
nlohmann::json jp = nlohmann::json::parse(props);
|
||||
if (jp.find("stairsHeight") != jp.end())
|
||||
stairsHeight = jp["stairsHeight"].get<float>();
|
||||
if (jp.find("stairsOffset") != jp.end())
|
||||
stairsOffset = jp["stairsOffset"].get<float>();
|
||||
if (jp.find("stepHeight") != jp.end())
|
||||
stepHeight = jp["stepHeight"].get<float>();
|
||||
if (jp.find("stepDepth") != jp.end())
|
||||
stepDepth = jp["stepDepth"].get<float>();
|
||||
if (jp.find("pierPath") != jp.end()) {
|
||||
pierPath.reserve(jp["pierPath"].size());
|
||||
for (auto &jpt : jp["pierPath"]) {
|
||||
Ogre::Vector3 pt;
|
||||
from_json(jpt, pt);
|
||||
pierPath.push_back(pt);
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
Procedural::Shape *pierShape = new Procedural::Shape();
|
||||
pierShape->addPoint(8.f, -0.7f);
|
||||
pierShape->addPoint(6.f, 0.7f);
|
||||
pierShape->addPoint(6.05f, 0.65f);
|
||||
pierShape->addPoint(0.f, 0.6f);
|
||||
pierShape->addPoint(-6.05f, 0.65f);
|
||||
pierShape->addPoint(-6.0f, 0.7f);
|
||||
pierShape->addPoint(-8.f, -0.7f);
|
||||
pierShape->close();
|
||||
|
||||
Procedural::CubicHermiteSpline3 *pierCurve;
|
||||
Procedural::Path pierCurvePath;
|
||||
if (jp.find("pierPath") != jp.end()) {
|
||||
pierPath.reserve(jp["pierPath"].size());
|
||||
pierCurve = new Procedural::CubicHermiteSpline3();
|
||||
// pierCurve = new Procedural::RoundedCornerSpline3();
|
||||
#if 0
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 5; i++) {
|
||||
Ogre::Vector3 pt;
|
||||
from_json(jp["pierPath"][i], pt);
|
||||
pierPath.push_back(pt);
|
||||
pierCurve->addPoint(
|
||||
pt, pt - Ogre::Vector3(0, 0, -1),
|
||||
pt + Ogre::Vector3(0, 0, 1));
|
||||
}
|
||||
Ogre::Vector3 pt2;
|
||||
from_json(jp["pierPath"].back(), pt2);
|
||||
pierPath.push_back(pt2);
|
||||
pierCurve->addPoint(pt2);
|
||||
for (const auto &m : pierPath) {
|
||||
std::cout << m << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if 1
|
||||
for (auto &jpt : jp["pierPath"]) {
|
||||
Ogre::Vector3 pt;
|
||||
from_json(jpt, pt);
|
||||
pierPath.push_back(pt);
|
||||
pierCurve->addPoint(pt, Ogre::Vector3(0, 0, 1));
|
||||
// pierCurve->addPoint(pt);
|
||||
}
|
||||
#endif
|
||||
OgreAssert(pierPath.size() > 0, "empty path");
|
||||
// pierCurve->setNumSeg(8);
|
||||
pierCurvePath = pierCurve->realizePath();
|
||||
// V
|
||||
Procedural::Track shapeTextureTrack =
|
||||
Procedural::Track(Procedural::Track::AM_POINT)
|
||||
.addKeyFrame(0, 0.0f)
|
||||
.addKeyFrame(6, 0.1f);
|
||||
// U
|
||||
Procedural::Track pathTextureTrack =
|
||||
Procedural::Track(Procedural::Track::AM_POINT)
|
||||
.addKeyFrame(0, 0.45f)
|
||||
.addKeyFrame(6, 0.9f);
|
||||
Procedural::Extruder extruder;
|
||||
extruder.setShapeTextureTrack(&shapeTextureTrack)
|
||||
.setPathTextureTrack(&pathTextureTrack)
|
||||
.setShapeToExtrude(pierShape)
|
||||
.setExtrusionPath(&pierCurvePath)
|
||||
.setEnableNormals(true)
|
||||
.setUTile(1.0f)
|
||||
.setVTile(1.0f)
|
||||
.addToTriangleBuffer(tb);
|
||||
for (auto &v : tb.getVertices()) {
|
||||
v.mUV.x = Ogre::Math::Clamp(v.mUV.x, 0.41f, 0.9f);
|
||||
v.mUV.y = Ogre::Math::Clamp(v.mUV.y, 0.0f, 0.1f);
|
||||
}
|
||||
#if 0
|
||||
for (const auto &v : tb.getVertices()) {
|
||||
std::cout << "UV: " << v.mUV << std::endl;
|
||||
}
|
||||
OgreAssert(false, "uvs");
|
||||
#endif
|
||||
#if 0
|
||||
Ogre::LodConfig config(extrudedMesh);
|
||||
setupLods(config);
|
||||
Ogre::Entity *pathEnt =
|
||||
ECS::get<EngineData>().mScnMgr->createEntity(
|
||||
extrudedMesh);
|
||||
pathEnt->setMaterial(harbourMaterial);
|
||||
float xofft = 0.0f;
|
||||
Ogre::Vector3 worldPosition =
|
||||
sceneNode->_getDerivedPosition() +
|
||||
sceneNode->_getDerivedOrientation() *
|
||||
Ogre::Vector3::UNIT_Z * 0.0f;
|
||||
Ogre::Quaternion worldOrientation =
|
||||
sceneNode->_getDerivedOrientation();
|
||||
Ogre::Vector3 xoffset =
|
||||
worldOrientation * (Ogre::Vector3::UNIT_X * xofft);
|
||||
geo->addEntity(pathEnt, worldPosition + xoffset,
|
||||
worldOrientation, Ogre::Vector3(1, 1, 1));
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < pierPath.size(); i++) {
|
||||
if (i == 0)
|
||||
continue;
|
||||
Ogre::Vector3 lvec = pierPath[i] - pierPath[i - 1];
|
||||
Ogre::Vector3 xvec = Ogre::Vector3::UNIT_Y.crossProduct(lvec);
|
||||
Ogre::Vector3 n = lvec.crossProduct(xvec).normalisedCopy();
|
||||
Ogre::Vector3 pos = (pierPath[i] + pierPath[i - 1]) * 0.5f;
|
||||
Procedural::PlaneGenerator()
|
||||
.setNormal(n)
|
||||
.setNumSegX(2)
|
||||
.setNumSegY(2)
|
||||
.setSizeX(1)
|
||||
.setSizeY(1)
|
||||
.setPosition(pos)
|
||||
.addToTriangleBuffer(tb);
|
||||
}
|
||||
#endif
|
||||
Ogre::String meshName =
|
||||
"pierPathMesh" + Ogre::StringConverter::toString(e.id());
|
||||
Ogre::MeshPtr mesh =
|
||||
Ogre::MeshManager::getSingleton().getByName(meshName);
|
||||
if (mesh)
|
||||
Ogre::MeshManager::getSingleton().remove(mesh);
|
||||
mesh = tb.transformToMesh(meshName);
|
||||
Ogre::LodConfig config(mesh);
|
||||
setupLods(config);
|
||||
Ogre::Entity *pathEnt =
|
||||
ECS::get<EngineData>().mScnMgr->createEntity(mesh);
|
||||
pathEnt->setMaterial(harbourMaterial);
|
||||
float xofft = 0.0f;
|
||||
Ogre::Vector3 worldPosition = sceneNode->_getDerivedPosition() +
|
||||
sceneNode->_getDerivedOrientation() *
|
||||
Ogre::Vector3::UNIT_Z * 0.0f;
|
||||
Ogre::Quaternion worldOrientation = sceneNode->_getDerivedOrientation();
|
||||
Ogre::Vector3 xoffset =
|
||||
worldOrientation * (Ogre::Vector3::UNIT_X * xofft);
|
||||
geo->addEntity(pathEnt, worldPosition + xoffset, worldOrientation,
|
||||
Ogre::Vector3(1, 1, 1));
|
||||
ECS::get<EngineData>().mScnMgr->destroyEntity(pathEnt);
|
||||
}
|
||||
void createPier(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo)
|
||||
{
|
||||
Ogre::MaterialPtr harbourMaterial;
|
||||
harbourMaterial = Ogre::MaterialManager::getSingleton().getByName(
|
||||
"proceduralMaterialHarbour" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
harbourMaker hm(e);
|
||||
Ogre::Vector3 position = sceneNode->_getDerivedPosition();
|
||||
Ogre::String props = e.get<TerrainItem>().properties;
|
||||
nlohmann::json jp = nlohmann::json::parse(props);
|
||||
float pierHeight = 0.0f, pierLength = 6.0f, pierDepth = 6.0f;
|
||||
if (jp.find("pierLength") != jp.end())
|
||||
pierLength = jp["pierLength"].get<float>();
|
||||
if (jp.find("pierDepth") != jp.end())
|
||||
pierDepth = jp["pierDepth"].get<float>();
|
||||
if (jp.find("pierHeight") != jp.end())
|
||||
pierHeight = jp["pierHeight"].get<float>();
|
||||
Procedural::TriangleBuffer tb;
|
||||
float plankLength = 2.0f;
|
||||
float plankWidth = 4.01f;
|
||||
float plankHeight = 0.3f;
|
||||
const float beamLength = 6.0f;
|
||||
const float beamWidth = 5.5f;
|
||||
float beamHeight = 0.3f;
|
||||
if (pierLength < 12.0f)
|
||||
pierLength = 12.0f;
|
||||
auto processGrid = [&sceneNode, &geo](float stepLength, float length,
|
||||
float zoffset, float yofft,
|
||||
float xofft, Ogre::Entity *ent) {
|
||||
float step = 0.0f;
|
||||
while (step < length) {
|
||||
Ogre::Vector3 worldPosition =
|
||||
sceneNode->_getDerivedPosition() +
|
||||
sceneNode->_getDerivedOrientation() *
|
||||
Ogre::Vector3::UNIT_Z *
|
||||
(step + zoffset);
|
||||
Ogre::Quaternion worldOrientation =
|
||||
sceneNode->_getDerivedOrientation();
|
||||
Ogre::Vector3 xoffset = worldOrientation *
|
||||
(Ogre::Vector3::UNIT_X * xofft);
|
||||
Ogre::Vector3 yoffset = worldOrientation *
|
||||
(Ogre::Vector3::UNIT_Y * yofft);
|
||||
geo->addEntity(ent, worldPosition + xoffset + yoffset,
|
||||
worldOrientation,
|
||||
Ogre::Vector3(1, 1, 1));
|
||||
step += stepLength;
|
||||
}
|
||||
};
|
||||
float xofftPlanks;
|
||||
for (xofftPlanks = -plankWidth; xofftPlanks <= plankWidth;
|
||||
xofftPlanks += plankWidth)
|
||||
processGrid(plankLength, pierLength, plankLength / 2.0f,
|
||||
plankHeight / 2.0f + beamHeight / 2.0f, xofftPlanks,
|
||||
hm.planks);
|
||||
{
|
||||
Procedural::TriangleBuffer tbPillars, tbBollards;
|
||||
float step = 0.0f;
|
||||
while (step < pierLength) {
|
||||
// pillars
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(0.5f)
|
||||
.setSizeY(pierDepth)
|
||||
.setSizeZ(0.5f)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(
|
||||
-5.0f, -pierDepth / 2.0f + 0.5f, step))
|
||||
.addToTriangleBuffer(tbPillars);
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(0.5f)
|
||||
.setSizeY(pierDepth)
|
||||
.setSizeZ(0.5f)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(
|
||||
5.0f, -pierDepth / 2.0f + 0.5f, step))
|
||||
.addToTriangleBuffer(tbPillars);
|
||||
step += 6.0f;
|
||||
}
|
||||
step = pierLength - 0.5f;
|
||||
while (step >= 0.0f) {
|
||||
// bollards
|
||||
Procedural::CylinderGenerator()
|
||||
.setHeight(0.8f)
|
||||
.setRadius(0.3f)
|
||||
.setPosition(Ogre::Vector3(
|
||||
-5.3f, 0.4f + 0.5f + 0.1f, step))
|
||||
.addToTriangleBuffer(tbBollards);
|
||||
Procedural::CylinderGenerator()
|
||||
.setHeight(0.8f)
|
||||
.setRadius(0.3f)
|
||||
.setPosition(Ogre::Vector3(
|
||||
5.3f, 0.4f + 0.5f + 0.1f, step))
|
||||
.addToTriangleBuffer(tbBollards);
|
||||
step -= 12.0f;
|
||||
}
|
||||
// beams
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(0.5f)
|
||||
.setSizeY(beamHeight)
|
||||
.setSizeZ(pierLength)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(-5.0f,
|
||||
0.2 + beamHeight / 2.0f,
|
||||
pierLength / 2.0f))
|
||||
.addToTriangleBuffer(tbPillars);
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(0.5f)
|
||||
.setSizeY(beamHeight)
|
||||
.setSizeZ(pierLength)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(5.0f,
|
||||
0.2 + beamHeight / 2.0f,
|
||||
pierLength / 2.0f))
|
||||
.addToTriangleBuffer(tbPillars);
|
||||
for (auto &v : tbPillars.getVertices()) {
|
||||
v.mUV *= 0.08f;
|
||||
v.mUV += Ogre::Vector2(0.01f, 0.01f);
|
||||
v.mUV.x = Ogre::Math::Clamp(v.mUV.x, 0.0f, 0.1f);
|
||||
v.mUV.y = Ogre::Math::Clamp(v.mUV.y, 0.0f, 0.1f);
|
||||
}
|
||||
for (auto &v : tbBollards.getVertices()) {
|
||||
v.mUV *= 0.08f;
|
||||
v.mUV.x += 0.21f;
|
||||
v.mUV.y += 0.01f;
|
||||
v.mUV.x = Ogre::Math::Clamp(v.mUV.x, 0.2f, 0.3f);
|
||||
v.mUV.y = Ogre::Math::Clamp(v.mUV.y, 0.0f, 0.1f);
|
||||
}
|
||||
tb.append(tbPillars);
|
||||
tb.append(tbBollards);
|
||||
}
|
||||
Ogre::String meshName =
|
||||
"pier" + Ogre::StringConverter::toString(e.id());
|
||||
{
|
||||
Ogre::MeshPtr mesh =
|
||||
Ogre::MeshManager::getSingleton().getByName(meshName);
|
||||
if (mesh)
|
||||
Ogre::MeshManager::getSingleton().remove(mesh);
|
||||
|
||||
mesh = tb.transformToMesh(meshName);
|
||||
Ogre::LodConfig config(mesh);
|
||||
// config.advanced.useCompression = false;
|
||||
// config.advanced.useVertexNormals = true;
|
||||
setupLods(config);
|
||||
Ogre::Entity *ent =
|
||||
ECS::get<EngineData>().mScnMgr->createEntity(mesh);
|
||||
ent->setMaterial(harbourMaterial);
|
||||
float xofft = 0.0f;
|
||||
Ogre::Vector3 worldPosition =
|
||||
sceneNode->_getDerivedPosition() +
|
||||
sceneNode->_getDerivedOrientation() *
|
||||
Ogre::Vector3::UNIT_Z * 0.0f;
|
||||
Ogre::Quaternion worldOrientation =
|
||||
sceneNode->_getDerivedOrientation();
|
||||
Ogre::Vector3 xoffset =
|
||||
worldOrientation * (Ogre::Vector3::UNIT_X * xofft);
|
||||
geo->addEntity(ent, worldPosition + xoffset, worldOrientation,
|
||||
Ogre::Vector3(1, 1, 1));
|
||||
}
|
||||
std::cout << meshName << std::endl;
|
||||
}
|
||||
void createPlazza(flecs::entity e, const nlohmann::json &district,
|
||||
Ogre::SceneNode *sceneNode, Ogre::StaticGeometry *geo)
|
||||
{
|
||||
Ogre::MaterialPtr harbourMaterial;
|
||||
harbourMaterial = Ogre::MaterialManager::getSingleton().getByName(
|
||||
"proceduralMaterialHarbour" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
Ogre::Vector3 worldPosition = sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion worldOrientation = sceneNode->_getDerivedOrientation();
|
||||
const nlohmann::json &jp = district;
|
||||
Procedural::TriangleBuffer tb;
|
||||
float centerOffset = 0.0f;
|
||||
float plazzaRadius = 5.0f;
|
||||
float plazzaHeight = 0.2f;
|
||||
float plazzaElevation = 0.0f;
|
||||
if (jp.find("centerOffset") != jp.end())
|
||||
centerOffset = jp["centerOffset"].get<float>();
|
||||
if (jp.find("plazzaRadius") != jp.end())
|
||||
plazzaRadius = jp["plazzaRadius"].get<float>();
|
||||
if (jp.find("plazzaHeight") != jp.end())
|
||||
plazzaHeight = jp["plazzaHeight"].get<float>();
|
||||
if (jp.find("plazzaElevation") != jp.end())
|
||||
plazzaElevation = jp["plazzaElevation"].get<float>();
|
||||
if (plazzaHeight < 0.1f)
|
||||
plazzaHeight = 0.1f;
|
||||
if (plazzaRadius < 5.0f)
|
||||
plazzaRadius = 5.0f;
|
||||
Ogre::Vector3 worldPlazzaCenter = worldPosition;
|
||||
#if 0
|
||||
Procedural::CylinderGenerator()
|
||||
.setHeight(plazzaHeight)
|
||||
.setRadius(plazzaRadius)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(
|
||||
0.0f, plazzaHeight / 2.0f + plazzaElevation, 0.0f))
|
||||
.addToTriangleBuffer(tb);
|
||||
#endif
|
||||
float mh = 4.0f;
|
||||
Procedural::Shape *plazzaShape = new Procedural::Shape();
|
||||
plazzaShape->addPoint(0, -plazzaHeight - mh - mh);
|
||||
plazzaShape->addPoint(plazzaRadius * 0.5f + mh,
|
||||
-plazzaHeight - mh - mh);
|
||||
plazzaShape->addPoint(plazzaRadius + mh, -plazzaHeight - mh);
|
||||
plazzaShape->addPoint(plazzaRadius, -plazzaHeight);
|
||||
plazzaShape->addPoint(plazzaRadius, 0.0f);
|
||||
plazzaShape->addPoint(plazzaRadius - 0.1f, 0.1f);
|
||||
plazzaShape->addPoint(plazzaRadius - mh + 0.1f, plazzaHeight);
|
||||
plazzaShape->addPoint(plazzaRadius - mh, plazzaHeight + 0.1f);
|
||||
plazzaShape->addPoint(plazzaRadius * 0.5f + mh, plazzaHeight);
|
||||
plazzaShape->addPoint(0, plazzaHeight);
|
||||
Procedural::Lathe()
|
||||
.setShapeToExtrude(plazzaShape)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(
|
||||
0.0f, plazzaHeight / 2.0f + plazzaElevation, 0.0f))
|
||||
.setNumSeg(24)
|
||||
.addToTriangleBuffer(tb);
|
||||
for (auto &v : tb.getVertices()) {
|
||||
v.mUV *= 0.08f;
|
||||
v.mUV.x += 0.41f;
|
||||
v.mUV.x = Ogre::Math::Clamp(v.mUV.x, 0.4f, 0.5f);
|
||||
v.mUV.y = Ogre::Math::Clamp(v.mUV.y, 0.0f, 0.1f);
|
||||
}
|
||||
Ogre::String meshName =
|
||||
"plazzaMesh" + Ogre::StringConverter::toString(e.id());
|
||||
Ogre::MeshPtr mesh =
|
||||
Ogre::MeshManager::getSingleton().getByName(meshName);
|
||||
if (mesh)
|
||||
Ogre::MeshManager::getSingleton().remove(mesh);
|
||||
mesh = tb.transformToMesh(meshName);
|
||||
Ogre::LodConfig config(mesh);
|
||||
setupLods(config);
|
||||
Ogre::Entity *pathEnt =
|
||||
ECS::get<EngineData>().mScnMgr->createEntity(mesh);
|
||||
pathEnt->setMaterial(harbourMaterial);
|
||||
geo->addEntity(pathEnt, worldPlazzaCenter, worldOrientation,
|
||||
Ogre::Vector3(1, 1, 1));
|
||||
}
|
||||
|
||||
void createBuildings(flecs::entity e, const nlohmann::json &district,
|
||||
Ogre::SceneNode *sceneNode, Ogre::StaticGeometry *geo)
|
||||
{
|
||||
Ogre::MaterialPtr harbourMaterial;
|
||||
harbourMaterial = Ogre::MaterialManager::getSingleton().getByName(
|
||||
"proceduralMaterialHarbour" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
nlohmann::json jbuildings = nlohmann::json::array();
|
||||
if (district.find("centerBuildings") != district.end())
|
||||
jbuildings = district["centerBuildings"];
|
||||
Ogre::Vector3 centerPosition = sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion centerOrientation =
|
||||
sceneNode->_getDerivedOrientation();
|
||||
int count = 0;
|
||||
float baseHeight = 4.0f;
|
||||
for (const auto &jb : jbuildings) {
|
||||
Procedural::TriangleBuffer tb;
|
||||
float angle = 0.0f;
|
||||
float depth = 50.0f;
|
||||
float width = 100.0f;
|
||||
float distance = 100.0f;
|
||||
float elevation = 0.0f;
|
||||
std::cout << jb.dump() << std::endl;
|
||||
if (jb.find("angle") != jb.end())
|
||||
angle = jb["angle"].get<float>();
|
||||
if (jb.find("depth") != jb.end())
|
||||
depth = jb["depth"].get<float>();
|
||||
if (jb.find("width") != jb.end())
|
||||
width = jb["width"].get<float>();
|
||||
if (jb.find("distance") != jb.end())
|
||||
distance = jb["distance"].get<float>();
|
||||
if (jb.find("elevation") != jb.end())
|
||||
elevation = jb["elevation"].get<float>();
|
||||
|
||||
OgreAssert(width > 1 && depth > 1 && baseHeight > 1,
|
||||
"Bad stuff happen");
|
||||
|
||||
Ogre::Quaternion rotation = Ogre::Quaternion(
|
||||
Ogre::Degree(angle), Ogre::Vector3::UNIT_Y);
|
||||
Ogre::Vector3 offset = centerOrientation * rotation *
|
||||
(Ogre::Vector3::UNIT_Z * distance);
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(width)
|
||||
.setSizeY(baseHeight)
|
||||
.setSizeZ(depth)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(
|
||||
0.0f, -baseHeight / 2.0f + elevation, 0.0f))
|
||||
.addToTriangleBuffer(tb);
|
||||
OgreAssert(tb.getVertices().size() > 8, "bad box");
|
||||
for (auto &v : tb.getVertices()) {
|
||||
float c = 1.0 + 1.0 / (v.mPosition.y + baseHeight +
|
||||
elevation);
|
||||
v.mPosition.x *= c;
|
||||
v.mPosition.z *= c;
|
||||
v.mUV *= 0.08f;
|
||||
v.mUV.x += 0.41f;
|
||||
v.mUV.x = Ogre::Math::Clamp(v.mUV.x, 0.4f, 0.5f);
|
||||
v.mUV.y = Ogre::Math::Clamp(v.mUV.y, 0.0f, 0.1f);
|
||||
}
|
||||
Ogre::String meshName =
|
||||
"lotbase" + Ogre::StringConverter::toString(count) +
|
||||
"_" + Ogre::StringConverter::toString(e.id());
|
||||
Ogre::MeshPtr mesh =
|
||||
Ogre::MeshManager::getSingleton().getByName(meshName);
|
||||
if (mesh)
|
||||
Ogre::MeshManager::getSingleton().remove(mesh);
|
||||
mesh = tb.transformToMesh(meshName);
|
||||
Ogre::LodConfig config(mesh);
|
||||
setupLods(config);
|
||||
Ogre::Entity *ent =
|
||||
ECS::get<EngineData>().mScnMgr->createEntity(
|
||||
"Ent" + meshName, mesh);
|
||||
ent->setMaterial(harbourMaterial);
|
||||
geo->addEntity(ent, centerPosition + offset, rotation,
|
||||
Ogre::Vector3::UNIT_SCALE);
|
||||
ECS::get<EngineData>().mScnMgr->destroyEntity(ent);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
void createHarbour(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo)
|
||||
{
|
||||
std::cout << "createHarbour " << e.id() << std::endl;
|
||||
Ogre::MaterialPtr harbourMaterial;
|
||||
harbourMaterial = Ogre::MaterialManager::getSingleton().getByName(
|
||||
"proceduralMaterialHarbour" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
if (!harbourMaterial) {
|
||||
Procedural::TextureBuffer colorAtlas(1024);
|
||||
Procedural::RectangleTexture drawAtlas(&colorAtlas);
|
||||
Ogre::ColourValue normalYellow(0.8f, 0.6f, 0, 1);
|
||||
Ogre::ColourValue roadBrown(0.4f, 0.3f, 0.3f, 1);
|
||||
Ogre::ColourValue bollardGrey(0.2f, 0.2f, 0.2f, 1);
|
||||
drawAtlas.setRectangle(Ogre::RealRect(0.0f, 0.0f, 0.4f, 1.0f))
|
||||
.setColour(normalYellow)
|
||||
.process();
|
||||
drawAtlas.setRectangle(Ogre::RealRect(0.2f, 0.0f, 0.3f, 1.0f))
|
||||
.setColour(bollardGrey)
|
||||
.process();
|
||||
drawAtlas.setRectangle(Ogre::RealRect(0.4f, 0.0f, 1.0f, 1.0f))
|
||||
.setColour(roadBrown)
|
||||
.process();
|
||||
Ogre::TexturePtr pierTexture = colorAtlas.createTexture(
|
||||
"proceduralTextureHarbour" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
colorAtlas.saveImage("tmp.png");
|
||||
harbourMaterial =
|
||||
Ogre::MaterialManager::getSingletonPtr()->create(
|
||||
"proceduralMaterialHarbour" +
|
||||
Ogre::StringConverter::toString(e.id()),
|
||||
Ogre::ResourceGroupManager::
|
||||
DEFAULT_RESOURCE_GROUP_NAME);
|
||||
harbourMaterial->getTechnique(0)->getPass(0)->setShininess(0);
|
||||
harbourMaterial->getTechnique(0)->getPass(0)->setDiffuse(
|
||||
Ogre::ColourValue::White);
|
||||
harbourMaterial->getTechnique(0)->getPass(0)->setSpecular(
|
||||
Ogre::ColourValue(1.0f, 1.0f, 0.9f));
|
||||
harbourMaterial->getTechnique(0)
|
||||
->getPass(0)
|
||||
->createTextureUnitState(
|
||||
"proceduralTextureHarbour" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
if (Ogre::RTShader::ShaderGenerator::initialize()) {
|
||||
harbourMaterial->prepare();
|
||||
Ogre::RTShader::ShaderGenerator *mShaderGenerator =
|
||||
Ogre::RTShader::ShaderGenerator::
|
||||
getSingletonPtr();
|
||||
mShaderGenerator->createShaderBasedTechnique(
|
||||
*harbourMaterial,
|
||||
Ogre::MaterialManager::DEFAULT_SCHEME_NAME,
|
||||
Ogre::RTShader::ShaderGenerator::
|
||||
DEFAULT_SCHEME_NAME);
|
||||
Ogre::RTShader::RenderState *pMainRenderState =
|
||||
mShaderGenerator->getRenderState(
|
||||
Ogre::RTShader::ShaderGenerator::
|
||||
DEFAULT_SCHEME_NAME,
|
||||
*harbourMaterial);
|
||||
}
|
||||
}
|
||||
{
|
||||
Ogre::String props = e.get<TerrainItem>().properties;
|
||||
nlohmann::json jp = nlohmann::json::parse(props);
|
||||
float pierOffset = 0.0f;
|
||||
float centerOffset = 0.0f;
|
||||
float plazzaRadius = 5.0f;
|
||||
bool plazza = false;
|
||||
nlohmann::json jcenter = nlohmann::json::object();
|
||||
if (jp.find("center") != jp.end())
|
||||
jcenter = jp["center"];
|
||||
if (jcenter.find("plazzaRadius") != jcenter.end())
|
||||
plazzaRadius = jcenter["plazzaRadius"];
|
||||
if (jp.find("pierOffset") != jp.end())
|
||||
pierOffset = jp["pierOffset"].get<float>();
|
||||
if (jp.find("plazza") != jp.end())
|
||||
plazza = jp["plazza"].get<bool>();
|
||||
if (jp.find("centerOffset") != jp.end())
|
||||
centerOffset = jp["centerOffset"].get<float>();
|
||||
Ogre::Vector3 worldPosition =
|
||||
sceneNode->_getDerivedPosition() +
|
||||
sceneNode->_getDerivedOrientation() *
|
||||
Ogre::Vector3::UNIT_Z * (pierOffset);
|
||||
float xofft = 0.0f;
|
||||
float stairLengthZ = worldPosition.y;
|
||||
float stairsOffset = 0.0f;
|
||||
stairsOffset = stairLengthZ;
|
||||
jp["stairsHeight"] = worldPosition.y;
|
||||
jp["stairsOffset"] = stairsOffset;
|
||||
e.get_mut<TerrainItem>().properties = jp.dump();
|
||||
e.modified<TerrainItem>();
|
||||
worldPosition.y = 0.0f;
|
||||
Ogre::Quaternion worldOrientation =
|
||||
sceneNode->_getDerivedOrientation();
|
||||
Ogre::Vector3 xoffset =
|
||||
worldOrientation * (Ogre::Vector3::UNIT_X * xofft);
|
||||
Ogre::Vector3 zoffset =
|
||||
worldOrientation *
|
||||
(Ogre::Vector3::UNIT_Z * (stairsOffset - 1));
|
||||
Ogre::SceneNode *elevatorNode =
|
||||
sceneNode->createChildSceneNode();
|
||||
Ogre::SceneNode *pierNode = sceneNode->createChildSceneNode();
|
||||
pierNode->_setDerivedPosition(worldPosition + zoffset +
|
||||
xoffset);
|
||||
Ogre::Vector3 worldPlazzaCenter =
|
||||
sceneNode->_getDerivedPosition() +
|
||||
sceneNode->_getDerivedOrientation() *
|
||||
Ogre::Vector3::UNIT_Z *
|
||||
(-centerOffset - plazzaRadius + 2.0f);
|
||||
Ogre::SceneNode *centerNode = sceneNode->createChildSceneNode();
|
||||
centerNode->_setDerivedPosition(worldPlazzaCenter);
|
||||
createBridge(e, elevatorNode, geo);
|
||||
createPier(e, pierNode, geo);
|
||||
createPlazza(e, jcenter, centerNode, geo);
|
||||
createBuildings(e, jcenter, centerNode, geo);
|
||||
}
|
||||
geo->build();
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/gamedata/items/harbour.h
Normal file
25
src/gamedata/items/harbour.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef __HARBOUR_H__
|
||||
#define __HARBOUR_H__
|
||||
#include <flecs.h>
|
||||
namespace ECS
|
||||
{
|
||||
namespace Items
|
||||
{
|
||||
void createHarbourPopup(const std::pair<flecs::entity, Ogre::String> item);
|
||||
void createHarbourMenu();
|
||||
}
|
||||
namespace Geometry
|
||||
{
|
||||
void createHarbour(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
void createBridge(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
void createPier(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
void createPlazza(flecs::entity e, const nlohmann::json &district,
|
||||
Ogre::SceneNode *sceneNode, Ogre::StaticGeometry *geo);
|
||||
void createBuildings(flecs::entity e, const nlohmann::json &district,
|
||||
Ogre::SceneNode *sceneNode, Ogre::StaticGeometry *geo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
223
src/gamedata/items/items.cpp
Normal file
223
src/gamedata/items/items.cpp
Normal file
@@ -0,0 +1,223 @@
|
||||
#include <iostream>
|
||||
#include <Ogre.h>
|
||||
#include <OgreImGuiOverlay.h>
|
||||
#include <OgreTerrainGroup.h>
|
||||
#include <OgreRTShaderSystem.h>
|
||||
#include <OgreMeshLodGenerator.h>
|
||||
#include <Procedural.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
#include "StaticGeometryModule.h"
|
||||
#include "EditorGizmoModule.h"
|
||||
#include "TerrainModule.h"
|
||||
#include "physics.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "harbour.h"
|
||||
#include "temple.h"
|
||||
#include "town.h"
|
||||
#include "items.h"
|
||||
namespace ECS
|
||||
{
|
||||
namespace Items
|
||||
{
|
||||
void showItemPopup(const std::pair<flecs::entity, Ogre::String> &item)
|
||||
{
|
||||
Ogre::String popupLabel =
|
||||
"EditPopup" + Ogre::StringConverter::toString(item.first.id());
|
||||
if (ImGui::BeginPopup(popupLabel.c_str())) {
|
||||
Ogre::String prop =
|
||||
StaticGeometryModule::getItemProperties(item.first);
|
||||
nlohmann::json j = nlohmann::json::parse(prop);
|
||||
Ogre::String itemType = j["type"].get<Ogre::String>();
|
||||
if (itemType == "harbour")
|
||||
createHarbourPopup(item);
|
||||
else if (itemType == "temple")
|
||||
createTemplePopup(item);
|
||||
else if (itemType == "town")
|
||||
createTownPopup(item);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
void showItemButtons(const std::pair<flecs::entity, Ogre::String> &item)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
Ogre::String upd_label =
|
||||
"Update Height##" +
|
||||
Ogre::StringConverter::toString(item.first.id());
|
||||
if (ImGui::SmallButton(upd_label.c_str())) {
|
||||
TerrainItem &uitem = item.first.get_mut<TerrainItem>();
|
||||
uitem.position.y =
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainGroup->getHeightAtWorldPosition(
|
||||
uitem.position);
|
||||
StaticGeometryModule::saveItems();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
Ogre::String edit_label =
|
||||
"Edit##" + Ogre::StringConverter::toString(item.first.id());
|
||||
Ogre::String popupLabel =
|
||||
"EditPopup" + Ogre::StringConverter::toString(item.first.id());
|
||||
if (ImGui::SmallButton(edit_label.c_str()))
|
||||
ImGui::OpenPopup(popupLabel.c_str());
|
||||
ImGui::SameLine();
|
||||
Ogre::String del_label =
|
||||
"delete##" + Ogre::StringConverter::toString(item.first.id());
|
||||
if (ImGui::SmallButton(del_label.c_str())) {
|
||||
item.first.destruct();
|
||||
StaticGeometryModule::saveItems();
|
||||
}
|
||||
ImGui::Spacing();
|
||||
}
|
||||
void createItemsMenu()
|
||||
{
|
||||
if (ImGui::BeginMenu("Harbour")) {
|
||||
Items::createHarbourMenu();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Temple")) {
|
||||
Items::createTempleMenu();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Town")) {
|
||||
Items::createTownMenu();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Geometry
|
||||
{
|
||||
void setupLods(Ogre::LodConfig &config)
|
||||
{
|
||||
// config.advanced.useCompression = false;
|
||||
// config.advanced.useVertexNormals = true;
|
||||
config.advanced.preventPunchingHoles = true;
|
||||
config.advanced.preventBreakingLines = true;
|
||||
config.createGeneratedLodLevel(10, 0.15f);
|
||||
config.createGeneratedLodLevel(30, 0.25f);
|
||||
config.createGeneratedLodLevel(60, 0.36f);
|
||||
config.createGeneratedLodLevel(150, 0.65f);
|
||||
config.advanced.useBackgroundQueue = false;
|
||||
Ogre::MeshLodGenerator::getSingleton().generateLodLevels(config);
|
||||
}
|
||||
|
||||
Ogre::StaticGeometry *createStaticGeometry(flecs::entity e)
|
||||
{
|
||||
Ogre::String props = e.get<TerrainItem>().properties;
|
||||
nlohmann::json jp = nlohmann::json::parse(props);
|
||||
if (jp.find("type") != jp.end()) {
|
||||
Ogre::String itemType = jp["type"].get<Ogre::String>();
|
||||
Ogre::String geoName = itemType + "_" +
|
||||
Ogre::StringConverter::toString(e.id());
|
||||
OgreAssert((ECS::get<EngineData>().mScnMgr->hasStaticGeometry(
|
||||
geoName)) == false,
|
||||
"" + geoName + " already exists for some reason");
|
||||
Ogre::StaticGeometry *geo =
|
||||
ECS::get<EngineData>().mScnMgr->createStaticGeometry(
|
||||
geoName);
|
||||
return geo;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
void createItemGeometry(flecs::entity e)
|
||||
{
|
||||
OgreAssert(!e.has<TerrainItemNode>(), "Geometry already created");
|
||||
std::cout << "creating geometry for item: " << e.id() << std::endl;
|
||||
Ogre::String props = e.get<TerrainItem>().properties;
|
||||
nlohmann::json jp = nlohmann::json::parse(props);
|
||||
Ogre::SceneNode *itemNode = ECS::get<EngineData>()
|
||||
.mScnMgr->getRootSceneNode()
|
||||
->createChildSceneNode();
|
||||
itemNode->_setDerivedPosition(e.get<TerrainItem>().position);
|
||||
itemNode->_setDerivedOrientation(e.get<TerrainItem>().orientation);
|
||||
if (jp.find("staticMesh") != jp.end()) {
|
||||
Ogre::String meshName = jp["staticMesh"].get<Ogre::String>();
|
||||
Ogre::MeshPtr mesh =
|
||||
Ogre::MeshManager::getSingleton().getByName(meshName);
|
||||
if (mesh) {
|
||||
Ogre::Entity *ent =
|
||||
ECS::get<EngineData>().mScnMgr->createEntity(
|
||||
mesh);
|
||||
itemNode->attachObject(ent);
|
||||
}
|
||||
} else if (jp.find("type") != jp.end()) {
|
||||
Ogre::String itemType = jp["type"].get<Ogre::String>();
|
||||
std::cout << "type: " << itemType << std::endl;
|
||||
std::cout << "props: " << props << std::endl;
|
||||
Ogre::StaticGeometry *geo = createStaticGeometry(e);
|
||||
if (geo) {
|
||||
geo->setRegionDimensions(Ogre::Vector3(140, 140, 140));
|
||||
Ogre::Vector3 geoposition =
|
||||
itemNode->_getDerivedPosition();
|
||||
geoposition.y = 0.0f;
|
||||
geo->setOrigin(geoposition);
|
||||
}
|
||||
if (itemType == "harbour") {
|
||||
OgreAssert(geo, "Can't create static geometry");
|
||||
Geometry::createHarbour(e, itemNode, geo);
|
||||
e.set<TerrainItemNode>({ itemNode, geo });
|
||||
} else if (itemType == "temple") {
|
||||
OgreAssert(geo, "Can't create static geometry");
|
||||
createTemple(e, itemNode, geo);
|
||||
e.set<TerrainItemNode>({ itemNode, geo });
|
||||
} else if (itemType == "town") {
|
||||
OgreAssert(geo, "Can't create static geometry");
|
||||
createTown(e, itemNode, geo);
|
||||
e.set<TerrainItemNode>({ itemNode, geo });
|
||||
std::cout << " town created: " << e.id() << std::endl;
|
||||
} else {
|
||||
OgreAssert(geo, "Can't create static geometry");
|
||||
e.set<TerrainItemNode>({ itemNode, geo });
|
||||
OgreAssert(false, "Unknown item type: " + itemType);
|
||||
}
|
||||
} else {
|
||||
std::cout << "can't build item" << std::endl;
|
||||
std::cout << "props: " << props << std::endl;
|
||||
OgreAssert(false, "can't create item");
|
||||
}
|
||||
}
|
||||
|
||||
void destroyItemGeometry(flecs::entity e)
|
||||
{
|
||||
OgreAssert(e.has<TerrainItemNode>(), "No geometry created");
|
||||
#if 0
|
||||
ECS::get<EngineData>().mScnMgr->destroyStaticGeometry()
|
||||
e.get<TerrainItemNode>().geo->destroy();
|
||||
e.get_mut<TerrainItemNode>().geo = nullptr;
|
||||
e.modified<TerrainItemNode>();
|
||||
#endif
|
||||
e.remove<TerrainItemNode>();
|
||||
}
|
||||
flecs::entity createMeshGeometry(const Ogre::String &meshName,
|
||||
flecs::entity parente,
|
||||
Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo)
|
||||
{
|
||||
Ogre::MeshPtr mesh = Ogre::MeshManager::getSingleton().load(
|
||||
meshName,
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
OgreAssert(mesh, "mesh " + meshName + " not found");
|
||||
Ogre::LodConfig config(mesh);
|
||||
setupLods(config);
|
||||
Ogre::Entity *ent = ECS::get<EngineData>().mScnMgr->createEntity(
|
||||
"Ent" + meshName, mesh);
|
||||
geo->addEntity(ent, sceneNode->_getDerivedPosition(),
|
||||
sceneNode->_getDerivedOrientation());
|
||||
ECS::get<EngineData>().mScnMgr->destroyEntity(ent);
|
||||
JPH::ShapeRefC shape =
|
||||
JoltPhysicsWrapper::getSingleton().createMeshShape(mesh);
|
||||
JPH::BodyID id = JoltPhysicsWrapper::getSingleton().createBody(
|
||||
shape.GetPtr(), 0, sceneNode, JPH::EMotionType::Static,
|
||||
Layers::NON_MOVING);
|
||||
flecs::entity e = ECS::get()
|
||||
.entity()
|
||||
.child_of(parente)
|
||||
.set<JPH::BodyID>(id)
|
||||
.set<TerrainItemMeshNode>({ sceneNode, geo });
|
||||
JoltPhysicsWrapper::getSingleton().addBody(id,
|
||||
JPH::EActivation::Activate);
|
||||
return e;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
89
src/gamedata/items/items.h
Normal file
89
src/gamedata/items/items.h
Normal file
@@ -0,0 +1,89 @@
|
||||
#ifndef __ITEMS_H__
|
||||
#define __ITEMS_H__
|
||||
#include <OgreMeshLodGenerator.h>
|
||||
#include <flecs.h>
|
||||
namespace ECS
|
||||
{
|
||||
namespace Items
|
||||
{
|
||||
void showItemPopup(const std::pair<flecs::entity, Ogre::String> &item);
|
||||
void showItemButtons(const std::pair<flecs::entity, Ogre::String> &item);
|
||||
void createItemsMenu();
|
||||
}
|
||||
namespace Geometry
|
||||
{
|
||||
void setupLods(Ogre::LodConfig &config);
|
||||
struct harbourMaker {
|
||||
Ogre::Entity *planks, *pillar, *beam;
|
||||
Ogre::String makeName(const Ogre::String &base, flecs::entity e)
|
||||
{
|
||||
return base + Ogre::StringConverter::toString(e.id());
|
||||
}
|
||||
harbourMaker(flecs::entity e)
|
||||
{
|
||||
Ogre::String planksName = makeName("Plank", e);
|
||||
Ogre::String beamName = makeName("Beam", e);
|
||||
Ogre::String pillarName = makeName("Pillar", e);
|
||||
std::pair<Ogre::String, Ogre::Entity **> sets[] = {
|
||||
{ planksName, &planks },
|
||||
{ beamName, &beam },
|
||||
{ pillarName, &pillar }
|
||||
};
|
||||
std::map<Ogre::String, Ogre::String> meshes = {
|
||||
{ planksName, "pier-plank.glb" },
|
||||
{ beamName, "pier-beam.glb" },
|
||||
{ pillarName, "pier-pillar.glb" },
|
||||
};
|
||||
for (auto &p : sets) {
|
||||
if (ECS::get<EngineData>().mScnMgr->hasEntity(p.first))
|
||||
*p.second =
|
||||
ECS::get<EngineData>()
|
||||
.mScnMgr->getEntity(p.first);
|
||||
else {
|
||||
*p.second = ECS::get<EngineData>()
|
||||
.mScnMgr->createEntity(
|
||||
p.first,
|
||||
meshes.at(p.first));
|
||||
Ogre::MeshPtr mesh = (*p.second)->getMesh();
|
||||
Ogre::LodConfig config(mesh);
|
||||
setupLods(config);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
void createItemGeometry(flecs::entity e);
|
||||
void destroyItemGeometry(flecs::entity e);
|
||||
flecs::entity createMeshGeometry(const Ogre::String &meshName,
|
||||
flecs::entity parente,
|
||||
Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
|
||||
}
|
||||
static void to_json(nlohmann::json &j, const Ogre::Vector3 &position)
|
||||
{
|
||||
j["x"] = position.x;
|
||||
j["y"] = position.y;
|
||||
j["z"] = position.z;
|
||||
}
|
||||
static void to_json(nlohmann::json &j, const Ogre::Quaternion &orientation)
|
||||
{
|
||||
j["w"] = orientation.w;
|
||||
j["x"] = orientation.x;
|
||||
j["y"] = orientation.y;
|
||||
j["z"] = orientation.z;
|
||||
}
|
||||
static void from_json(const nlohmann::json &j, Ogre::Vector3 &position)
|
||||
{
|
||||
position.x = j["x"].get<float>();
|
||||
position.y = j["y"].get<float>();
|
||||
position.z = j["z"].get<float>();
|
||||
}
|
||||
static void from_json(const nlohmann::json &j, Ogre::Quaternion &orientation)
|
||||
{
|
||||
orientation.w = j["w"].get<float>();
|
||||
orientation.x = j["x"].get<float>();
|
||||
orientation.y = j["y"].get<float>();
|
||||
orientation.z = j["z"].get<float>();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
240
src/gamedata/items/temple.cpp
Normal file
240
src/gamedata/items/temple.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
#include <iostream>
|
||||
#include <Ogre.h>
|
||||
#include <OgreTerrainGroup.h>
|
||||
#include <OgreImGuiOverlay.h>
|
||||
#include <OgreRTShaderSystem.h>
|
||||
#include <Procedural.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
#include "EditorGizmoModule.h"
|
||||
#include "TerrainModule.h"
|
||||
#include "StaticGeometryModule.h"
|
||||
#include "physics.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "items.h"
|
||||
#include "temple.h"
|
||||
namespace ECS
|
||||
{
|
||||
namespace Items
|
||||
{
|
||||
void createTempleItem()
|
||||
{
|
||||
Ogre::Vector3 itemPosition =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion itemOrientation =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedOrientation();
|
||||
flecs::entity e = StaticGeometryModule::createItem(
|
||||
itemPosition, itemOrientation, "temple");
|
||||
Ogre::String prop = StaticGeometryModule::getItemProperties(e);
|
||||
nlohmann::json j = nlohmann::json::parse(prop);
|
||||
j["size"] = 40.0f;
|
||||
j["form"] = "rect";
|
||||
j["pillarHeight"] = 16.0f;
|
||||
j["pillarRadius"] = 0.5f;
|
||||
j["pillarCount"] = 20;
|
||||
StaticGeometryModule::setItemProperties(e, j.dump());
|
||||
StaticGeometryModule::saveItems();
|
||||
}
|
||||
void createTempleMenu()
|
||||
{
|
||||
if (ImGui::MenuItem("Create"))
|
||||
createTempleItem();
|
||||
}
|
||||
void createTemplePopup(const std::pair<flecs::entity, Ogre::String> item)
|
||||
{
|
||||
float size = 40.0f;
|
||||
float pillarRadius = 0.5f;
|
||||
float pillarHeight = 16.0f;
|
||||
int pillarCount = 20;
|
||||
Ogre::String form;
|
||||
|
||||
Ogre::String prop = StaticGeometryModule::getItemProperties(item.first);
|
||||
nlohmann::json j = nlohmann::json::parse(prop);
|
||||
bool changed = false;
|
||||
if (j.find("size") != j.end())
|
||||
size = j["size"].get<float>();
|
||||
if (j.find("pillarRadius") != j.end())
|
||||
pillarRadius = j["pillarRadius"].get<float>();
|
||||
if (j.find("pillarHeight") != j.end())
|
||||
pillarHeight = j["pillarHeight"].get<float>();
|
||||
if (j.find("pillarCount") != j.end())
|
||||
pillarCount = j["pillarCount"].get<int>();
|
||||
if (ImGui::SliderFloat("Temple Size", &size, 40.0f, 100.0f))
|
||||
changed = true;
|
||||
if (ImGui::SliderFloat("Temple Pillar Radius", &pillarRadius, 0.5f,
|
||||
2.0f))
|
||||
changed = true;
|
||||
if (ImGui::SliderFloat("Temple Pillar Height", &pillarHeight, 16.0f,
|
||||
60.0f))
|
||||
changed = true;
|
||||
if (ImGui::SliderInt("Pillar Count", &pillarCount, 1, 200))
|
||||
changed = true;
|
||||
if (changed) {
|
||||
j["size"] = size;
|
||||
j["pillarRadius"] = pillarRadius;
|
||||
j["pillarHeight"] = pillarHeight;
|
||||
j["pillarCount"] = pillarCount;
|
||||
StaticGeometryModule::setItemProperties(item.first, j.dump());
|
||||
StaticGeometryModule::saveItems();
|
||||
StaticGeometryModule::destroyItemGeometry(item.first);
|
||||
StaticGeometryModule::createItemGeometry(item.first);
|
||||
}
|
||||
ImGui::Text("%s", j.dump(4).c_str());
|
||||
}
|
||||
}
|
||||
namespace Geometry
|
||||
{
|
||||
void createTemple(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo)
|
||||
{
|
||||
Ogre::String props = e.get<TerrainItem>().properties;
|
||||
nlohmann::json jp = nlohmann::json::parse(props);
|
||||
float size = 20.0f;
|
||||
int pillarCount = 4;
|
||||
float pillarRadius = 0.5f, pillarHeight = 10.0f;
|
||||
if (jp.find("size") != jp.end())
|
||||
size = jp["size"].get<float>();
|
||||
if (jp.find("pillarCount") != jp.end())
|
||||
pillarCount = jp["pillarCount"].get<int>();
|
||||
if (jp.find("pillarHeight") != jp.end())
|
||||
pillarHeight = jp["pillarHeight"].get<float>();
|
||||
if (jp.find("pillarCount") != jp.end())
|
||||
size = jp["size"].get<float>();
|
||||
Procedural::TriangleBuffer tb, colliderTb;
|
||||
float elevation = 0.0f;
|
||||
Ogre::MaterialPtr templeMaterial;
|
||||
templeMaterial = Ogre::MaterialManager::getSingleton().getByName(
|
||||
"proceduralMaterialTemple" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
if (!templeMaterial) {
|
||||
Procedural::TextureBuffer colorAtlas(1024);
|
||||
Procedural::RectangleTexture drawAtlas(&colorAtlas);
|
||||
Ogre::ColourValue normalGreen(0.6f, 0.8f, 0.5f, 1);
|
||||
drawAtlas.setRectangle(Ogre::RealRect(0.0f, 0.0f, 0.4f, 1.0f))
|
||||
.setColour(normalGreen)
|
||||
.process();
|
||||
Ogre::TexturePtr pierTexture = colorAtlas.createTexture(
|
||||
"proceduralTextureTemple" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
colorAtlas.saveImage("tmp2.png");
|
||||
templeMaterial = Ogre::MaterialManager::getSingletonPtr()->create(
|
||||
"proceduralMaterialTemple" +
|
||||
Ogre::StringConverter::toString(e.id()),
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
templeMaterial->getTechnique(0)->getPass(0)->setShininess(0);
|
||||
templeMaterial->getTechnique(0)->getPass(0)->setDiffuse(
|
||||
Ogre::ColourValue::White);
|
||||
templeMaterial->getTechnique(0)->getPass(0)->setSpecular(
|
||||
Ogre::ColourValue(1.0f, 1.0f, 0.9f));
|
||||
templeMaterial->getTechnique(0)
|
||||
->getPass(0)
|
||||
->createTextureUnitState(
|
||||
"proceduralTextureTemple" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
if (Ogre::RTShader::ShaderGenerator::initialize()) {
|
||||
templeMaterial->prepare();
|
||||
Ogre::RTShader::ShaderGenerator *mShaderGenerator =
|
||||
Ogre::RTShader::ShaderGenerator::
|
||||
getSingletonPtr();
|
||||
mShaderGenerator->createShaderBasedTechnique(
|
||||
*templeMaterial,
|
||||
Ogre::MaterialManager::DEFAULT_SCHEME_NAME,
|
||||
Ogre::RTShader::ShaderGenerator::
|
||||
DEFAULT_SCHEME_NAME);
|
||||
Ogre::RTShader::RenderState *pMainRenderState =
|
||||
mShaderGenerator->getRenderState(
|
||||
Ogre::RTShader::ShaderGenerator::
|
||||
DEFAULT_SCHEME_NAME,
|
||||
*templeMaterial);
|
||||
}
|
||||
}
|
||||
Ogre::Vector3 worldPosition = sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion worldOrientation = sceneNode->_getDerivedOrientation();
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(size)
|
||||
.setSizeY(20)
|
||||
.setSizeZ(size)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(
|
||||
Ogre::Vector3(0.0f, -20.0f / 2.0f + elevation, 0.0f))
|
||||
.addToTriangleBuffer(tb);
|
||||
float pillarStep = 0.0f;
|
||||
float pillarStepSize = size * 4.0f / (float)pillarCount;
|
||||
int pcount = pillarCount;
|
||||
while (pillarStep < size - pillarRadius * 2.0f && pcount > 0) {
|
||||
float s = pillarStep - size / 2.0f + pillarStepSize / 2.0f;
|
||||
Procedural::CylinderGenerator()
|
||||
.setHeight(pillarHeight)
|
||||
.setRadius(pillarRadius)
|
||||
.setNumSegBase(8)
|
||||
.setPosition(s, 0.0f, -size / 2.0f + pillarRadius)
|
||||
.addToTriangleBuffer(tb);
|
||||
Procedural::CylinderGenerator()
|
||||
.setHeight(pillarHeight)
|
||||
.setRadius(pillarRadius)
|
||||
.setNumSegBase(8)
|
||||
.setPosition(s, 0.0f, size / 2.0f - pillarRadius)
|
||||
.addToTriangleBuffer(tb);
|
||||
Procedural::CylinderGenerator()
|
||||
.setHeight(pillarHeight)
|
||||
.setRadius(pillarRadius)
|
||||
.setNumSegBase(8)
|
||||
.setPosition(-size / 2.0f + pillarRadius, 0.0f, s)
|
||||
.addToTriangleBuffer(tb);
|
||||
Procedural::CylinderGenerator()
|
||||
.setHeight(pillarHeight)
|
||||
.setRadius(pillarRadius)
|
||||
.setNumSegBase(8)
|
||||
.setPosition(size / 2.0f - pillarRadius, 0.0f, s)
|
||||
.addToTriangleBuffer(tb);
|
||||
pillarStep += pillarStepSize;
|
||||
pcount--;
|
||||
pcount--;
|
||||
pcount--;
|
||||
pcount--;
|
||||
}
|
||||
OgreAssert(tb.getVertices().size() > 8, "bad box");
|
||||
for (auto &v : tb.getVertices()) {
|
||||
#if 0
|
||||
float c = 1.0 + 1.0 / (v.mPosition.y + baseHeight +
|
||||
elevation);
|
||||
v.mPosition.x *= c;
|
||||
v.mPosition.z *= c;
|
||||
#endif
|
||||
v.mUV *= 0.08f;
|
||||
v.mUV.x += 0.01f;
|
||||
v.mUV.x = Ogre::Math::Clamp(v.mUV.x, 0.0f, 0.4f);
|
||||
v.mUV.y = Ogre::Math::Clamp(v.mUV.y, 0.0f, 0.1f);
|
||||
}
|
||||
Ogre::String meshName =
|
||||
"Temple" + Ogre::StringConverter::toString(e.id());
|
||||
Ogre::MeshPtr mesh =
|
||||
Ogre::MeshManager::getSingleton().getByName(meshName);
|
||||
if (mesh)
|
||||
Ogre::MeshManager::getSingleton().remove(mesh);
|
||||
mesh = tb.transformToMesh(meshName);
|
||||
Ogre::LodConfig config(mesh);
|
||||
Geometry::setupLods(config);
|
||||
Ogre::Entity *ent = ECS::get<EngineData>().mScnMgr->createEntity(
|
||||
"Ent" + meshName, mesh);
|
||||
ent->setMaterial(templeMaterial);
|
||||
geo->addEntity(ent, worldPosition, worldOrientation,
|
||||
Ogre::Vector3::UNIT_SCALE);
|
||||
ECS::get<EngineData>().mScnMgr->destroyEntity(ent);
|
||||
// TODO set altar position
|
||||
createMeshGeometry("altar.glb", e, sceneNode->createChildSceneNode(),
|
||||
geo);
|
||||
geo->build();
|
||||
JPH::ShapeRefC shape =
|
||||
JoltPhysicsWrapper::getSingleton().createMeshShape(mesh);
|
||||
JPH::BodyID id = JoltPhysicsWrapper::getSingleton().createBody(
|
||||
shape.GetPtr(), 0, sceneNode, JPH::EMotionType::Static,
|
||||
Layers::NON_MOVING);
|
||||
e.set<JPH::BodyID>(id);
|
||||
JoltPhysicsWrapper::getSingleton().addBody(id,
|
||||
JPH::EActivation::Activate);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
20
src/gamedata/items/temple.h
Normal file
20
src/gamedata/items/temple.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef __TEMPLE_H__
|
||||
#define __TEMPLE_H__
|
||||
#include <OgreMeshLodGenerator.h>
|
||||
#include <flecs.h>
|
||||
namespace ECS
|
||||
{
|
||||
namespace Items
|
||||
{
|
||||
void createTempleItem();
|
||||
void createTempleMenu();
|
||||
void createTemplePopup(const std::pair<flecs::entity, Ogre::String> item);
|
||||
}
|
||||
namespace Geometry
|
||||
{
|
||||
void createTemple(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
71
src/gamedata/items/town.cpp
Normal file
71
src/gamedata/items/town.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <iostream>
|
||||
#include <Ogre.h>
|
||||
#include <OgreTerrainGroup.h>
|
||||
#include <OgreImGuiOverlay.h>
|
||||
#include <OgreRTShaderSystem.h>
|
||||
#include <Procedural.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
#include "EditorGizmoModule.h"
|
||||
#include "TerrainModule.h"
|
||||
#include "StaticGeometryModule.h"
|
||||
#include "physics.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "items.h"
|
||||
#include "town.h"
|
||||
namespace ECS
|
||||
{
|
||||
namespace Items
|
||||
{
|
||||
void createTownItem()
|
||||
{
|
||||
Ogre::Vector3 itemPosition =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion itemOrientation =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedOrientation();
|
||||
flecs::entity e = StaticGeometryModule::createItem(
|
||||
itemPosition, itemOrientation, "town");
|
||||
Ogre::String prop = StaticGeometryModule::getItemProperties(e);
|
||||
nlohmann::json j = nlohmann::json::parse(prop);
|
||||
j["districts"] = nlohmann::json::array();
|
||||
StaticGeometryModule::setItemProperties(e, j.dump());
|
||||
// setHarbourSurface();
|
||||
StaticGeometryModule::saveItems();
|
||||
// updateWorldTexture();
|
||||
// updateHeightmap();
|
||||
// TerrainModule::save_heightmap();
|
||||
}
|
||||
void createTownMenu()
|
||||
{
|
||||
if (ImGui::MenuItem("Create"))
|
||||
createTownItem();
|
||||
}
|
||||
void createTownPopup(const std::pair<flecs::entity, Ogre::String> item)
|
||||
{
|
||||
Ogre::String prop = StaticGeometryModule::getItemProperties(item.first);
|
||||
nlohmann::json j = nlohmann::json::parse(prop);
|
||||
bool changed = false;
|
||||
if (ImGui::SmallButton("Add district")) {
|
||||
nlohmann::json d;
|
||||
d["radius"] = 50.0f;
|
||||
d["lots"] = nlohmann::json::array();
|
||||
j["districts"].push_back(d);
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
StaticGeometryModule::setItemProperties(item.first, j.dump());
|
||||
StaticGeometryModule::saveItems();
|
||||
StaticGeometryModule::destroyItemGeometry(item.first);
|
||||
StaticGeometryModule::createItemGeometry(item.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace Geometry
|
||||
{
|
||||
void createTown(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/gamedata/items/town.h
Normal file
19
src/gamedata/items/town.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __TOWN_H__
|
||||
#define __TOWN_H__
|
||||
#include <OgreMeshLodGenerator.h>
|
||||
#include <flecs.h>
|
||||
namespace ECS
|
||||
{
|
||||
namespace Items
|
||||
{
|
||||
void createTownItem();
|
||||
void createTownMenu();
|
||||
void createTownPopup(const std::pair<flecs::entity, Ogre::String> item);
|
||||
}
|
||||
namespace Geometry
|
||||
{
|
||||
void createTown(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user