Started town procedural generation code
This commit is contained in:
@@ -30,11 +30,7 @@ void createTownItem()
|
||||
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()
|
||||
{
|
||||
@@ -44,16 +40,103 @@ void createTownMenu()
|
||||
void createTownPopup(const std::pair<flecs::entity, Ogre::String> item)
|
||||
{
|
||||
Ogre::String prop = StaticGeometryModule::getItemProperties(item.first);
|
||||
Ogre::Vector3 townPosition;
|
||||
Ogre::Quaternion townRotation;
|
||||
StaticGeometryModule::getItemPositionAndRotation(
|
||||
item.first, townPosition, townRotation);
|
||||
nlohmann::json j = nlohmann::json::parse(prop);
|
||||
bool changed = false;
|
||||
int count = 0;
|
||||
ImGui::Text("Town");
|
||||
nlohmann::json districts = nlohmann::json::array();
|
||||
for (auto &district : j["districts"])
|
||||
districts.push_back(district);
|
||||
count = 0;
|
||||
for (auto &district : districts) {
|
||||
ImGui::Separator();
|
||||
Ogre::String districtLabel =
|
||||
"district" + Ogre::StringConverter::toString(count);
|
||||
ImGui::Text("%s", districtLabel.c_str());
|
||||
nlohmann::json lots = nlohmann::json::array();
|
||||
for (const auto &lot : district["lots"])
|
||||
lots.push_back(lot);
|
||||
int lotCount = 0;
|
||||
for (auto &lot : lots) {
|
||||
Ogre::String lotLabel =
|
||||
"lot" +
|
||||
Ogre::StringConverter::toString(lotCount);
|
||||
ImGui::Text("%s", lotLabel.c_str());
|
||||
ImGui::Separator();
|
||||
if (ImGui::SmallButton("Delete")) {
|
||||
lots.erase(lotCount);
|
||||
break;
|
||||
}
|
||||
lotCount++;
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::SmallButton("Add lot")) {
|
||||
nlohmann::json l;
|
||||
l["angle"] = 0.0f;
|
||||
l["width"] = 10.0f;
|
||||
l["depth"] = 10.0f;
|
||||
l["elevation"] = 0.0f;
|
||||
lots.push_back(l);
|
||||
changed = true;
|
||||
}
|
||||
district["lots"] = lots;
|
||||
bool plazza = false;
|
||||
if (district.find("plazza") != district.end())
|
||||
plazza = district["plazza"].get<bool>();
|
||||
if (ImGui::Checkbox("Plazza", &plazza)) {
|
||||
changed = true;
|
||||
district["plazza"] = plazza;
|
||||
}
|
||||
float elevation = 0.0f, height = 0.2f;
|
||||
if (district.find("elevation") != district.end())
|
||||
elevation = district["elevation"].get<float>();
|
||||
if (district.find("height") != district.end())
|
||||
height = district["height"].get<float>();
|
||||
if (ImGui::SliderFloat("Height", &height, 0.1f, 10.0f)) {
|
||||
district["height"] = height;
|
||||
changed = true;
|
||||
}
|
||||
if (ImGui::SliderFloat("Elevation", &elevation, -10.0f,
|
||||
10.0f)) {
|
||||
district["elevation"] = elevation;
|
||||
changed = true;
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::SmallButton("Delete")) {
|
||||
districts.erase(count);
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::SmallButton("Add district")) {
|
||||
Ogre::Vector3 cursorPosition =
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion cursorOrientation =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode->_getDerivedOrientation();
|
||||
Ogre::Vector3 localPosition = cursorPosition - townPosition;
|
||||
Ogre::Quaternion localRotation =
|
||||
townRotation.Inverse() * cursorOrientation;
|
||||
nlohmann::json d;
|
||||
d["radius"] = 50.0f;
|
||||
d["lots"] = nlohmann::json::array();
|
||||
j["districts"].push_back(d);
|
||||
to_json(d["position"], localPosition);
|
||||
to_json(d["rotation"], localRotation);
|
||||
d["elevation"] = 0.0f;
|
||||
d["plazza"] = false;
|
||||
districts.push_back(d);
|
||||
changed = true;
|
||||
}
|
||||
ImGui::Separator();
|
||||
ImGui::Text("%s", j.dump(4).c_str());
|
||||
if (changed) {
|
||||
j["districts"] = districts;
|
||||
StaticGeometryModule::setItemProperties(item.first, j.dump());
|
||||
StaticGeometryModule::saveItems();
|
||||
StaticGeometryModule::destroyItemGeometry(item.first);
|
||||
@@ -66,6 +149,147 @@ namespace Geometry
|
||||
void createTown(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo)
|
||||
{
|
||||
std::cout << "createTown " << e.id() << std::endl;
|
||||
Ogre::MaterialPtr townMaterial;
|
||||
townMaterial = Ogre::MaterialManager::getSingleton().getByName(
|
||||
"proceduralMaterialTown" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
if (!townMaterial) {
|
||||
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(
|
||||
"proceduralTextureTown" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
colorAtlas.saveImage("tmp4.png");
|
||||
townMaterial = Ogre::MaterialManager::getSingletonPtr()->create(
|
||||
"proceduralMaterialTown" +
|
||||
Ogre::StringConverter::toString(e.id()),
|
||||
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
||||
townMaterial->getTechnique(0)->getPass(0)->setShininess(0);
|
||||
townMaterial->getTechnique(0)->getPass(0)->setDiffuse(
|
||||
Ogre::ColourValue::White);
|
||||
townMaterial->getTechnique(0)->getPass(0)->setSpecular(
|
||||
Ogre::ColourValue(1.0f, 1.0f, 0.9f));
|
||||
townMaterial->getTechnique(0)
|
||||
->getPass(0)
|
||||
->createTextureUnitState(
|
||||
"proceduralTextureTown" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
if (Ogre::RTShader::ShaderGenerator::initialize()) {
|
||||
townMaterial->prepare();
|
||||
Ogre::RTShader::ShaderGenerator *mShaderGenerator =
|
||||
Ogre::RTShader::ShaderGenerator::
|
||||
getSingletonPtr();
|
||||
mShaderGenerator->createShaderBasedTechnique(
|
||||
*townMaterial,
|
||||
Ogre::MaterialManager::DEFAULT_SCHEME_NAME,
|
||||
Ogre::RTShader::ShaderGenerator::
|
||||
DEFAULT_SCHEME_NAME);
|
||||
Ogre::RTShader::RenderState *pMainRenderState =
|
||||
mShaderGenerator->getRenderState(
|
||||
Ogre::RTShader::ShaderGenerator::
|
||||
DEFAULT_SCHEME_NAME,
|
||||
*townMaterial);
|
||||
}
|
||||
}
|
||||
{
|
||||
Ogre::String props = e.get<TerrainItem>().properties;
|
||||
nlohmann::json jp = nlohmann::json::parse(props);
|
||||
Ogre::Vector3 worldPosition = sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion worldOrientation =
|
||||
sceneNode->_getDerivedOrientation();
|
||||
for (const auto &jdistrict : jp["districts"]) {
|
||||
createTownPlazza(e, jdistrict, sceneNode, geo);
|
||||
}
|
||||
}
|
||||
geo->build();
|
||||
}
|
||||
void createTownPlazza(flecs::entity e, const nlohmann::json &jdistrict,
|
||||
Ogre::SceneNode *sceneNode, Ogre::StaticGeometry *geo)
|
||||
{
|
||||
Ogre::MaterialPtr townMaterial;
|
||||
townMaterial = Ogre::MaterialManager::getSingleton().getByName(
|
||||
"proceduralMaterialTown" +
|
||||
Ogre::StringConverter::toString(e.id()));
|
||||
Ogre::Vector3 worldPosition = sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion worldOrientation = sceneNode->_getDerivedOrientation();
|
||||
const nlohmann::json &jp = jdistrict;
|
||||
Procedural::TriangleBuffer tb;
|
||||
float radius = 5.0f;
|
||||
float height = 0.2f;
|
||||
float elevation = 0.0f;
|
||||
bool plazza = false;
|
||||
Ogre::Vector3 localPosition(0, 0, 0);
|
||||
Ogre::Quaternion localRotation = Ogre::Quaternion::IDENTITY;
|
||||
if (jp.find("plazza") != jp.end())
|
||||
plazza = jp["plazza"].get<bool>();
|
||||
if (!plazza)
|
||||
return;
|
||||
if (jp.find("radius") != jp.end())
|
||||
radius = jp["radius"].get<float>();
|
||||
if (jp.find("height") != jp.end())
|
||||
height = jp["height"].get<float>();
|
||||
if (jp.find("elevation") != jp.end())
|
||||
elevation = jp["elevation"].get<float>();
|
||||
from_json(jp["position"], localPosition);
|
||||
from_json(jp["rotation"], localRotation);
|
||||
if (height < 0.1f)
|
||||
height = 0.1f;
|
||||
if (radius < 5.0f)
|
||||
radius = 5.0f;
|
||||
Ogre::Vector3 worldPlazzaCenter = worldPosition + localPosition;
|
||||
float mh = 4.0f;
|
||||
Procedural::Shape *plazzaShape = new Procedural::Shape();
|
||||
plazzaShape->addPoint(0, -height - mh - mh);
|
||||
plazzaShape->addPoint(radius * 0.5f + mh, -height - mh - mh);
|
||||
plazzaShape->addPoint(radius + mh, -height - mh);
|
||||
plazzaShape->addPoint(radius, -height);
|
||||
plazzaShape->addPoint(radius, 0.0f);
|
||||
plazzaShape->addPoint(radius - 0.1f, 0.1f);
|
||||
plazzaShape->addPoint(radius - mh + 0.1f, height);
|
||||
plazzaShape->addPoint(radius - mh, height + 0.1f);
|
||||
plazzaShape->addPoint(radius * 0.5f + mh, height);
|
||||
plazzaShape->addPoint(0, height);
|
||||
Procedural::Lathe()
|
||||
.setShapeToExtrude(plazzaShape)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(
|
||||
Ogre::Vector3(0.0f, height / 2.0f + elevation, 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(townMaterial);
|
||||
geo->addEntity(pathEnt, worldPlazzaCenter,
|
||||
worldOrientation * localRotation,
|
||||
Ogre::Vector3(1, 1, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ namespace Geometry
|
||||
{
|
||||
void createTown(flecs::entity e, Ogre::SceneNode *sceneNode,
|
||||
Ogre::StaticGeometry *geo);
|
||||
void createTownPlazza(flecs::entity e, const nlohmann::json &jdistrict,
|
||||
Ogre::SceneNode *sceneNode, Ogre::StaticGeometry *geo);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user