Spaces:
Sleeping
Sleeping
File size: 2,706 Bytes
1829efb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | import { useEffect, useMemo } from 'react'
import * as THREE from 'three'
const AXIS_LENGTH = 0.2
interface ObjectHoverGuidesProps {
size: THREE.Vector3 | [number, number, number]
}
function sizeTuple(size: THREE.Vector3 | [number, number, number]): [number, number, number] {
return Array.isArray(size) ? size : [size.x, size.y, size.z]
}
function useLineGeometry(positions: number[], colors?: number[]) {
const geometry = useMemo(() => {
const next = new THREE.BufferGeometry()
next.setAttribute('position', new THREE.Float32BufferAttribute(positions, 3))
if (colors) next.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3))
return next
}, [colors, positions])
useEffect(() => () => geometry.dispose(), [geometry])
return geometry
}
export function ObjectHoverGuides({ size }: ObjectHoverGuidesProps) {
const [width, height, depth] = sizeTuple(size)
const safeWidth = Math.max(width, 0.01)
const safeHeight = Math.max(height, 0.01)
const safeDepth = Math.max(depth, 0.01)
const halfWidth = safeWidth / 2
const halfHeight = safeHeight / 2
const halfDepth = safeDepth / 2
const axisGeometry = useLineGeometry([
0, 0, 0, AXIS_LENGTH, 0, 0,
0, 0, 0, 0, AXIS_LENGTH, 0,
0, 0, 0, 0, 0, AXIS_LENGTH,
], [
1, 0.15, 0.15, 1, 0.15, 0.15,
0.2, 1, 0.2, 0.2, 1, 0.2,
0.25, 0.5, 1, 0.25, 0.5, 1,
])
const boxGeometry = useLineGeometry([
-halfWidth, -halfHeight, -halfDepth, halfWidth, -halfHeight, -halfDepth,
halfWidth, -halfHeight, -halfDepth, halfWidth, -halfHeight, halfDepth,
halfWidth, -halfHeight, halfDepth, -halfWidth, -halfHeight, halfDepth,
-halfWidth, -halfHeight, halfDepth, -halfWidth, -halfHeight, -halfDepth,
-halfWidth, halfHeight, -halfDepth, halfWidth, halfHeight, -halfDepth,
halfWidth, halfHeight, -halfDepth, halfWidth, halfHeight, halfDepth,
halfWidth, halfHeight, halfDepth, -halfWidth, halfHeight, halfDepth,
-halfWidth, halfHeight, halfDepth, -halfWidth, halfHeight, -halfDepth,
-halfWidth, -halfHeight, -halfDepth, -halfWidth, halfHeight, -halfDepth,
halfWidth, -halfHeight, -halfDepth, halfWidth, halfHeight, -halfDepth,
halfWidth, -halfHeight, halfDepth, halfWidth, halfHeight, halfDepth,
-halfWidth, -halfHeight, halfDepth, -halfWidth, halfHeight, halfDepth,
])
return (
<group>
<lineSegments geometry={axisGeometry}>
<lineBasicMaterial vertexColors depthTest depthWrite toneMapped={false} />
</lineSegments>
<lineSegments geometry={boxGeometry} position={[0, halfHeight, 0]}>
<lineBasicMaterial color={0xffffff} depthTest depthWrite toneMapped={false} />
</lineSegments>
</group>
)
}
|