different level edition + fix

This commit is contained in:
wass08
2026-01-20 08:26:47 +09:00
parent f59e12193d
commit dabaefc57a
8 changed files with 99 additions and 57 deletions
+24 -2
View File
@@ -13,7 +13,7 @@ import { useGridEvents, useViewer, Viewer } from "@pascal-app/viewer";
import { CameraControls, CameraControlsImpl, Stats } from "@react-three/drei";
import { useFrame, useThree } from "@react-three/fiber";
import { useEffect, useMemo, useRef } from "react";
import { Color, Object3D } from "three";
import { Color, MathUtils, Mesh, Object3D } from "three";
import { outline } from "three/addons/tsl/display/OutlineNode.js";
import {
color,
@@ -254,9 +254,31 @@ const Grid = ({
]);
const handlers = useGridEvents();
const gridRef = useRef<Mesh>(null!);
useFrame((_, delta) => {
const currentLevelId = useViewer.getState().currentLevelId;
let targetY = 0;
if (currentLevelId) {
const levelMesh = sceneRegistry.nodes.get(currentLevelId);
if (levelMesh) {
targetY = levelMesh.position.y;
}
}
gridRef.current.position.y = MathUtils.lerp(
gridRef.current.position.y,
targetY,
12 * delta,
);
});
return (
<mesh rotation-x={-Math.PI / 2} material={material} {...handlers}>
<mesh
rotation-x={-Math.PI / 2}
material={material}
{...handlers}
ref={gridRef}
>
<planeGeometry args={[fadeDistance * 2, fadeDistance * 2]} />
</mesh>
);
@@ -82,7 +82,7 @@ export const ItemTool: React.FC = () => {
gridPosition.current.y,
gridPosition.current.z,
],
name: "Draft Item",
name: selectedItem.name,
asset: selectedItem,
});
useScene.getState().createNode(draftItem.current, currentLevelId);
@@ -98,11 +98,11 @@ export const ItemTool: React.FC = () => {
gridPosition.current.set(
Math.round(event.position[0] * 2) / 2,
0,
Math.round(event.position[1] * 2) / 2,
Math.round(event.position[2] * 2) / 2,
);
cursorRef.current.position.set(
gridPosition.current.x,
0,
event.position[1],
gridPosition.current.z,
);
checkCanPlace();
@@ -212,6 +212,7 @@ export const ItemTool: React.FC = () => {
Math.round(event.position[1] * 2) / 2,
Math.round(event.position[2] * 2) / 2,
);
const {
node: { start, end },
} = event;
+50 -37
View File
@@ -1,45 +1,45 @@
import { emitter, GridEvent, useScene, WallNode } from "@pascal-app/core";
import { useViewer } from "@pascal-app/viewer";
import { useEffect, useRef } from "react"
import { useEffect, useRef } from "react";
import { Line, Mesh, Vector3 } from "three";
const commitWallDrawing = (start: [number, number], end: [number, number]) => {
const { currentLevelId } = useViewer.getState();
const { createNode } = useScene.getState();
if (!currentLevelId) return;
const wall = WallNode.parse({ start, end });
createNode(wall, currentLevelId);
};
export const WallTool: React.FC = () => {
const cursorRef = useRef<Mesh>(null);
const drawingLineRef = useRef<Line>(null!);
useEffect(() => {
let buildingState = 0;
const startingPoint = new Vector3(0, 0, 0);
const endingPoint = new Vector3(0, 0, 0);
let gridPosition: [number, number] = [0, 0];
drawingLineRef.current.geometry.setFromPoints([
startingPoint,
endingPoint,
]);
drawingLineRef.current.geometry.setFromPoints([startingPoint, endingPoint]);
const onGridMove = (event: GridEvent) => {
if (!cursorRef.current) return;
gridPosition = [Math.round(event.position[0] * 2) / 2, Math.round(event.position[1] * 2) / 2];
cursorRef.current.position.set(gridPosition[0], 0.1, gridPosition[1]);
gridPosition = [
Math.round(event.position[0] * 2) / 2,
Math.round(event.position[2] * 2) / 2,
];
cursorRef.current.position.set(
gridPosition[0],
event.position[1],
gridPosition[1],
);
if (buildingState === 1) {
endingPoint.set(gridPosition[0], 0.1, gridPosition[1]);
endingPoint.set(gridPosition[0], event.position[1], gridPosition[1]);
}
drawingLineRef.current.geometry.setFromPoints([
startingPoint,
@@ -48,42 +48,55 @@ export const WallTool: React.FC = () => {
};
const onGridClick = (event: GridEvent) => {
if (buildingState === 0) {
startingPoint.set(gridPosition[0], 0.1, gridPosition[1]);
startingPoint.set(gridPosition[0], event.position[1], gridPosition[1]);
buildingState = 1;
console.log('starting building at:', startingPoint);
console.log("starting building at:", startingPoint);
drawingLineRef.current.visible = true;
} else if (buildingState === 1) {
commitWallDrawing([startingPoint.x, startingPoint.z], [gridPosition[0], gridPosition[1]]);
commitWallDrawing(
[startingPoint.x, startingPoint.z],
[endingPoint.x, endingPoint.z],
);
drawingLineRef.current.visible = false;
buildingState = 0;
}
};
emitter.on('grid:move', onGridMove);
emitter.on('grid:click', onGridClick);
emitter.on("grid:move", onGridMove);
emitter.on("grid:click", onGridClick);
return () => {
emitter.off('grid:move', onGridMove);
emitter.off('grid:click', onGridClick);
emitter.off("grid:move", onGridMove);
emitter.off("grid:click", onGridClick);
};
}, []);
return (
<group>
<mesh ref={cursorRef}>
<boxGeometry args={[0.2, 0.2, 0.2]} />
<meshStandardMaterial color="red" />
</mesh>
<group>
{/* @ts-ignore */}
<line ref={drawingLineRef} frustumCulled={false} renderOrder={1} visible={false}>
<bufferGeometry />
<lineDashedNodeMaterial color="blue" linewidth={4} linecap="round" depthTest={false} depthWrite={false} dashSize={2} gapSize={0.1} />
</line>
<mesh ref={cursorRef}>
<boxGeometry args={[0.2, 0.2, 0.2]} />
<meshStandardMaterial color="red" />
</mesh>
<group>
{/* @ts-ignore */}
<line
ref={drawingLineRef}
frustumCulled={false}
renderOrder={1}
visible={false}
>
<bufferGeometry />
<lineDashedNodeMaterial
color="blue"
linewidth={4}
linecap="round"
depthTest={false}
depthWrite={false}
dashSize={2}
gapSize={0.1}
/>
</line>
</group>
</group>
</group>
)
}
);
};
@@ -18,13 +18,13 @@ export function WallTreeNode({ node, depth }: WallTreeNodeProps) {
const wallLength = Math.sqrt(
Math.pow(node.end[0] - node.start[0], 2) +
Math.pow(node.end[1] - node.start[1], 2)
Math.pow(node.end[1] - node.start[1], 2),
).toFixed(1);
return (
<TreeNodeWrapper
icon={<Square className="w-3.5 h-3.5" />}
label={node.name || `Wall (${wallLength}m)`}
label={node.name || `Wall (${wallLength}m/${node.height || 2.5}m)`}
depth={depth}
hasChildren={node.children.length > 0}
expanded={expanded}