custom cam control

This commit is contained in:
wass08
2026-01-21 07:19:00 +09:00
parent 980dd4c3dc
commit bc8293b120
2 changed files with 58 additions and 34 deletions
@@ -0,0 +1,49 @@
"use client";
import { sceneRegistry } from "@pascal-app/core";
import { useViewer } from "@pascal-app/viewer";
import { CameraControls, CameraControlsImpl } from "@react-three/drei";
import { useEffect, useMemo, useRef } from "react";
import { Vector3 } from "three";
export const CustomCameraControls = () => {
const controls = useRef<CameraControlsImpl>(null!);
const currentLevelId = useViewer((state) => state.currentLevelId);
useEffect(() => {
let targetY = 0;
if (currentLevelId) {
const levelMesh = sceneRegistry.nodes.get(currentLevelId);
if (levelMesh) {
targetY = levelMesh.position.y;
}
}
const currentTarget = new Vector3();
(controls.current as CameraControlsImpl).getTarget(currentTarget);
(controls.current as CameraControlsImpl).moveTo(
currentTarget.x,
targetY,
currentTarget.z,
true,
);
}, [currentLevelId]);
// Configure mouse buttons based on control mode and camera mode
const mouseButtons = useMemo(() => {
// Use ZOOM for orthographic camera, DOLLY for perspective camera
// const wheelAction =
// cameraMode === 'orthographic'
// ? CameraControlsImpl.ACTION.ZOOM
// : CameraControlsImpl.ACTION.DOLLY
const wheelAction = CameraControlsImpl.ACTION.DOLLY;
return {
left: CameraControlsImpl.ACTION.NONE,
middle: CameraControlsImpl.ACTION.SCREEN_PAN,
right: CameraControlsImpl.ACTION.ROTATE,
wheel: wheelAction,
};
}, []);
return <CameraControls ref={controls} mouseButtons={mouseButtons} />;
};
@@ -10,10 +10,10 @@ import {
WallNode, WallNode,
} from "@pascal-app/core"; } from "@pascal-app/core";
import { useGridEvents, useViewer, Viewer } from "@pascal-app/viewer"; import { useGridEvents, useViewer, Viewer } from "@pascal-app/viewer";
import { CameraControls, CameraControlsImpl, Stats } from "@react-three/drei";
import { useFrame, useThree } from "@react-three/fiber"; import { useFrame, useThree } from "@react-three/fiber";
import { useEffect, useMemo, useRef } from "react"; import { useEffect, useMemo, useRef } from "react";
import { Color, MathUtils, Mesh, Object3D } from "three"; import { Color, MathUtils, Mesh, Object3D, Vector3 } from "three";
import { outline } from "three/addons/tsl/display/OutlineNode.js"; import { outline } from "three/addons/tsl/display/OutlineNode.js";
import { import {
color, color,
@@ -28,10 +28,11 @@ import {
uniform, uniform,
} from "three/tsl"; } from "three/tsl";
import { MeshBasicNodeMaterial, PostProcessing } from "three/webgpu"; import { MeshBasicNodeMaterial, PostProcessing } from "three/webgpu";
import { ActionMenu } from "./ui/action-menu"; import { ActionMenu } from "../ui/action-menu";
import { ToolManager } from "./tools/tool-manager"; import { ToolManager } from "../tools/tool-manager";
import { AppSidebar } from "./ui/sidebar/app-sidebar"; import { AppSidebar } from "../ui/sidebar/app-sidebar";
import { SidebarProvider } from "./ui/primitives/sidebar"; import { SidebarProvider } from "../ui/primitives/sidebar";
import { CustomCameraControls } from "./custom-camera-controls";
const selectedObjects: Object3D[] = []; const selectedObjects: Object3D[] = [];
@@ -40,7 +41,7 @@ useScene.getState().loadScene();
export default function Editor() { export default function Editor() {
return ( return (
<div className="w-full h-full bg-pink-50"> <div className="w-full h-full">
{/* <LevelModeSwitcher /> */} {/* <LevelModeSwitcher /> */}
<TestUndo /> <TestUndo />
@@ -55,37 +56,11 @@ export default function Editor() {
<Grid cellColor="#666" sectionColor="#999" fadeDistance={30} /> <Grid cellColor="#666" sectionColor="#999" fadeDistance={30} />
<Passes /> <Passes />
<ToolManager /> <ToolManager />
<EditorCameraManager /> <CustomControls />
</Viewer> </Viewer>
</div> </div>
); );
} }
const EditorCameraManager = () => {
const controls = useRef<CameraControlsImpl>(null!);
const currentLevelId = useViewer((state) => state.currentLevelId);
useEffect(() => {
let targetY = 0;
if (currentLevelId) {
const levelMesh = sceneRegistry.nodes.get(currentLevelId);
if (levelMesh) {
targetY = levelMesh.position.y;
}
}
const { position } = controls.current.camera;
controls.current.setLookAt(
position.x,
targetY + 5,
position.z,
0,
targetY,
0,
true,
);
}, [currentLevelId]);
return <CameraControls ref={controls} />;
};
const TestUndo = () => { const TestUndo = () => {
const { undo, redo, futureStates, pastStates } = useScene.temporal.getState(); const { undo, redo, futureStates, pastStates } = useScene.temporal.getState();