Move render systems out of core

This commit is contained in:
sudhir
2026-05-01 15:07:47 +05:30
parent eee7af9e25
commit 23eec44714
18 changed files with 126 additions and 109 deletions
@@ -0,0 +1,63 @@
import { useFrame } from '@react-three/fiber'
import {
type AnyNodeId,
getScaledDimensions,
type ItemNode,
resolveLevelId,
sceneRegistry,
spatialGridManager,
useScene,
type WallNode,
} from '@pascal-app/core'
import type * as THREE from 'three'
// ============================================================================
// ITEM SYSTEM
// ============================================================================
export const ItemSystem = () => {
const dirtyNodes = useScene((state) => state.dirtyNodes)
const clearDirty = useScene((state) => state.clearDirty)
useFrame(() => {
if (dirtyNodes.size === 0) return
const nodes = useScene.getState().nodes
dirtyNodes.forEach((id) => {
const node = nodes[id]
if (!node || node.type !== 'item') return
const item = node as ItemNode
const mesh = sceneRegistry.nodes.get(id) as THREE.Object3D
if (!mesh) return
if (item.asset.attachTo === 'wall-side') {
// Wall-attached item: offset Z by half the parent wall's thickness
const parentWall = item.parentId ? nodes[item.parentId as AnyNodeId] : undefined
if (parentWall && parentWall.type === 'wall') {
const wallThickness = (parentWall as WallNode).thickness ?? 0.1
const side = item.side === 'front' ? 1 : -1
mesh.position.z = (wallThickness / 2) * side
}
} else if (!item.asset.attachTo) {
// If parented to another item (surface placement), R3F handles positioning via the hierarchy
const parentNode = item.parentId ? nodes[item.parentId as AnyNodeId] : undefined
if (parentNode?.type !== 'item') {
// Floor item: elevate by slab height (using full footprint overlap)
const levelId = resolveLevelId(item, nodes)
const slabElevation = spatialGridManager.getSlabElevationForItem(
levelId,
item.position,
getScaledDimensions(item),
item.rotation,
)
mesh.position.y = slabElevation + item.position[1]
}
}
clearDirty(id as AnyNodeId)
})
}, 2)
return null
}