🚀 Auto-deploy: melhoria no snap e medição AR em 24/05/2026 02:00:33
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useRef, useMemo, useState, useCallback } from 'react';
|
||||
import { useFrame, useThree } from '@react-three/fiber';
|
||||
import { Grid } from '@react-three/drei';
|
||||
import { Grid, Billboard } from '@react-three/drei';
|
||||
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
||||
import * as THREE from 'three';
|
||||
import { useModelStore, type SceneModel } from '@/stores/useModelStore';
|
||||
@@ -8,6 +8,15 @@ import { findNearestVertex } from './SmartMeasure';
|
||||
import { registerModelLocalGroup, unregisterModelLocalGroup } from '@/lib/modelTransforms';
|
||||
import { parseIFCtoThree } from '@/lib/convertIFC';
|
||||
|
||||
function findModelId(obj: THREE.Object3D): string | undefined {
|
||||
let cur: THREE.Object3D | null = obj;
|
||||
while (cur) {
|
||||
if (cur.userData?.modelId) return cur.userData.modelId as string;
|
||||
cur = cur.parent;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// ─── XRModel ───────────────────────────────────────────
|
||||
export function XRModel({ sceneModel }: { sceneModel: SceneModel }) {
|
||||
const [rawScene, setRawScene] = useState<THREE.Object3D | null>(null);
|
||||
@@ -282,15 +291,17 @@ function XRMeasurementText({ text, color }: { text: string; color: string }) {
|
||||
}, [text, color]);
|
||||
|
||||
return (
|
||||
<mesh renderOrder={999}>
|
||||
<planeGeometry args={[0.08, 0.02]} />
|
||||
<meshBasicMaterial
|
||||
map={texture}
|
||||
transparent
|
||||
depthTest={false}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
<Billboard follow={true}>
|
||||
<mesh renderOrder={999}>
|
||||
<planeGeometry args={[0.08, 0.02]} />
|
||||
<meshBasicMaterial
|
||||
map={texture}
|
||||
transparent
|
||||
depthTest={false}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
</Billboard>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -444,7 +455,8 @@ export function XRSnapHandler() {
|
||||
if (hit && hit.object instanceof THREE.Mesh) {
|
||||
const canvas = gl.domElement;
|
||||
const snap = findNearestVertex(hit.object, hit.point, camera, { width: canvas.clientWidth, height: canvas.clientHeight }, 10);
|
||||
setSnapPoint(snap ? { x: snap.x, y: snap.y, z: snap.z } : null);
|
||||
const hitModelId = findModelId(hit.object);
|
||||
setSnapPoint(snap ? { x: snap.x, y: snap.y, z: snap.z, modelId: hitModelId } : null);
|
||||
} else {
|
||||
setSnapPoint(null);
|
||||
}
|
||||
@@ -455,7 +467,7 @@ export function XRSnapHandler() {
|
||||
if (gl.xr.isPresenting) return;
|
||||
const onClick = (e: MouseEvent) => {
|
||||
if (snapPoint) {
|
||||
addMeasurePoint({ x: snapPoint.x, y: snapPoint.y, z: snapPoint.z });
|
||||
addMeasurePoint({ x: snapPoint.x, y: snapPoint.y, z: snapPoint.z, modelId: snapPoint.modelId });
|
||||
return;
|
||||
}
|
||||
const rect = gl.domElement.getBoundingClientRect();
|
||||
@@ -464,7 +476,10 @@ export function XRSnapHandler() {
|
||||
raycaster.setFromCamera(mouse, camera);
|
||||
const intersects = raycaster.intersectObjects(scene.children, true);
|
||||
const hit = intersects.find(i => i.object instanceof THREE.Mesh && !i.object.userData.__edgeLine);
|
||||
if (hit) addMeasurePoint({ x: hit.point.x, y: hit.point.y, z: hit.point.z });
|
||||
if (hit) {
|
||||
const hitModelId = findModelId(hit.object);
|
||||
addMeasurePoint({ x: hit.point.x, y: hit.point.y, z: hit.point.z, modelId: hitModelId });
|
||||
}
|
||||
};
|
||||
gl.domElement.addEventListener('click', onClick);
|
||||
return () => gl.domElement.removeEventListener('click', onClick);
|
||||
|
||||
Reference in New Issue
Block a user