Support terrain grid resize directions for terrain manipulation functions

This commit is contained in:
2026-05-13 14:10:26 +02:00
parent 215569cf96
commit 3e2808f18a
2 changed files with 79 additions and 15 deletions

View File

@@ -292,6 +292,8 @@ import {
import {
areTerrainsEqual,
createTerrain,
DEFAULT_TERRAIN_GRID_RESIZE_DIRECTION_X,
DEFAULT_TERRAIN_GRID_RESIZE_DIRECTION_Z,
getTerrainBounds,
getTerrainFootprintDepth,
getTerrainFootprintWidth,
@@ -301,6 +303,8 @@ import {
MAX_TERRAIN_LAYER_COUNT,
MIN_TERRAIN_SAMPLE_COUNT,
resizeTerrainGrid,
type TerrainGridResizeDirectionX,
type TerrainGridResizeDirectionZ,
type Terrain
} from "../document/terrains";
import { BUNDLED_FOLIAGE_PROTOTYPES } from "../foliage/bundled-foliage-manifest";
@@ -3488,6 +3492,14 @@ export function App({
const [terrainSampleCountXDraft, setTerrainSampleCountXDraft] = useState("9");
const [terrainSampleCountZDraft, setTerrainSampleCountZDraft] = useState("9");
const [terrainCellSizeDraft, setTerrainCellSizeDraft] = useState("1");
const [terrainResizeDirectionXDraft, setTerrainResizeDirectionXDraft] =
useState<TerrainGridResizeDirectionX>(
DEFAULT_TERRAIN_GRID_RESIZE_DIRECTION_X
);
const [terrainResizeDirectionZDraft, setTerrainResizeDirectionZDraft] =
useState<TerrainGridResizeDirectionZ>(
DEFAULT_TERRAIN_GRID_RESIZE_DIRECTION_Z
);
const [terrainLodGridVisibleTerrainIds, setTerrainLodGridVisibleTerrainIds] =
useState<readonly string[]>([]);
const [activeFoliageLayerId, setActiveFoliageLayerId] = useState<

View File

@@ -1573,9 +1573,15 @@ function createLocalPositionResampledTerrainFoliageBlockerMask(
export function changeTerrainCellSizePreservingFootprint(
terrain: Terrain,
requestedCellSize: number
requestedCellSize: number,
resizeDirectionX: TerrainGridResizeDirectionX = DEFAULT_TERRAIN_GRID_RESIZE_DIRECTION_X,
resizeDirectionZ: TerrainGridResizeDirectionZ = DEFAULT_TERRAIN_GRID_RESIZE_DIRECTION_Z
): Terrain {
const cellSize = normalizeTerrainCellSize(requestedCellSize);
const normalizedResizeDirectionX =
normalizeTerrainGridResizeDirectionX(resizeDirectionX);
const normalizedResizeDirectionZ =
normalizeTerrainGridResizeDirectionZ(resizeDirectionZ);
const sampleCountX = getTerrainSampleCountForFootprint(
getTerrainFootprintWidth(terrain),
cellSize
@@ -1584,10 +1590,18 @@ export function changeTerrainCellSizePreservingFootprint(
getTerrainFootprintDepth(terrain),
cellSize
);
const nextPosition = getTerrainPositionForResize(
terrain,
sampleCountX,
sampleCountZ,
cellSize,
normalizedResizeDirectionX,
normalizedResizeDirectionZ
);
return createTerrain({
...terrain,
position: cloneVec3(terrain.position),
position: nextPosition,
sampleCountX,
sampleCountZ,
cellSize,
@@ -1595,25 +1609,29 @@ export function changeTerrainCellSizePreservingFootprint(
terrain,
sampleCountX,
sampleCountZ,
cellSize
cellSize,
nextPosition
),
paintWeights: createLocalPositionResampledTerrainPaintWeights(
terrain,
sampleCountX,
sampleCountZ,
cellSize
cellSize,
nextPosition
),
foliageMasks: createLocalPositionResampledTerrainFoliageMasks(
terrain,
sampleCountX,
sampleCountZ,
cellSize
cellSize,
nextPosition
),
foliageBlockerMask: createLocalPositionResampledTerrainFoliageBlockerMask(
terrain,
sampleCountX,
sampleCountZ,
cellSize
cellSize,
nextPosition
)
});
}
@@ -1621,7 +1639,9 @@ export function changeTerrainCellSizePreservingFootprint(
export function changeTerrainSampleCountsByExtendingOrCropping(
terrain: Terrain,
requestedSampleCountX: number,
requestedSampleCountZ: number
requestedSampleCountZ: number,
resizeDirectionX: TerrainGridResizeDirectionX = DEFAULT_TERRAIN_GRID_RESIZE_DIRECTION_X,
resizeDirectionZ: TerrainGridResizeDirectionZ = DEFAULT_TERRAIN_GRID_RESIZE_DIRECTION_Z
): Terrain {
const sampleCountX = normalizeTerrainSampleCount(
requestedSampleCountX,
@@ -1632,10 +1652,22 @@ export function changeTerrainSampleCountsByExtendingOrCropping(
"Terrain sampleCountZ"
);
const cellSize = terrain.cellSize;
const normalizedResizeDirectionX =
normalizeTerrainGridResizeDirectionX(resizeDirectionX);
const normalizedResizeDirectionZ =
normalizeTerrainGridResizeDirectionZ(resizeDirectionZ);
const nextPosition = getTerrainPositionForResize(
terrain,
sampleCountX,
sampleCountZ,
cellSize,
normalizedResizeDirectionX,
normalizedResizeDirectionZ
);
return createTerrain({
...terrain,
position: cloneVec3(terrain.position),
position: nextPosition,
sampleCountX,
sampleCountZ,
cellSize,
@@ -1643,43 +1675,63 @@ export function changeTerrainSampleCountsByExtendingOrCropping(
terrain,
sampleCountX,
sampleCountZ,
cellSize
cellSize,
nextPosition
),
paintWeights: createLocalPositionResampledTerrainPaintWeights(
terrain,
sampleCountX,
sampleCountZ,
cellSize
cellSize,
nextPosition
),
foliageMasks: createLocalPositionResampledTerrainFoliageMasks(
terrain,
sampleCountX,
sampleCountZ,
cellSize
cellSize,
nextPosition
),
foliageBlockerMask: createLocalPositionResampledTerrainFoliageBlockerMask(
terrain,
sampleCountX,
sampleCountZ,
cellSize
cellSize,
nextPosition
)
});
}
export function resizeTerrainGrid(
terrain: Terrain,
options: Pick<Terrain, "sampleCountX" | "sampleCountZ" | "cellSize">
options: Pick<Terrain, "sampleCountX" | "sampleCountZ" | "cellSize"> & {
resizeDirectionX?: TerrainGridResizeDirectionX;
resizeDirectionZ?: TerrainGridResizeDirectionZ;
}
): Terrain {
const cellSize = normalizeTerrainCellSize(options.cellSize);
const resizeDirectionX = normalizeTerrainGridResizeDirectionX(
options.resizeDirectionX
);
const resizeDirectionZ = normalizeTerrainGridResizeDirectionZ(
options.resizeDirectionZ
);
if (cellSize !== terrain.cellSize) {
return changeTerrainCellSizePreservingFootprint(terrain, cellSize);
return changeTerrainCellSizePreservingFootprint(
terrain,
cellSize,
resizeDirectionX,
resizeDirectionZ
);
}
return changeTerrainSampleCountsByExtendingOrCropping(
terrain,
options.sampleCountX,
options.sampleCountZ
options.sampleCountZ,
resizeDirectionX,
resizeDirectionZ
);
}