Compare commits
2 Commits
81a78990ce
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 9bb9e2c09b | |||
| 3f99099919 |
@@ -76,6 +76,7 @@ add_subdirectory(src/world)
|
||||
add_subdirectory(src/tests)
|
||||
add_subdirectory(src/physics)
|
||||
add_subdirectory(src/editor)
|
||||
add_subdirectory(assets/blender/buildings/parts)
|
||||
|
||||
add_executable(Game Game.cpp ${WATER_SRC})
|
||||
target_include_directories(Game PRIVATE src/gamedata)
|
||||
|
||||
17
assets/blender/buildings/parts/CMakeLists.txt
Normal file
17
assets/blender/buildings/parts/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
project(building-parts)
|
||||
set(PARTS_FILES pier.blend)
|
||||
set(PARTS_OUTPUT_DIRS)
|
||||
foreach(PARTS_FILE ${PARTS_FILES})
|
||||
get_filename_component(FILE_NAME ${PARTS_FILE} NAME_WE)
|
||||
set(PARTS_OUTPUT_DIR ${CMAKE_BINARY_DIR}/resources/buildings/parts/${FILE_NAME})
|
||||
add_custom_command(
|
||||
OUTPUT ${PARTS_OUTPUT_DIR}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${PARTS_OUTPUT_DIR}
|
||||
COMMAND ${BLENDER} ${CMAKE_CURRENT_SOURCE_DIR}/${PARTS_FILE}
|
||||
-b -Y -P
|
||||
${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_building_parts.py
|
||||
-- ${PARTS_OUTPUT_DIR}
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${PARTS_FILE} ${CMAKE_SOURCE_DIR}/assets/blender/scripts/export_building_parts.py)
|
||||
list(APPEND PARTS_OUTPUT_DIRS ${PARTS_OUTPUT_DIR})
|
||||
endforeach()
|
||||
add_custom_target(import_building_parts ALL DEPENDS ${PARTS_OUTPUT_DIRS})
|
||||
BIN
assets/blender/buildings/parts/pier.blend
LFS
Normal file
BIN
assets/blender/buildings/parts/pier.blend
LFS
Normal file
Binary file not shown.
@@ -20,6 +20,7 @@ FileSystem=resources/terrain
|
||||
[General]
|
||||
FileSystem=skybox
|
||||
FileSystem=resources/buildings
|
||||
FileSystem=resources/buildings/parts/pier
|
||||
FileSystem=resources/vehicles
|
||||
FileSystem=resources/debug
|
||||
FileSystem=resources/fonts
|
||||
|
||||
@@ -9,7 +9,7 @@ find_package(OgreProcedural REQUIRED CONFIG)
|
||||
find_package(pugixml REQUIRED CONFIG)
|
||||
find_package(flecs REQUIRED CONFIG)
|
||||
|
||||
set(COPY_DIRECTORIES resources skybox water)
|
||||
set(COPY_DIRECTORIES resources skybox water resources/buildings/parts)
|
||||
set(INSTALL_DEPS ${CMAKE_CURRENT_BINARY_DIR}/resources.cfg)
|
||||
foreach(DIR_NAME ${COPY_DIRECTORIES})
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${DIR_NAME}
|
||||
@@ -19,7 +19,7 @@ foreach(DIR_NAME ${COPY_DIRECTORIES})
|
||||
list(APPEND INSTALL_DEPS ${CMAKE_CURRENT_BINARY_DIR}/${DIR_NAME})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(install_resources DEPENDS ${INSTALL_DEPS})
|
||||
add_custom_target(install_resources DEPENDS import_buildings import_building_parts ${INSTALL_DEPS})
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/resources.cfg
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/../../resources.cfg ${CMAKE_CURRENT_BINARY_DIR}/resources.cfg
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../../resources.cfg
|
||||
|
||||
@@ -3,17 +3,18 @@ set(CMAKE_CXX_STANDARD 17)
|
||||
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(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
|
||||
VehicleManagerModule.cpp AppModule.cpp SmartObject.cpp SlotsModule.cpp goap.cpp)
|
||||
VehicleManagerModule.cpp AppModule.cpp StaticGeometryModule.cpp SmartObject.cpp SlotsModule.cpp goap.cpp)
|
||||
target_link_libraries(GameData PUBLIC
|
||||
lua
|
||||
flecs::flecs_static
|
||||
nlohmann_json::nlohmann_json
|
||||
OgreMain
|
||||
OgreBites
|
||||
OgrePaging OgreTerrain OgreOverlay
|
||||
OgrePaging OgreTerrain OgreOverlay OgreProcedural::OgreProcedural
|
||||
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)
|
||||
|
||||
@@ -9,11 +9,16 @@
|
||||
#include <OgreImGuiInputListener.h>
|
||||
#include <OgreFontManager.h>
|
||||
#include <OgreTerrainGroup.h>
|
||||
#include <OgrePagedWorld.h>
|
||||
#include <OgreTerrainPaging.h>
|
||||
#include <OgreTerrainPagedWorldSection.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "GameData.h"
|
||||
#include "Components.h"
|
||||
#include "LuaData.h"
|
||||
#include "AppModule.h"
|
||||
#include "TerrainModule.h"
|
||||
#include "StaticGeometryModule.h"
|
||||
#include "EditorGizmoModule.h"
|
||||
#include "GUIModule.h"
|
||||
namespace ECS
|
||||
@@ -701,6 +706,7 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
float strength = 0.0f;
|
||||
int size = 0;
|
||||
long slot_x, slot_y;
|
||||
float cursorAngle = 0;
|
||||
void updateWorldTexture()
|
||||
{
|
||||
// Get the hardware pixel buffer
|
||||
@@ -733,21 +739,16 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainGroup->convertWorldPositionToTerrainSlot(
|
||||
worldPos, &x, &y);
|
||||
int i, j;
|
||||
for (j = -1; j < 2; j++)
|
||||
for (i = -1; i < 2; i++) {
|
||||
Ogre::Terrain *terrain =
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainGroup->getTerrain(
|
||||
x + j, y + i);
|
||||
if (terrain && terrain->isLoaded()) {
|
||||
terrain->dirty();
|
||||
terrain->update(true);
|
||||
terrain->waitForDerivedProcesses();
|
||||
}
|
||||
}
|
||||
|
||||
ECS::get<Terrain>().mTerrainGroup->update(true);
|
||||
for (auto &slot :
|
||||
ECS::get<Terrain>().mTerrainGroup->getTerrainSlots()) {
|
||||
Ogre::uint32 page =
|
||||
ECS::get<Terrain>().mTerrainGroup->packIndex(
|
||||
slot.second->x, slot.second->y);
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainPagedWorldSection->unloadPage(page,
|
||||
false);
|
||||
}
|
||||
ECS::get<Terrain>().mTerrainGroup->update(false);
|
||||
}
|
||||
void setCursorPos(Ogre::Vector3 &cursorPosition,
|
||||
Ogre::Quaternion &orientation)
|
||||
@@ -793,8 +794,327 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
.mCameraGoal->_getDerivedOrientation());
|
||||
updateHeightmap();
|
||||
}
|
||||
void setCursorSelectedPos(flecs::entity e, Ogre::Vector3 &position,
|
||||
Ogre::Quaternion &orientation)
|
||||
{
|
||||
StaticGeometryModule::getItemPositionAndRotation(e, position,
|
||||
orientation);
|
||||
selected_x = TerrainModule::get_img_x(position.x);
|
||||
selected_y = TerrainModule::get_img_y(position.z);
|
||||
ECS::get<EditorGizmo>().sceneNode->_setDerivedPosition(
|
||||
position);
|
||||
ECS::get<EditorGizmo>().sceneNode->_setDerivedOrientation(
|
||||
orientation);
|
||||
}
|
||||
void setCameraSelectedPos(flecs::entity e)
|
||||
{
|
||||
Ogre::Vector3 cursorPos;
|
||||
Ogre::Quaternion cursorOrientation;
|
||||
setCursorSelectedPos(e, cursorPos, cursorOrientation);
|
||||
Ogre::Vector3 cameraPos =
|
||||
ECS::get<Camera>().mCameraPivot->_getDerivedPosition();
|
||||
Ogre::Vector3 cameraOffset =
|
||||
cursorOrientation * Ogre::Vector3::UNIT_Z * 30.0f;
|
||||
cameraPos.x = cursorPos.x;
|
||||
cameraPos.z = cursorPos.z;
|
||||
cameraPos += cameraOffset;
|
||||
cameraPos.y =
|
||||
TerrainModule::get_height(
|
||||
ECS::get<Terrain>().mTerrainGroup, cameraPos) +
|
||||
10.0f;
|
||||
if (cameraPos.y < 0.0f)
|
||||
cameraPos.y = 10.0f;
|
||||
ECS::get<Camera>().mCameraPivot->_setDerivedPosition(cameraPos);
|
||||
ECS::get<Camera>().mCameraPivot->_setDerivedOrientation(
|
||||
cursorOrientation);
|
||||
cameraPos =
|
||||
ECS::get<Camera>().mCameraGoal->_getDerivedPosition();
|
||||
ECS::get<Camera>().mCameraNode->_setDerivedPosition(cameraPos);
|
||||
ECS::get<Camera>().mCameraNode->_setDerivedOrientation(
|
||||
ECS::get<Camera>()
|
||||
.mCameraGoal->_getDerivedOrientation());
|
||||
updateHeightmap();
|
||||
}
|
||||
void setSurfaceLevel(int actualSize, int center_x, int center_y,
|
||||
float level)
|
||||
{
|
||||
int i, j;
|
||||
float original = level;
|
||||
if (actualSize == 1)
|
||||
level += 0.4f;
|
||||
else if (actualSize == 2)
|
||||
level += 0.35f;
|
||||
original = Ogre::Math::Clamp(original, 0.0f, 1.0f);
|
||||
for (i = -actualSize; i < actualSize + 1; i++)
|
||||
for (j = -actualSize; j < actualSize + 1; j++) {
|
||||
if (i * i + j * j > actualSize * actualSize)
|
||||
continue;
|
||||
if (center_x + j < 0 ||
|
||||
center_x + j >= worldMap->getWidth())
|
||||
continue;
|
||||
if (center_y + i < 0 ||
|
||||
center_y + i >= worldMap->getHeight())
|
||||
continue;
|
||||
Ogre::ColourValue cv =
|
||||
worldMapImage.getColourAt(
|
||||
center_x + j, center_y + i, 0);
|
||||
cv.r = original;
|
||||
worldMapImage.setColourAt(cv, center_x + j,
|
||||
center_y + i, 0);
|
||||
}
|
||||
updateWorldTexture();
|
||||
updateHeightmap();
|
||||
}
|
||||
void setHarbourSurface()
|
||||
{
|
||||
int base_size = 3;
|
||||
float base_height = 0.517f;
|
||||
float base_step = 0.1f;
|
||||
float deep = 0.25f;
|
||||
float shallow = 0.35f;
|
||||
float maxStep = 600.0f;
|
||||
Ogre::Vector3 basePos =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion baseRot =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode->_getDerivedOrientation();
|
||||
float baseOffset = 200.0f;
|
||||
Ogre::Vector3 stepOffset =
|
||||
baseRot * Ogre::Vector3::NEGATIVE_UNIT_Z * baseOffset;
|
||||
std::vector<float> heights = { deep, shallow, base_height,
|
||||
base_height + base_step,
|
||||
base_height + base_step * 2.0f };
|
||||
int step_count = 0;
|
||||
for (float height : heights) {
|
||||
float localStep = 0.0f;
|
||||
Ogre::Vector3 currentPosition =
|
||||
basePos + stepOffset * (float)step_count -
|
||||
stepOffset * 0.5f;
|
||||
float goTill = maxStep;
|
||||
if (step_count < 2)
|
||||
goTill += 420.0f;
|
||||
while (localStep <
|
||||
goTill - 150.0f * (float)step_count) {
|
||||
localStep += baseOffset;
|
||||
currentPosition += stepOffset;
|
||||
int center_x = TerrainModule::get_img_x(
|
||||
currentPosition.x);
|
||||
int center_y = TerrainModule::get_img_y(
|
||||
currentPosition.z);
|
||||
int size = base_size + 10 - step_count * 2;
|
||||
if (step_count < 2)
|
||||
size = base_size + 14 - step_count * 2;
|
||||
if (step_count == 0)
|
||||
size += 1;
|
||||
|
||||
setSurfaceLevel(size, center_x, center_y,
|
||||
height);
|
||||
}
|
||||
step_count++;
|
||||
}
|
||||
}
|
||||
/* 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(std::vector<Ogre::Vector3> &path)
|
||||
{
|
||||
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 < 260.0f) {
|
||||
Ogre::Vector3 currentPosition =
|
||||
basePos + direction * (length);
|
||||
float dheight =
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainGroup->getHeightAtWorldPosition(
|
||||
currentPosition);
|
||||
Ogre::Vector3 localOffset =
|
||||
Ogre::Vector3(0, 0, 1) * length;
|
||||
if (dheight < 0 && path.size() == 0)
|
||||
return;
|
||||
if (path.size() == 0) {
|
||||
Ogre::Vector3 localFromWorld =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode
|
||||
->convertWorldToLocalPosition(
|
||||
{ currentPosition.x,
|
||||
dheight,
|
||||
currentPosition.z });
|
||||
path.push_back({ localOffset.x,
|
||||
localFromWorld.y,
|
||||
localOffset.z });
|
||||
} else {
|
||||
float height = path.back().y;
|
||||
if (height - dheight > 0.2f)
|
||||
dheight = height - 0.2f;
|
||||
height = dheight;
|
||||
if (height < 0) {
|
||||
height = 0;
|
||||
Ogre::Vector3 localFromWorld =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode
|
||||
->convertWorldToLocalPosition(
|
||||
{ currentPosition
|
||||
.x,
|
||||
height,
|
||||
currentPosition
|
||||
.z });
|
||||
path.push_back({ localOffset.x,
|
||||
localFromWorld.y,
|
||||
localOffset.z });
|
||||
break;
|
||||
|
||||
} else {
|
||||
Ogre::Vector3 localFromWorld =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode
|
||||
->convertWorldToLocalPosition(
|
||||
{ currentPosition
|
||||
.x,
|
||||
height,
|
||||
currentPosition
|
||||
.z });
|
||||
path.push_back({ localOffset.x,
|
||||
localFromWorld.y,
|
||||
localOffset.z });
|
||||
}
|
||||
}
|
||||
length += 0.5f;
|
||||
}
|
||||
}
|
||||
static void to_json(nlohmann::json &j, const Ogre::Vector3 &position)
|
||||
{
|
||||
j["x"] = position.x;
|
||||
j["y"] = position.y;
|
||||
j["z"] = position.z;
|
||||
}
|
||||
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(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();
|
||||
}
|
||||
void worldMapView()
|
||||
{
|
||||
bool riseLower = false;
|
||||
bool riseLower2 = false;
|
||||
bool smooth = false;
|
||||
bool setLevel = false;
|
||||
float setLevelValue = 0.0f;
|
||||
float riseLowerChange = 0.0f;
|
||||
OgreAssert(TerrainModule::get_img_x(0) ==
|
||||
worldMap->getWidth() / 2,
|
||||
"get_img_x");
|
||||
@@ -829,7 +1149,108 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
ImVec2(768, 768));
|
||||
// ImGui::SetNextWindowScroll(
|
||||
// ImVec2(worldMap->getWidth(), worldMap->getHeight()));
|
||||
ImGui::Begin("WorldMap...");
|
||||
ImGui::Begin("WorldMap...", nullptr, ImGuiWindowFlags_MenuBar);
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
if (ImGui::BeginMenu("Create")) {
|
||||
if (ImGui::BeginMenu("Harbour")) {
|
||||
createHarbourMenu();
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("Heightmap")) {
|
||||
if (ImGui::MenuItem("Update terrain"))
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainGroup->update(false);
|
||||
ImGui::Separator();
|
||||
ImGui::SliderFloat("Strength...", &strength,
|
||||
0.0f, 1.0f);
|
||||
ImGui::SliderInt("Size", &size, 0, 32);
|
||||
ImGui::Separator();
|
||||
if (ImGui::Button("Elevate")) {
|
||||
riseLower = true;
|
||||
riseLowerChange = strength;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Elevate2")) {
|
||||
riseLower2 = true;
|
||||
riseLowerChange = strength;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Lower")) {
|
||||
riseLower = true;
|
||||
riseLowerChange = -strength;
|
||||
}
|
||||
if (ImGui::Button("Deepest")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.0f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Deep")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.25f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Shallow1")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.35f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Shallow2")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.47f;
|
||||
}
|
||||
if (ImGui::Button("Beach")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.516f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Shore1")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.536f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Shore2")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.556f;
|
||||
}
|
||||
if (ImGui::Button("Shore3")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.586f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Shore4")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.606f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Shore5")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.626f;
|
||||
}
|
||||
if (ImGui::Button("Shore6")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.646f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Highest")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 1.0f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Smooth")) {
|
||||
smooth = true;
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem("Save heightmap")) {
|
||||
updateWorldTexture();
|
||||
updateHeightmap();
|
||||
TerrainModule::save_heightmap();
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
ImGui::Spacing();
|
||||
ImGui::BeginChild("WorldMap...", ImVec2(480, 480),
|
||||
ImGuiChildFlags_None,
|
||||
@@ -885,20 +1306,29 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
1.0f, IM_COL32(0, 255, 0, 255));
|
||||
{
|
||||
std::list<Ogre::Vector3> positions;
|
||||
TerrainModule::getItemPositions(&positions);
|
||||
StaticGeometryModule::getItemPositions(&positions);
|
||||
for (auto pos : positions) {
|
||||
int item_x = TerrainModule::get_img_x(pos.x);
|
||||
int item_y = TerrainModule::get_img_y(pos.z);
|
||||
draw_list->AddCircleFilled(
|
||||
ImVec2(top_x + item_x, top_y + item_y),
|
||||
3.0f, IM_COL32(255, 255, 0, 255));
|
||||
std::cout << pos << std::endl;
|
||||
}
|
||||
}
|
||||
if (locationSelected)
|
||||
draw_list->AddCircleFilled(
|
||||
ImVec2(top_x + selected_x, top_y + selected_y),
|
||||
4.0f, IM_COL32(64, 255, 64, 255));
|
||||
{
|
||||
Ogre::Vector3 cursorPos =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode->_getDerivedPosition();
|
||||
int cursor_x = TerrainModule::get_img_x(cursorPos.x);
|
||||
int cursor_y = TerrainModule::get_img_y(cursorPos.z);
|
||||
draw_list->AddCircleFilled(
|
||||
ImVec2(top_x + cursor_x, top_y + cursor_y),
|
||||
4.0f, IM_COL32(255, 64, 64, 128));
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::Spacing();
|
||||
ImGui::EndChild();
|
||||
@@ -923,87 +1353,65 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
ImGui::Text("Cursor position %f %f %f", position.x,
|
||||
position.y, position.z);
|
||||
}
|
||||
if (ImGui::Button("Update terrain")) {
|
||||
ECS::get<Terrain>().mTerrainGroup->update(true);
|
||||
}
|
||||
ImGui::SliderFloat("Strength...", &strength, 0.0f, 0.2f);
|
||||
ImGui::SliderInt("Size", &size, 0, 8);
|
||||
bool riseLower = false;
|
||||
bool riseLower2 = false;
|
||||
bool smooth = false;
|
||||
bool setLevel = false;
|
||||
float setLevelValue = 0.0f;
|
||||
float riseLowerChange = 0.0f;
|
||||
if (ImGui::Button("Elevate")) {
|
||||
riseLower = true;
|
||||
riseLowerChange = strength;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Lower")) {
|
||||
riseLower = true;
|
||||
riseLowerChange = -strength;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Smooth")) {
|
||||
smooth = true;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Elevate2")) {
|
||||
riseLower2 = true;
|
||||
riseLowerChange = strength;
|
||||
}
|
||||
if (ImGui::Button("Deepest")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.0f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Highest")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 1.0f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Beach")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.516f;
|
||||
}
|
||||
if (ImGui::Button("Shore1")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.536f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Shore2")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.556f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Shore3")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.586f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Shore4")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.606f;
|
||||
}
|
||||
if (ImGui::Button("Shore5")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.626f;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Shore6")) {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.646f;
|
||||
}
|
||||
if (ImGui::Button("Harbour")) {
|
||||
Ogre::Vector3 itemPosition =
|
||||
if (ImGui::Button("Update cursor position")) {
|
||||
Ogre::Vector3 position =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion itemOrientation =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode->_getDerivedOrientation();
|
||||
TerrainModule::createItem(itemPosition, itemOrientation,
|
||||
"harbour");
|
||||
TerrainModule::saveItems();
|
||||
position.y =
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainGroup
|
||||
->getHeightAtWorldPosition(position);
|
||||
ECS::get<EditorGizmo>().sceneNode->_setDerivedPosition(
|
||||
position);
|
||||
}
|
||||
ImGui::SliderFloat("Cursor Angle...", &cursorAngle, -180.0f,
|
||||
180.0f);
|
||||
ECS::get<EditorGizmo>().sceneNode->_setDerivedOrientation(
|
||||
Ogre::Quaternion(Ogre::Degree(cursorAngle),
|
||||
Ogre::Vector3::UNIT_Y));
|
||||
flecs::entity selected_item;
|
||||
bool item_is_selected = false;
|
||||
{
|
||||
std::list<std::pair<flecs::entity, Ogre::String> > items;
|
||||
StaticGeometryModule::getItemsProperties(&items);
|
||||
for (const auto &item : items) {
|
||||
Ogre::String label =
|
||||
Ogre::StringConverter::toString(
|
||||
item.first.id());
|
||||
label += item.second.substr(0, 32);
|
||||
if (ImGui::SmallButton(
|
||||
label.c_str())) { /* select */
|
||||
selected_item = item.first;
|
||||
item_is_selected = true;
|
||||
setCameraSelectedPos(selected_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 del_label =
|
||||
"delete##" +
|
||||
Ogre::StringConverter::toString(
|
||||
item.first.id());
|
||||
if (ImGui::SmallButton(del_label.c_str())) {
|
||||
item.first.destruct();
|
||||
StaticGeometryModule::saveItems();
|
||||
}
|
||||
ImGui::Spacing();
|
||||
}
|
||||
}
|
||||
if (riseLower) {
|
||||
int actualSize = 1 + size * 2;
|
||||
@@ -1058,12 +1466,6 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
float actualStrength =
|
||||
riseLowerChange /
|
||||
(1.0f + (float)(i * i + j * j));
|
||||
if (i * i + j * j ==
|
||||
actualSize * actualSize) {
|
||||
std::cout << actualStrength
|
||||
<< std::endl;
|
||||
// OgreAssert(false, "strength");
|
||||
}
|
||||
Ogre::ColourValue cv =
|
||||
worldMapImage.getColourAt(
|
||||
selected_x + j,
|
||||
@@ -1167,11 +1569,6 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
updateWorldTexture();
|
||||
updateHeightmap();
|
||||
}
|
||||
if (ImGui::Button("Save heightmap")) {
|
||||
updateWorldTexture();
|
||||
updateHeightmap();
|
||||
TerrainModule::save_heightmap();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::Spacing();
|
||||
ImGui::End();
|
||||
@@ -1597,6 +1994,7 @@ EditorGUIModule::EditorGUIModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<EditorGUIModule>();
|
||||
ecs.import <AppModule>();
|
||||
ecs.import <StaticGeometryModule>();
|
||||
ecs.component<GUI>()
|
||||
.on_add([](GUI &gui) {
|
||||
gui.enabled = true;
|
||||
|
||||
@@ -99,6 +99,7 @@ void setup(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
false,
|
||||
{ 0, 0, 0 } });
|
||||
if (!ecs.has<LuaBase>())
|
||||
@@ -175,6 +176,7 @@ void setupEditor(Ogre::SceneManager *scnMgr, Ogre::SceneNode *cameraNode,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
false,
|
||||
{ 0, 0, 0 } });
|
||||
ecs.set<GUI>({ true, true, true, false, false, "", {}, -1 });
|
||||
|
||||
1076
src/gamedata/StaticGeometryModule.cpp
Normal file
1076
src/gamedata/StaticGeometryModule.cpp
Normal file
File diff suppressed because it is too large
Load Diff
47
src/gamedata/StaticGeometryModule.h
Normal file
47
src/gamedata/StaticGeometryModule.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef _STATIC_GEOMETRY_MODULE_H_
|
||||
#define _STATIC_GEOMETRY_MODULE_H_
|
||||
#include <flecs.h>
|
||||
#include <Ogre.h>
|
||||
namespace ECS
|
||||
{
|
||||
struct TerrainSlotParent {
|
||||
std::pair<long, long> slot;
|
||||
};
|
||||
struct TerrainItem {
|
||||
Ogre::Vector3 position;
|
||||
Ogre::Quaternion orientation;
|
||||
Ogre::String properties;
|
||||
};
|
||||
struct TerrainItemNode {
|
||||
Ogre::SceneNode *itemNode;
|
||||
};
|
||||
|
||||
struct StaticGeometryModule {
|
||||
StaticGeometryModule(flecs::world &ecs);
|
||||
static void addGeometryForSlot(long x, long y);
|
||||
static void removeGeometryForSlot(long x, long y);
|
||||
static flecs::entity createItem(const Ogre::Vector3 &position,
|
||||
const Ogre::Quaternion &orientation,
|
||||
const Ogre::String &type);
|
||||
static void setItemProperties(flecs::entity id,
|
||||
Ogre::String properties);
|
||||
static const Ogre::String &getItemProperties(flecs::entity id);
|
||||
static void saveItems();
|
||||
static void loadItems();
|
||||
static void getItemPositionPerSlot(long x, long y,
|
||||
std::list<Ogre::Vector3> *positions);
|
||||
static void getItemPositions(std::list<Ogre::Vector3> *positions);
|
||||
static void getItemPositionAndRotation(flecs::entity e,
|
||||
Ogre::Vector3 &position,
|
||||
Ogre::Quaternion &orientation);
|
||||
static void getItemsProperties(
|
||||
std::list<std::pair<flecs::entity, Ogre::String> > *items);
|
||||
static void createItemGeometry(flecs::entity e);
|
||||
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);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -16,10 +16,11 @@
|
||||
#include "CharacterModule.h"
|
||||
#include "SunModule.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "StaticGeometryModule.h"
|
||||
#include "TerrainModule.h"
|
||||
|
||||
#define TERRAIN_SIZE 129
|
||||
#define TERRAIN_WORLD_SIZE 1000.0f
|
||||
#define TERRAIN_SIZE 65
|
||||
#define TERRAIN_WORLD_SIZE 500.0f
|
||||
#define ENDLESS_TERRAIN_FILE_PREFIX Ogre::String("EndlessWorldTerrain")
|
||||
#define ENDLESS_TERRAIN_FILE_SUFFIX Ogre::String("dat")
|
||||
|
||||
@@ -32,6 +33,12 @@
|
||||
#define ENDLESS_PAGE_MAX_Y 0x7FFF
|
||||
namespace ECS
|
||||
{
|
||||
class DummyPageProvider;
|
||||
/* Components */
|
||||
struct TerrainPrivate {
|
||||
DummyPageProvider *mDummyPageProvider;
|
||||
Ogre::Timer mSunUpdate;
|
||||
};
|
||||
|
||||
#define BRUSH_SIZE 64
|
||||
struct HeightData {
|
||||
@@ -83,15 +90,17 @@ struct HeightData {
|
||||
}
|
||||
int get_img_x(float world_x)
|
||||
{
|
||||
float world_img_x = world_x + img.getWidth() * BRUSH_SIZE / 2;
|
||||
int ret = world_img_x / BRUSH_SIZE;
|
||||
float world_img_x = world_x + (float)img.getWidth() *
|
||||
(float)BRUSH_SIZE / 2.0f;
|
||||
int ret = (world_img_x + BRUSH_SIZE - 1) / BRUSH_SIZE;
|
||||
// ret = Ogre::Math::Clamp(ret, 0, (int)img.getWidth() - 1);
|
||||
return ret;
|
||||
}
|
||||
int get_img_y(float world_z)
|
||||
{
|
||||
float world_img_y = world_z + img.getHeight() * BRUSH_SIZE / 2;
|
||||
int ret = world_img_y / BRUSH_SIZE;
|
||||
float world_img_y = world_z + (float)img.getHeight() *
|
||||
(float)BRUSH_SIZE / 2.0f;
|
||||
int ret = (world_img_y + BRUSH_SIZE - 1) / BRUSH_SIZE;
|
||||
// ret = Ogre::Math::Clamp(ret, 0, (int)img.getHeight() - 1);
|
||||
return ret;
|
||||
}
|
||||
@@ -234,6 +243,7 @@ class FlatTerrainDefiner
|
||||
long y;
|
||||
};
|
||||
std::deque<struct gen_collider> collider_queue;
|
||||
std::deque<struct gen_collider> colliderRemove_queue;
|
||||
|
||||
public:
|
||||
FlatTerrainDefiner(Ogre::SceneManager *
|
||||
@@ -247,10 +257,13 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex mtx;
|
||||
|
||||
public:
|
||||
void createTerrainChunk(Ogre::TerrainGroup *terrainGroup, long x,
|
||||
long y)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mtx);
|
||||
Ogre::Terrain *terrain = terrainGroup->getTerrain(x, y);
|
||||
float minH = terrain->getMinHeight();
|
||||
float maxH = terrain->getMaxHeight();
|
||||
@@ -276,6 +289,7 @@ public:
|
||||
}
|
||||
void define(Ogre::TerrainGroup *terrainGroup, long x, long y) override
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(mtx);
|
||||
uint16_t terrainSize = terrainGroup->getTerrainSize();
|
||||
float *heightMap = OGRE_ALLOC_T(float, terrainSize *terrainSize,
|
||||
MEMCATEGORY_GEOMETRY);
|
||||
@@ -295,19 +309,9 @@ public:
|
||||
long world_y = (long)(worldPos.z + i -
|
||||
(terrainSize - 1) / 2);
|
||||
float height = 0.0f;
|
||||
int k, l;
|
||||
for (l = -1; l < 2; l++)
|
||||
for (k = -1; k < 2; k++) {
|
||||
height +=
|
||||
HeightData::get_singleton()
|
||||
->get_height(
|
||||
terrainGroup,
|
||||
world_x +
|
||||
4 * k,
|
||||
world_y +
|
||||
4 * l);
|
||||
}
|
||||
height /= 9.0f;
|
||||
height +=
|
||||
HeightData::get_singleton()->get_height(
|
||||
terrainGroup, world_x, world_y);
|
||||
|
||||
// height = -2.0f;
|
||||
heightMap[i * terrainSize + j] = height;
|
||||
@@ -421,6 +425,9 @@ public:
|
||||
what->setOrientation(item.rotation);
|
||||
what->setPosition(item.position);
|
||||
}
|
||||
/* Spawn items */
|
||||
StaticGeometryModule::addGeometryForSlot(x, y);
|
||||
|
||||
} else {
|
||||
output.push_back(collider_queue.front());
|
||||
collider_queue.pop_front();
|
||||
@@ -453,6 +460,10 @@ public:
|
||||
bool unloadProceduralPage(Ogre::Page *page,
|
||||
Ogre::PagedWorldSection *section)
|
||||
{
|
||||
long x, y;
|
||||
ECS::get<Terrain>().mTerrainGroup->unpackIndex(page->CHUNK_ID,
|
||||
&x, &y);
|
||||
StaticGeometryModule::removeGeometryForSlot(x, y);
|
||||
return true;
|
||||
}
|
||||
bool unprepareProceduralPage(Ogre::Page *page,
|
||||
@@ -461,20 +472,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
struct TerrainPrivate {
|
||||
DummyPageProvider *mDummyPageProvider;
|
||||
Ogre::Timer mSunUpdate;
|
||||
};
|
||||
|
||||
struct TerrainSlotParent {
|
||||
std::pair<long, long> slot;
|
||||
};
|
||||
struct TerrainItem {
|
||||
Ogre::Vector3 position;
|
||||
Ogre::Quaternion orientation;
|
||||
Ogre::String properties;
|
||||
};
|
||||
|
||||
TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
{
|
||||
struct CanSetPlayerPosition {};
|
||||
@@ -482,12 +479,11 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
ecs.component<CanSetPlayerPosition>().add(flecs::Singleton);
|
||||
ecs.component<Terrain>().add(flecs::Singleton);
|
||||
ecs.component<TerrainPrivate>().add(flecs::Singleton);
|
||||
ecs.component<TerrainSlotParent>();
|
||||
ecs.component<TerrainItem>();
|
||||
ecs.component<PlacementObjects>();
|
||||
ecs.component<TerrainReady>().add(flecs::Singleton);
|
||||
ecs.import <CharacterModule>();
|
||||
ecs.import <SunModule>();
|
||||
ecs.import <StaticGeometryModule>();
|
||||
ecs.set<TerrainPrivate>({ nullptr, {} });
|
||||
ecs.system<const EngineData, const Camera, const Sun, Terrain,
|
||||
TerrainPrivate>("SetupUpdateTerrain")
|
||||
@@ -523,11 +519,11 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
terrain.mTerrainGroup->setOrigin(
|
||||
terrain.mTerrainPos);
|
||||
// Configure global
|
||||
terrain.mTerrainGlobals->setMaxPixelError(0);
|
||||
terrain.mTerrainGlobals->setMaxPixelError(1);
|
||||
// testing composite map
|
||||
// mTerrainGlobals->setCompositeMapDistance(30);
|
||||
terrain.mTerrainGlobals->setCompositeMapDistance(
|
||||
500);
|
||||
300);
|
||||
//mTerrainGlobals->setUseRayBoxDistanceCalculation(true);
|
||||
terrain.mTerrainGlobals
|
||||
->getDefaultMaterialGenerator()
|
||||
@@ -547,7 +543,8 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
defaultimp.terrainSize = TERRAIN_SIZE;
|
||||
defaultimp.worldSize = TERRAIN_WORLD_SIZE;
|
||||
defaultimp.inputScale = 1.0f;
|
||||
defaultimp.minBatchSize = 33;
|
||||
// defaultimp.minBatchSize = 33;
|
||||
defaultimp.minBatchSize = 5;
|
||||
defaultimp.maxBatchSize = 65;
|
||||
Ogre::Image combined;
|
||||
combined.loadTwoImagesAsRGBA(
|
||||
@@ -575,24 +572,33 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
terrain.mPageManager);
|
||||
terrain.mPagedWorld =
|
||||
terrain.mPageManager->createWorld();
|
||||
#if 0
|
||||
terrain.mTerrainGroup->setAutoUpdateLod(
|
||||
Ogre::TerrainAutoUpdateLodFactory::
|
||||
getAutoUpdateLod(
|
||||
Ogre::BY_DISTANCE));
|
||||
#endif
|
||||
|
||||
terrain.mTerrainPagedWorldSection =
|
||||
terrain.mTerrainPaging
|
||||
->createWorldSection(
|
||||
terrain.mPagedWorld,
|
||||
terrain.mTerrainGroup,
|
||||
300, 800,
|
||||
300, 500,
|
||||
ENDLESS_PAGE_MIN_X,
|
||||
ENDLESS_PAGE_MIN_Y,
|
||||
ENDLESS_PAGE_MAX_X,
|
||||
ENDLESS_PAGE_MAX_Y);
|
||||
terrain.definer = OGRE_NEW FlatTerrainDefiner(
|
||||
eng.mScnMgr /*, eng.mWorld */);
|
||||
|
||||
terrain.mTerrainPagedWorldSection->setDefiner(
|
||||
OGRE_NEW FlatTerrainDefiner(
|
||||
eng.mScnMgr /*, eng.mWorld */));
|
||||
terrain.definer);
|
||||
|
||||
terrain.mTerrainGroup->freeTemporaryResources();
|
||||
std::cout << "Terrain setup done\n";
|
||||
ECS::get().set<PlacementObjects>({});
|
||||
terrain.mTerrainGroup->loadAllTerrains(true);
|
||||
}
|
||||
if (sun.mSun &&
|
||||
priv.mSunUpdate.getMilliseconds() > 1000) {
|
||||
@@ -607,6 +613,7 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
.getPitch()
|
||||
<< "\n";
|
||||
priv.mSunUpdate.reset();
|
||||
//terrain.mTerrainGroup->autoUpdateLodAll()
|
||||
}
|
||||
});
|
||||
ecs.system<const ECS::Camera, const Terrain>("UpdateTerrainStatus")
|
||||
@@ -738,11 +745,13 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
player.modified<CharacterLocation>();
|
||||
ECS::get().remove<CanSetPlayerPosition>();
|
||||
});
|
||||
ecs.observer<const Terrain>("LoadTerrainItems")
|
||||
.event(flecs::OnSet)
|
||||
ecs.system<const Terrain>("UpdateTerrainGroup")
|
||||
.kind(flecs::OnUpdate)
|
||||
.interval(2.0f)
|
||||
.each([](const Terrain &terrain) {
|
||||
if (terrain.mTerrainGroup)
|
||||
loadItems();
|
||||
if (!terrain.mTerrainGroup
|
||||
->isDerivedDataUpdateInProgress())
|
||||
terrain.mTerrainGroup->update(false);
|
||||
});
|
||||
}
|
||||
float TerrainModule::get_height(Ogre::TerrainGroup *group,
|
||||
@@ -783,167 +792,9 @@ void TerrainModule::save_heightmap()
|
||||
{
|
||||
HeightData::get_singleton()->save_heightmap();
|
||||
}
|
||||
flecs::entity TerrainModule::createItem(const Ogre::Vector3 &position,
|
||||
const Ogre::Quaternion &orientation,
|
||||
const Ogre::String &type)
|
||||
void TerrainModule::defineTerrain(long x, long y)
|
||||
{
|
||||
long x, y;
|
||||
ECS::get<Terrain>().mTerrainGroup->convertWorldPositionToTerrainSlot(
|
||||
position, &x, &y);
|
||||
std::pair<long, long> pos{ x, y };
|
||||
flecs::entity slot =
|
||||
ECS::get().query_builder<const TerrainSlotParent>().build().find(
|
||||
[&](const TerrainSlotParent &slot) -> bool {
|
||||
return slot.slot == pos;
|
||||
});
|
||||
if (!slot.is_valid())
|
||||
slot = ECS::get().entity().add<TerrainSlotParent>();
|
||||
flecs::entity item = ECS::get().entity().child_of(slot);
|
||||
nlohmann::json jproperties;
|
||||
jproperties["type"] = type;
|
||||
item.set<TerrainItem>({ position, orientation, jproperties.dump() });
|
||||
return item;
|
||||
}
|
||||
void TerrainModule::setItemProperties(flecs::entity id, Ogre::String properties)
|
||||
{
|
||||
OgreAssert(id.is_valid(), "bad id");
|
||||
id.get_mut<TerrainItem>().properties = properties;
|
||||
id.modified<TerrainItem>();
|
||||
}
|
||||
const Ogre::String &TerrainModule::getItemProperties(flecs::entity id)
|
||||
{
|
||||
OgreAssert(id.is_valid(), "bad id");
|
||||
return id.get<TerrainItem>().properties;
|
||||
}
|
||||
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>();
|
||||
}
|
||||
void TerrainModule::saveItems()
|
||||
{
|
||||
Ogre::String path = "resources/buildings/items.list";
|
||||
if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(
|
||||
"items.list")) {
|
||||
Ogre::String group =
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.findGroupContainingResource("items.list");
|
||||
Ogre::FileInfoListPtr fileInfoList(
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.findResourceFileInfo(group, "items.list"));
|
||||
OgreAssert(fileInfoList->size() == 1,
|
||||
"worpd_map.png should be there and only once");
|
||||
path = fileInfoList->at(0).archive->getName() + "/" +
|
||||
"items.list";
|
||||
Ogre::FileSystemLayer::removeFile(path);
|
||||
}
|
||||
std::fstream fout(path.c_str(), std::ios::out);
|
||||
nlohmann::json jitemlist;
|
||||
ECS::get().query_builder<const TerrainItem>().build().each(
|
||||
[&](flecs::entity e, const TerrainItem &item) {
|
||||
nlohmann::json jitem;
|
||||
to_json(jitem["position"], item.position);
|
||||
to_json(jitem["orientation"], item.orientation);
|
||||
to_json(jitem["properties"], item.properties);
|
||||
jitemlist.push_back(jitem);
|
||||
});
|
||||
fout << jitemlist.dump();
|
||||
fout.close();
|
||||
}
|
||||
void TerrainModule::loadItems()
|
||||
{
|
||||
if (!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(
|
||||
"items.list"))
|
||||
return;
|
||||
Ogre::String group = Ogre::ResourceGroupManager::getSingleton()
|
||||
.findGroupContainingResource("items.list");
|
||||
Ogre::DataStreamPtr stream =
|
||||
Ogre::ResourceGroupManager::getSingleton().openResource(
|
||||
"items.list", group);
|
||||
Ogre::String json = stream->getAsString();
|
||||
nlohmann::json jlist = nlohmann::json::parse(json);
|
||||
ECS::get().delete_with<TerrainItem>();
|
||||
ECS::get().delete_with<TerrainSlotParent>();
|
||||
|
||||
for (const auto &v : jlist) {
|
||||
Ogre::Vector3 position;
|
||||
Ogre::Quaternion orientation;
|
||||
Ogre::String properties;
|
||||
from_json(v["position"], position);
|
||||
from_json(v["orientation"], orientation);
|
||||
properties = v["properties"].get<Ogre::String>();
|
||||
long x, y;
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainGroup->convertWorldPositionToTerrainSlot(
|
||||
position, &x, &y);
|
||||
std::pair<long, long> pos{ x, y };
|
||||
flecs::entity slot =
|
||||
ECS::get()
|
||||
.query_builder<const TerrainSlotParent>()
|
||||
.build()
|
||||
.find([&](const TerrainSlotParent &slot)
|
||||
-> bool {
|
||||
return slot.slot == pos;
|
||||
});
|
||||
if (!slot.is_valid())
|
||||
slot = ECS::get().entity().add<TerrainSlotParent>();
|
||||
flecs::entity item = ECS::get().entity().child_of(slot);
|
||||
item.set<TerrainItem>({ position, orientation, properties });
|
||||
std::cout << "position: " << item.id() << " " << position
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
void TerrainModule::getItemPositionPerSlot(long x, long y,
|
||||
std::list<Ogre::Vector3> *positions)
|
||||
{
|
||||
std::pair<long, long> pos{ x, y };
|
||||
if (!positions)
|
||||
return;
|
||||
flecs::entity slot =
|
||||
ECS::get().query_builder<const TerrainSlotParent>().build().find(
|
||||
[&](const TerrainSlotParent &slot) -> bool {
|
||||
return slot.slot == pos;
|
||||
});
|
||||
if (!slot.is_valid())
|
||||
return;
|
||||
ECS::get()
|
||||
.query_builder<const TerrainItem>()
|
||||
.with(flecs::ChildOf, slot)
|
||||
.build()
|
||||
.each([&](flecs::entity e, const TerrainItem &item) {
|
||||
positions->push_back(item.position);
|
||||
std::cout << e.id() << " " << item.position
|
||||
<< std::endl;
|
||||
});
|
||||
}
|
||||
void TerrainModule::getItemPositions(std::list<Ogre::Vector3> *positions)
|
||||
{
|
||||
ECS::get().query_builder<const TerrainItem>().build().each(
|
||||
[&](flecs::entity e, const TerrainItem &item) {
|
||||
positions->push_back(item.position);
|
||||
std::cout << e.id() << " " << item.position
|
||||
<< std::endl;
|
||||
});
|
||||
ECS::get<Terrain>().definer->define(ECS::get<Terrain>().mTerrainGroup,
|
||||
x, y);
|
||||
}
|
||||
}
|
||||
@@ -12,12 +12,14 @@ class TerrainPagedWorldSection;
|
||||
}
|
||||
namespace ECS
|
||||
{
|
||||
class FlatTerrainDefiner;
|
||||
struct Terrain {
|
||||
Ogre::TerrainGlobalOptions *mTerrainGlobals;
|
||||
Ogre::TerrainGroup *mTerrainGroup;
|
||||
Ogre::TerrainPaging *mTerrainPaging;
|
||||
Ogre::PageManager *mPageManager;
|
||||
Ogre::PagedWorld *mPagedWorld;
|
||||
FlatTerrainDefiner *definer;
|
||||
Ogre::TerrainPagedWorldSection *mTerrainPagedWorldSection;
|
||||
bool mTerrainReady;
|
||||
|
||||
@@ -41,17 +43,7 @@ struct TerrainModule {
|
||||
static int get_img_y(float world_z);
|
||||
static void update_heightmap(const Ogre::Image &heightmap);
|
||||
static void save_heightmap();
|
||||
static flecs::entity createItem(const Ogre::Vector3 &position,
|
||||
const Ogre::Quaternion &orientation,
|
||||
const Ogre::String &type);
|
||||
static void setItemProperties(flecs::entity id,
|
||||
Ogre::String properties);
|
||||
static const Ogre::String &getItemProperties(flecs::entity id);
|
||||
static void saveItems();
|
||||
static void loadItems();
|
||||
static void getItemPositionPerSlot(long x, long y,
|
||||
std::list<Ogre::Vector3> *positions);
|
||||
static void getItemPositions(std::list<Ogre::Vector3> *positions);
|
||||
static void defineTerrain(long x, long y);
|
||||
};
|
||||
struct TerrainReady {};
|
||||
}
|
||||
|
||||
@@ -852,6 +852,8 @@ public:
|
||||
JPH::BodyInterface &body_interface =
|
||||
physics_system.GetBodyInterface();
|
||||
JPH::Body *body = body_interface.CreateBody(settings);
|
||||
if (!body)
|
||||
return JPH::BodyID();
|
||||
return body->GetID();
|
||||
}
|
||||
void removeBody(const JPH::BodyID &id)
|
||||
|
||||
Reference in New Issue
Block a user