Fix wall move junction ownership

This commit is contained in:
sudhir
2026-05-11 23:46:57 +05:30
parent afadfb2ea8
commit be41511474
9 changed files with 694 additions and 81 deletions
@@ -156,9 +156,12 @@ const ModelRenderer = ({ node }: { node: ItemNode }) => {
const lightEffects =
interactive?.effects.filter((e): e is LightEffect => e.kind === 'light') ?? []
// useGLTF caches scenes, and Clone shares child geometry/material references.
// Undo can unmount one item while another clone of the same asset still needs them.
return (
<>
<Clone
dispose={null}
object={scene}
position={node.asset.offset}
ref={ref}
@@ -1,12 +1,27 @@
import { useRegistry, useScene, type WallNode } from '@pascal-app/core'
import { useLayoutEffect, useRef } from 'react'
import type { Mesh } from 'three'
import { useEffect, useLayoutEffect, useMemo, useRef } from 'react'
import { BufferGeometry, Float32BufferAttribute, type Mesh } from 'three'
import { useNodeEvents } from '../../../hooks/use-node-events'
import { getVisibleWallMaterials } from '../../../systems/wall/wall-materials'
import { NodeRenderer } from '../node-renderer'
function createEmptyWallGeometry() {
const geometry = new BufferGeometry()
geometry.setAttribute('position', new Float32BufferAttribute([], 3))
geometry.addGroup(0, 0, 0)
geometry.addGroup(0, 0, 1)
geometry.addGroup(0, 0, 2)
return geometry
}
export const WallRenderer = ({ node }: { node: WallNode }) => {
const ref = useRef<Mesh>(null!)
const placeholderGeometry = useMemo(createEmptyWallGeometry, [])
const collisionPlaceholderGeometry = useMemo(() => {
const geometry = new BufferGeometry()
geometry.setAttribute('position', new Float32BufferAttribute([], 3))
return geometry
}, [])
useRegistry(node.id, 'wall', ref)
@@ -14,15 +29,31 @@ export const WallRenderer = ({ node }: { node: WallNode }) => {
useScene.getState().markDirty(node.id)
}, [node.id])
useEffect(() => {
return () => {
placeholderGeometry.dispose()
collisionPlaceholderGeometry.dispose()
}
}, [collisionPlaceholderGeometry, placeholderGeometry])
const handlers = useNodeEvents(node, 'wall')
const material = getVisibleWallMaterials(node)
return (
<mesh castShadow material={material} receiveShadow ref={ref} visible={node.visible}>
<boxGeometry args={[0, 0, 0]} />
<mesh name="collision-mesh" visible={false} {...handlers}>
<boxGeometry args={[0, 0, 0]} />
</mesh>
<mesh
castShadow
geometry={placeholderGeometry}
material={material}
receiveShadow
ref={ref}
visible={node.visible}
>
<mesh
geometry={collisionPlaceholderGeometry}
name="collision-mesh"
visible={false}
{...handlers}
/>
{node.children.map((childId) => (
<NodeRenderer key={`${node.id}:${childId}`} nodeId={childId} />
+6 -4
View File
@@ -271,16 +271,18 @@ export function createMaterial(material?: MaterialSchema): THREE.MeshStandardMat
}
const map = getTexture(material)
const threeMaterial = new THREE.MeshStandardMaterial({
const materialParams: THREE.MeshStandardMaterialParameters = {
color: props.color,
roughness: props.roughness,
metalness: props.metalness,
opacity: props.opacity,
transparent: props.transparent,
side: sideMap[props.side],
map,
})
}
if (map) materialParams.map = map
const threeMaterial = new THREE.MeshStandardMaterial(materialParams)
materialCache.set(cacheKey, threeMaterial)
return threeMaterial