wip: continuous backbone floor profile for the cave planner (L134 design 4, untested)
Written by Luna before the Codex usage limit cut the round: one shared distance/floor profile across backbone rooms and edges, edge cubic floors derived from it, sloped route-room floors, lower-floor backing cap at overlaps, and validator checks for joint height/slope continuity. Not yet built or audited. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
1 parent
379093401e
commit
4a97023b24
3 files changed
+296
-19
No files matched your search
@@ -3583,6 +3583,7 @@ private:
|
||||
double minimumFloorMetres=std::numeric_limits<double>::infinity();
|
||||
double maximumFloorMetres=-std::numeric_limits<double>::infinity();
|
||||
double maximumSegmentGrade=0.0;
|
||||
std::array<double,2> floorGradient{};
|
||||
std::array<float,3> centerVoxels{},halfExtentsVoxels{};
|
||||
std::array<std::array<float,3>,4> controlPointsVoxels{};
|
||||
float floorVoxels=0.0f;
|
||||
@@ -4011,8 +4012,10 @@ private:
|
||||
{
|
||||
CavernRuntime.clear();CavernSpatialNodes.clear();CavernSpatialOrder.clear();
|
||||
if(!ResolvedLayout||!Owner||Owner->CoreVoxelSizeMicrons==0
|
||||
||ResolvedLayout->cavernGraphVocabularyVersion
|
||||
!=VoxelForgeCore::ResolvedLayoutCavernGraphVocabularyVersionV1)return;
|
||||
||(ResolvedLayout->cavernGraphVocabularyVersion
|
||||
!=VoxelForgeCore::ResolvedLayoutCavernGraphVocabularyVersionV1
|
||||
&&ResolvedLayout->cavernGraphVocabularyVersion
|
||||
!=VoxelForgeCore::ResolvedLayoutCavernGraphVocabularyVersionV2))return;
|
||||
const auto isNativeGraphStrate=[this](std::int32_t strateIndex)
|
||||
{
|
||||
const auto found=std::find_if(ResolvedLayout->strates.begin(),
|
||||
@@ -4042,6 +4045,8 @@ private:
|
||||
}
|
||||
runtime.floorVoxels=static_cast<float>(
|
||||
static_cast<double>(room.floorMicrometres)/micronsPerVoxel);
|
||||
runtime.floorGradient={room.floorGradientQ16[0]/65536.0,
|
||||
room.floorGradientQ16[1]/65536.0};
|
||||
runtime.smoothWidthVoxels=static_cast<float>(
|
||||
static_cast<double>(room.smoothWidthMicrometres)/micronsPerVoxel);
|
||||
runtime.irregularityAmplitudeVoxels=static_cast<float>(
|
||||
@@ -5314,7 +5319,18 @@ public:
|
||||
(std::sqrt(normalizedMinimumSquared)-1.0)*meanRadius,
|
||||
(std::sqrt(normalizedMaximumSquared)-1.0)*meanRadius,true};
|
||||
const double floorZ=feature.room->floorMicrometres/1000000.0;
|
||||
const FMetricInterval floor={floorZ-hi[2],floorZ-lo[2],true};
|
||||
const double centerX=feature.room->centerMicrometres[0]/1000000.0;
|
||||
const double centerY=feature.room->centerMicrometres[1]/1000000.0;
|
||||
const double gx=feature.room->floorGradientQ16[0]/65536.0;
|
||||
const double gy=feature.room->floorGradientQ16[1]/65536.0;
|
||||
const double x0=lo[0]-centerX,x1=hi[0]-centerX;
|
||||
const double y0=lo[1]-centerY,y1=hi[1]-centerY;
|
||||
const double gradientMinimum=(gx>=0.0?gx*x0:gx*x1)
|
||||
+(gy>=0.0?gy*y0:gy*y1);
|
||||
const double gradientMaximum=(gx>=0.0?gx*x1:gx*x0)
|
||||
+(gy>=0.0?gy*y1:gy*y0);
|
||||
const FMetricInterval floor={floorZ-hi[2]+gradientMinimum,
|
||||
floorZ-lo[2]+gradientMaximum,true};
|
||||
const double width=feature.room->smoothWidthMicrometres/1000000.0;
|
||||
featureVoid={SmoothMaxMetres(ellipsoid.minimum,floor.minimum,width),
|
||||
SmoothMaxMetres(ellipsoid.maximum,floor.maximum,width),true};
|
||||
@@ -7463,6 +7479,7 @@ private:
|
||||
double floorSupportScore=std::numeric_limits<double>::infinity();
|
||||
double floorSupportDepth=0.0,floorSupportFloor=0.0,floorSupportGrade=0.0;
|
||||
const std::string* floorSupportEdgeId=nullptr;
|
||||
const std::string* floorSupportProfileId=nullptr;
|
||||
for(const std::uint32_t index:*candidates)
|
||||
{
|
||||
if(index>=CavernRuntime.size())continue;
|
||||
@@ -7491,7 +7508,9 @@ private:
|
||||
feature.irregularityWavelengthVoxels,feature.irregularitySeed)
|
||||
*feature.irregularityAmplitudeVoxels*metresPerVoxel*fade;
|
||||
}
|
||||
const double floor=feature.room->floorMicrometres/1000000.0-point[2];
|
||||
const double floor=feature.room->floorMicrometres/1000000.0-point[2]
|
||||
+feature.floorGradient[0]*(point[0]-feature.centerMetres[0])
|
||||
+feature.floorGradient[1]*(point[1]-feature.centerMetres[1]);
|
||||
const double width=feature.room->smoothWidthMicrometres/1000000.0;
|
||||
featureVoid=SmoothMaxMetres(ellipsoid,floor,width);
|
||||
}
|
||||
@@ -7599,10 +7618,32 @@ private:
|
||||
{
|
||||
const double deltaZ=point[2]-nearestFloor;
|
||||
const double candidateScore=nearestRadial*nearestRadial+deltaZ*deltaZ;
|
||||
if(candidateScore<floorSupportScore
|
||||
||(candidateScore==floorSupportScore
|
||||
&&(!floorSupportEdgeId
|
||||
||feature.edge->stableId<*floorSupportEdgeId)))
|
||||
if(!feature.edge->floorProfileStableId.empty())
|
||||
{
|
||||
const bool sameProfile=floorSupportProfileId
|
||||
&&*floorSupportProfileId==feature.edge->floorProfileStableId;
|
||||
if(!floorSupportProfileId||sameProfile)
|
||||
{
|
||||
// Backbone edges share h(s). At a geometric joint their
|
||||
// cave volumes overlap, so the backing top is the lower
|
||||
// of the local floors, never the closer higher segment.
|
||||
if(!floorSupportProfileId||nearestFloor<floorSupportFloor
|
||||
||(nearestFloor==floorSupportFloor
|
||||
&&feature.edge->stableId<*floorSupportEdgeId))
|
||||
{
|
||||
floorSupportDepth=candidateSupportDepth;
|
||||
floorSupportFloor=nearestFloor;
|
||||
floorSupportGrade=nearestGrade;
|
||||
floorSupportEdgeId=&feature.edge->stableId;
|
||||
}
|
||||
floorSupportProfileId=&feature.edge->floorProfileStableId;
|
||||
}
|
||||
}
|
||||
else if(!floorSupportProfileId
|
||||
&&(candidateScore<floorSupportScore
|
||||
||(candidateScore==floorSupportScore
|
||||
&&(!floorSupportEdgeId
|
||||
||feature.edge->stableId<*floorSupportEdgeId))))
|
||||
{
|
||||
floorSupportScore=candidateScore;
|
||||
floorSupportDepth=candidateSupportDepth;
|
||||
|
||||
Reference in new issue
Block a user