UNPKG

threex

Version:

Game Extensions for three.js http://www.threejsgames.com/extensions/

227 lines (193 loc) 7.85 kB
<!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>