-
Notifications
You must be signed in to change notification settings - Fork 30
/
ThreeScene.jsx
118 lines (105 loc) · 3.21 KB
/
ThreeScene.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import React, { Component } from 'react'
import * as THREE from 'three'
import * as _ from 'lodash'
import TrackballControls from './TrackballControls'
import { getTruncated } from 'math/operations'
function toTriangles(polygon) {
const [p0, ...ps] = polygon
return _(ps)
.initial()
.map((pn, i) => [p0, pn, ps[i + 1]])
.value()
}
function getGeometry(solid) {
const truncated = getTruncated(solid, 0)
solid = getTruncated(solid, 1)
console.log(truncated, solid)
const geometry = new THREE.Geometry()
solid.vertices.forEach(vertex =>
geometry.vertices.push(new THREE.Vector3(...vertex)),
)
_.flatten(solid.faces.map(toTriangles)).forEach(face =>
geometry.faces.push(new THREE.Face3(...face)),
)
geometry.computeVertexNormals()
console.log('solid vertices', solid.vertices)
console.log('geometry vertices', geometry.vertices)
console.log(
'truncated vertices',
truncated.vertices.map(vertex => new THREE.Vector3(...vertex)),
)
geometry.morphTargets.push({
name: 'truncated',
vertices: truncated.vertices.map(vertex => new THREE.Vector3(...vertex)),
})
return geometry
}
// https://github.com/mrdoob/three.js/blob/master/examples/webgl_interactive_draggablecubes.html
export default class ThreeScene extends Component {
componentDidMount() {
this.init()
this.animate()
}
render() {
return <div ref={container => (this.container = container)} />
}
componentWillReceiveProps(nextProps) {
if (this.props.solid === nextProps.solid) {
return
}
const { solid } = nextProps
this.object.geometry = getGeometry(solid)
}
init = () => {
const { solid } = this.props
const camera = (this.camera = new THREE.PerspectiveCamera(
70,
window.innerWidth / window.innerHeight,
1,
1000,
))
camera.position.z = 5
const scene = (this.scene = new THREE.Scene())
scene.background = new THREE.Color(0xf0f0f0)
const object = (this.object = new THREE.Mesh(
getGeometry(solid),
new THREE.MeshLambertMaterial({
color: Math.random() * 0xffffff,
morphTargets: true,
}),
))
scene.add(object)
const controls = (this.controls = new TrackballControls(camera))
controls.rotateSpeed = 4.0
controls.zoomSpeed = 1.2
controls.panSpeed = 0.8
controls.noZoom = false
controls.noPan = false
controls.staticMoving = true
controls.dynamicDampingFactor = 0.3
var light = new THREE.DirectionalLight(0xffffff, 1)
light.position.set(1, 1, 1).normalize()
camera.add(light)
scene.add(camera)
const renderer = (this.renderer = new THREE.WebGLRenderer({
antialias: true,
}))
renderer.setPixelRatio(window.devicePixelRatio)
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
renderer.shadowMap.type = THREE.PCFShadowMap
this.container.appendChild(renderer.domElement)
}
animate = () => {
requestAnimationFrame(this.animate)
this.doRender()
// stats.update()
}
doRender = () => {
this.controls.update()
if (this.object.morphTargetInfluences[0] < 1.0) {
this.object.morphTargetInfluences[0] += 0.01
}
this.renderer.render(this.scene, this.camera)
}
}