@@ -9,6 +9,7 @@ export const BuildingRenderer = ({ node }: { node: BuildingNode }) => {
|
||||
|
||||
useRegistry(node.id, node.type, ref)
|
||||
const handlers = useNodeEvents(node, 'building')
|
||||
|
||||
return (
|
||||
<group
|
||||
position={node.position}
|
||||
|
||||
@@ -100,7 +100,6 @@ const Viewer: React.FC<ViewerProps> = ({
|
||||
perf = false,
|
||||
}) => {
|
||||
const theme = useViewer((state) => state.theme)
|
||||
|
||||
return (
|
||||
<Canvas
|
||||
camera={{ position: [50, 50, 50], fov: 50 }}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export { default as Viewer } from './components/viewer'
|
||||
export { SSGI_PARAMS } from './components/viewer/post-processing'
|
||||
export { WalkthroughControls } from './components/viewer/walkthrough-controls'
|
||||
export { ASSETS_CDN_URL, resolveAssetUrl, resolveCdnUrl } from './lib/asset-url'
|
||||
export { SCENE_LAYER, ZONE_LAYER } from './lib/layers'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { sceneRegistry } from '@pascal-app/core'
|
||||
import { emitter, sceneRegistry } from '@pascal-app/core'
|
||||
import { useEffect } from 'react'
|
||||
import useViewer from '../../store/use-viewer'
|
||||
|
||||
@@ -14,5 +14,30 @@ export const GuideSystem = () => {
|
||||
}
|
||||
})
|
||||
}, [showGuides])
|
||||
|
||||
useEffect(() => {
|
||||
const hideForCapture = () => {
|
||||
const guides = sceneRegistry.byType.guide || new Set()
|
||||
guides.forEach((guideId) => {
|
||||
const node = sceneRegistry.nodes.get(guideId)
|
||||
if (node) node.visible = false
|
||||
})
|
||||
}
|
||||
const restoreAfterCapture = () => {
|
||||
const showGuidesNow = useViewer.getState().showGuides
|
||||
const guides = sceneRegistry.byType.guide || new Set()
|
||||
guides.forEach((guideId) => {
|
||||
const node = sceneRegistry.nodes.get(guideId)
|
||||
if (node) node.visible = showGuidesNow
|
||||
})
|
||||
}
|
||||
emitter.on('thumbnail:before-capture', hideForCapture)
|
||||
emitter.on('thumbnail:after-capture', restoreAfterCapture)
|
||||
return () => {
|
||||
emitter.off('thumbnail:before-capture', hideForCapture)
|
||||
emitter.off('thumbnail:after-capture', restoreAfterCapture)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { sceneRegistry } from '@pascal-app/core'
|
||||
import { emitter, sceneRegistry } from '@pascal-app/core'
|
||||
import { useEffect } from 'react'
|
||||
import useViewer from '../../store/use-viewer'
|
||||
|
||||
@@ -14,5 +14,30 @@ export const ScanSystem = () => {
|
||||
}
|
||||
})
|
||||
}, [showScans])
|
||||
|
||||
useEffect(() => {
|
||||
const hideForCapture = () => {
|
||||
const scans = sceneRegistry.byType.scan || new Set()
|
||||
scans.forEach((scanId) => {
|
||||
const node = sceneRegistry.nodes.get(scanId)
|
||||
if (node) node.visible = false
|
||||
})
|
||||
}
|
||||
const restoreAfterCapture = () => {
|
||||
const showScansNow = useViewer.getState().showScans
|
||||
const scans = sceneRegistry.byType.scan || new Set()
|
||||
scans.forEach((scanId) => {
|
||||
const node = sceneRegistry.nodes.get(scanId)
|
||||
if (node) node.visible = showScansNow
|
||||
})
|
||||
}
|
||||
emitter.on('thumbnail:before-capture', hideForCapture)
|
||||
emitter.on('thumbnail:after-capture', restoreAfterCapture)
|
||||
return () => {
|
||||
emitter.off('thumbnail:before-capture', hideForCapture)
|
||||
emitter.off('thumbnail:after-capture', restoreAfterCapture)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import {
|
||||
type AnyNodeId,
|
||||
baseMaterial,
|
||||
emitter,
|
||||
sceneRegistry,
|
||||
useScene,
|
||||
type WallNode,
|
||||
} from '@pascal-app/core'
|
||||
import { useFrame } from '@react-three/fiber'
|
||||
import { useRef } from 'react'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import type { Material } from 'three'
|
||||
import { Color } from 'three'
|
||||
import { Fn, float, fract, length, mix, positionLocal, smoothstep, step, vec2 } from 'three/tsl'
|
||||
import { type Mesh, MeshStandardNodeMaterial, Vector3 } from 'three/webgpu'
|
||||
@@ -273,5 +275,41 @@ export const WallCutout = () => {
|
||||
lastHighlightKey.current = highlightKey
|
||||
}
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const snapshot = new Map<Mesh, Material>()
|
||||
|
||||
const restoreForCapture = () => {
|
||||
sceneRegistry.byType.wall.forEach((wallId) => {
|
||||
const wallMesh = sceneRegistry.nodes.get(wallId) as Mesh | undefined
|
||||
if (!wallMesh) return
|
||||
const wallNode = useScene.getState().nodes[wallId as AnyNodeId] as WallNode | undefined
|
||||
if (!wallNode || wallNode.type !== 'wall') return
|
||||
const mats = getMaterialsForWall(wallNode)
|
||||
const current = wallMesh.material as Material
|
||||
snapshot.set(wallMesh, current)
|
||||
if (current === mats.highlightedVisible || current === mats.deleteVisible) {
|
||||
wallMesh.material = mats.visible
|
||||
} else if (current === mats.highlightedInvisible || current === mats.deleteInvisible) {
|
||||
wallMesh.material = mats.invisible
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const reapplyAfterCapture = () => {
|
||||
snapshot.forEach((mat, mesh) => {
|
||||
mesh.material = mat
|
||||
})
|
||||
snapshot.clear()
|
||||
}
|
||||
|
||||
emitter.on('thumbnail:before-capture', restoreForCapture)
|
||||
emitter.on('thumbnail:after-capture', reapplyAfterCapture)
|
||||
return () => {
|
||||
emitter.off('thumbnail:before-capture', restoreForCapture)
|
||||
emitter.off('thumbnail:after-capture', reapplyAfterCapture)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user