UNPKG

threex

Version:

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

220 lines (185 loc) 7.9 kB
<!DOCTYPE html> <script src='../../../vendor/three.js/build/three.js'></script> <script src='../threex.flockingcontrols.js'></script> <!-- include for threex.glowdatgui --> <script src='../threex.flockingcontrolsdatgui.js'></script> <script src='../../../vendor/three.js/examples/js/libs/dat.gui.min.js'></script> <body style='margin: 0px; background-color: #000000; 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 = 20; // camera.position.z = 2; ////////////////////////////////////////////////////////////////////////////////// // 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 ) })() // var arrow = new THREE.ArrowHelper(new THREE.Vector3(1,0,0), new THREE.Vector3, 1, 'blue') // scene.add(arrow) // window.arrow = arrow ////////////////////////////////////////////////////////////////////////////////// // 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.1); var geometry = new THREE.CylinderGeometry(0, 0.1, 0.5) // var geometry = new THREE.CylinderGeometry(0, 0.1, 0.25) geometry.applyMatrix( new THREE.Matrix4().makeRotationX( Math.PI/2 ) ); // geometry.applyMatrix( new THREE.Matrix4().makeTranslation( 0,0, -0.5 ) ); var material = new THREE.MeshNormalMaterial(); var baseObject3d= new THREE.Mesh( geometry, material ); var mapWidth = 20 var mapHeight = 20 var mapDepth = 0 var bodiesControls = [] var nBodies = 400 // var nBodies = 3 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)*mapWidth object3d.position.y = (Math.random()-0.5)*mapHeight object3d.position.z = (Math.random()-0.5)*mapDepth // init controls for body if( i === 0 ) var controls = new THREEx.FlockingControls(object3d, undefined, true) else var controls = new THREEx.FlockingControls(object3d) // make sure all controls are on the same ```.opts``` object, it helps dat.gui tunning if( i !== 0 ) controls.opts = bodiesControls[0].opts // attach debug if needed if( controls.debug ) scene.add( controls.debugObject3d ) // centralize all controls in bodiesControls bodiesControls.push(controls) // init initial velocity controls.velocity.x = (Math.random()-0.5)*2 controls.velocity.y = (Math.random()-0.5)*2 controls.velocity.z = (Math.random()-0.5)*2 controls.velocity.z = (Math.random()-0.5)*0 // make object3d look at the velocity onRenderFcts.push(function(){ object3d.lookAt(object3d.position.clone().add(controls.velocity)) }) object3d.userData.controls = controls })() } ////////////////////////////////////////////////////////////////////////////////// // dat.gui tuning // ////////////////////////////////////////////////////////////////////////////////// ;(function(){ var datGui = new dat.GUI({ autoPlace: false }) document.body.appendChild(datGui.domElement) datGui.domElement.style.position = 'absolute' datGui.domElement.style.top = '0px' var controls = bodiesControls[0] new THREEx.addFlockingControls2DatGui(controls, datGui) ////////////////////////////////////////////////////////////////////////////////// // actions // ////////////////////////////////////////////////////////////////////////////////// var actions = { reset : function(){ bodiesControls.forEach(function(controls){ var object3d = controls.object3d // set body position object3d.position.x = (Math.random()-0.5)*mapWidth object3d.position.y = (Math.random()-0.5)*mapHeight object3d.position.z = (Math.random()-0.5)*mapDepth // init initial velocity controls.velocity.x = (Math.random()-0.5)*2 controls.velocity.y = (Math.random()-0.5)*2 controls.velocity.z = (Math.random()-0.5)*2 controls.velocity.z = (Math.random()-0.5)*0 }) } } var folder = datGui.addFolder('Actions'); folder.add(actions, 'reset') folder.open() })() ////////////////////////////////////////////////////////////////////////////////// // apply physics // ////////////////////////////////////////////////////////////////////////////////// setInterval(function(){ bodiesControls.forEach(function(controls, controlsIdx){ controls.computeForces(bodiesControls, controlsIdx) }) bodiesControls.forEach(function(controls){ controls.applyForces() }) // clamp all boids within a cube bodiesControls.forEach(function(controls){ var position = controls.position if( position.x < mapWidth /2 ) position.x += mapWidth if( position.x > mapWidth /2 ) position.x -= mapWidth if( position.y < mapHeight/2 ) position.y += mapHeight if( position.y > mapHeight/2 ) position.y -= mapHeight if( position.z < mapDepth /2 ) position.z += mapDepth if( position.z > mapDepth /2 ) position.z -= mapDepth }) }, 1000/60) ////////////////////////////////////////////////////////////////////////////////// // 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>