Creating pier
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user