overlay is temporarily restored
This commit is contained in:
@@ -21,13 +21,13 @@ import {
|
|||||||
ImportMeshAsync,
|
ImportMeshAsync,
|
||||||
PointerEventTypes,
|
PointerEventTypes,
|
||||||
PointerInfo,
|
PointerInfo,
|
||||||
|
Matrix,
|
||||||
} from '@babylonjs/core'
|
} from '@babylonjs/core'
|
||||||
import '@babylonjs/loaders'
|
import '@babylonjs/loaders'
|
||||||
|
|
||||||
import SceneToolbar from './SceneToolbar';
|
import SceneToolbar from './SceneToolbar';
|
||||||
import LoadingSpinner from '../ui/LoadingSpinner'
|
import LoadingSpinner from '../ui/LoadingSpinner'
|
||||||
|
|
||||||
|
|
||||||
export interface ModelViewerProps {
|
export interface ModelViewerProps {
|
||||||
modelPath: string
|
modelPath: string
|
||||||
onSelectModel: (path: string) => void;
|
onSelectModel: (path: string) => void;
|
||||||
@@ -202,7 +202,6 @@ const ModelViewer: React.FC<ModelViewerProps> = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
isDisposedRef.current = false
|
isDisposedRef.current = false
|
||||||
isInitializedRef.current = false
|
isInitializedRef.current = false
|
||||||
@@ -548,6 +547,49 @@ const ModelViewer: React.FC<ModelViewerProps> = ({
|
|||||||
}
|
}
|
||||||
}, [focusSensorId, modelReady])
|
}, [focusSensorId, modelReady])
|
||||||
|
|
||||||
|
// Расчет позиции оверлея
|
||||||
|
const computeOverlayPosition = React.useCallback((mesh: AbstractMesh | null) => {
|
||||||
|
if (!sceneRef.current || !mesh) return null
|
||||||
|
const scene = sceneRef.current
|
||||||
|
try {
|
||||||
|
const bbox = (typeof mesh.getHierarchyBoundingVectors === 'function')
|
||||||
|
? mesh.getHierarchyBoundingVectors()
|
||||||
|
: { min: mesh.getBoundingInfo().boundingBox.minimumWorld, max: mesh.getBoundingInfo().boundingBox.maximumWorld }
|
||||||
|
const center = bbox.min.add(bbox.max).scale(0.5)
|
||||||
|
|
||||||
|
const viewport = scene.activeCamera?.viewport.toGlobal(engineRef.current!.getRenderWidth(), engineRef.current!.getRenderHeight())
|
||||||
|
if (!viewport) return null
|
||||||
|
|
||||||
|
const projected = Vector3.Project(center, Matrix.Identity(), scene.getTransformMatrix(), viewport)
|
||||||
|
if (!projected) return null
|
||||||
|
|
||||||
|
return { left: projected.x, top: projected.y }
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[ModelViewer] Error computing overlay position:', error)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// Позиция оверлея изначально
|
||||||
|
useEffect(() => {
|
||||||
|
if (!chosenMeshRef.current || !overlayData) return
|
||||||
|
const pos = computeOverlayPosition(chosenMeshRef.current)
|
||||||
|
setOverlayPos(pos)
|
||||||
|
}, [overlayData, computeOverlayPosition])
|
||||||
|
|
||||||
|
// Позиция оверлея при движущейся камере
|
||||||
|
useEffect(() => {
|
||||||
|
if (!sceneRef.current || !chosenMeshRef.current || !overlayData) return
|
||||||
|
const scene = sceneRef.current
|
||||||
|
|
||||||
|
const updateOverlayPosition = () => {
|
||||||
|
const pos = computeOverlayPosition(chosenMeshRef.current)
|
||||||
|
setOverlayPos(pos)
|
||||||
|
}
|
||||||
|
scene.registerBeforeRender(updateOverlayPosition)
|
||||||
|
return () => scene.unregisterBeforeRender(updateOverlayPosition)
|
||||||
|
}, [overlayData, computeOverlayPosition])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-screen relative bg-gray-900 overflow-hidden">
|
<div className="w-full h-screen relative bg-gray-900 overflow-hidden">
|
||||||
{!modelPath ? (
|
{!modelPath ? (
|
||||||
@@ -603,16 +645,9 @@ const ModelViewer: React.FC<ModelViewerProps> = ({
|
|||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{renderOverlay
|
{renderOverlay && overlayPos && overlayData
|
||||||
? renderOverlay({ anchor: overlayPos, info: overlayData })
|
? renderOverlay({ anchor: overlayPos, info: overlayData })
|
||||||
: (overlayData && overlayPos && (
|
: null
|
||||||
<div className="absolute z-40 pointer-events-none" style={{ left: overlayPos.left, top: overlayPos.top }}>
|
|
||||||
<div className="rounded bg-black/70 text-white text-xs px-3 py-2 shadow-lg">
|
|
||||||
<div className="font-semibold truncate max-w-[200px]">{overlayData.name || 'Sensor'}</div>
|
|
||||||
{overlayData.sensorId && <div className="opacity-80">ID: {overlayData.sensorId}</div>}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user