Skip to content

Commit

Permalink
fix: remove prototype.function.call because it doesn't work in classes
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuaellis committed Mar 19, 2021
1 parent 1d08c90 commit 932021a
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 11 deletions.
55 changes: 55 additions & 0 deletions .storybook/stories/Line.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { Color, AmbientLight, DirectionalLight, PointLight, SpotLight, Vector3 } from 'three'
import { useEffect } from '@storybook/client-api'

import { useThree } from '../setup'

//@ts-ignore
import { hilbert3D, Line2, LineMaterial, LineGeometry } from '../../src'

export default {
title: 'Geometry/Line',
}

export const Default = () => {
// must run in this so the canvas has mounted in the iframe & can be accessed by `three`
useEffect(() => {
console.log('calling effect')
const points = hilbert3D(new Vector3(0), 5).map((p: Vector3) => [p.x, p.y, p.z]) as [number, number, number][]

const lineGeometry = new LineGeometry()
const pValues = points.map((p) => (p instanceof Vector3 ? p.toArray() : p))
lineGeometry.setPositions(pValues.flat())

const line2 = new Line2(
lineGeometry,
new LineMaterial({
color: 'red',
lineWidth: 3,
}),
)
line2.computeLineDistances()

const ambientLight = new AmbientLight('white', 0.2)
const directionalLight = new DirectionalLight('pink', 2)
directionalLight.position.set(0, -5, 0)
const pointLight1 = new PointLight('pink', 0.4)
pointLight1.position.set(-10, -10, 10)
const pointLight2 = new PointLight('white', 0.2)
pointLight2.position.set(-10, -10, 10)
const spotLight = new SpotLight('white', 2, 35, Math.PI / 4, 2, 3.5)
spotLight.position.set(-3, 6, -4)

const { renderer, scene } = useThree({
// useFrame: (_, delta) => {},
})

scene.background = new Color(0x000000).convertSRGBToLinear()
scene.add(ambientLight, directionalLight, pointLight1, pointLight2, spotLight, line2)

return () => {
renderer.dispose()
}
}, [])

return ''
}
69 changes: 69 additions & 0 deletions demos/ssr/components/Line.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import * as React from 'react'
import { Vector2, Vector3, Color } from 'three'
import { ReactThreeFiber } from 'react-three-fiber'
//@ts-ignore
import { LineGeometry, LineMaterial, LineMaterialParameters, Line2 } from 'three-stdlib'

export type LineProps = {
points: Array<Vector3 | [number, number, number]>
color?: Color | string | number
vertexColors?: Array<Color | [number, number, number]>
lineWidth?: number
} & Omit<ReactThreeFiber.Object3DNode<Line2, typeof Line2>, 'args'> &
Omit<
ReactThreeFiber.Object3DNode<LineMaterial, [LineMaterialParameters]>,
'color' | 'vertexColors' | 'resolution' | 'args'
>

export const Line = React.forwardRef<Line2, LineProps>(function Line(
{ points, color = 'black', vertexColors, lineWidth, dashed, ...rest },
ref,
) {
const [line2] = React.useState(() => new Line2())
const [lineMaterial] = React.useState(() => new LineMaterial())
const [resolution] = React.useState(() => new Vector2(512, 512))

const lineGeom = React.useMemo(() => {
const geom = new LineGeometry()
const pValues = points.map((p) => (p instanceof Vector3 ? p.toArray() : p))
geom.setPositions(pValues.flat())

if (vertexColors) {
const cValues = vertexColors.map((c) => (c instanceof Color ? c.toArray() : c))
geom.setColors(cValues.flat())
}

return geom
}, [points, vertexColors])

React.useLayoutEffect(() => {
line2.computeLineDistances()
}, [points, line2])

React.useLayoutEffect(() => {
if (dashed) {
lineMaterial.defines.USE_DASH = ''
} else {
// Setting lineMaterial.defines.USE_DASH to undefined is apparently not sufficient.
delete lineMaterial.defines.USE_DASH
}
lineMaterial.needsUpdate = true
}, [dashed, lineMaterial])

return (
<primitive dispose={undefined} object={line2} ref={ref} {...rest}>
<primitive dispose={undefined} object={lineGeom} attach="geometry" />
<primitive
dispose={undefined}
object={lineMaterial}
attach="material"
color={color}
vertexColors={Boolean(vertexColors)}
resolution={resolution}
linewidth={lineWidth}
dashed={dashed}
{...rest}
/>
</primitive>
)
})
15 changes: 15 additions & 0 deletions demos/ssr/pages/lines.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Canvas } from 'react-three-fiber'
import styled from 'styled-components'

export default function LinesPage(): JSX.Element {
return (
<Root>
<Canvas></Canvas>
</Root>
)
}

const Root = styled.main`
width: 100vw;
height: 100vh;
`
78 changes: 72 additions & 6 deletions src/controls/TransformControls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class TransformControls extends Object3D {
return this
}

