control bar

This commit is contained in:
wass08
2026-01-29 10:14:40 +09:00
parent 406a4f51b5
commit f4125db6a8
8 changed files with 174 additions and 31 deletions
@@ -7,6 +7,7 @@ import * as THREE from 'three/webgpu'
import { LevelSystem } from '../../systems/level/level-system'
import { SceneRenderer } from '../renderers/scene-renderer'
import PostProcessing from './post-processing'
import { ViewerCamera } from './viewer-camera'
declare module '@react-three/fiber' {
interface ThreeElements extends ThreeToJSXElements<typeof THREE> {}
@@ -31,6 +32,7 @@ const Viewer: React.FC<ViewerProps> = ({ children }) => {
camera={{ position: [50, 50, 50], fov: 50 }}
>
<color attach="background" args={['#ececec']} />
<ViewerCamera />
<directionalLight position={[10, 10, 5]} intensity={0.5} castShadow />
<Environment preset="sunset" environmentIntensity={0.3} />
@@ -0,0 +1,11 @@
import { OrthographicCamera, PerspectiveCamera } from "@react-three/drei"
import useViewer from "../../store/use-viewer"
export const ViewerCamera = () => {
const cameraMode = useViewer((state) => state.cameraMode)
return cameraMode === 'perspective' ? (
<PerspectiveCamera far={1000} fov={50} makeDefault near={0.1} position={[10, 10, 10]} />
) : (
<OrthographicCamera far={1000} makeDefault near={-1000} position={[10, 10, 10]} zoom={20} />
)
}
+12
View File
@@ -34,6 +34,12 @@ type ViewerState = {
levelMode: "stacked" | "exploded" | "solo" | "manual";
setLevelMode: (mode: "stacked" | "exploded" | "solo" | "manual") => void;
showScans: boolean;
setShowScans: (show: boolean) => void;
showGuides: boolean;
setShowGuides: (show: boolean) => void;
// Smart selection update
setSelection: (updates: Partial<SelectionPath>) => void;
resetSelection: () => void;
@@ -52,6 +58,12 @@ const useViewer = create<ViewerState>()((set, get) => ({
levelMode: "stacked",
setLevelMode: (mode) => set({ levelMode: mode }),
showScans: true,
setShowScans: (show) => set({ showScans: show }),
showGuides: true,
setShowGuides: (show) => set({ showGuides: show }),
setSelection: (updates) =>
set((state) => {
const newSelection = { ...state.selection, ...updates };
@@ -9,14 +9,17 @@ const EXPLODED_GAP = 5
export const LevelSystem = () => {
useFrame((_, delta) => {
const levelMode = useViewer.getState().levelMode
const selectedLevel = useViewer.getState().selection.levelId
sceneRegistry.byType.level.forEach((levelId) => {
const obj = sceneRegistry.nodes.get(levelId)
if (obj) {
const level = useScene.getState().nodes[levelId as LevelNode['id']]
const targetY =
((level as any).level || 0) *
(LEVEL_HEIGHT + (levelMode === 'stacked' ? 0 : EXPLODED_GAP))
(LEVEL_HEIGHT + (levelMode === 'exploded' ? EXPLODED_GAP: 0))
obj.position.y = lerp(obj.position.y, targetY, delta * 3)
obj.visible = levelMode !== 'solo' || level?.id === selectedLevel || !selectedLevel
}
})
})