Refactor terrain paint weight calculation to dynamically use actual layer count and stored weight count.
This commit is contained in:
@@ -248,6 +248,24 @@ function normalizeTerrainLayers(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function normalizeTerrainLayerCount(layerCount: number): number {
|
||||||
|
if (
|
||||||
|
!Number.isInteger(layerCount) ||
|
||||||
|
layerCount < MIN_TERRAIN_LAYER_COUNT ||
|
||||||
|
layerCount > MAX_TERRAIN_LAYER_COUNT
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
`Terrain layer count must be an integer between ${MIN_TERRAIN_LAYER_COUNT} and ${MAX_TERRAIN_LAYER_COUNT}.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return layerCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTerrainStoredPaintWeightCount(layerCount: number): number {
|
||||||
|
return Math.max(0, normalizeTerrainLayerCount(layerCount) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
export function createFlatTerrainHeights(
|
export function createFlatTerrainHeights(
|
||||||
sampleCountX: number,
|
sampleCountX: number,
|
||||||
sampleCountZ: number,
|
sampleCountZ: number,
|
||||||
@@ -271,7 +289,8 @@ export function createFlatTerrainHeights(
|
|||||||
|
|
||||||
export function createFlatTerrainPaintWeights(
|
export function createFlatTerrainPaintWeights(
|
||||||
sampleCountX: number,
|
sampleCountX: number,
|
||||||
sampleCountZ: number
|
sampleCountZ: number,
|
||||||
|
layerCount = TERRAIN_LAYER_COUNT
|
||||||
): number[] {
|
): number[] {
|
||||||
const normalizedSampleCountX = normalizeTerrainSampleCount(
|
const normalizedSampleCountX = normalizeTerrainSampleCount(
|
||||||
sampleCountX,
|
sampleCountX,
|
||||||
@@ -281,11 +300,12 @@ export function createFlatTerrainPaintWeights(
|
|||||||
sampleCountZ,
|
sampleCountZ,
|
||||||
"Terrain sampleCountZ"
|
"Terrain sampleCountZ"
|
||||||
);
|
);
|
||||||
|
const normalizedLayerCount = normalizeTerrainLayerCount(layerCount);
|
||||||
|
|
||||||
return new Array(
|
return new Array(
|
||||||
normalizedSampleCountX *
|
normalizedSampleCountX *
|
||||||
normalizedSampleCountZ *
|
normalizedSampleCountZ *
|
||||||
(TERRAIN_LAYER_COUNT - 1)
|
getTerrainStoredPaintWeightCount(normalizedLayerCount)
|
||||||
).fill(0);
|
).fill(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,11 +365,14 @@ export function getTerrainSampleIndex(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getTerrainPaintWeightSampleOffset(
|
export function getTerrainPaintWeightSampleOffset(
|
||||||
terrain: Pick<Terrain, "sampleCountX" | "sampleCountZ">,
|
terrain: Pick<Terrain, "sampleCountX" | "sampleCountZ" | "layers">,
|
||||||
sampleX: number,
|
sampleX: number,
|
||||||
sampleZ: number
|
sampleZ: number
|
||||||
): number {
|
): number {
|
||||||
return getTerrainSampleIndex(terrain, sampleX, sampleZ) * (TERRAIN_LAYER_COUNT - 1);
|
return (
|
||||||
|
getTerrainSampleIndex(terrain, sampleX, sampleZ) *
|
||||||
|
getTerrainStoredPaintWeightCount(terrain.layers.length)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTerrainHeightAtSample(
|
export function getTerrainHeightAtSample(
|
||||||
@@ -363,13 +386,14 @@ export function getTerrainHeightAtSample(
|
|||||||
function normalizeTerrainPaintWeights(
|
function normalizeTerrainPaintWeights(
|
||||||
sampleCountX: number,
|
sampleCountX: number,
|
||||||
sampleCountZ: number,
|
sampleCountZ: number,
|
||||||
|
layerCount: number,
|
||||||
paintWeights: readonly number[] | undefined
|
paintWeights: readonly number[] | undefined
|
||||||
): number[] {
|
): number[] {
|
||||||
const expectedLength =
|
const storedWeightCount = getTerrainStoredPaintWeightCount(layerCount);
|
||||||
sampleCountX * sampleCountZ * (TERRAIN_LAYER_COUNT - 1);
|
const expectedLength = sampleCountX * sampleCountZ * storedWeightCount;
|
||||||
const normalizedPaintWeights =
|
const normalizedPaintWeights =
|
||||||
paintWeights === undefined
|
paintWeights === undefined
|
||||||
? createFlatTerrainPaintWeights(sampleCountX, sampleCountZ)
|
? createFlatTerrainPaintWeights(sampleCountX, sampleCountZ, layerCount)
|
||||||
: [...paintWeights];
|
: [...paintWeights];
|
||||||
|
|
||||||
if (normalizedPaintWeights.length !== expectedLength) {
|
if (normalizedPaintWeights.length !== expectedLength) {
|
||||||
@@ -383,14 +407,10 @@ function normalizeTerrainPaintWeights(
|
|||||||
sampleIndex < sampleCountX * sampleCountZ;
|
sampleIndex < sampleCountX * sampleCountZ;
|
||||||
sampleIndex += 1
|
sampleIndex += 1
|
||||||
) {
|
) {
|
||||||
const offset = sampleIndex * (TERRAIN_LAYER_COUNT - 1);
|
const offset = sampleIndex * storedWeightCount;
|
||||||
let weightSum = 0;
|
let weightSum = 0;
|
||||||
|
|
||||||
for (
|
for (let layerOffset = 0; layerOffset < storedWeightCount; layerOffset += 1) {
|
||||||
let layerOffset = 0;
|
|
||||||
layerOffset < TERRAIN_LAYER_COUNT - 1;
|
|
||||||
layerOffset += 1
|
|
||||||
) {
|
|
||||||
const value = normalizedPaintWeights[offset + layerOffset];
|
const value = normalizedPaintWeights[offset + layerOffset];
|
||||||
|
|
||||||
if (!Number.isFinite(value)) {
|
if (!Number.isFinite(value)) {
|
||||||
@@ -408,11 +428,7 @@ function normalizeTerrainPaintWeights(
|
|||||||
|
|
||||||
const scale = 1 / weightSum;
|
const scale = 1 / weightSum;
|
||||||
|
|
||||||
for (
|
for (let layerOffset = 0; layerOffset < storedWeightCount; layerOffset += 1) {
|
||||||
let layerOffset = 0;
|
|
||||||
layerOffset < TERRAIN_LAYER_COUNT - 1;
|
|
||||||
layerOffset += 1
|
|
||||||
) {
|
|
||||||
normalizedPaintWeights[offset + layerOffset] *= scale;
|
normalizedPaintWeights[offset + layerOffset] *= scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user