auto-git:

[change] src/commands/apply-terrain-brush-patch-command.ts
This commit is contained in:
2026-05-01 18:03:29 +02:00
parent 4c904e3ac9
commit 0dad5d9e77

View File

@@ -4,7 +4,13 @@ import type {
TerrainBrushPatch, TerrainBrushPatch,
TerrainSampleValuePatch TerrainSampleValuePatch
} from "../core/terrain-brush"; } from "../core/terrain-brush";
import { updateTerrainBoundsCacheAfterHeightPatch } from "../document/terrains"; import {
markTerrainRenderSamplesDirty,
TERRAIN_LAYER_COUNT,
updateTerrainBoundsCacheAfterHeightPatch,
type Terrain,
type TerrainSampleBounds
} from "../document/terrains";
import type { ToolMode } from "../core/tool-mode"; import type { ToolMode } from "../core/tool-mode";
import type { CommandContext, EditorCommand } from "./command"; import type { CommandContext, EditorCommand } from "./command";
@@ -43,6 +49,31 @@ export function isTerrainBrushPatchEmpty(patch: TerrainBrushPatch): boolean {
return patch.heightSamples.length === 0 && patch.paintWeights.length === 0; return patch.heightSamples.length === 0 && patch.paintWeights.length === 0;
} }
function mergeTerrainSampleIndexIntoBounds(
bounds: TerrainSampleBounds | null,
terrain: Terrain,
sampleIndex: number
): TerrainSampleBounds {
const sampleX = sampleIndex % terrain.sampleCountX;
const sampleZ = Math.floor(sampleIndex / terrain.sampleCountX);
if (bounds === null) {
return {
minSampleX: sampleX,
maxSampleX: sampleX,
minSampleZ: sampleZ,
maxSampleZ: sampleZ
};
}
return {
minSampleX: Math.min(bounds.minSampleX, sampleX),
maxSampleX: Math.max(bounds.maxSampleX, sampleX),
minSampleZ: Math.min(bounds.minSampleZ, sampleZ),
maxSampleZ: Math.max(bounds.maxSampleZ, sampleZ)
};
}
export function createApplyTerrainBrushPatchCommand( export function createApplyTerrainBrushPatchCommand(
options: ApplyTerrainBrushPatchCommandOptions options: ApplyTerrainBrushPatchCommandOptions
): EditorCommand { ): EditorCommand {
@@ -71,10 +102,17 @@ export function createApplyTerrainBrushPatchCommand(
after: direction === "forward" ? entry.after : entry.before after: direction === "forward" ? entry.after : entry.before
})); }));
let renderDirtyBounds: TerrainSampleBounds | null = null;
for (const entry of patch.heightSamples) { for (const entry of patch.heightSamples) {
assertValidPatchEntry(entry, terrain.heights.length, "Terrain height"); assertValidPatchEntry(entry, terrain.heights.length, "Terrain height");
terrain.heights[entry.index] = terrain.heights[entry.index] =
direction === "forward" ? entry.after : entry.before; direction === "forward" ? entry.after : entry.before;
renderDirtyBounds = mergeTerrainSampleIndexIntoBounds(
renderDirtyBounds,
terrain,
entry.index
);
} }
updateTerrainBoundsCacheAfterHeightPatch(terrain, heightPatchForBounds); updateTerrainBoundsCacheAfterHeightPatch(terrain, heightPatchForBounds);
@@ -87,8 +125,15 @@ export function createApplyTerrainBrushPatchCommand(
); );
terrain.paintWeights[entry.index] = terrain.paintWeights[entry.index] =
direction === "forward" ? entry.after : entry.before; direction === "forward" ? entry.after : entry.before;
renderDirtyBounds = mergeTerrainSampleIndexIntoBounds(
renderDirtyBounds,
terrain,
Math.floor(entry.index / (TERRAIN_LAYER_COUNT - 1))
);
} }
markTerrainRenderSamplesDirty(terrain, renderDirtyBounds);
context.setDocument({ context.setDocument({
...currentDocument, ...currentDocument,
terrains: { terrains: {