public updateMatrixWorld = () => {
public updateMatrixWorld = (force: boolean): void => {
if (this._object !== undefined) {
this._object.updateMatrixWorld()

Expand All @@ -224,7 +224,29 @@ class TransformControls extends Object3D {

this._eye.copy(this._cameraPosition).sub(this._worldPosition).normalize()

Object3D.prototype.updateMatrixWorld.call(this)
if (this.matrixAutoUpdate) {
this.updateMatrix()
}

if (this.matrixWorldNeedsUpdate || force) {
if (this.parent === null) {
this.matrixWorld.copy(this.matrix)
} else {
this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix)
}

this.matrixWorldNeedsUpdate = false

force = true
}

// update children

const children = this.children

for (let i = 0, l = children.length; i < l; i++) {
children[i].updateMatrixWorld(force)
}
}

private pointerHover = (pointer: TransformControlsPointerObject) => {
Expand Down Expand Up @@ -986,7 +1008,7 @@ class TransformControlsGizmo extends Object3D {
}

// updateMatrixWorld will update transformations and appearance of individual handles
public updateMatrixWorld = () => {
public updateMatrixWorld = (force: boolean): void => {
let space = this._space

if (this._mode === 'scale') space = 'local' // scale always oriented to local rotation
Expand Down Expand Up @@ -1274,7 +1296,29 @@ class TransformControlsGizmo extends Object3D {
}
}

Object3D.prototype.updateMatrixWorld.call(this)
if (this.matrixAutoUpdate) {
this.updateMatrix()
}

if (this.matrixWorldNeedsUpdate || force) {
if (this.parent === null) {
this.matrixWorld.copy(this.matrix)
} else {
this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix)
}

this.matrixWorldNeedsUpdate = false

force = true
}

// update children

const children = this.children

for (let i = 0, l = children.length; i < l; i++) {
children[i].updateMatrixWorld(force)
}
}
}

Expand Down Expand Up @@ -1318,7 +1362,7 @@ class TransformControlsPlane extends Mesh<PlaneGeometry, MeshBasicMaterial> {
private _mode: 'translate' | 'rotate' | 'scale' = 'translate'
private _space = 'world'

updateMatrixWorld = () => {
public updateMatrixWorld = (force: boolean): void => {
let space = this._space

this.position.copy(this._worldPosition)
Expand Down Expand Up @@ -1381,7 +1425,29 @@ class TransformControlsPlane extends Mesh<PlaneGeometry, MeshBasicMaterial> {
this.quaternion.setFromRotationMatrix(this.tempMatrix)
}

Object3D.prototype.updateMatrixWorld.call(this)
if (this.matrixAutoUpdate) {
this.updateMatrix()
}

if (this.matrixWorldNeedsUpdate || force) {
if (this.parent === null) {
this.matrixWorld.copy(this.matrix)
} else {
this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix)
}

this.matrixWorldNeedsUpdate = false

force = true
}

// update children

const children = this.children

for (let i = 0, l = children.length; i < l; i++) {
children[i].updateMatrixWorld(force)
}
}
}

Expand Down
28 changes: 25 additions & 3 deletions src/lines/LineGeometry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Line } from 'three'
import { Line, InstancedInterleavedBuffer, InterleavedBufferAttribute } from 'three'
import { LineSegmentsGeometry } from './LineSegmentsGeometry'

class LineGeometry extends LineSegmentsGeometry {
Expand All @@ -25,7 +25,26 @@ class LineGeometry extends LineSegmentsGeometry {
points[2 * i + 5] = array[i + 5]
}

LineSegmentsGeometry.prototype.setPositions.call(this, points)
let lineSegments

if (array instanceof Float32Array) {
lineSegments = array
} else if (Array.isArray(array)) {
lineSegments = new Float32Array(array)
} else {
console.error('LineSegmentsGeometry.setPosition requires either a Float32Array or regular array of numbers')
return this
}

const instanceBuffer = new InstancedInterleavedBuffer(lineSegments, 6, 1) // xyz, xyz

this.setAttribute('instanceStart', new InterleavedBufferAttribute(instanceBuffer, 3, 0)) // xyz
this.setAttribute('instanceEnd', new InterleavedBufferAttribute(instanceBuffer, 3, 3)) // xyz

//

this.computeBoundingBox()
this.computeBoundingSphere()

return this
}
Expand All @@ -46,7 +65,10 @@ class LineGeometry extends LineSegmentsGeometry {
colors[2 * i + 5] = array[i + 5]
}

LineSegmentsGeometry.prototype.setColors.call(this, colors)
const instanceColorBuffer = new InstancedInterleavedBuffer(colors, 6, 1) // rgb, rgb

this.setAttribute('instanceColorStart', new InterleavedBufferAttribute(instanceColorBuffer, 3, 0)) // rgb
this.setAttribute('instanceColorEnd', new InterleavedBufferAttribute(instanceColorBuffer, 3, 3)) // rgb

return this
}
Expand Down
4 changes: 2 additions & 2 deletions src/lines/LineMaterial.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ class LineMaterial extends ShaderMaterial {

this.dashed = false

this.setValues(parameters)

Object.defineProperties(this, {
color: {
enumerable: true,
Expand Down Expand Up @@ -333,8 +335,6 @@ class LineMaterial extends ShaderMaterial {
enumerable: true,
},
})

this.setValues(parameters)
}
}

Expand Down

0 comments on commit 932021a

Please sign in to comment.