diff --git a/app/web/src/components/IdeViewer/IdeViewer.tsx b/app/web/src/components/IdeViewer/IdeViewer.tsx
index 86c73ff..38faa9a 100644
--- a/app/web/src/components/IdeViewer/IdeViewer.tsx
+++ b/app/web/src/components/IdeViewer/IdeViewer.tsx
@@ -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 (
-
-
-
+
+
+
+
+
+
+
+
)
}
@@ -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 (
-
+
)
}
@@ -214,6 +222,12 @@ const IdeViewer = ({ Loading }) => {
material-transparent
rotation-x={Math.PI / 2}
/>
+
+
+
{state.objectData?.type === 'png' && (
<>
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
+}