auto-git:

[change] src/app/App.tsx
 [change] tests/domain/terrains.test.ts
 [change] tests/unit/terrain-foundation.integration.test.tsx
This commit is contained in:
2026-05-13 13:58:17 +02:00
parent 17f64bd424
commit 6f64954ee0
3 changed files with 50 additions and 101 deletions

View File

@@ -2816,11 +2816,12 @@ export function App({
terrainList
);
const selectedPath = getSelectedPath(editorState.selection, pathList);
const splineCorridorJunctionCandidates = detectSplineCorridorJunctionCandidates({
paths: pathList,
junctions: editorState.document.splineCorridorJunctions,
terrains: terrainList.filter((terrain) => terrain.enabled)
});
const splineCorridorJunctionCandidates =
detectSplineCorridorJunctionCandidates({
paths: pathList,
junctions: editorState.document.splineCorridorJunctions,
terrains: terrainList.filter((terrain) => terrain.enabled)
});
const selectedPathJunctionCandidates =
selectedPath === null
? []
@@ -9650,10 +9651,7 @@ export function App({
const handleTerrainPaintLayerChange = (value: string) => {
setActiveTerrainPaintLayerIndex(
clampTerrainPaintLayerIndex(
Number(value),
selectedTerrain?.layers.length
)
clampTerrainPaintLayerIndex(Number(value), selectedTerrain?.layers.length)
);
};
@@ -9994,7 +9992,9 @@ export function App({
const handleDeleteSplineCorridorJunction = (junctionId: string) => {
try {
store.executeCommand(createDeleteSplineCorridorJunctionCommand(junctionId));
store.executeCommand(
createDeleteSplineCorridorJunctionCommand(junctionId)
);
setStatusMessage("Deleted spline corridor junction.");
} catch (error) {
setStatusMessage(getErrorMessage(error));
@@ -21491,7 +21491,10 @@ export function App({
<div className="terrain-layer-list">
{selectedTerrain.layers.map((layer, layerIndex) => (
<div key={layerIndex} className="form-field">
<label className="label" htmlFor={`terrain-layer-material-${layerIndex}`}>
<label
className="label"
htmlFor={`terrain-layer-material-${layerIndex}`}
>
{getTerrainLayerLabel(layerIndex)}
</label>
<div className="inline-actions">
@@ -21518,7 +21521,9 @@ export function App({
type="button"
data-testid={`terrain-layer-remove-${layerIndex}`}
disabled={layerIndex === 0}
onClick={() => handleDeleteTerrainLayer(layerIndex)}
onClick={() =>
handleDeleteTerrainLayer(layerIndex)
}
>
Remove
</button>
@@ -22488,10 +22493,9 @@ export function App({
handlePathRoadChange(
{
...selectedPath.road,
heightOffset:
normalizeScenePathRoadHeightOffset(
Number(event.currentTarget.value)
)
heightOffset: normalizeScenePathRoadHeightOffset(
Number(event.currentTarget.value)
)
},
"Updated Path road height offset."
)
@@ -22545,7 +22549,8 @@ export function App({
</label>
{(["left", "right"] as const).map((side) => {
const edge = selectedPath.road.edges[side];
const edgeLabel = side === "left" ? "Left Edge" : "Right Edge";
const edgeLabel =
side === "left" ? "Left Edge" : "Right Edge";
return (
<div className="form-section" key={side}>
@@ -22717,10 +22722,7 @@ export function App({
{selectedPathJunctionCandidates
.slice(0, 6)
.map((candidate, candidateIndex) => (
<div
className="compact-card"
key={candidate.id}
>
<div className="compact-card" key={candidate.id}>
<div className="compact-card__header">
<strong>
Candidate {candidateIndex + 1}
@@ -23337,8 +23339,8 @@ export function App({
Edit authored point positions directly. Keep at least{" "}
{MIN_SCENE_PATH_POINT_COUNT} points. <code>Shift+W</code>{" "}
adds a point after the selected control point, or appends
to the end when the whole path is selected. When a point is
selected, <code>Shift+D</code> adds one and starts grab
to the end when the whole path is selected. When a point
is selected, <code>Shift+D</code> adds one and starts grab
mode.
</div>
{selectedPathPointIndex === null ? null : (

View File

@@ -100,12 +100,12 @@ describe("terrain grid resizing", () => {
cellSize: 0.5
});
expect(sampleTerrainHeightAtLocalPosition(resizedTerrain, 2.5, 3.5)).toBeCloseTo(
sampleTerrainHeightAtLocalPosition(terrain, 2.5, 3.5) ?? 0
);
expect(sampleTerrainHeightAtLocalPosition(resizedTerrain, 6, 1)).toBeCloseTo(
sampleTerrainHeightAtLocalPosition(terrain, 6, 1) ?? 0
);
expect(
sampleTerrainHeightAtLocalPosition(resizedTerrain, 2.5, 3.5)
).toBeCloseTo(sampleTerrainHeightAtLocalPosition(terrain, 2.5, 3.5) ?? 0);
expect(
sampleTerrainHeightAtLocalPosition(resizedTerrain, 6, 1)
).toBeCloseTo(sampleTerrainHeightAtLocalPosition(terrain, 6, 1) ?? 0);
});
it("preserves paint weights at representative local positions when Cell Size changes", () => {
@@ -123,7 +123,11 @@ describe("terrain grid resizing", () => {
cellSize: 0.5
});
const originalOffset = getTerrainPaintWeightSampleOffset(terrain, 4, 2);
const resizedOffset = getTerrainPaintWeightSampleOffset(resizedTerrain, 8, 4);
const resizedOffset = getTerrainPaintWeightSampleOffset(
resizedTerrain,
8,
4
);
expect(resizedTerrain.paintWeights[resizedOffset]).toBeCloseTo(
terrain.paintWeights[originalOffset] ?? 0
@@ -292,20 +296,7 @@ describe("terrain material layers", () => {
id: "terrain-add-layer",
sampleCountX: 2,
sampleCountZ: 2,
paintWeights: [
0.2,
0.3,
0.1,
0.4,
0.1,
0,
0,
0.5,
0,
0.25,
0.25,
0.25
]
paintWeights: [0.2, 0.3, 0.1, 0.4, 0.1, 0, 0, 0.5, 0, 0.25, 0.25, 0.25]
});
const nextTerrain = createTerrainWithAddedLayer(terrain, "road-material");
@@ -322,18 +313,12 @@ describe("terrain material layers", () => {
expect(nextTerrain.layers).toHaveLength(5);
expect(nextTerrain.layers[4]).toEqual({ materialId: "road-material" });
expect(nextTerrain.paintWeights.slice(firstSampleOffset, firstSampleOffset + 4)).toEqual([
0.2,
0.3,
0.1,
0
]);
expect(nextTerrain.paintWeights.slice(secondSampleOffset, secondSampleOffset + 4)).toEqual([
0.4,
0.1,
0,
0
]);
expect(
nextTerrain.paintWeights.slice(firstSampleOffset, firstSampleOffset + 4)
).toEqual([0.2, 0.3, 0.1, 0]);
expect(
nextTerrain.paintWeights.slice(secondSampleOffset, secondSampleOffset + 4)
).toEqual([0.4, 0.1, 0, 0]);
});
it("removes non-base layers by compacting explicit weights", () => {
@@ -342,20 +327,7 @@ describe("terrain material layers", () => {
id: "terrain-remove-layer",
sampleCountX: 2,
sampleCountZ: 2,
paintWeights: [
0.2,
0.3,
0.1,
0.4,
0.1,
0,
0,
0.5,
0,
0.25,
0.25,
0.25
]
paintWeights: [0.2, 0.3, 0.1, 0.4, 0.1, 0, 0, 0.5, 0, 0.25, 0.25, 0.25]
}),
"fifth-material"
);
@@ -364,18 +336,7 @@ describe("terrain material layers", () => {
expect(nextTerrain.layers).toHaveLength(4);
expect(nextTerrain.paintWeights).toEqual([
0.2,
0.1,
0,
0.4,
0,
0,
0,
0,
0,
0.25,
0.25,
0
0.2, 0.1, 0, 0.4, 0, 0, 0, 0, 0, 0.25, 0.25, 0
]);
});
});
@@ -446,28 +407,13 @@ describe("terrain foliage masks", () => {
expect(clonedTerrain.foliageMasks[foliageLayerId]).not.toBe(mask);
expect(getTerrainFoliageMaskValueAtSample(mask!, 1, 1)).toBe(0.5);
expect(
sampleTerrainFoliageMaskAtWorldPosition(
terrain,
foliageLayerId,
11,
21
)
sampleTerrainFoliageMaskAtWorldPosition(terrain, foliageLayerId, 11, 21)
).toBeCloseTo(0.375);
expect(
sampleTerrainFoliageMaskAtWorldPosition(
terrain,
"missing-layer",
11,
21
)
sampleTerrainFoliageMaskAtWorldPosition(terrain, "missing-layer", 11, 21)
).toBe(0);
expect(
sampleTerrainFoliageMaskAtWorldPosition(
terrain,
foliageLayerId,
99,
99
)
sampleTerrainFoliageMaskAtWorldPosition(terrain, foliageLayerId, 99, 99)
).toBeNull();
});
});

View File

@@ -173,7 +173,8 @@ describe("Terrain foundation", () => {
fireEvent.click(screen.getByTestId("terrain-grid-apply"));
await waitFor(() => {
const updatedTerrain = store.getState().document.terrains[createdTerrain.id];
const updatedTerrain =
store.getState().document.terrains[createdTerrain.id];
expect(updatedTerrain?.sampleCountX).toBe(5);
expect(updatedTerrain?.sampleCountZ).toBe(5);