Skip to content

Instantly share code, notes, and snippets.

@agm1984
Last active April 6, 2018 03:30
Show Gist options
  • Save agm1984/1fa1368631293fc694522aa1e50aaea7 to your computer and use it in GitHub Desktop.
Save agm1984/1fa1368631293fc694522aa1e50aaea7 to your computer and use it in GitHub Desktop.
Some THREE.js experiementation
import React, { Component } from 'react'
import * as THREE from 'three'
// import * as OBJLoader from 'three-obj-loader'
// import MTLLoader from 'three-react-mtl-loader'
// import OBJLoader from 'three-react-obj-loader'
// const loader = require('three-json-loader')(THREE)
const OrbitControls = require('three-orbit-controls')(THREE)
// OrbitControls: for Camera
// - This file should contain all the basic ingredients and how they fit together
// based on about 100 hours research.
// - This file's utility will magnify as you gain experience.
class Scene extends Component {
constructor(props) {
super(props)
this.state = {}
this.cat = {
rotation: {
x: 0,
y: 0,
z: 0,
},
}
this.adamAction = {}
this.isLoaded = false
this.clock = null
this.delta = 0
this.adamAction = {}
this.adamMixer = null
this.from = null
this.to = null
this.activeActionName = 'idle'
this.arrAnimations = ['idle', 'walk', 'run', 'hello']
this.currentAnimation = 0
this.mount = null
this.handleDoubleClick = this.handleDoubleClick.bind(this)
this.start = this.start.bind(this)
this.stop = this.stop.bind(this)
this.animate = this.animate.bind(this)
}
componentDidMount() {
// SETUP
this.clock = new THREE.Clock()
this.width = this.mount.clientWidth
this.height = this.mount.clientHeight
this.windowHalfX = this.mount.clientWidth / 2
this.windowHalfY = this.mount.clientHeight / 2
// CAMERA
this.camera = new THREE.PerspectiveCamera(85, this.width / this.height, 1, 4000)
// this.camera.up = new THREE.Vector3(0, 0, 1)
// this.camera.lookAt(new THREE.Vector3(0, 0, 10))
this.camera.position.x = 5
this.camera.position.y = 5
this.camera.position.z = 5
this.camera.position.set(0, 0, -10)
// this.controls = new THREE.FirstPersonControls(this.camera, this.mount)
// this.controls.movementSpeed = 50
// this.controls.lookSpeed = 0.05
// this.controls.noFly = true
// this.controls.lookVertical = false
// SCENE
this.scene = new THREE.Scene()
this.ambient = new THREE.AmbientLight(0xffffff, 1.0)
this.scene.add(this.ambient)
// LIGHTS
// this.keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 100%, 75%)'), 1.0)
// this.keyLight.position.set(-100, 0, 100)
// this.fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 100%, 75%)'), 0.75)
// this.fillLight.position.set(100, 0, 100)
// this.backLight = new THREE.DirectionalLight(0xffffff, 1.0)
// this.backLight.position.set(100, 0, -100).normalize()
// this.scene.add(this.keyLight)
// this.scene.add(this.fillLight)
// this.scene.add(this.backLight)
// // FEMALE MODEL
// this.mtlLoader = new MTLLoader()
// this.mtlLoader.setBaseUrl('')
// this.mtlLoader.setPath('female3d/')
// this.mtlLoader.load('female-croupier-2013-03-26.mtl', (materials) => {
// materials.preload() /* eslint-disable no-param-reassign */
// materials.materials.default.map.magFilter = THREE.NearestFilter
// materials.materials.default.map.minFilter = THREE.LinearFilter
// this.objLoader = new OBJLoader() /* eslint-enable no-param-reassign */
// this.objLoader.setMaterials(materials)
// this.objLoader.setPath('guy/')
// this.objLoader.load('female-croupier-2013-03-26.obj', (object) => {
// this.scene.add(object)
// })
// })
// ADAM MODEL
this.adamLoader = new THREE.JSONLoader()
this.adamLoader.load('anime.json', (geometry, materials) => {
materials.forEach((material) => {
material.skinning = true // eslint-disable-line no-param-reassign
})
this.adamCharacter = new THREE.SkinnedMesh(
geometry,
new THREE.MeshFaceMaterial(materials),
)
this.adamMixer = new THREE.AnimationMixer(this.adamCharacter)
this.adamAction.hello = this.adamMixer.clipAction(geometry.animations[0])
this.adamAction.idle = this.adamMixer.clipAction(geometry.animations[1])
this.adamAction.run = this.adamMixer.clipAction(geometry.animations[3])
this.adamAction.walk = this.adamMixer.clipAction(geometry.animations[4])
this.adamAction.hello.setEffectiveWeight(1)
this.adamAction.idle.setEffectiveWeight(1)
this.adamAction.run.setEffectiveWeight(1)
this.adamAction.walk.setEffectiveWeight(1)
this.adamAction.hello.setLoop(THREE.LoopOnce, 0)
this.adamAction.hello.clampWhenFinished = true
this.adamAction.hello.enabled = true
this.adamAction.idle.enabled = true
this.adamAction.run.enabled = true
this.adamAction.walk.enabled = true
this.scene.add(this.adamCharacter)
// window.addEventListener('resize', onWindowResize, false)
// window.addEventListener('click', onDoubleClick, false)
console.log('Double click to change animation')
this.animate()
this.isLoaded = true
this.adamAction.idle.play()
})
// CAT MODEL
this.catMaterial = new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture('newCat.png'),
side: THREE.DoubleSide,
})
this.catLoader = new THREE.JSONLoader()
this.catLoader.load('newCat.json', (geometry) => {
this.cat = new THREE.Mesh(geometry, this.catMaterial)
this.cat.position.x = 2
this.cat.position.y = 0
this.cat.position.z = -1
// this.cat.dir = (Math.random() - Math.random()) * 0.1
this.scene.add(this.cat)
})
// // GUY MODEL
// this.guyMaterial = new THREE.MeshBasicMaterial({
// map: THREE.ImageUtils.loadTexture('guy/Malcom_Body_Diffuse.png'),
// side: THREE.DoubleSide,
// })
// this.guyLoader = new THREE.JSONLoader() //
// this.guyLoader.load('guy/walking-animation.json', (geometry) => {
// this.guy = new THREE.Mesh(geometry, this.guyMaterial)
// this.guy.position.x = 0
// this.guy.position.y = 0
// this.guy.position.z = -2
// // this.guy.dir = (Math.random() - Math.random()) * 0.1
// this.scene.add(this.guy)
// })
// RENDER
this.renderer = new THREE.WebGLRenderer()
this.renderer.setPixelRatio(window.devicePixelRatio)
this.renderer.setSize(this.width, this.height)
this.renderer.setClearColor(new THREE.Color('hsl(0, 0%, 10%)'))
this.mount.appendChild(this.renderer.domElement)
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
this.controls.center.set(0, 0, 0)
this.controls.addEventListener('change', this.renderScene)
// // TERRAIN
// const geometry = new THREE.PlaneGeometry(600, 600, 30, 30)
// const { length } = geometry.vertices
// for (let index = 0; index < length; index += 1) {
// geometry.vertices[index].z = Math.floor((Math.random() * 10) + 1)
// }
// const material = new THREE.MeshBasicMaterial({
// wireframe: true,
// color: '#66FCF1',
// })
// this.terrain = new THREE.Mesh(geometry, material)
// this.terrain.overdraw = true
// this.terrain.rotation.x = 90
// this.terrain.rotation.y = 0
// this.terrain.rotation.z = 0
// this.terrain.position.x = 0
// this.terrain.position.y = 2
// this.terrain.position.z = 0
// this.scene.add(this.terrain)
window.scene = this.scene
window.THREE = THREE
this.start()
}
componentWillUnmount() {
this.stop()
this.mount.removeChild(this.renderer.domElement)
}
handleDoubleClick() {
this.currentAnimation += 1
this.fadeAction(this.arrAnimations[this.currentAnimation])
}
fadeAction(name) {
this.from = this.adamAction[this.activeActionName].play()
this.to = this.adamAction[name].play()
this.from.enabled = true
this.to.enabled = true
if (this.to.loop === THREE.LoopOnce) {
this.to.reset()
}
this.from.crossFadeTo(this.to, 0.3)
this.activeActionName = name
}
start() {
if (!this.frameId) {
this.frameId = requestAnimationFrame(this.animate)
}
}
stop() {
cancelAnimationFrame(this.frameId)
}
animate = () => {
// this.cat = this.cat || {}
// this.cat.position.x += 0.01
// this.cat.rotation.y += 0.01
// this.cat.rotation.z += 0.01
// this.camera.position.z += 0.01
this.frameId = window.requestAnimationFrame(this.animate)
this.controls.update()
this.renderScene()
}
renderScene = () => {
if (!this.adamMixer) {
return
}
this.delta = this.clock.getDelta()
this.adamMixer.update(this.delta)
this.renderer.render(this.scene, this.camera)
}
render() {
return (
<div
style={{
overflow: 'hidden',
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100vh',
}}
ref={(mount) => { this.mount = mount }}
onDoubleClick={this.handleDoubleClick}
/>
)
}
}
export default Scene
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment