registry / systems / renderer
This commit is contained in:
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user