Add utilities for managing and sampling terrain foliage masks
This commit is contained in:
@@ -856,6 +856,72 @@ function getStoredTerrainPaintWeightAtSample(
|
|||||||
return terrain.paintWeights[offset + layerOffset] ?? 0;
|
return terrain.paintWeights[offset + layerOffset] ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getTerrainFoliageMaskSampleIndex(
|
||||||
|
mask: Pick<TerrainFoliageMask, "resolutionX" | "resolutionZ">,
|
||||||
|
sampleX: number,
|
||||||
|
sampleZ: number
|
||||||
|
): number {
|
||||||
|
if (
|
||||||
|
!Number.isInteger(sampleX) ||
|
||||||
|
sampleX < 0 ||
|
||||||
|
sampleX >= mask.resolutionX
|
||||||
|
) {
|
||||||
|
throw new Error(`Terrain foliage mask sampleX ${sampleX} is out of range.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!Number.isInteger(sampleZ) ||
|
||||||
|
sampleZ < 0 ||
|
||||||
|
sampleZ >= mask.resolutionZ
|
||||||
|
) {
|
||||||
|
throw new Error(`Terrain foliage mask sampleZ ${sampleZ} is out of range.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sampleZ * mask.resolutionX + sampleX;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTerrainFoliageMaskValueAtSample(
|
||||||
|
mask: TerrainFoliageMask,
|
||||||
|
sampleX: number,
|
||||||
|
sampleZ: number
|
||||||
|
): number {
|
||||||
|
return (
|
||||||
|
mask.values[getTerrainFoliageMaskSampleIndex(mask, sampleX, sampleZ)] ?? 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTerrainFoliageMask(
|
||||||
|
terrain: Pick<Terrain, "foliageMasks">,
|
||||||
|
layerId: string
|
||||||
|
): TerrainFoliageMask | null {
|
||||||
|
return terrain.foliageMasks[layerId] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOrCreateTerrainFoliageMask(
|
||||||
|
terrain: Terrain,
|
||||||
|
layerId: string
|
||||||
|
): TerrainFoliageMask {
|
||||||
|
const normalizedLayerId = normalizeTerrainFoliageLayerId(
|
||||||
|
layerId,
|
||||||
|
"Terrain foliage mask layerId"
|
||||||
|
);
|
||||||
|
const currentMask = terrain.foliageMasks[normalizedLayerId];
|
||||||
|
|
||||||
|
if (currentMask !== undefined) {
|
||||||
|
return currentMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextMask = createEmptyTerrainFoliageMask(terrain, normalizedLayerId);
|
||||||
|
terrain.foliageMasks[normalizedLayerId] = nextMask;
|
||||||
|
return nextMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isTerrainFoliageMaskEmpty(
|
||||||
|
mask: TerrainFoliageMask
|
||||||
|
): boolean {
|
||||||
|
return mask.values.every((value) => value === 0);
|
||||||
|
}
|
||||||
|
|
||||||
function sampleTerrainPaintWeightAtGridCoordinate(
|
function sampleTerrainPaintWeightAtGridCoordinate(
|
||||||
terrain: Terrain,
|
terrain: Terrain,
|
||||||
sampleX: number,
|
sampleX: number,
|
||||||
|
|||||||
Reference in New Issue
Block a user