threex
Version:
Game Extensions for three.js http://www.threejsgames.com/extensions/
227 lines (193 loc) • 7.85 kB
HTML
<!DOCTYPE html>
<script src='../../../vendor/three.js/build/three.min.js'></script>
<script src='../threex.magnetcontrols.js'></script>
<body style='margin: 0px; background-color: #bbbbbb; overflow: hidden;'><script>
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var onRenderFcts= [];
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 1000);
camera.position.z = 25;
//////////////////////////////////////////////////////////////////////////////////
// set 3 point lighting //
//////////////////////////////////////////////////////////////////////////////////
;(function(){
// add a ambient light
var light = new THREE.AmbientLight( 0x020202 )
scene.add( light )
// add a light in front
var light = new THREE.DirectionalLight('white', 1)
light.position.set(0.5, 0.5, 2)
scene.add( light )
// add a light behind
var light = new THREE.DirectionalLight('white', 0.75)
light.position.set(-0.5, -0.5, -2)
scene.add( light )
})()
//////////////////////////////////////////////////////////////////////////////////
// handle window resize //
//////////////////////////////////////////////////////////////////////////////////
// handle resize events
window.addEventListener( 'resize', function() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}, false);
//////////////////////////////////////////////////////////////////////////////////
// add an object and make it move //
//////////////////////////////////////////////////////////////////////////////////
var geometry = new THREE.CubeGeometry(1,1,1);
var geometry = new THREE.SphereGeometry(0.5);
var material = new THREE.MeshNormalMaterial();
var baseObject3d= new THREE.Mesh( geometry, material );
var bodiesControls = []
var nBodies = 200
for(var i = 0; i < nBodies; i++){
;(function(){
// create the body
var object3d = baseObject3d.clone()
object3d.material = new THREE.MeshPhongMaterial({
color : 'cyan'
});
scene.add( object3d );
// set body position
object3d.position.x = (Math.random()-0.5)*4
object3d.position.y = (Math.random()-0.5)*4
// init controls for body
var controls = new THREEx.MagnetControls(object3d)
// centralize all controls in bodiesControls
bodiesControls.push(controls)
object3d.userData.controls = controls
})()
}
setInterval(function(){
bodiesControls.forEach(function(controls, controlsIdx){
controls.computeForces(bodiesControls, controlsIdx)
})
bodiesControls.forEach(function(controls){
controls.applyForces()
})
}, 1000/60)
//////////////////////////////////////////////////////////////////////////////////
// keep mouse coordinates //
//////////////////////////////////////////////////////////////////////////////////
var mouse = new THREE.Vector3()
document.body.addEventListener('mousemove', function( event ){
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight) * 2 + 1;
})
//////////////////////////////////////////////////////////////////////////////////
// handle the drag force //
//////////////////////////////////////////////////////////////////////////////////
var draggingState = false
var draggedObject = null
function draggingStart(object3d){
console.assert(draggingState === false)
draggingState = true
draggedObject = object3d
}
function draggingStop(){
console.assert(draggingState === true)
draggingState = false
draggedObject = null
}
onRenderFcts.push(function(delta, now){
// if not draggingState, do nothing
if( !draggingState ) return
// set some variables
var object3d = draggedObject
var position = object3d.position
var controls = object3d.userData.controls
// compute screen position
var screenPos = projector.projectVector(position.clone(), camera );
screenPos.z = 0
// compute the force based on mouse screen position, and the object screen position
// - thus the strength of the force
var force = mouse.clone().sub(screenPos).multiplyScalar(0.5)
// add it in acceleration
controls.acceleration.add(force)
// add it to the position directly
// controls.object3d.position.add(force)
})
//////////////////////////////////////////////////////////////////////////////////
// object selector //
//////////////////////////////////////////////////////////////////////////////////
var projector = new THREE.Projector()
var raycaster = new THREE.Raycaster()
var intersected = null
document.addEventListener('mouseup', function(){
// if draggingState, and mouseup, stop dragging
if( draggingState ) draggingStop()
// reset the color of the intersected
if( intersected ){
intersected.material.color.setHex( intersected.backupColor );
intersected = null;
}
}, false)
document.addEventListener('mousedown', function(){
// TODO strange conflict with the camera controls. not sure why
// - maybe moving the camera make it fails ?
// - to experience more
// setup projector and raycaster
var vector = new THREE.Vector3(mouse.x, mouse.y, 1);
projector.unprojectVector( vector, camera );
raycaster.set( camera.position, vector.sub( camera.position ).normalize() );
// compute intersection with all scene.children
var intersects = raycaster.intersectObjects( scene.children );
// if there is no intersection, return now
if( intersects.length === 0 ) return
// if the intersection is on the same object, return now
if( intersected === intersects[ 0 ].object ) return
// if not yet draggin, do it now
if( !draggingState ){
draggingStart(intersects[ 0 ].object)
}
//
if( intersected ){
intersected.material.color.setHex( intersected.backupColor );
}
// set intersected
intersected = intersects[ 0 ].object;
// backup current color
intersected.backupColor = intersected.material.color.getHex();
// change the color to mark it as intersected
intersected.material.color.setHex( 0xff0000 );
})
//////////////////////////////////////////////////////////////////////////////////
// Camera Controls //
//////////////////////////////////////////////////////////////////////////////////
// var mouse = {x : 0, y : 0}
// document.addEventListener('mousemove', function(event){
// mouse.x = (event.clientX / window.innerWidth ) - 0.5
// mouse.y = (event.clientY / window.innerHeight) - 0.5
// }, false)
// onRenderFcts.push(function(delta, now){
// camera.position.x += (mouse.x*5 - camera.position.x) * (delta*3)
// camera.position.y += (mouse.y*5 - camera.position.y) * (delta*3)
// camera.lookAt( scene.position )
// })
//////////////////////////////////////////////////////////////////////////////////
// render the scene //
//////////////////////////////////////////////////////////////////////////////////
onRenderFcts.push(function(){
renderer.render( scene, camera );
})
//////////////////////////////////////////////////////////////////////////////////
// loop runner //
//////////////////////////////////////////////////////////////////////////////////
var lastTimeMsec= null
requestAnimationFrame(function animate(nowMsec){
// keep looping
requestAnimationFrame( animate );
// measure time
lastTimeMsec = lastTimeMsec || nowMsec-1000/60
var deltaMsec = Math.min(200, nowMsec - lastTimeMsec)
lastTimeMsec = nowMsec
// call each update function
onRenderFcts.forEach(function(onRenderFct){
onRenderFct(deltaMsec/1000, nowMsec/1000)
})
})
</script></body>