From d2ee8be7e1d9f08f5fe61c2c13ad39700995f8fa Mon Sep 17 00:00:00 2001 From: Kurt Hutten Date: Tue, 10 Aug 2021 17:35:14 +1000 Subject: [PATCH 1/3] some progress on getting the gizmo work but with jank. --- .../src/components/IdeViewer/IdeViewer.tsx | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/app/web/src/components/IdeViewer/IdeViewer.tsx b/app/web/src/components/IdeViewer/IdeViewer.tsx index 86c73ff..068defa 100644 --- a/app/web/src/components/IdeViewer/IdeViewer.tsx +++ b/app/web/src/components/IdeViewer/IdeViewer.tsx @@ -1,8 +1,7 @@ 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 { useRef, useState, useEffect } from 'react' +import { Canvas, useThree } from '@react-three/fiber' +import { PerspectiveCamera, useEdgeSplit, GizmoHelper, GizmoViewport, OrbitControls } from '@react-three/drei' import { Vector3 } from 'three' import { requestRender } from 'src/helpers/hooks/useIdeState' import texture from './dullFrontLitMetal.png' @@ -13,8 +12,6 @@ import DelayedPingAnimation from 'src/components/DelayedPingAnimation/DelayedPin const loader = new TextureLoader() const colorMap = loader.load(texture) -extend({ OrbitControls }) - function Asset({ geometry: incomingGeo }) { const mesh = useEdgeSplit((12 * Math.PI) / 180, true) if (!incomingGeo) return null @@ -46,9 +43,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,12 +98,11 @@ function Controls({ onCameraChange, onDragStart, onInit }) { } }, [camera, controls]) - useFrame(() => controls.current?.update()) return ( - ) } @@ -214,6 +207,19 @@ const IdeViewer = ({ Loading }) => { material-transparent rotation-x={Math.PI / 2} /> + + + {state.objectData?.type === 'png' && ( <> From 5afa5d953c8eaaaaa2926e1a003fe861d416a180 Mon Sep 17 00:00:00 2001 From: Kurt Hutten Date: Tue, 10 Aug 2021 20:36:30 +1000 Subject: [PATCH 2/3] Add edges to models --- .../src/components/IdeViewer/IdeViewer.tsx | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/app/web/src/components/IdeViewer/IdeViewer.tsx b/app/web/src/components/IdeViewer/IdeViewer.tsx index 068defa..222768a 100644 --- a/app/web/src/components/IdeViewer/IdeViewer.tsx +++ b/app/web/src/components/IdeViewer/IdeViewer.tsx @@ -1,7 +1,14 @@ import { useIdeContext } from 'src/helpers/hooks/useIdeContext' +import * as THREE from 'three' import { useRef, useState, useEffect } from 'react' import { Canvas, useThree } from '@react-three/fiber' -import { PerspectiveCamera, useEdgeSplit, GizmoHelper, GizmoViewport, OrbitControls } from '@react-three/drei' +import { + PerspectiveCamera, + useEdgeSplit, + GizmoHelper, + GizmoViewport, + OrbitControls, +} from '@react-three/drei' import { Vector3 } from 'three' import { requestRender } from 'src/helpers/hooks/useIdeState' import texture from './dullFrontLitMetal.png' @@ -14,6 +21,11 @@ const colorMap = loader.load(texture) function Asset({ geometry: incomingGeo }) { const mesh = useEdgeSplit((12 * Math.PI) / 180, true) + const edges = React.useMemo( + () => + incomingGeo.length ? null : new THREE.EdgesGeometry(incomingGeo, 15), + [incomingGeo] + ) if (!incomingGeo) return null if (incomingGeo.length) @@ -22,9 +34,14 @@ function Asset({ geometry: incomingGeo }) { )) return ( - - - + + + + + + + + ) } @@ -99,11 +116,7 @@ function Controls({ onCameraChange, onDragStart, onInit }) { }, [camera, controls]) return ( - + ) } @@ -207,18 +220,11 @@ const IdeViewer = ({ Loading }) => { material-transparent rotation-x={Math.PI / 2} /> - - + + {state.objectData?.type === 'png' && ( <> From 799a32544b6142466e61b3c8366ffc56b2635325 Mon Sep 17 00:00:00 2001 From: Kurt Hutten Date: Wed, 11 Aug 2021 07:01:09 +1000 Subject: [PATCH 3/3] Use forked useEdegeSplit to allow updating geomerty --- .../src/components/IdeViewer/IdeViewer.tsx | 8 +++-- app/web/src/helpers/hooks/useEdegeSplit.ts | 30 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 app/web/src/helpers/hooks/useEdegeSplit.ts diff --git a/app/web/src/components/IdeViewer/IdeViewer.tsx b/app/web/src/components/IdeViewer/IdeViewer.tsx index 222768a..38faa9a 100644 --- a/app/web/src/components/IdeViewer/IdeViewer.tsx +++ b/app/web/src/components/IdeViewer/IdeViewer.tsx @@ -4,11 +4,11 @@ import { useRef, useState, useEffect } from 'react' import { Canvas, useThree } from '@react-three/fiber' import { PerspectiveCamera, - useEdgeSplit, 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' @@ -19,11 +19,13 @@ import DelayedPingAnimation from 'src/components/DelayedPingAnimation/DelayedPin const loader = new TextureLoader() const colorMap = loader.load(texture) +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, 15), + incomingGeo.length ? null : new THREE.EdgesGeometry(incomingGeo, thresholdAngle), [incomingGeo] ) if (!incomingGeo) return null diff --git a/app/web/src/helpers/hooks/useEdegeSplit.ts b/app/web/src/helpers/hooks/useEdegeSplit.ts new file mode 100644 index 0000000..47d3bf1 --- /dev/null +++ b/app/web/src/helpers/hooks/useEdegeSplit.ts @@ -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() + const original = React.useRef() + const modifier = React.useRef() + + 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 +}