Compare commits
2 Commits
64b03abb48
...
d8122e3275
| Author | SHA1 | Date | |
|---|---|---|---|
| d8122e3275 | |||
| 0ebba40867 |
@@ -119,6 +119,15 @@ struct CellGridComponent {
|
||||
// Generation script (Lua or custom format)
|
||||
std::string generationScript;
|
||||
|
||||
// Texture rectangle names for different parts (from ProceduralTexture)
|
||||
std::string floorRectName;
|
||||
std::string ceilingRectName;
|
||||
std::string extWallRectName;
|
||||
std::string intWallRectName;
|
||||
std::string doorRectName;
|
||||
std::string windowRectName;
|
||||
std::string roofRectName;
|
||||
|
||||
// Dirty flag - triggers rebuild
|
||||
bool dirty = true;
|
||||
unsigned int version = 0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -46,6 +46,7 @@ private:
|
||||
void buildDoors(const struct CellGridComponent& grid, std::vector<Procedural::TriangleBuffer>& doorTbs);
|
||||
void buildWindows(const struct CellGridComponent& grid, std::vector<Procedural::TriangleBuffer>& windowTbs);
|
||||
void buildCorners(const struct CellGridComponent& grid, Procedural::TriangleBuffer& extWallTb);
|
||||
void buildInternalCorners(const struct CellGridComponent& grid, Procedural::TriangleBuffer& intWallTb);
|
||||
|
||||
// Build roofs
|
||||
void buildRoofs(flecs::entity lotEntity, const struct CellGridComponent& grid, Procedural::TriangleBuffer& roofTb);
|
||||
@@ -60,7 +61,10 @@ private:
|
||||
Ogre::MeshPtr convertToMesh(const std::string& name, Procedural::TriangleBuffer& tb, const std::string& materialName);
|
||||
|
||||
// Apply UV mapping from color rects
|
||||
void applyUVMapping(Procedural::TriangleBuffer& tb, const struct TownComponent& town, const std::string& rectName);
|
||||
void applyUVMapping(Procedural::TriangleBuffer& tb, flecs::entity entity, const std::string& rectName);
|
||||
|
||||
// Apply UV mapping using texture coordinates directly
|
||||
void applyUVMappingToBuffer(Procedural::TriangleBuffer& tb, const std::string& rectName, flecs::entity materialEntity);
|
||||
|
||||
// Destroy existing mesh
|
||||
void destroyCellGridMeshes(struct CellGridComponent& grid);
|
||||
|
||||
@@ -1269,6 +1269,15 @@ nlohmann::json SceneSerializer::serializeCellGrid(flecs::entity entity)
|
||||
json["cellHeight"] = grid.cellHeight;
|
||||
json["generationScript"] = grid.generationScript;
|
||||
|
||||
// Serialize texture rectangles
|
||||
json["floorRectName"] = grid.floorRectName;
|
||||
json["ceilingRectName"] = grid.ceilingRectName;
|
||||
json["extWallRectName"] = grid.extWallRectName;
|
||||
json["intWallRectName"] = grid.intWallRectName;
|
||||
json["doorRectName"] = grid.doorRectName;
|
||||
json["windowRectName"] = grid.windowRectName;
|
||||
json["roofRectName"] = grid.roofRectName;
|
||||
|
||||
// Serialize cells
|
||||
nlohmann::json cellsJson = nlohmann::json::array();
|
||||
for (const auto& cell : grid.cells) {
|
||||
@@ -1433,6 +1442,15 @@ void SceneSerializer::deserializeCellGrid(flecs::entity entity, const nlohmann::
|
||||
grid.cellHeight = json.value("cellHeight", 4.0f);
|
||||
grid.generationScript = json.value("generationScript", "");
|
||||
|
||||
// Deserialize texture rectangles
|
||||
grid.floorRectName = json.value("floorRectName", "");
|
||||
grid.ceilingRectName = json.value("ceilingRectName", "");
|
||||
grid.extWallRectName = json.value("extWallRectName", "");
|
||||
grid.intWallRectName = json.value("intWallRectName", "");
|
||||
grid.doorRectName = json.value("doorRectName", "");
|
||||
grid.windowRectName = json.value("windowRectName", "");
|
||||
grid.roofRectName = json.value("roofRectName", "");
|
||||
|
||||
// Deserialize cells
|
||||
if (json.contains("cells") && json["cells"].is_array()) {
|
||||
for (const auto& cellJson : json["cells"]) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "CellGridEditor.hpp"
|
||||
#include "../components/CellGrid.hpp"
|
||||
#include "../components/ProceduralMaterial.hpp"
|
||||
#include "../components/ProceduralTexture.hpp"
|
||||
#include <OgreStringConverter.h>
|
||||
|
||||
bool CellGridEditor::renderComponent(flecs::entity entity, CellGridComponent& grid)
|
||||
@@ -42,6 +44,11 @@ bool CellGridEditor::renderComponent(flecs::entity entity, CellGridComponent& gr
|
||||
renderFurnitureEditor(grid);
|
||||
}
|
||||
|
||||
// Texture rectangle editor
|
||||
if (ImGui::CollapsingHeader("Texture Rectangles")) {
|
||||
renderTextureRectEditor(entity, grid);
|
||||
}
|
||||
|
||||
// Script editor
|
||||
if (ImGui::CollapsingHeader("Generation Script")) {
|
||||
renderScriptEditor(grid);
|
||||
@@ -91,6 +98,7 @@ void CellGridEditor::renderCellEditor(CellGridComponent& grid)
|
||||
|
||||
auto flags = CellGridComponent::getAllFlags();
|
||||
for (const auto& [flag, name] : flags) {
|
||||
ImGui::PushID((int)flag);
|
||||
bool hasFlag = cell->hasFlag(flag);
|
||||
if (ImGui::Checkbox(name, &hasFlag)) {
|
||||
if (hasFlag) {
|
||||
@@ -100,6 +108,7 @@ void CellGridEditor::renderCellEditor(CellGridComponent& grid)
|
||||
}
|
||||
grid.markDirty();
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
if (ImGui::Button("Delete Cell")) {
|
||||
@@ -223,3 +232,123 @@ void CellGridEditor::renderScriptEditor(CellGridComponent& grid)
|
||||
grid.markDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CellGridEditor::renderTextureRectEditor(flecs::entity entity, CellGridComponent& grid)
|
||||
{
|
||||
// Find available texture rectangles from parent material
|
||||
flecs::entity textureEntity = flecs::entity::null();
|
||||
flecs::entity parent = entity.parent();
|
||||
while (parent.is_alive()) {
|
||||
if (parent.has<LotComponent>()) {
|
||||
auto& lot = parent.get<LotComponent>();
|
||||
if (lot.proceduralMaterialEntity.is_alive() &&
|
||||
lot.proceduralMaterialEntity.has<ProceduralMaterialComponent>()) {
|
||||
const auto& mat = lot.proceduralMaterialEntity.get<ProceduralMaterialComponent>();
|
||||
if (mat.diffuseTextureEntity.is_alive()) {
|
||||
textureEntity = mat.diffuseTextureEntity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parent.has<DistrictComponent>()) {
|
||||
auto& district = parent.get<DistrictComponent>();
|
||||
if (district.proceduralMaterialEntity.is_alive() &&
|
||||
district.proceduralMaterialEntity.has<ProceduralMaterialComponent>()) {
|
||||
const auto& mat = district.proceduralMaterialEntity.get<ProceduralMaterialComponent>();
|
||||
if (mat.diffuseTextureEntity.is_alive()) {
|
||||
textureEntity = mat.diffuseTextureEntity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parent.has<TownComponent>()) {
|
||||
auto& town = parent.get<TownComponent>();
|
||||
if (town.proceduralMaterialEntity.is_alive() &&
|
||||
town.proceduralMaterialEntity.has<ProceduralMaterialComponent>()) {
|
||||
const auto& mat = town.proceduralMaterialEntity.get<ProceduralMaterialComponent>();
|
||||
if (mat.diffuseTextureEntity.is_alive()) {
|
||||
textureEntity = mat.diffuseTextureEntity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
parent = parent.parent();
|
||||
}
|
||||
|
||||
if (!textureEntity.is_alive() || !textureEntity.has<ProceduralTextureComponent>()) {
|
||||
ImGui::TextDisabled("No ProceduralMaterial with texture found in parent hierarchy");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& texture = textureEntity.get<ProceduralTextureComponent>();
|
||||
const auto& namedRects = texture.getAllNamedRects();
|
||||
|
||||
if (namedRects.empty()) {
|
||||
ImGui::TextDisabled("No named rectangles defined in texture");
|
||||
return;
|
||||
}
|
||||
|
||||
// Build list of rect names
|
||||
std::vector<std::string> rectNames;
|
||||
rectNames.push_back("(default)");
|
||||
for (const auto& pair : namedRects) {
|
||||
rectNames.push_back(pair.first);
|
||||
}
|
||||
|
||||
auto renderRectCombo = [&](const char* label, std::string& currentValue) {
|
||||
int currentIndex = 0;
|
||||
for (size_t i = 1; i < rectNames.size(); ++i) {
|
||||
if (currentValue == rectNames[i]) {
|
||||
currentIndex = (int)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string comboItems;
|
||||
for (size_t i = 0; i < rectNames.size(); ++i) {
|
||||
if (i > 0) comboItems += '\0';
|
||||
comboItems += rectNames[i];
|
||||
}
|
||||
comboItems += '\0';
|
||||
|
||||
int newIndex = currentIndex;
|
||||
if (ImGui::Combo(label, &newIndex, comboItems.c_str())) {
|
||||
if (newIndex == 0) {
|
||||
currentValue.clear();
|
||||
} else {
|
||||
currentValue = rectNames[newIndex];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
ImGui::Text("Select texture rectangles for each part:");
|
||||
ImGui::Indent();
|
||||
|
||||
if (renderRectCombo("Floor", grid.floorRectName)) {
|
||||
grid.markDirty();
|
||||
}
|
||||
if (renderRectCombo("Ceiling", grid.ceilingRectName)) {
|
||||
grid.markDirty();
|
||||
}
|
||||
if (renderRectCombo("External Walls", grid.extWallRectName)) {
|
||||
grid.markDirty();
|
||||
}
|
||||
if (renderRectCombo("Internal Walls", grid.intWallRectName)) {
|
||||
grid.markDirty();
|
||||
}
|
||||
if (renderRectCombo("Doors", grid.doorRectName)) {
|
||||
grid.markDirty();
|
||||
}
|
||||
if (renderRectCombo("Windows", grid.windowRectName)) {
|
||||
grid.markDirty();
|
||||
}
|
||||
if (renderRectCombo("Roof", grid.roofRectName)) {
|
||||
grid.markDirty();
|
||||
}
|
||||
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ private:
|
||||
void renderCellEditor(CellGridComponent& grid);
|
||||
void renderFurnitureEditor(CellGridComponent& grid);
|
||||
void renderScriptEditor(CellGridComponent& grid);
|
||||
void renderTextureRectEditor(flecs::entity entity, CellGridComponent& grid);
|
||||
|
||||
// State for UI
|
||||
int selectedCellX = 0, selectedCellY = 0, selectedCellZ = 0;
|
||||
|
||||
Reference in New Issue
Block a user