Skip to content

Commit

Permalink
BREAKING CHANGE: Upgrade Three.js to r125 (#262)
Browse files Browse the repository at this point in the history
* chore: update Three.js dependency

* refactor: remove subdivision modifier

* fix: remove use of FaceNormalsHelper as it no longer exists in Three

* fix: update typings for THREE

* fix: update modifiers to work without THREE.Geometry

* docs: update README

* chore: add Three.js peer dependency
jure authored Jan 27, 2021
1 parent 19a0326 commit 487cb5a
Showing 13 changed files with 32 additions and 137 deletions.
5 changes: 3 additions & 2 deletions .storybook/stories/useEdgeSplit.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react'
import { useLoader } from 'react-three-fiber'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader'
import { withKnobs, number } from '@storybook/addon-knobs'
import { withKnobs, number, boolean } from '@storybook/addon-knobs'

import { Setup } from '../Setup'

@@ -17,8 +17,9 @@ function CerberusModel() {
const { children } = useLoader(OBJLoader, 'cerberus.obj')

const cutoffEdge = number('Cut Off Edge', 20, { range: true, min: 0, max: 180, step: 1 })
const tryKeepNormals = boolean('Keep normals', true)

const meshRef = useEdgeSplit(cutoffEdge * (Math.PI / 180))
const meshRef = useEdgeSplit(cutoffEdge * (Math.PI / 180), tryKeepNormals)

return (
<mesh scale={[8, 8, 8]} ref={meshRef} geometry={(children[0] as THREE.Mesh).geometry}>
2 changes: 0 additions & 2 deletions .storybook/stories/useHelper.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as React from 'react'
import { BoxHelper, CameraHelper } from 'three'
import { VertexNormalsHelper } from 'three/examples/jsm/helpers/VertexNormalsHelper'
import { FaceNormalsHelper } from 'three/examples/jsm/helpers/FaceNormalsHelper'

import { Setup } from '../Setup'

@@ -17,7 +16,6 @@ function Scene() {
const mesh = React.useRef()
useHelper(mesh, BoxHelper, 'royalblue')
useHelper(mesh, VertexNormalsHelper, 1, 'red')
useHelper(mesh, FaceNormalsHelper, 1, 'hotpink')

return (
<Sphere ref={mesh}>
27 changes: 0 additions & 27 deletions .storybook/stories/useSubdivision.stories.tsx

This file was deleted.

8 changes: 4 additions & 4 deletions .storybook/stories/useTessellation.stories.tsx
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ export default {

const VertexDisplaceMaterial = shaderMaterial(
{
amplitude: 1,
amplitude: 1.0,
},
`
uniform float amplitude;
@@ -60,8 +60,8 @@ declare global {
}

function UseTessellationScene() {
const passes = number('passes', 3)
const maxEdgeLength = number('maxEdgeLength', 3)
const passes = number('passes', 4)
const maxEdgeLength = number('maxEdgeLength', 0.1)
const meshRef = useTessellation(passes, maxEdgeLength)

React.useEffect(() => {
@@ -86,7 +86,7 @@ function UseTessellationScene() {
geometry.setAttribute('displacement', new THREE.BufferAttribute(displacement, 3))
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
}, [meshRef.current && meshRef.current.geometry])

useFrame(({ clock }) => {
const { current: mesh } = meshRef
21 changes: 1 addition & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -102,7 +102,6 @@ The `native` route of the library **does not** export `Html` or `Loader`. There
<ul>
<li><a href="#curvemodifier">CurveModifier</a></li>
<li><a href="#useedgesplit">useEdgeSplit</a></li>
<li><a href="#usesubdivision">useSubdivision</a></li>
<li><a href="#usetessellation">useTessellation</a></li>
<li><a href="#usesimplification">useSimplification</a></li>
</ul>
@@ -781,7 +780,7 @@ return (
[![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.react-spring.io/?path=/story/modifiers-useedgesplit)
This hook mutates a mesh geometry using [three's Edge Split modifier](https://threejs.org/examples/?q=modifier#webgl_modifier_edgesplit).
This hook mutates a mesh geometry using [three's Edge Split modifier](https://threejs.org/examples/?q=modifier#webgl_modifier_edgesplit). The first parameter is the cut-off angle, and the second parameter is a `tryKeepNormals` flag (default `true`).
```jsx
const meshRef = useEdgeSplit(Math.PI / 2)
@@ -793,24 +792,6 @@ return (
)
```
#### useSubdivision
[![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.react-spring.io/?path=/story/modifiers-usesubdivision)
This hook mutates a mesh geometry using [three's Subdivision modifier](https://threejs.org/examples/webgl_modifier_subdivision.html).
👉 Vertex count is quadrupled for each subdivision.
```jsx
const meshRef = useSubdivision(4)

return (
<mesh ref={meshRef}>
<boxBufferGeometry args={[10, 10]} />
</mesh>
)
```
#### useSimplification
[![](https://img.shields.io/badge/-storybook-%23ff69b4)](https://drei.react-spring.io/?path=/story/modifiers-usesimplification)
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -112,14 +112,15 @@
"rollup-plugin-multi-input": "^1.1.1",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-size-snapshot": "^0.12.0",
"three": "0.123.0",
"three": "0.125.0",
"typescript": "^3.9.7",
"use-asset": "^1.0.2"
},
"peerDependencies": {
"react": ">=16.13",
"react-dom": ">=16.13",
"react-three-fiber": ">=5.0"
"react-three-fiber": ">=5.0",
"three": ">=0.125.0"
},
"peerDependenciesMeta": {
"react-dom": {
4 changes: 2 additions & 2 deletions src/core/CurveModifier.tsx
Original file line number Diff line number Diff line change
@@ -4,13 +4,13 @@ import { Flow } from 'three/examples/jsm/modifiers/CurveModifier'

export interface CurveModifierProps {
children: React.ReactElement<JSX.IntrinsicElements['mesh']>
curve?: THREE.Curve<THREE.Vector2 | THREE.Vector3 | THREE.Vector4>
curve?: THREE.Curve<THREE.Vector3>
}

export type CurveModifierRef = Pick<Flow, 'moveAlongCurve'>

export const CurveModifier = React.forwardRef(({ children, curve }: CurveModifierProps, ref) => {
const [object3D, setObj] = React.useState()
const [object3D, setObj] = React.useState<THREE.Object3D | undefined>()
const original = React.useRef<THREE.Mesh>()
const modifier = React.useRef<Flow>()

1 change: 0 additions & 1 deletion src/core/index.ts
Original file line number Diff line number Diff line change
@@ -45,7 +45,6 @@ export * from './useFBO'

// Modifiers
export * from './useSimplification'
export * from './useSubdivision'
export * from './useTessellation'
export * from './useEdgeSplit'
export * from './CurveModifier'
16 changes: 6 additions & 10 deletions src/core/useEdgeSplit.tsx
Original file line number Diff line number Diff line change
@@ -2,9 +2,9 @@ import * as React from 'react'
import * as THREE from 'three'
import { EdgeSplitModifier } from 'three/examples/jsm/modifiers/EdgeSplitModifier'

export function useEdgeSplit(cutOffAngle: number) {
export function useEdgeSplit(cutOffAngle: number, tryKeepNormals: boolean = true) {
const ref = React.useRef<THREE.Mesh>()
const original = React.useRef<THREE.BufferGeometry | THREE.Geometry>()
const original = React.useRef<THREE.BufferGeometry>()
const modifier = React.useRef<EdgeSplitModifier>()

React.useEffect(() => {
@@ -16,20 +16,16 @@ export function useEdgeSplit(cutOffAngle: number) {

React.useEffect(() => {
if (original.current && ref.current && modifier.current) {
let geometry = new THREE.Geometry()
let geometry = new THREE.BufferGeometry()

if (original.current instanceof THREE.BufferGeometry) {
geometry.fromBufferGeometry(original.current)
} else {
geometry = original.current.clone()
}
geometry = original.current.clone()

const modifiedGeometry = modifier.current.modify(geometry, cutOffAngle)
const modifiedGeometry = modifier.current.modify(geometry, cutOffAngle, tryKeepNormals)
modifiedGeometry.computeVertexNormals()

ref.current.geometry = modifiedGeometry
}
}, [cutOffAngle])
}, [cutOffAngle, tryKeepNormals])

return ref
}
8 changes: 2 additions & 6 deletions src/core/useSimplification.tsx
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ import { SimplifyModifier } from 'three/examples/jsm/modifiers/SimplifyModifier'

export function useSimplification(simplePercent: number) {
const ref = React.useRef<THREE.Mesh>()
const original = React.useRef<THREE.BufferGeometry | THREE.Geometry>()
const original = React.useRef<THREE.BufferGeometry>()
const modifier = React.useRef<SimplifyModifier>()

React.useEffect(() => {
@@ -18,11 +18,7 @@ export function useSimplification(simplePercent: number) {
if (original.current && ref.current) {
let geometry = new THREE.BufferGeometry()

if (original.current instanceof THREE.BufferGeometry) {
geometry = original.current.clone()
} else {
geometry = geometry.fromGeometry(original.current)
}
geometry = original.current.clone()

const count = Math.floor(geometry.attributes.position.count * simplePercent) // number of vertices to remove
ref.current.geometry = modifier.current!.modify(geometry, count)
40 changes: 0 additions & 40 deletions src/core/useSubdivision.tsx

This file was deleted.

24 changes: 7 additions & 17 deletions src/core/useTessellation.tsx
Original file line number Diff line number Diff line change
@@ -4,38 +4,28 @@ import { TessellateModifier } from 'three/examples/jsm/modifiers/TessellateModif

export function useTessellation(passes = 3, maxEdgeLength) {
const ref = React.useRef<THREE.Mesh>()
const original = React.useRef<THREE.BufferGeometry | THREE.Geometry>()
const original = React.useRef<THREE.BufferGeometry>()
const modifier = React.useRef<TessellateModifier>()

React.useEffect(() => {
if (!original.current) {
original.current = ref.current!.geometry.clone()
modifier.current = new TessellateModifier(parseInt(maxEdgeLength))
modifier.current = new TessellateModifier(parseInt(maxEdgeLength), passes)
}
}, [maxEdgeLength])
}, [maxEdgeLength, passes])

React.useEffect(() => {
modifier.current!.maxEdgeLength = maxEdgeLength
}, [maxEdgeLength])

React.useEffect(() => {
if (original.current && ref.current) {
let geometry = new THREE.Geometry()

if (original.current instanceof THREE.BufferGeometry) {
geometry.fromBufferGeometry(original.current)
} else {
geometry = original.current.clone()
}

const bufferGeometry = new THREE.BufferGeometry()
let geometry = new THREE.BufferGeometry()

for (let i = 0; i < passes; i++) {
modifier.current!.modify(geometry)
}
geometry = original.current.clone()
geometry = modifier.current!.modify(geometry)

const tessellated = bufferGeometry.fromGeometry(geometry)
ref.current.geometry = tessellated
ref.current.geometry = geometry
}
}, [maxEdgeLength, passes])

8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
@@ -11888,10 +11888,10 @@ [email protected], text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=

three@0.123.0:
version "0.123.0"
resolved "https://registry.yarnpkg.com/three/-/three-0.123.0.tgz#3bb6d8f908a432eb7cd450f7eab6dd40fde53085"
integrity sha512-KNnx/IbilvoHRkxOtL0ouozoDoElyuvAXhFB21RK7F5IPWSmqyFelICK6x3hJerLNSlAdHxR0hkuvMMhH9pqXg==
three@0.125.0:
version "0.125.0"
resolved "https://registry.yarnpkg.com/three/-/three-0.125.0.tgz#19e922b9dc51ad0b706893aeee888de68e99850a"
integrity sha512-qL36qUGsPQ/Ofo/RZdXwHwM7A8wzUSAIyawtjIebJSPvounUQeneSqxI0aBY2iwKpseGy+RUtj3C5f/z4poyXw==

throat@^5.0.0:
version "5.0.0"

0 comments on commit 487cb5a

Please sign in to comment.