Trim cross corner sidewalk tip and fix outer arc skirt
Drop the sidewalk fan to (±jr,±jr) that made a sharp property-corner spike, and emit a walk-height sidewalk vertical on the outer gray arc so the skirt faces render instead of showing through. Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>
This commit is contained in:
2 files changed
+18
-9
No files matched your search
@@ -574,24 +574,24 @@ Result<void> bakeJunction(MeshBuild& mesh, const RoadNetwork& network, const Roa
|
||||
const V3 b1 = arcPt(r1, t1);
|
||||
const V3 c0 = arcPt(r2, t0);
|
||||
const V3 c1 = arcPt(r2, t1);
|
||||
// Toward the outer corner center (sidewalk side).
|
||||
// Toward the outer corner center (property side) / toward asphalt.
|
||||
const V3 inToCorner = normalize(V3{cx - a0.x, 0.f, cz - a0.z});
|
||||
const V3 outToRoad = inToCorner * -1.f;
|
||||
|
||||
// Tops: asphalt-face → curb → sidewalk → corner disk, all +Y.
|
||||
// Tops: asphalt-face → curb → sidewalk ring. No fan to (jr,jr) —
|
||||
// that disk tip is the sharp property-corner spike.
|
||||
appendOrientedQuad(mesh, V3{a0.x, curbTop, a0.z}, V3{b0.x, curbTop, b0.z},
|
||||
V3{b1.x, curbTop, b1.z}, V3{a1.x, curbTop, a1.z}, upN, 0.f, 1.f, 0.f, 1.f,
|
||||
RoadMaterial::Curb);
|
||||
appendOrientedQuad(mesh, V3{b0.x, walkY, b0.z}, V3{c0.x, walkY, c0.z}, V3{c1.x, walkY, c1.z},
|
||||
V3{b1.x, walkY, b1.z}, upN, 0.f, 1.f, 0.f, 1.f, RoadMaterial::Sidewalk);
|
||||
appendOrientedTri(mesh, V3{cx, walkY, cz}, V3{c0.x, walkY, c0.z}, V3{c1.x, walkY, c1.z}, upN,
|
||||
RoadMaterial::Sidewalk);
|
||||
|
||||
// Vertical curb face toward asphalt / toward corner.
|
||||
// Vertical curb toward asphalt; sidewalk skirt on the outer gray arc.
|
||||
appendOrientedQuad(mesh, V3{a0.x, y, a0.z}, V3{a1.x, y, a1.z}, V3{a1.x, curbTop, a1.z},
|
||||
V3{a0.x, curbTop, a0.z}, outToRoad, 0.f, 1.f, 0.f, 1.f, RoadMaterial::Curb);
|
||||
appendOrientedQuad(mesh, V3{c0.x, y, c0.z}, V3{c1.x, y, c1.z}, V3{c1.x, curbTop, c1.z},
|
||||
V3{c0.x, curbTop, c0.z}, inToCorner, 0.f, 1.f, 0.f, 1.f, RoadMaterial::Curb);
|
||||
appendOrientedQuad(mesh, V3{c0.x, y, c0.z}, V3{c1.x, y, c1.z}, V3{c1.x, walkY, c1.z},
|
||||
V3{c0.x, walkY, c0.z}, inToCorner, 0.f, 1.f, 0.f, 1.f,
|
||||
RoadMaterial::Sidewalk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-2
@@ -327,9 +327,11 @@ TEST_CASE("procgen.road.scenes.crossJunctionCornerSidewalks") {
|
||||
CHECK_GE(sidewalkGroup, 0);
|
||||
auto sw = baked.value().mesh.copyGroup(sidewalkGroup);
|
||||
REQUIRE(sw);
|
||||
// Outward-center curb returns: sidewalks sit near (jr,jr) inside the corner disk.
|
||||
// Outward-center curb returns: sidewalk ring around (jr,jr), no tip disk to the center.
|
||||
const float jr = hubJr;
|
||||
int arcHits = 0;
|
||||
int tipHits = 0;
|
||||
int outerSkirtHits = 0;
|
||||
for (int i = 0; i < sw->getVertexCount(); ++i) {
|
||||
const float x = std::fabs(sw->getPositionX(i));
|
||||
const float z = std::fabs(sw->getPositionZ(i));
|
||||
@@ -337,10 +339,17 @@ TEST_CASE("procgen.road.scenes.crossJunctionCornerSidewalks") {
|
||||
const float dz = jr - z;
|
||||
if (dx < 0.05f || dz < 0.05f) continue;
|
||||
const float r = std::sqrt(dx * dx + dz * dz);
|
||||
// Between sidewalk outer and curb face radii from the outer corner center.
|
||||
// Sidewalk annulus between outer skirt and curb (no fan into r≈0 tip).
|
||||
if (r > 0.9f && r < 2.9f) ++arcHits;
|
||||
if (r < 0.55f) ++tipHits;
|
||||
const float nx = sw->getNormalX(i);
|
||||
const float nz = sw->getNormalZ(i);
|
||||
// Outer skirt faces toward the property corner (±jr,±jr).
|
||||
if (r > 0.7f && r < 1.4f && (nx * dx + nz * dz) > 0.3f) ++outerSkirtHits;
|
||||
}
|
||||
CHECK_GT(arcHits, 16);
|
||||
CHECK_EQ(tipHits, 0);
|
||||
CHECK_GT(outerSkirtHits, 8);
|
||||
|
||||
// Top faces must carry +Y normals (mesh3D CCW / lighting); flipped windings show dark.
|
||||
int upHits = 0, downHits = 0;
|
||||
|
||||
Reference in new issue
Block a user