registry / systems / renderer

This commit is contained in:
wass08
2026-01-15 10:43:32 +09:00
parent 7a4d6e397d
commit 0c07c482a5
93 changed files with 440 additions and 75 deletions
@@ -0,0 +1,25 @@
import { ItemNode, useRegistry } from "@pascal-app/core";
import { Clone } from "@react-three/drei/core/Clone";
import { useGLTF } from "@react-three/drei/core/Gltf";
import { useRef } from "react";
import { Group } from "three";
export const ItemRenderer = ({ node }: { node: ItemNode }) => {
const ref = useRef<Group>(null!);
const { scene, nodes } = useGLTF(node.asset.src);
useRegistry(node.id, node.type, ref);
if (nodes.cutout) {
nodes.cutout.visible = false;
}
return (
<Clone
ref={ref}
object={scene}
position={node.position}
rotation={node.rotation}
/>
);
};
@@ -0,0 +1,21 @@
import { LevelNode, useRegistry } from "@pascal-app/core";
import { useRef } from "react";
import { Group } from "three";
import { NodeRenderer } from "../node-renderer";
export const LevelRenderer = ({ node }: { node: LevelNode }) => {
const ref = useRef<Group>(null!);
useRegistry(node.id, node.type, ref);
return (
<group ref={ref}>
<mesh receiveShadow>
<boxGeometry args={[10, 0.1, 10]} />
<meshStandardMaterial color="orange" />
</mesh>
{node.children.map((childId) => (
<NodeRenderer key={childId} nodeId={childId} />
))}
</group>
);
};
@@ -0,0 +1,20 @@
"use client";
import { AnyNode, useScene } from "@pascal-app/core";
import { ItemRenderer } from "./item/item-renderer";
import { LevelRenderer } from "./level/level-renderer";
import { WallRenderer } from "./wall/wall-renderer";
export const NodeRenderer = ({ nodeId }: { nodeId: AnyNode["id"] }) => {
const node = useScene((state) => state.nodes[nodeId]);
if (!node) return null;
return (
<>
{node.type === "level" && <LevelRenderer node={node} />}
{node.type === "item" && <ItemRenderer node={node} />}
{node.type === "wall" && <WallRenderer node={node} />}
</>
);
};
@@ -1,8 +1,7 @@
"use client";
import { AnyNode, LevelNode, useScene, WallNode } from "@pascal-app/core";
import { useRef } from "react";
import * as THREE from "three/webgpu";
import { useScene } from "@pascal-app/core";
import { NodeRenderer } from "./node-renderer";
export const SceneRenderer = () => {
const rootNodes = useScene((state) => state.rootNodeIds);
@@ -11,56 +10,3 @@ export const SceneRenderer = () => {
<NodeRenderer key={nodeId} nodeId={nodeId} />
));
};
const NodeRenderer = ({ nodeId }: { nodeId: AnyNode["id"] }) => {
const node = useScene((state) => state.nodes[nodeId]);
if (!node) return null;
return (
<>
{node.type === "level" && <LevelRenderer node={node} />}
{/* {node.type === "item" && <ItemRenderer node={node} />} */}
{node.type === "wall" && <WallRenderer node={node} />}
</>
);
};
const LevelRenderer = ({ node }: { node: LevelNode }) => {
const ref = useRef<THREE.Group>(null!);
// useRegistry(node.id, node.type, ref);
return (
<group ref={ref}>
<mesh receiveShadow>
<boxGeometry args={[10, 0.1, 10]} />
<meshStandardMaterial color="orange" />
</mesh>
{node.children.map((childId) => (
<NodeRenderer key={childId} nodeId={childId} />
))}
</group>
);
};
const WallRenderer = ({ node }: { node: WallNode }) => {
const ref = useRef<THREE.Mesh>(null!);
console.log("node", node);
// useRegistry(node.id, "wall", ref);
return (
<mesh ref={ref} castShadow receiveShadow>
{/* WallSystem will replace this geometry in the next frame */}
<boxGeometry args={[1, 2, 0.1]} />
<meshStandardMaterial color="lightgray" />
{/* If you want windows to be inside the wall's local coordinate system:
render children here.
*/}
{/* {node.children.map((childId) => (
<NodeRenderer key={childId} nodeId={childId} />
))} */}
</mesh>
);
};
@@ -0,0 +1,22 @@
import { useRegistry, WallNode } from "@pascal-app/core";
import { useRef } from "react";
import { Mesh } from "three";
import { NodeRenderer } from "../node-renderer";
export const WallRenderer = ({ node }: { node: WallNode }) => {
const ref = useRef<Mesh>(null!);
useRegistry(node.id, "wall", ref);
return (
<mesh ref={ref} castShadow receiveShadow>
{/* WallSystem will replace this geometry in the next frame */}
<boxGeometry args={[0, 0, 0]} />
<meshStandardMaterial color="lightgray" />
{node.children.map((childId) => (
<NodeRenderer key={childId} nodeId={childId} />
))}
</mesh>
);
};
@@ -3,6 +3,7 @@
import { Environment, OrbitControls } from "@react-three/drei";
import { Canvas, ThreeToJSXElements } from "@react-three/fiber";
import { LevelSystem, WallSystem } from "@pascal-app/core";
import { extend } from "@react-three/fiber";
import * as THREE from "three/webgpu";
import { SceneRenderer } from "../renderers/scene-renderer";
@@ -25,10 +26,15 @@ const Viewer: React.FC<ViewerProps> = () => {
return renderer;
}}
shadows
camera={{ position: [3, 3, 3], fov: 50 }}
>
<OrbitControls />
<Environment preset="sunset" />
<SceneRenderer />
{/* Default Systems */}
<LevelSystem />
<WallSystem />
</Canvas>
);
};