Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-05-21 20:50:28 +00:00
parent 1139337dbb
commit e0377d49fa
+12 -5
View File
@@ -260,19 +260,26 @@ function SceneModels() {
); );
} }
/** Sphere marker at a 3D point — scaled per-frame to keep constant screen size */ /** Sphere marker at a 3D point — scaled per-frame to keep constant screen size.
* Compensates for any cumulative parent world scale so it stays the same screen
* size whether mounted in world space or inside a transformed model group. */
function PointMarker({ position, color = '#e8a838' }: { position: [number, number, number]; color?: string }) { function PointMarker({ position, color = '#e8a838' }: { position: [number, number, number]; color?: string }) {
const ref = useRef<THREE.Mesh>(null); const ref = useRef<THREE.Mesh>(null);
const { camera, size } = useThree(); const { camera, size } = useThree();
const tmpVec = useMemo(() => new THREE.Vector3(), []);
const worldPos = useMemo(() => new THREE.Vector3(), []);
useFrame(() => { useFrame(() => {
if (!ref.current) return; if (!ref.current) return;
const dist = camera.position.distanceTo(ref.current.position); ref.current.getWorldPosition(worldPos);
const dist = camera.position.distanceTo(worldPos);
const perspCam = camera as THREE.PerspectiveCamera; const perspCam = camera as THREE.PerspectiveCamera;
const fov = (perspCam.fov ?? 50) * (Math.PI / 180); const fov = (perspCam.fov ?? 50) * (Math.PI / 180);
const worldPerPixel = (2 * dist * Math.tan(fov / 2)) / size.height; const worldPerPixel = (2 * dist * Math.tan(fov / 2)) / size.height;
// Target: ~6 px radius (radius = 1 in base geometry → scale = 6*wpp) // Target: ~6 px radius (radius = 1 in base geometry → scale = 6*wpp).
const s = Math.max(0.0005, 6 * worldPerPixel); const targetWorld = Math.max(0.0005, 6 * worldPerPixel);
ref.current.scale.setScalar(s); // Divide by parent world scale so the final world size matches `targetWorld`.
const parentScale = ref.current.parent ? ref.current.parent.getWorldScale(tmpVec).x || 1 : 1;
ref.current.scale.setScalar(targetWorld / parentScale);
}); });
return ( return (
<mesh ref={ref} position={position}> <mesh ref={ref} position={position}>