Adjusted frame geometry
This commit is contained in:
@@ -1715,6 +1715,73 @@ void CellGridSystem::buildRoofs(flecs::entity lotEntity,
|
||||
if (!lotEntity.has<LotComponent>())
|
||||
return;
|
||||
|
||||
// Get material for roofs (prefer ProceduralMaterial from Lot/District/Town)
|
||||
std::string materialName;
|
||||
flecs::entity materialEntity = flecs::entity::null();
|
||||
|
||||
// Look for ProceduralMaterial in parent hierarchy
|
||||
flecs::entity parent = lotEntity.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.created && !mat.materialName.empty()) {
|
||||
materialName = mat.materialName;
|
||||
materialEntity =
|
||||
lot.proceduralMaterialEntity;
|
||||
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.created && !mat.materialName.empty()) {
|
||||
materialName = mat.materialName;
|
||||
materialEntity =
|
||||
district.proceduralMaterialEntity;
|
||||
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.created && !mat.materialName.empty()) {
|
||||
materialName = mat.materialName;
|
||||
materialEntity =
|
||||
town.proceduralMaterialEntity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Fall back to generated material
|
||||
if (!town.materialName.empty()) {
|
||||
materialName = town.materialName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
parent = parent.parent();
|
||||
}
|
||||
|
||||
// Get roof rect name for UV mapping
|
||||
std::string roofRectName =
|
||||
grid.extWallRectName; // Default to exterior wall color
|
||||
|
||||
// Get roof components from lot's children
|
||||
lotEntity.children([&](flecs::entity child) {
|
||||
if (child.has<RoofComponent>()) {
|
||||
@@ -1728,38 +1795,187 @@ void CellGridSystem::buildRoofs(flecs::entity lotEntity,
|
||||
float depth = roof.sizeZ * grid.cellSize;
|
||||
float height = roof.maxHeight - roof.baseHeight;
|
||||
|
||||
// EXTEND constant for roof edges (like old code)
|
||||
const float EXTEND = 0.2f;
|
||||
|
||||
switch (roof.type) {
|
||||
case RoofComponent::Flat: {
|
||||
Procedural::BoxGenerator box;
|
||||
box.setSizeX(width);
|
||||
box.setSizeY(roof.baseHeight);
|
||||
box.setSizeZ(depth);
|
||||
box.setPosition(Ogre::Vector3(
|
||||
origin.x + width / 2.0f -
|
||||
grid.cellSize / 2.0f,
|
||||
origin.y + roof.baseHeight / 2.0f,
|
||||
origin.z + depth / 2.0f -
|
||||
grid.cellSize / 2.0f));
|
||||
box.addToTriangleBuffer(roofTb);
|
||||
// Main roof box
|
||||
float baseY = origin.y + roof.baseHeight / 2.0f;
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(width)
|
||||
.setSizeY(roof.baseHeight)
|
||||
.setSizeZ(depth)
|
||||
.setNumSegY(1)
|
||||
.setNumSegX(1)
|
||||
.setNumSegZ(1)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(
|
||||
origin.x, baseY, origin.z))
|
||||
.addToTriangleBuffer(roofTb);
|
||||
|
||||
// Edge trim pieces (Z+ edge)
|
||||
float trimBaseY =
|
||||
origin.y + roof.baseHeight / 2.0f;
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(width)
|
||||
.setSizeY(roof.baseHeight +
|
||||
EXTEND * 2.0f)
|
||||
.setSizeZ(EXTEND)
|
||||
.setNumSegY(1)
|
||||
.setNumSegX(1)
|
||||
.setNumSegZ(1)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(
|
||||
origin.x, trimBaseY + EXTEND,
|
||||
origin.z + depth / 2.0f +
|
||||
EXTEND / 2.0f))
|
||||
.addToTriangleBuffer(roofTb);
|
||||
|
||||
// Z- edge
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(width)
|
||||
.setSizeY(roof.baseHeight +
|
||||
EXTEND * 2.0f)
|
||||
.setSizeZ(EXTEND)
|
||||
.setNumSegY(1)
|
||||
.setNumSegX(1)
|
||||
.setNumSegZ(1)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(
|
||||
origin.x, trimBaseY + EXTEND,
|
||||
origin.z - depth / 2.0f -
|
||||
EXTEND / 2.0f))
|
||||
.addToTriangleBuffer(roofTb);
|
||||
|
||||
// X+ edge
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(EXTEND)
|
||||
.setSizeY(roof.baseHeight +
|
||||
EXTEND * 2.0f)
|
||||
.setSizeZ(depth + EXTEND * 2.0f)
|
||||
.setNumSegY(1)
|
||||
.setNumSegX(1)
|
||||
.setNumSegZ(1)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(
|
||||
origin.x + width / 2.0f +
|
||||
EXTEND / 2.0f,
|
||||
trimBaseY + EXTEND, origin.z))
|
||||
.addToTriangleBuffer(roofTb);
|
||||
|
||||
// X- edge
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(EXTEND)
|
||||
.setSizeY(roof.baseHeight +
|
||||
EXTEND * 2.0f)
|
||||
.setSizeZ(depth + EXTEND * 2.0f)
|
||||
.setNumSegY(1)
|
||||
.setNumSegX(1)
|
||||
.setNumSegZ(1)
|
||||
.setEnableNormals(true)
|
||||
.setPosition(Ogre::Vector3(
|
||||
origin.x - width / 2.0f -
|
||||
EXTEND / 2.0f,
|
||||
trimBaseY + EXTEND, origin.z))
|
||||
.addToTriangleBuffer(roofTb);
|
||||
break;
|
||||
}
|
||||
case RoofComponent::Normal: {
|
||||
// Gable roof along X axis (ridge runs along Z)
|
||||
// Two angled boxes forming a roof
|
||||
float q = width / 2.0f;
|
||||
float m = 1.0f;
|
||||
float d = Ogre::Math::Sqrt(2.0f) * (q + m);
|
||||
float baseY = origin.y;
|
||||
|
||||
// First angled box
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(d)
|
||||
.setSizeY(roof.baseHeight / 2.0f)
|
||||
.setSizeZ(depth)
|
||||
.setNumSegY(1)
|
||||
.setNumSegX(1)
|
||||
.setNumSegZ(1)
|
||||
.setEnableNormals(true)
|
||||
.setOrientation(Ogre::Quaternion(
|
||||
Ogre::Degree(45),
|
||||
Ogre::Vector3::NEGATIVE_UNIT_Z))
|
||||
.setPosition(Ogre::Vector3(
|
||||
origin.x - width / 2.0f + q +
|
||||
q / 2.0f + m / 2.0f,
|
||||
baseY + roof.baseHeight +
|
||||
q / 2.0f - m / 2.0f,
|
||||
origin.z))
|
||||
.addToTriangleBuffer(roofTb);
|
||||
|
||||
// Second angled box
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(d)
|
||||
.setSizeY(roof.baseHeight / 2.0f)
|
||||
.setSizeZ(depth)
|
||||
.setNumSegY(1)
|
||||
.setNumSegX(1)
|
||||
.setNumSegZ(1)
|
||||
.setEnableNormals(true)
|
||||
.setOrientation(Ogre::Quaternion(
|
||||
Ogre::Degree(-45),
|
||||
Ogre::Vector3::NEGATIVE_UNIT_Z))
|
||||
.setPosition(Ogre::Vector3(
|
||||
origin.x - width / 2.0f +
|
||||
q / 2.0f - m / 2.0f,
|
||||
baseY + roof.baseHeight +
|
||||
q / 2.0f - m / 2.0f,
|
||||
origin.z))
|
||||
.addToTriangleBuffer(roofTb);
|
||||
break;
|
||||
}
|
||||
case RoofComponent::Normal:
|
||||
case RoofComponent::Normal2: {
|
||||
// Gable roof using two rotated boxes or a prism
|
||||
// Simplified as a box for now
|
||||
Procedural::BoxGenerator box;
|
||||
box.setSizeX(width);
|
||||
box.setSizeY(roof.baseHeight + height / 2.0f);
|
||||
box.setSizeZ(depth);
|
||||
box.setPosition(Ogre::Vector3(
|
||||
origin.x + width / 2.0f -
|
||||
grid.cellSize / 2.0f,
|
||||
origin.y + (roof.baseHeight +
|
||||
height / 2.0f) /
|
||||
2.0f,
|
||||
origin.z + depth / 2.0f -
|
||||
grid.cellSize / 2.0f));
|
||||
box.addToTriangleBuffer(roofTb);
|
||||
// Gable roof along Z axis (ridge runs along X)
|
||||
float q = depth / 2.0f;
|
||||
float m = 1.0f;
|
||||
float d = Ogre::Math::Sqrt(2.0f) * (q + m);
|
||||
float baseY = origin.y;
|
||||
|
||||
// First angled box
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(width)
|
||||
.setSizeY(roof.baseHeight / 2.0f)
|
||||
.setSizeZ(d)
|
||||
.setNumSegY(1)
|
||||
.setNumSegX(1)
|
||||
.setNumSegZ(1)
|
||||
.setEnableNormals(true)
|
||||
.setOrientation(Ogre::Quaternion(
|
||||
Ogre::Degree(45),
|
||||
Ogre::Vector3::NEGATIVE_UNIT_X))
|
||||
.setPosition(Ogre::Vector3(
|
||||
origin.x,
|
||||
baseY + roof.baseHeight +
|
||||
q / 2.0f - m / 2.0f,
|
||||
origin.z - depth / 2.0f +
|
||||
q / 2.0f - m / 2.0f))
|
||||
.addToTriangleBuffer(roofTb);
|
||||
|
||||
// Second angled box
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(width)
|
||||
.setSizeY(roof.baseHeight / 2.0f)
|
||||
.setSizeZ(d)
|
||||
.setNumSegX(1)
|
||||
.setNumSegY(1)
|
||||
.setNumSegZ(1)
|
||||
.setEnableNormals(true)
|
||||
.setOrientation(Ogre::Quaternion(
|
||||
Ogre::Degree(-45),
|
||||
Ogre::Vector3::NEGATIVE_UNIT_X))
|
||||
.setPosition(Ogre::Vector3(
|
||||
origin.x,
|
||||
baseY + roof.baseHeight +
|
||||
q / 2.0f - m / 2.0f,
|
||||
origin.z - depth / 2.0f + q +
|
||||
q / 2.0f + m / 2.0f))
|
||||
.addToTriangleBuffer(roofTb);
|
||||
break;
|
||||
}
|
||||
case RoofComponent::Cone: {
|
||||
@@ -2846,7 +3062,7 @@ void CellGridSystem::createDoorFrameMeshes(const CellGridComponent &grid,
|
||||
|
||||
// Create external door frame mesh
|
||||
Procedural::TriangleBuffer extFrameTb;
|
||||
float stepDepth = frameDepth * 1.3f;
|
||||
float stepDepth = frameDepth * 1.2f;
|
||||
|
||||
// Left frame with step
|
||||
Procedural::BoxGenerator()
|
||||
@@ -2893,16 +3109,28 @@ void CellGridSystem::createDoorFrameMeshes(const CellGridComponent &grid,
|
||||
float stepWidth = doorWidth + frameThickness * 4;
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(stepWidth)
|
||||
.setSizeY(frameThickness)
|
||||
.setSizeY(frameThickness * 2.0f)
|
||||
.setSizeZ(stepDepth)
|
||||
.setNumSegX(2)
|
||||
.setNumSegY(1)
|
||||
.setNumSegZ(1)
|
||||
.setPosition(
|
||||
Ogre::Vector3(0, frameThickness / 2 + 0.1f,
|
||||
Ogre::Vector3(0, frameThickness,
|
||||
(stepDepth - frameDepth) / 2 + 0.05f))
|
||||
.setEnableNormals(true)
|
||||
.addToTriangleBuffer(extFrameTb);
|
||||
Procedural::BoxGenerator()
|
||||
.setSizeX(stepWidth)
|
||||
.setSizeY(frameThickness)
|
||||
.setSizeZ(stepDepth)
|
||||
.setNumSegX(2)
|
||||
.setNumSegY(1)
|
||||
.setNumSegZ(1)
|
||||
.setPosition(Ogre::Vector3(0, frameThickness * 0.5f,
|
||||
(stepDepth - frameDepth) / 2 +
|
||||
0.05f + stepDepth))
|
||||
.setEnableNormals(true)
|
||||
.addToTriangleBuffer(extFrameTb);
|
||||
|
||||
applyUVMappingToBuffer(extFrameTb, grid.extDoorFrameRectName,
|
||||
materialEntity);
|
||||
|
||||
Reference in New Issue
Block a user