feat(core): ore vein records and a materialAt query, off by default (L50); research R18, R19
Versioned capsule vein records (stable ID, resource ID, endpoints, radius, seeded irregularity) resolved into the snapshot only when requested, placed beside the route and away from passages, landings and landmarks (forced-passage control rejected). The bound field table gains materialAt (host + two resource IDs + Q16 weights) behind a per-tile BVH; mesh export v2 carries per-vertex materials; a measurement-only yield computes removed resource volume (0 on already-air space). With veins on, every density, mesh, payload and topology hash is unchanged; demo off: owner hashes identical to L47. fast/medium/full PASS. Research R18 (cavern-graph planner) and R19 (why FloatingIslands costs ~10x SurfaceWorld). 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
b9ccff4ad6
commit
ca85e876ad
15 files changed
+1573
-19
No files matched your search
@@ -34,6 +34,7 @@ namespace
|
||||
float Height;
|
||||
float WorldPosition[3];
|
||||
float TileData[4];
|
||||
float Material[4]{};
|
||||
};
|
||||
|
||||
struct FScene
|
||||
@@ -121,11 +122,12 @@ namespace
|
||||
if(!File){Error="cannot open mesh scene";return false;}
|
||||
char Magic[8]{};
|
||||
File.read(Magic,sizeof(Magic));
|
||||
if(!File||std::memcmp(Magic,"VFMSH001",8)!=0)
|
||||
const bool HasMaterials=File&&std::memcmp(Magic,"VFMSH002",8)==0;
|
||||
if(!File||(!HasMaterials&&std::memcmp(Magic,"VFMSH001",8)!=0))
|
||||
{Error="mesh scene magic is invalid";return false;}
|
||||
std::uint32_t Version=0,ExpectedTiles=0;
|
||||
if(!Read(File,Version)||!Read(File,Scene.VoxelSizeMicrons)||!Read(File,ExpectedTiles)
|
||||
||Version!=1||Scene.VoxelSizeMicrons==0||ExpectedTiles>1000000)
|
||||
||Version!=(HasMaterials?2u:1u)||Scene.VoxelSizeMicrons==0||ExpectedTiles>1000000)
|
||||
{Error="mesh scene header is malformed";return false;}
|
||||
for(double& Value:Scene.CameraMeters)if(!Read(File,Value))
|
||||
{Error="mesh scene camera is truncated";return false;}
|
||||
@@ -161,6 +163,19 @@ namespace
|
||||
Scene.MinimumHeight=std::min(Scene.MinimumHeight,Scene.Vertices[I].Height);
|
||||
Scene.MaximumHeight=std::max(Scene.MaximumHeight,Scene.Vertices[I].Height);
|
||||
}
|
||||
if(HasMaterials)
|
||||
for(std::size_t I=Base;I<Base+VertexCount;++I)
|
||||
{
|
||||
std::uint16_t Host=0,Ids[2]{},Weights[2]{};
|
||||
if(!Read(File,Host)||!Read(File,Ids[0])||!Read(File,Ids[1])
|
||||
||!Read(File,Weights[0])||!Read(File,Weights[1]))
|
||||
{Error="tile material attributes are truncated";return false;}
|
||||
Scene.Vertices[I].Material[0]=static_cast<float>(Ids[0]);
|
||||
Scene.Vertices[I].Material[1]=static_cast<float>(Weights[0])/65535.0f;
|
||||
Scene.Vertices[I].Material[2]=static_cast<float>(Ids[1]);
|
||||
Scene.Vertices[I].Material[3]=static_cast<float>(Weights[1])/65535.0f;
|
||||
(void)Host;
|
||||
}
|
||||
const double TileVoxels=static_cast<double>(32u<<Key[3]);
|
||||
const float TileExtentMeters=static_cast<float>(TileVoxels
|
||||
*static_cast<double>(Scene.VoxelSizeMicrons)/1000000.0);
|
||||
@@ -540,10 +555,12 @@ layout(location=1) in vec3 inNormal;
|
||||
layout(location=2) in float inHeight;
|
||||
layout(location=3) in vec3 inWorldPosition;
|
||||
layout(location=4) in vec4 inTileData;
|
||||
layout(location=5) in vec4 inMaterial;
|
||||
out vec3 vNormal;
|
||||
out float vHeight;
|
||||
out vec3 vWorldPosition;
|
||||
out vec4 vTileData;
|
||||
out vec4 vMaterial;
|
||||
uniform float uTanHalfHorizontal;
|
||||
uniform float uTanHalfVertical;
|
||||
uniform float uNear;
|
||||
@@ -558,6 +575,7 @@ void main()
|
||||
vHeight=inHeight;
|
||||
vWorldPosition=inWorldPosition;
|
||||
vTileData=inTileData;
|
||||
vMaterial=inMaterial;
|
||||
})GLSL";
|
||||
static constexpr char FragmentSource[]=R"GLSL(#version 300 es
|
||||
precision highp float;
|
||||
@@ -565,6 +583,7 @@ in vec3 vNormal;
|
||||
in float vHeight;
|
||||
in vec3 vWorldPosition;
|
||||
in vec4 vTileData;
|
||||
in vec4 vMaterial;
|
||||
out vec4 outColor;
|
||||
uniform int uReadableMode;
|
||||
uniform int uTileEdges;
|
||||
@@ -582,6 +601,7 @@ void main()
|
||||
if(uClipEnabled!=0&&dot(vec4(vWorldPosition,1.0),uClipPlane)<0.0)discard;
|
||||
vec3 n=normalize(vNormal);
|
||||
vec3 color;
|
||||
float illumination=1.0;
|
||||
if(uReadableMode==0)
|
||||
{
|
||||
vec3 normalColor=abs(n)*0.78+vec3(0.12);
|
||||
@@ -597,10 +617,32 @@ void main()
|
||||
?mix(vec3(0.62,0.78,1.0),vec3(1.0,0.82,0.62),smoothHeightT)
|
||||
:vec3(1.0);
|
||||
float diffuse=max(dot(n,normalize(uLightDirection)),0.0);
|
||||
float illumination=uGrazingLight!=0?0.32+1.20*diffuse:
|
||||
illumination=uGrazingLight!=0?0.32+1.20*diffuse:
|
||||
uHeadlamp!=0?0.78+0.34*diffuse:0.62+0.38*diffuse;
|
||||
color=vec3(0.64,0.62,0.56)*heightTint*illumination;
|
||||
}
|
||||
if(uReadableMode!=0)
|
||||
{
|
||||
vec3 resourceColor=vec3(0.0);
|
||||
float resourceWeight=0.0;
|
||||
if(vMaterial.x>0.5)
|
||||
{
|
||||
float w=clamp(vMaterial.y,0.0,1.0);
|
||||
vec3 oreColor=vMaterial.x<1.5?vec3(0.94,0.36,0.12):
|
||||
vMaterial.x<2.5?vec3(0.20,0.48,0.92):vec3(0.25,0.88,0.84);
|
||||
resourceColor+=oreColor*w;resourceWeight+=w;
|
||||
}
|
||||
if(vMaterial.z>0.5)
|
||||
{
|
||||
float w=clamp(vMaterial.w,0.0,1.0);
|
||||
vec3 oreColor=vMaterial.z<1.5?vec3(0.94,0.36,0.12):
|
||||
vMaterial.z<2.5?vec3(0.20,0.48,0.92):vec3(0.25,0.88,0.84);
|
||||
resourceColor+=oreColor*w;resourceWeight+=w;
|
||||
}
|
||||
if(resourceWeight>0.0)
|
||||
color=mix(color,resourceColor/max(resourceWeight,0.001),
|
||||
clamp(resourceWeight,0.0,0.95))*illumination;
|
||||
}
|
||||
if(uTileEdges!=0&&vTileData.z>0.0)
|
||||
{
|
||||
vec2 local=mod(vWorldPosition.xy-vTileData.xy,vTileData.z);
|
||||
@@ -749,6 +791,8 @@ void main()
|
||||
reinterpret_cast<void*>(offsetof(FVertex,WorldPosition)));
|
||||
glEnableVertexAttribArray(4);glVertexAttribPointer(4,4,GL_FLOAT,GL_FALSE,sizeof(FVertex),
|
||||
reinterpret_cast<void*>(offsetof(FVertex,TileData)));
|
||||
glEnableVertexAttribArray(5);glVertexAttribPointer(5,4,GL_FLOAT,GL_FALSE,sizeof(FVertex),
|
||||
reinterpret_cast<void*>(offsetof(FVertex,Material)));
|
||||
glViewport(0,0,Width,Height);glDisable(GL_CULL_FACE);glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);glClearColor(0.035f,0.055f,0.075f,1.0f);
|
||||
glClearDepthf(1.0f);glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
Reference in new issue
Block a user