Add two-sided wall material targeting

This commit is contained in:
sudhir
2026-04-20 11:18:20 +05:30
parent 783b2e0c33
commit 71ddb7052b
14 changed files with 824 additions and 292 deletions
@@ -33,6 +33,7 @@ import {
type ZoneNode,
} from '@pascal-app/core'
import type { ThreeEvent } from '@react-three/fiber'
import type { BufferGeometry, Mesh } from 'three'
import useViewer from '../store/use-viewer'
type NodeConfig = {
@@ -55,6 +56,23 @@ type NodeConfig = {
type NodeType = keyof NodeConfig
function getIntersectionMaterialIndex(
object: ThreeEvent<PointerEvent>['object'],
faceIndex: number | undefined,
): number | undefined {
if (faceIndex === undefined) return undefined
const geometry = (object as Mesh).geometry as BufferGeometry | undefined
if (!geometry || geometry.groups.length === 0) return undefined
const triangleStart = faceIndex * 3
const group = geometry.groups.find(
(entry) => triangleStart >= entry.start && triangleStart < entry.start + entry.count,
)
return group?.materialIndex
}
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}`
@@ -64,6 +82,8 @@ export function useNodeEvents<T extends NodeType>(node: NodeConfig[T]['node'], t
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,
faceIndex: e.faceIndex ?? undefined,
materialIndex: getIntersectionMaterialIndex(e.object, e.faceIndex ?? undefined),
stopPropagation: () => e.stopPropagation(),
nativeEvent: e,
} as NodeConfig[T]['event']