drafting wall attach system
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
import { emitter, ItemNode, useRegistry } from "@pascal-app/core";
|
||||
import {
|
||||
AnyNodeId,
|
||||
emitter,
|
||||
ItemNode,
|
||||
useRegistry,
|
||||
useScene,
|
||||
} from "@pascal-app/core";
|
||||
import { Clone } from "@react-three/drei/core/Clone";
|
||||
import { useGLTF } from "@react-three/drei/core/Gltf";
|
||||
import { ThreeEvent } from "@react-three/fiber/dist/declarations/src/core/events";
|
||||
import { Suspense, useCallback, useRef } from "react";
|
||||
import { Suspense, useCallback, useEffect, useRef } from "react";
|
||||
import { Group } from "three";
|
||||
import { useNodeEvents } from "../../../hooks/use-node-events";
|
||||
|
||||
@@ -29,6 +35,11 @@ const ModelRenderer = ({ node }: { node: ItemNode }) => {
|
||||
|
||||
const handlers = useNodeEvents(node, "item");
|
||||
|
||||
useEffect(() => {
|
||||
if (!node.parentId) return;
|
||||
useScene.getState().dirtyNodes.add(node.parentId as AnyNodeId);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Clone
|
||||
object={scene}
|
||||
|
||||
@@ -12,15 +12,13 @@ export const WallRenderer = ({ node }: { node: WallNode }) => {
|
||||
const handlers = useNodeEvents(node, "wall");
|
||||
|
||||
return (
|
||||
<mesh
|
||||
ref={ref}
|
||||
castShadow
|
||||
receiveShadow
|
||||
{...handlers}
|
||||
>
|
||||
<mesh ref={ref} castShadow receiveShadow>
|
||||
{/* WallSystem will replace this geometry in the next frame */}
|
||||
<boxGeometry args={[0, 0, 0]} />
|
||||
<meshStandardMaterial color="lightgray" />
|
||||
<mesh name="collision-mesh" {...handlers} visible={false}>
|
||||
<boxGeometry args={[0, 0, 0]} />
|
||||
</mesh>
|
||||
|
||||
{node.children.map((childId) => (
|
||||
<NodeRenderer key={childId} nodeId={childId} />
|
||||
|
||||
@@ -18,12 +18,17 @@ type NodeConfig = {
|
||||
|
||||
type NodeType = keyof NodeConfig;
|
||||
|
||||
export function useNodeEvents<T extends NodeType>(node: NodeConfig[T]["node"], type: T) {
|
||||
export function useNodeEvents<T extends NodeType>(
|
||||
node: NodeConfig[T]["node"],
|
||||
type: T,
|
||||
) {
|
||||
const emit = (suffix: EventSuffix, e: ThreeEvent<PointerEvent>) => {
|
||||
const eventKey = `${type}:${suffix}` as `${T}:${EventSuffix}`;
|
||||
const localPoint = e.object.worldToLocal(e.point.clone());
|
||||
const payload = {
|
||||
node,
|
||||
position: [e.point.x, e.point.y, e.point.z],
|
||||
localPosition: [localPoint.x, localPoint.y, localPoint.z],
|
||||
normal: e.face
|
||||
? [e.face.normal.x, e.face.normal.y, e.face.normal.z]
|
||||
: undefined,
|
||||
@@ -52,4 +57,4 @@ export function useNodeEvents<T extends NodeType>(node: NodeConfig[T]["node"], t
|
||||
onDoubleClick: (e: ThreeEvent<PointerEvent>) => emit("double-click", e),
|
||||
onContextMenu: (e: ThreeEvent<PointerEvent>) => emit("context-menu", e),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user