topical media & game development

talk show tell print

mobile-query-three-plugins-physics-examples-collisions.htm / htm



  <!doctype html><title>Minimal tQuery Page</title>
  <script src="../../../build/tquery-bundle.js"></script>
  
  <script src="../vendor/physijs/physi.js"></script>
  <script src="../tquery.physijs.js"></script>
  
  <script src='../../shadowmap/tquery.light.shadowmap.js'></script>
  
  <body style="margin:0;padding:0;overflow:'hidden';"><div id="info" style="z-index: 2">
          Examples of tQuery.physics: collisions event
          - based on <a href="https://github.com/chandlerprall/Physijs" target="_blank">physijs</a>
          <br/>
          <a href="../../../www/vendor/doccoviewer/#../../../plugins/physics/examples/collisions.html" target="_blank">Annotated Source</a>
  </div><script>
          // Physics is important in 3D.
          // It makes scenes more realistic.
          // You can put your object into the scene and it will move nicely.
          // So you spend less time tuning each moves. I am quite lazy
          // so it matters :)
          
          // ## What about physics engine ?
          //
          // We already did physics with three.js.
          // It was with [microphysics.js](github.com/jeromeetienne/microphysics.js) for [marblesoccer](http://marblesoccer.com) minigame.
          // It is a micro library implementing 3D physics, only 500lines!
          // We talked quite a bit about it in
          // ["Lets Make a 3D Game: microphysics.js"](http://learningthreejs.com/blog/2011/10/17/lets-make-a-3d-game-microphysics-js/)
  	// and
          // ["Lets Make a 3D Game: microphysics.js, Even Easier"](http://learningthreejs.com/blog/2011/11/02/lets-make-a-3d-game-helper-for-microphysics-js/).
  	// Unfortunatly with this tiny size comes limitations.
          
          // Today we gonna use [physijs](github.com/chandlerprall/Physijs) by [Chandler Prall](twitter.com/#!/chandlerprall).
          // This is a nice library which make it easy to use
          // [ammo.js](github.com/kripken/ammo.js/)
          // with
          // [three.js](http://mrdoob.github.com/three.js/).
  	// ammo.js is "Direct port of the Bullet physics engine to JavaScript using
          // [Emscripten](github.com/kripken/emscripten).
          // The source code is translated directly to JavaScript, without human rewriting, so functionality should be identical to the original Bullet."
          // [bullet](http://bulletphysics.org/) is a full-blown physics engine well-known in the 3D community. 
          // It can do a lot as you can see in its [docs](http://bulletphysics.com/Bullet/BulletFull/).
  	// [ammo.js](github.com/kripken/ammo.js/)
          // supports all the features you can expect from a mature 3D physics engine.
                  
          // [physijs](github.com/chandlerprall/Physijs) has been written with performance in mind.
          // [ammo.js](github.com/kripken/ammo.js/) is running in a
          // [webworker](developer.mozilla.org/En/Using_web_workers).
          // So it most likely run on a second CPU. This is twice more cpu power for your javascript!
          // Coordinates are exchanged with
          // [transferable objects](http://updates.html5rocks.com/2011/12/Transferable-Objects-Lightning-Fast)
  	// when available.
          // Transferable objects is a special type of object which can be transfered between the main thread and the worker **without copying**
          // the data. Thus no matter how large the data are, it will be very low latency.
  
          // ## Lets Get Started
          
          // The code of today is a copy of the
          // [collision example](http://chandlerprall.github.com/Physijs/examples/collisions.html)
  	// from
          // [physijs](http://chandlerprall.github.com/Physijs/). It may usefull to reimplement the
          // same thing, just to be sure they both perform the same way :) So we got object falling
          // on the ground and slightly bouncing on it. Let's do just that.
  
          // First a classic. We create a tQuery.World. So you immediatly got
          // a scene, a renderer, camera and its controls. All that already
          // setup according to reasonable default.
          // ```.boilerplate()``` adds
          // the ["three.js boilerplate"](http://learningthreejs.com/blog/2011/12/20/boilerplate-for-three-js/)
  	// we did last year. We disable the camera controls as it will stay still in this scene.
          // Then we ```.start()``` to launch the render loop. 
          var world        = tQuery.createWorld().boilerplate({cameraControls: false}).start();
  
          // Now we setup the camera to be a bit far from the scene center. Thus
          // we got room to display larger objects
          world.tCamera().position.set( 70, 40, 70 );
          world.tCamera().lookAt( world.tScene().position );
  
          // Now we need to tell the renderer that shadow has to be casted. This is done by the simple lines below.
          // We saw the details in ["Casting Shadows"](http://learningthreejs.com/blog/2012/01/20/casting-shadows/) post.
          world.tRenderer().shadowMapEnabled        = true;
          world.tRenderer().shadowMapSoft                = true;
          world.tRenderer().setClearColorHex( 0xffffff, 1 );
  
          // Now we enable the physics into the world.
          // this is important. From now on, all the physics-enabled object
          // of this world will move according to realistic physics rules.
          world.enablePhysics();
  
          // ## Enlight your world
  
          // Here we setup the lights. For simplicity sake, we will use only one directional light.
          // First we tune the position and color to fit our tastes. Dont be shy, play with those parameters to get a feel of it.
          // Then we tune shadow parameters.
          // Those can be tricky to tune.
          // You can find more details in ["Casting Shadow"](http://learningthreejs.com/blog/2012/01/20/casting-shadows/) post.
          // It helps if you make the shaddow camera visible. You can do so with ```.shadowCameraVisible(true)```.
          tQuery.createDirectionalLight().addTo(world)
                  .position(20, 40, -15).color(0xffffff)
                  .castShadow(true).shadowMap(512*2,512*2)
                  .shadowCamera(60, -60, 60, -60, 20, 200)
                  .shadowDarkness(0.7).shadowBias(.002)
  
          // ## Let's create a ground to stand on
          
          // First we create the texture for our ground. We use ```rocks.jpg``` to have like a rock
          // effect. We use ```.RepeatWrapping``` to repeat the texture on the faces and get a
          // proper scale.
          var texture        = THREE.ImageUtils.loadTexture( "images/rocks.jpg" );
          texture.wrapS        = texture.wrapT = THREE.RepeatWrapping;
          texture.repeat.set( 3, 3 );
          
          
          // In fact, the ground is only a cube which is wide and flat, a bit like
          // the [old-vision of earth](http://en.wikipedia.org/wiki/Flat_Earth) :)
          // It is usual now, we setup the position, material and shadow.
          var ground        = tQuery.createCube(100, 1, 100).addTo(world)
                  .position(0, -10, 0)
                  .setLambertMaterial().map(texture).back()
                  .receiveShadow(true)
          // Now we just have to setup the physics for the ground. This is done
          // by ```.enablePhysics()```. The ```mass``` parameter define the mass
          // of the object in the physics. Here zeroing the mass is a special case, which say
          // "the mass is infinite, dont move, ever" :)
          ground.enablePhysics({
                  mass        : 0
          });
  
          // ## Spawning object in a 3D world        
  
          // Spawning is always a delicate matter in our world.
          
          // But first let's load the texture for the spawned objects.
          // It is done outside of the loop thus it get reused. Aka it is sent
          // only once to the GPU for all the objects. This is an important
          // point from performance point of view. Last year,
          // ["Performance: Caching Material"](http://learningthreejs.com/blog/2011/09/16/performance-caching-material/)
  	// post was about this very topic.        
          var cTexture        = THREE.ImageUtils.loadTexture( "images/plywood.jpg" );
  
          // Now we declare ```spawnObject()``` which gonna take care of spawning one object.
          // So we create a cube, setup its position, rotation and material. This is all good. Oh dont
          // forget to use ```.castShadow()``` as got [shadow mapping](http://en.wikipedia.org/wiki/Shadow_mapping) going on :)
          var spawnObject        = function(){
                  var object	= tQuery.createCube(4,4,4).addTo(world)
                          .rotation(Math.random()*Math.PI*2, Math.random()*Math.PI*2, Math.random()*Math.PI*2)
                          .position(Math.random()*15-7.5, 25, Math.random()*15-7.5)
                          .setLambertMaterial().map(cTexture).back()
                          .castShadow(true)
                  // Here we enable the physics on this object. So the world will handle all its move from now on.
                  // It will object to physics laws according to the parameters you setup.
                  // [friction](http://en.wikipedia.org/wiki/Friction) is the force resisting when 2 objects slides against each other.
                  // [resititution](http://en.wikipedia.org/wiki/Coefficient_of_restitution) is how bouncy the object is.
                  // For scientific definition, go read a book :)
                  object.enablePhysics({
                          friction        : 0.4,
                          restitution        : 0.6
                  });
                  
                  // Now we gonna play with the 'collision' event. Physijs is able to notify
                  // you when an object collide with another. Just use ```.addEventListener()``` on 'collision'.
                  // Here we gonna change the color of the object depending on the number of collisions
                  // they got.                
                  var nCollisions        = 0;
                  object.physics().addEventListener('collision', function(){
                          var colliColors        = [0xcc8855, 0xbb9955, 0xaaaa55, 0x99bb55, 0x88cc55, 0x77dd55];
                          if( ++nCollisions < colliColors.length ){
                                  var color        = colliColors[nCollisions];
                                  object.get(0).material.color.setHex( color );
                          }
                  })
          }
          // Now we simply use [```setInterval()```](developer.mozilla.org/en/DOM/window.setInterval) to
          // spawn an object every seconds.
          setInterval(spawnObject, 1000);
          
          // And we are DONE! We got a realistic physics in our 3D world! not bad hey :)
  </script></body>


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.