auto-git:
[change] src/commands/apply-terrain-brush-patch-command.ts
This commit is contained in:
@@ -81,6 +81,101 @@ function mergeTerrainSampleIndexIntoBounds(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function applyTerrainBrushPatchToDocument(
|
||||||
|
currentDocument: ReturnType<CommandContext["getDocument"]>,
|
||||||
|
patch: TerrainBrushPatch,
|
||||||
|
direction: "forward" | "backward"
|
||||||
|
): ReturnType<CommandContext["getDocument"]> {
|
||||||
|
const terrain = currentDocument.terrains[patch.terrainId];
|
||||||
|
|
||||||
|
if (terrain === undefined) {
|
||||||
|
throw new Error(`Terrain ${patch.terrainId} does not exist.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const heightPatchForBounds = patch.heightSamples.map((entry) => ({
|
||||||
|
index: entry.index,
|
||||||
|
before: direction === "forward" ? entry.before : entry.after,
|
||||||
|
after: direction === "forward" ? entry.after : entry.before
|
||||||
|
}));
|
||||||
|
|
||||||
|
let renderDirtyBounds: TerrainSampleBounds | null = null;
|
||||||
|
|
||||||
|
for (const entry of patch.heightSamples) {
|
||||||
|
assertValidPatchEntry(entry, terrain.heights.length, "Terrain height");
|
||||||
|
terrain.heights[entry.index] =
|
||||||
|
direction === "forward" ? entry.after : entry.before;
|
||||||
|
renderDirtyBounds = mergeTerrainSampleIndexIntoBounds(
|
||||||
|
renderDirtyBounds,
|
||||||
|
terrain,
|
||||||
|
entry.index
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTerrainBoundsCacheAfterHeightPatch(terrain, heightPatchForBounds);
|
||||||
|
|
||||||
|
for (const entry of patch.paintWeights) {
|
||||||
|
assertValidPatchEntry(
|
||||||
|
entry,
|
||||||
|
terrain.paintWeights.length,
|
||||||
|
"Terrain paint weight"
|
||||||
|
);
|
||||||
|
terrain.paintWeights[entry.index] =
|
||||||
|
direction === "forward" ? entry.after : entry.before;
|
||||||
|
renderDirtyBounds = mergeTerrainSampleIndexIntoBounds(
|
||||||
|
renderDirtyBounds,
|
||||||
|
terrain,
|
||||||
|
Math.floor(entry.index / (TERRAIN_LAYER_COUNT - 1))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const entry of patch.foliageMaskValues) {
|
||||||
|
if (currentDocument.foliageLayers[entry.layerId] === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
`Foliage layer ${entry.layerId} does not exist for terrain mask patch.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const mask = getOrCreateTerrainFoliageMask(terrain, entry.layerId);
|
||||||
|
assertValidPatchEntry(entry, mask.values.length, "Terrain foliage mask");
|
||||||
|
mask.values[entry.index] =
|
||||||
|
direction === "forward" ? entry.after : entry.before;
|
||||||
|
renderDirtyBounds = mergeTerrainSampleIndexIntoBounds(
|
||||||
|
renderDirtyBounds,
|
||||||
|
terrain,
|
||||||
|
entry.index
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isTerrainFoliageMaskEmpty(mask)) {
|
||||||
|
delete terrain.foliageMasks[entry.layerId];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const entry of patch.foliageBlockerMaskValues) {
|
||||||
|
assertValidPatchEntry(
|
||||||
|
entry,
|
||||||
|
terrain.foliageBlockerMask.values.length,
|
||||||
|
"Terrain foliage blocker mask"
|
||||||
|
);
|
||||||
|
terrain.foliageBlockerMask.values[entry.index] =
|
||||||
|
direction === "forward" ? entry.after : entry.before;
|
||||||
|
renderDirtyBounds = mergeTerrainSampleIndexIntoBounds(
|
||||||
|
renderDirtyBounds,
|
||||||
|
terrain,
|
||||||
|
entry.index
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
markTerrainRenderSamplesDirty(terrain, renderDirtyBounds);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...currentDocument,
|
||||||
|
terrains: {
|
||||||
|
...currentDocument.terrains,
|
||||||
|
[patch.terrainId]: terrain
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function createApplyTerrainBrushPatchCommand(
|
export function createApplyTerrainBrushPatchCommand(
|
||||||
options: ApplyTerrainBrushPatchCommandOptions
|
options: ApplyTerrainBrushPatchCommandOptions
|
||||||
): EditorCommand {
|
): EditorCommand {
|
||||||
@@ -102,99 +197,13 @@ export function createApplyTerrainBrushPatchCommand(
|
|||||||
context: CommandContext,
|
context: CommandContext,
|
||||||
direction: "forward" | "backward"
|
direction: "forward" | "backward"
|
||||||
) => {
|
) => {
|
||||||
const currentDocument = context.getDocument();
|
context.setDocument(
|
||||||
const terrain = currentDocument.terrains[patch.terrainId];
|
applyTerrainBrushPatchToDocument(
|
||||||
|
context.getDocument(),
|
||||||
if (terrain === undefined) {
|
patch,
|
||||||
throw new Error(`Terrain ${patch.terrainId} does not exist.`);
|
direction
|
||||||
}
|
)
|
||||||
|
);
|
||||||
const heightPatchForBounds = patch.heightSamples.map((entry) => ({
|
|
||||||
index: entry.index,
|
|
||||||
before: direction === "forward" ? entry.before : entry.after,
|
|
||||||
after: direction === "forward" ? entry.after : entry.before
|
|
||||||
}));
|
|
||||||
|
|
||||||
let renderDirtyBounds: TerrainSampleBounds | null = null;
|
|
||||||
|
|
||||||
for (const entry of patch.heightSamples) {
|
|
||||||
assertValidPatchEntry(entry, terrain.heights.length, "Terrain height");
|
|
||||||
terrain.heights[entry.index] =
|
|
||||||
direction === "forward" ? entry.after : entry.before;
|
|
||||||
renderDirtyBounds = mergeTerrainSampleIndexIntoBounds(
|
|
||||||
renderDirtyBounds,
|
|
||||||
terrain,
|
|
||||||
entry.index
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTerrainBoundsCacheAfterHeightPatch(terrain, heightPatchForBounds);
|
|
||||||
|
|
||||||
for (const entry of patch.paintWeights) {
|
|
||||||
assertValidPatchEntry(
|
|
||||||
entry,
|
|
||||||
terrain.paintWeights.length,
|
|
||||||
"Terrain paint weight"
|
|
||||||
);
|
|
||||||
terrain.paintWeights[entry.index] =
|
|
||||||
direction === "forward" ? entry.after : entry.before;
|
|
||||||
renderDirtyBounds = mergeTerrainSampleIndexIntoBounds(
|
|
||||||
renderDirtyBounds,
|
|
||||||
terrain,
|
|
||||||
Math.floor(entry.index / (TERRAIN_LAYER_COUNT - 1))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const entry of patch.foliageMaskValues) {
|
|
||||||
if (currentDocument.foliageLayers[entry.layerId] === undefined) {
|
|
||||||
throw new Error(
|
|
||||||
`Foliage layer ${entry.layerId} does not exist for terrain mask patch.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const mask = getOrCreateTerrainFoliageMask(terrain, entry.layerId);
|
|
||||||
assertValidPatchEntry(
|
|
||||||
entry,
|
|
||||||
mask.values.length,
|
|
||||||
"Terrain foliage mask"
|
|
||||||
);
|
|
||||||
mask.values[entry.index] =
|
|
||||||
direction === "forward" ? entry.after : entry.before;
|
|
||||||
renderDirtyBounds = mergeTerrainSampleIndexIntoBounds(
|
|
||||||
renderDirtyBounds,
|
|
||||||
terrain,
|
|
||||||
entry.index
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isTerrainFoliageMaskEmpty(mask)) {
|
|
||||||
delete terrain.foliageMasks[entry.layerId];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const entry of patch.foliageBlockerMaskValues) {
|
|
||||||
assertValidPatchEntry(
|
|
||||||
entry,
|
|
||||||
terrain.foliageBlockerMask.values.length,
|
|
||||||
"Terrain foliage blocker mask"
|
|
||||||
);
|
|
||||||
terrain.foliageBlockerMask.values[entry.index] =
|
|
||||||
direction === "forward" ? entry.after : entry.before;
|
|
||||||
renderDirtyBounds = mergeTerrainSampleIndexIntoBounds(
|
|
||||||
renderDirtyBounds,
|
|
||||||
terrain,
|
|
||||||
entry.index
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
markTerrainRenderSamplesDirty(terrain, renderDirtyBounds);
|
|
||||||
|
|
||||||
context.setDocument({
|
|
||||||
...currentDocument,
|
|
||||||
terrains: {
|
|
||||||
...currentDocument.terrains,
|
|
||||||
[patch.terrainId]: terrain
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user