feat: SurfaceWorld complete — biome blending wired, guard removed
The two biome checks added last commit printed nothing on success, so a passing run was indistinguishable from a block that never executed — the exact flaw I flagged twice this session and then wrote myself. Both now report their coverage. Step 2c closes SurfaceWorld: - FSurfaceColumnSource takes per-biome params and an OWNED IVoxelBiomeField. Empty params leaves the original path bit-for-bit unchanged. - The field is owned by the stack rather than borrowed: the adapter points at GetDensityAt's thread_local biome context and cache, and the stack is itself thread_local rebuilt in the same refetch block, so all three live and die together. Structural ownership beats a convention the next reader has to infer. - The overhang amp blends across biomes — Lerp(Amp(PD), Amp(PN), W) with slope and threshold from the dominant only, as ComputeSurfaceColumn does. Interpolating the slope would be meaningless; it measures the terrain rather than configuring it. - FGeneratorBiomeField lives in VoxelGenerator.cpp, on the side that knows the generator. The op sees a capability, never an owner — which is what lets it become an asset in Phase 3. - The no-biome guard is removed from UsesOperatorStackForChunk. Also: the two constructors now delegate to one body with one id counter. The first draft had two competing counters, one tagged with a high bit to avoid collision, which is a smell rather than a design. 5 of 8 archetypes ported: Maze, FlatPlain, CrystalChamber, SurfaceWorld. UNVERIFIED: not compiled. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include "CoreMinimal.h"
|
||||
#include "VoxelDensityOp.h"
|
||||
#include "VoxelStrateTypes.h" // FMazeGenerationParams
|
||||
#include "VoxelHeightOp.h" // IVoxelBiomeField — BuildSurfaceStack takes ownership of one
|
||||
|
||||
class UVoxelStrateManager;
|
||||
|
||||
@@ -200,16 +201,22 @@ namespace VoxelDensityOps
|
||||
int32 Seed);
|
||||
|
||||
/**
|
||||
* SurfaceWorld — ⚠️ PAS ENCORE COMPLET, et c'est délibéré. Équivaut exactement à
|
||||
* `GetSurfaceDensity`, c.-à-d. la version **sans overhang** et **sans mélange de biomes** :
|
||||
* • l'overhang a besoin d'une donnée par colonne que `GetSurfaceDensity` ne calcule pas
|
||||
* (il passe `OverhangAmp = 0`) — sa référence est le chemin caché ;
|
||||
* • le mélange de biomes est le combiner `Mask`, prototype de la Phase 3 (§5).
|
||||
* Les deux arrivent à l'étape 2b. Ne pas brancher dans un monde à biomes avant.
|
||||
* SurfaceWorld, COMPLET : colonne (sol + voûte) → densité, overhang 3D, post structurel, et le
|
||||
* mélange de biomes quand `PerBiomeParams` est non vide.
|
||||
*
|
||||
* @param PerBiomeParams vide ⇒ pas de biomes, chemin d'origine strictement inchangé. Non vide
|
||||
* ⇒ une pile de hauteur COMPLÈTE par biome, sol mélangé / voûte
|
||||
* sélectionnée, amplitude d'overhang interpolée (§5, combiner `Mask`).
|
||||
* @param BiomeField **transféré** à la pile, qui le possède. Doit répondre pour les mêmes
|
||||
* indices que `PerBiomeParams`. `nullptr` avec des params non vides ⇒
|
||||
* biome 0 partout (dégradation sûre, pas un crash).
|
||||
*/
|
||||
VOXELFORGE_API void BuildSurfaceStack(FVoxelOpStack& OutStack, const FSurfaceGenerationParams& P,
|
||||
int32 Seed, float SpineRadius,
|
||||
const UVoxelStrateManager* StrateManager);
|
||||
const UVoxelStrateManager* StrateManager,
|
||||
const TArray<FSurfaceGenerationParams>& PerBiomeParams =
|
||||
TArray<FSurfaceGenerationParams>(),
|
||||
TUniquePtr<IVoxelBiomeField> BiomeField = nullptr);
|
||||
|
||||
/**
|
||||
* FlatPlain ET CrystalChamber — la même pile, **sans branchement sur le type** :
|
||||
|
||||
Reference in New Issue
Block a user