Refactor App component and update terrain-related tests
This commit is contained in:
@@ -2816,12 +2816,11 @@ 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
|
||||
? []
|
||||
@@ -9651,7 +9650,10 @@ export function App({
|
||||
|
||||
const handleTerrainPaintLayerChange = (value: string) => {
|
||||
setActiveTerrainPaintLayerIndex(
|
||||
clampTerrainPaintLayerIndex(Number(value), selectedTerrain?.layers.length)
|
||||
clampTerrainPaintLayerIndex(
|
||||
Number(value),
|
||||
selectedTerrain?.layers.length
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -9992,9 +9994,7 @@ 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,10 +21491,7 @@ 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">
|
||||
@@ -21521,9 +21518,7 @@ export function App({
|
||||
type="button"
|
||||
data-testid={`terrain-layer-remove-${layerIndex}`}
|
||||
disabled={layerIndex === 0}
|
||||
onClick={() =>
|
||||
handleDeleteTerrainLayer(layerIndex)
|
||||
}
|
||||
onClick={() => handleDeleteTerrainLayer(layerIndex)}
|
||||
>
|
||||
Remove
|
||||
</button>
|
||||
@@ -22493,9 +22488,10 @@ export function App({
|
||||
handlePathRoadChange(
|
||||
{
|
||||
...selectedPath.road,
|
||||
heightOffset: normalizeScenePathRoadHeightOffset(
|
||||
Number(event.currentTarget.value)
|
||||
)
|
||||
heightOffset:
|
||||
normalizeScenePathRoadHeightOffset(
|
||||
Number(event.currentTarget.value)
|
||||
)
|
||||
},
|
||||
"Updated Path road height offset."
|
||||
)
|
||||
@@ -22549,8 +22545,7 @@ 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}>
|
||||
@@ -22722,7 +22717,10 @@ 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}
|
||||
@@ -23339,8 +23337,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 : (
|
||||
|
||||
@@ -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,11 +123,7 @@ 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
|
||||
@@ -296,7 +292,20 @@ 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");
|
||||
@@ -313,12 +322,18 @@ 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", () => {
|
||||
@@ -327,7 +342,20 @@ 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"
|
||||
);
|
||||
@@ -336,7 +364,18 @@ 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
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -407,13 +446,28 @@ 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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -173,8 +173,7 @@ 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);
|
||||
|
||||
Reference in New Issue
Block a user