Merge pull request #448 from Irev-Dev/kurt/383-add-gizmo-and-edges
Add gizmo and edges
This commit was merged in pull request #448.
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
import { useIdeContext } from 'src/helpers/hooks/useIdeContext'
|
||||
import { useRef, useState, useEffect, useLayoutEffect } from 'react'
|
||||
import { Canvas, extend, useFrame, useThree } from '@react-three/fiber'
|
||||
import { PerspectiveCamera, useEdgeSplit } from '@react-three/drei'
|
||||
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
|
||||
import * as THREE from 'three'
|
||||
import { useRef, useState, useEffect } from 'react'
|
||||
import { Canvas, useThree } from '@react-three/fiber'
|
||||
import {
|
||||
PerspectiveCamera,
|
||||
GizmoHelper,
|
||||
GizmoViewport,
|
||||
OrbitControls,
|
||||
} from '@react-three/drei'
|
||||
import { useEdgeSplit } from 'src/helpers/hooks/useEdegeSplit'
|
||||
import { Vector3 } from 'three'
|
||||
import { requestRender } from 'src/helpers/hooks/useIdeState'
|
||||
import texture from './dullFrontLitMetal.png'
|
||||
@@ -13,10 +19,15 @@ import DelayedPingAnimation from 'src/components/DelayedPingAnimation/DelayedPin
|
||||
const loader = new TextureLoader()
|
||||
const colorMap = loader.load(texture)
|
||||
|
||||
extend({ OrbitControls })
|
||||
const thresholdAngle = 12
|
||||
|
||||
function Asset({ geometry: incomingGeo }) {
|
||||
const mesh = useEdgeSplit((12 * Math.PI) / 180, true)
|
||||
const mesh = useEdgeSplit((thresholdAngle * Math.PI) / 180, true, incomingGeo)
|
||||
const edges = React.useMemo(
|
||||
() =>
|
||||
incomingGeo.length ? null : new THREE.EdgesGeometry(incomingGeo, thresholdAngle),
|
||||
[incomingGeo]
|
||||
)
|
||||
if (!incomingGeo) return null
|
||||
|
||||
if (incomingGeo.length)
|
||||
@@ -25,9 +36,14 @@ function Asset({ geometry: incomingGeo }) {
|
||||
))
|
||||
|
||||
return (
|
||||
<mesh ref={mesh} scale={[1, 1, 1]} geometry={incomingGeo}>
|
||||
<meshStandardMaterial map={colorMap} color="#F472B6" />
|
||||
</mesh>
|
||||
<group dispose={null}>
|
||||
<mesh ref={mesh} scale={[1, 1, 1]} geometry={incomingGeo}>
|
||||
<meshStandardMaterial map={colorMap} color="#F472B6" />
|
||||
</mesh>
|
||||
<lineSegments geometry={edges} renderOrder={100} opac>
|
||||
<lineBasicMaterial color="#555588" opacity={0.5} transparent />
|
||||
</lineSegments>
|
||||
</group>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -46,9 +62,6 @@ function Controls({ onCameraChange, onDragStart, onInit }) {
|
||||
camera.fov = 22.5 // matches default openscad fov
|
||||
camera.updateProjectionMatrix()
|
||||
|
||||
// Order matters with Euler rotations
|
||||
// We want it to rotate around the z or vertical axis first then the x axis to match openscad
|
||||
// in Three.js Y is the vertical axis (Z for openscad)
|
||||
camera.rotation._order = 'ZYX'
|
||||
const getRotations = (): number[] => {
|
||||
const { x, y, z } = camera?.rotation || {}
|
||||
@@ -104,13 +117,8 @@ function Controls({ onCameraChange, onDragStart, onInit }) {
|
||||
}
|
||||
}, [camera, controls])
|
||||
|
||||
useFrame(() => controls.current?.update())
|
||||
return (
|
||||
<orbitControls
|
||||
ref={controls}
|
||||
args={[camera, gl.domElement]}
|
||||
rotateSpeed={0.5}
|
||||
/>
|
||||
<OrbitControls makeDefault ref={controls} args={[camera, gl.domElement]} />
|
||||
)
|
||||
}
|
||||
|
||||
@@ -214,6 +222,12 @@ const IdeViewer = ({ Loading }) => {
|
||||
material-transparent
|
||||
rotation-x={Math.PI / 2}
|
||||
/>
|
||||
<GizmoHelper alignment={'top-left'} margin={[80, 80]}>
|
||||
<GizmoViewport
|
||||
axisColors={['red', 'green', 'blue']}
|
||||
labelColor="black"
|
||||
/>
|
||||
</GizmoHelper>
|
||||
{state.objectData?.type === 'png' && (
|
||||
<>
|
||||
<Sphere position={[0, 0, 0]} color={pink400} />
|
||||
|
||||
30
app/web/src/helpers/hooks/useEdegeSplit.ts
Normal file
30
app/web/src/helpers/hooks/useEdegeSplit.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
// This code has been copied from https://github.com/pmndrs/drei/blob/master/src/core/useEdgeSplit.tsx
|
||||
// but modified to allow for updating geometry with `dependantGeometry`
|
||||
|
||||
import * as React from 'react'
|
||||
import * as THREE from 'three'
|
||||
import { EdgeSplitModifier } from 'three-stdlib'
|
||||
|
||||
export function useEdgeSplit(cutOffAngle: number, tryKeepNormals: boolean = true, dependantGeometry?: any) {
|
||||
const ref = React.useRef<THREE.Mesh>()
|
||||
const original = React.useRef<THREE.BufferGeometry>()
|
||||
const modifier = React.useRef<EdgeSplitModifier>()
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!original.current && ref.current) {
|
||||
original.current = ref.current.geometry.clone()
|
||||
modifier.current = new EdgeSplitModifier()
|
||||
}
|
||||
}, [dependantGeometry])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (original.current && ref.current && modifier.current) {
|
||||
const modifiedGeometry = modifier.current.modify(original.current, cutOffAngle, tryKeepNormals)
|
||||
modifiedGeometry.computeVertexNormals()
|
||||
|
||||
ref.current.geometry = modifiedGeometry
|
||||
}
|
||||
}, [cutOffAngle, tryKeepNormals, dependantGeometry])
|
||||
|
||||
return ref
|
||||
}
|
||||
Reference in New Issue
Block a user