topical media & game development

talk show tell print

mobile-query-three-plugins-ogsworkshop-slides-index.htm / htm



  <!DOCTYPE html>
  <html>
  <head>
          <title>Three.js workshop</title>
          <base target=”_blank” />
          <meta charset='utf-8'/>
          <script src="vendor/jquery-1.7.2.min.js"></script>
          <script src='slides.js'></script>
  </head>
  
  <body style='display: none'> 
          <style>
                  article[data-markdown] em {
                          color                : orange;
                          font-style        : normal;
                          font-weight        : bolder;
                          
                  }
                  article[data-markdown] h3 {
                          font-size        : 180%;
                  }
                  span.orange {
                          color                : orange;
                  }
                  span.larger {
                          font-weight        : bolder;
                          font-size        : 120%;
                  }
          </style>
          <section class='slides layout-regular template-default'>
  
  <!-- *****************************************************************************
                  STAGE 0
  ****************************************************************************** -->
          <article data-markdown>
                  # 3D Game with tQuery API
          </article>
          <article data-markdown>
                  # You know jQuery ?
                  ## you know enougth to make a 3d game!
          </article>
          <article data-markdown>
                  # Stage 0
          </article>
          <article data-markdown>
                  # Install three.js + tQuery                
                  ## Have to start somewhere
          </article>
          <article data-markdown>
  
Links three.js in tQuery repo [tquery's repo](http://jeromeetienne.github.com/tquery)

info on distribs


*tquery.js* : core aka tquery only *tquery-bundle.js* : tquery core + three.js + boilerplate *tquery-bundle-require.js* : tquery bundle + require.js usefull to easily get plugins </article>

  <!-- *****************************************************************************
                  STAGE 1
  ****************************************************************************** -->
          <article data-markdown>
                  # Stage 1
          </article>
          <article data-markdown>
                  # Boilerplate                
                  ## What is the boilerplate
          </article>
          <article data-markdown>
  
First the code <pre> &lt;!doctype html&gt;&lt;title&gt;Minimal tQuery Page&lt;/title&gt; &lt;script src=&quot;../../build/tquery-bundle.js&quot;&gt;&lt;/script&gt; &lt;body&gt;&lt;script&gt; var world = tQuery.createWorld().boilerplate().start(); var object = tQuery.createTorus().addTo(world); &lt;/script&gt;&lt;/body&gt; </pre> Only *6 lines* Valid html5 page # Web can be nice ! </article> <article data-markdown> Second the show <iframe src='../examples/stage010.html'></iframe> </article> <article data-markdown> What is the world ``` var world = tQuery.createWorld().boilerplate().start(); ``` scene renderer camera + its controls rendering loop </article> <article data-markdown> What is the boilerplate ``` var world = tQuery.createWorld().boilerplate().start(); ``` include three.js boilerplate easy way to get you started # includes full screen view window resize press 'p' for screenshot press 'f' for fullscreen </article> <article data-markdown> ## Nice blank screen! </article> <article data-markdown> Lets add an object ``` var object = tQuery.createTorus().addTo(world); ``` Create an object torus creator for each included geometry Sphere, Cube, cylinder and others Objects creators use 'normalMaterial' weird blueish thing nice to debug Then add it to the world </article> <article data-markdown> So end up with that <iframe src='../examples/stage010.html'></iframe> </article> <article data-markdown> ## So only a torus in the middle of the screen ? </article> <!-- ***************************************************************************** STAGE 2 ***************************************************************************** --> <article data-markdown> # Stage 2 </article> <article data-markdown> # Minecraft character ## Lets add that :) </article> <article data-markdown> First require.js

                  ```
                  require([], function(){
                          // create the world, add the boilerplate and start
                          var world        = tQuery.createWorld().boilerplate().start();
                          // create a torus and add it to the world
                          tQuery.createTorus().addTo(world);
                  });
                  ```
                  
  
# Why require.js easy download of plugins load files in proper orders May pack+minify with r.js for prod Load only what is needed </article> <article data-markdown> Include minecraft plugin

                  ```
                  require(['tquery.minecraft'], function(){
                          // create the world, add the boilerplate and start
                          var world        = tQuery.createWorld().boilerplate().start();
                          // create a torus and add it to the world
                          tQuery.createTorus().addTo(world);
                  });
                  ```
                  
  
# Possibilities multiple skins create characters animate them control them with keyboard </article> <article data-markdown> Use minecraft plugin

  
# Add default character [See More](../../minecraft/examples/char.html) ``` tQuery.createMinecraftChar().addTo(world); ```

  
# Add Agent smith skin compatible with minecraft ones 15 available already. [See more](../../minecraft/examples/index.html)

                  ```
                  tQuery.createMinecraftChar({
                          skinUrl        : '../../minecraft/examples/images/agentsmith.png'
                  }).addTo(world);
                  ```
          </article>
  <!-- ****************************************************************************
                  Put a world around it
  ********************************************************************************* -->
          <article data-markdown>
                  # Stage 3
          </article>
          <article data-markdown>
                  # Put a world around
                  ## no more flying in ether :)
          </article>
          <article data-markdown>
  
Notes on designing scenes # Principle *Make the space visible* or "antimatter via nutra sweet"! reveal the void # Techniques lights good moving ones better shadows casting skymap cool fog, god ray </article> <article data-markdown> First the sky define skymap create a infinitly huge square appears as sphere via gpu tricks

  
# Several maps already available 7 of them list with following line in jsconsole

                  ```
                  Object.keys(tQuery.TextureCube.WellKnownUrls)
                  ```
          </article>
          <article data-markdown>
  
skymap for sky ``` tQuery.createSkymap('skybox').addTo(world); ``` </article> <article data-markdown> skymap for reflection define [reflection](http://en.wikipedia.org/wiki/Reflection_mapping) ``` var material = tQuery.createMaterial({ envMap : tQuery.createCubeTexture('skybox') }); tQuery.createCube().material(material).addTo(world) ```

  		* good trick for a material
  		  * examples of [car](../../car/examples/)
  		  * look at the arches
  		  * look at the engines (swedish castle :)
          </article>
          <article data-markdown>
  
skymap for refraction TODO link to definition TODO get code link to gello drop </article> <article data-markdown> # a ground to stand on ## light on your feet </article> <article data-markdown> Grass on the ground Nature is healthy. [See More](../../grassground/examples) similar a checkerboard [See More](../../checkerboard/examples) ``` require(['tquery.grassground'], function(){ // ... var ground = tQuery.createGrassGround({ textureRepeatX : 20, textureRepeatY : 20, }).addTo(world) }) ``` # anisotropy is funny - looks cool even at a distance

                  ```
                  ground.get(0).material.map.anisotropy = 16;
                  ```
          </article>
  <!-- ****************************************************************************
                  Put a world around it
  ********************************************************************************* -->
          <article data-markdown>
                  # Stage 4
          </article>
          <article data-markdown>
                  # Make it move
          </article>
          <article data-markdown>
  
Rendering loop # What is it ? part of the tQuery.World use requestanimationframe() called only when anims are ok visible use submillisecond timer ms time unsuitable at 60fps # Notify 2 times *delta* aka nb seconds since last iteration *now* aka nb seconds in absolute time </article> <article data-markdown> Rendering loop # how to hook it

                  ```
                  world.loop().hook(function(delta, now){
                          // your stuff here
                  });
                  ```
                  
  
# in action ``` world.loop().hook(function(delta, now){ var mesh = character.object3D('root'); mesh.rotateY(delta * Math.PI*2) }); ```

  		* [See More](../examples/stage040.html)
          </article>
          <article data-markdown>
  
keyboard controls # What is it ? read and store keyboard state Must be available during rendering loop cant be done via event </article> <article data-markdown> keyboard controls # How to code it ``` world.loop().hook(function(delta, now){ var mesh = character.object3D('root'); var keyboard = tQuery.keyboard(); if( keyboard.pressed('left') ) mesh.translateX(-1 * delta) if( keyboard.pressed('right') ) mesh.translateX(+1 * delta) if( keyboard.pressed('up') ) mesh.translateZ(-1 * delta) if( keyboard.pressed('down') ) mesh.translateZ(+1 * delta) }); ```

  		* depends on **delta**
  		   * Thus same move no matter the fps
  		* [See It](../examples/stage041.html)
          </article>
          <article data-markdown>
  
character animation

  
# Pick a body part armR/armL/legR/legL/body/head say right arm ``` var mesh = character.object3D('armR'); ``` # Make it move [action](../examples/stage042.html) ``` world.loop().hook(function(delta, now){ var mesh = character.object3D('armR'); var angle = now * Math.PI * 2; mesh.rotationX(Math.sin(angle)); }); ``` </article> <article data-markdown> Make it move baby # animating of the character use generic system based on keyframe tweening from one to another # what is an animation succession of keyframes with a name move properties, any property position, rotation, scale whatever generic </article> <article data-markdown> Move your body miner *rigging:* can move head/arms/legs/body several animations already done [see here](../../minecraft/examples/animation.html) run/walk/stand wave/hiwave

  
# 3 for the head yes/no/still </article> <!-- **************************************************************************** Lets give it a weapon ******************************************************************************** --> <article data-markdown> # Stage 5 </article> <article data-markdown> # Lets give a weapon ## fighting time! </article> <article data-markdown> Get the weapon # extruding spritesheet scary words what does this means show it [here](../../minecraft/examples/items.html) from [that](../../minecraft/examples/images/items/items.png) # One can even animate it show it [here](../../minecraft/examples/spritesheet.html) </article> <article data-markdown> Create a sword # Initiation ``` var spritesheet = tQuery.createSpritesheet({ url : 'images/items/items.png', imgW : 256, imgH : 256, spriteW : 16, spriteH : 16 }); ``` # Usage ``` spritesheet.createMesh(2,4).addTo(world); ``` </article> <article data-markdown> Sword in minecraft hand ``` var sword = items.createMesh(2, 4) .addTo(character.parts.armR) .position(0,-10/35,8/35) .rotation(Math.PI/2,Math.PI/2,Math.PI/4) .scaleBy(1/2) ``` what is ```.scaleBy()``` ? what is ```.position()``` ? what is ```.rotation()``` ? # noticed ```.addTo(armR)``` ? </article> <article data-markdown> A word on scenegraph # principles 3d objects are in a scene scene is a tree features are inherited from parents # consequences change parent scale => it change children scale </article> <article data-markdown> Lets play with that

  		* see [running code](../examples/stage050.html)
  		* copy that in live editor
  		* change scale
          </article>
  <!-- ****************************************************************************
                  Stage 6
  ********************************************************************************* -->
          <article data-markdown>
                  # Stage 6
          </article>
          <article data-markdown>
                  # Sound with WebAudioAPI
                  ## Crack boom hue
          </article>
          <article data-markdown>
  
Web Audio API # What is it new audio api efficient, flexible based on OpenAL my [slidedeck on webaudio](http://jeromeetienne.github.com/slides/webaudioapi)

Availability


chrome, safari and iOS firefox implementing it </article> <article data-markdown> # Sound in modern browsers ! ## First time in history!! </article> <article data-markdown> Web Audio API # Super cool for 3d directional sound sound for 3d position/velocity dopler! listener follows camera!!! </article> <article data-markdown> Webaudio.js

  
# motivation web audio api is verbose kinda like webgl little lib to make it easier to use # Info mit license [homepage](http://jeromeetienne.github.com/webaudio.js) * [github](github.com/jeromeetienne/webaudio.js/) </article> <article data-markdown> Webaudio.js

  
# some Examples real time sound analysis [here](http://jeromeetienne.github.com/webaudio.js/examples/histotquery.html) * directional sound [here](http://jeromeetienne.github.com/webaudio.js/examples/sample-tquery.html) * procedural sound generation with jsfx [here](http://jeromeetienne.github.com/webaudio.js/examples/jsfx/) * playground to test [here](http://jeromeetienne.github.com/webaudio.js/examples/playground/) > <article data-markdown> Webaudio.js basic

  
# enable it ``` world.enableWebAudio(); ``` setup a typical node chain based on [html5rocks advices](
http://www.html5rocks.com/en/tutorials/webaudio/games/) * configure listener on camera </article> <article data-markdown> Webaudio.js basic

  
# load a sound ``` var sound = tQuery.createSound().load('../sounds/checkpoint.wav'); ```

  
# play it ``` sound.play() ```

  
# What about the 3d ? ``` sound.follow(mesh) ```

  		* blah!! got localisation + dopler!
  		* not too hard hey ? :)
          </article>
  <!-- ****************************************************************************
                  Stage 7
  ********************************************************************************* -->
          <article data-markdown>
                  # Stage 7
          </article>
          <article data-markdown>
                  # Multiplayer!!
          </article>
          <article data-markdown>
  
Intro not an easy problem fighting latency is hard various strategy are possible [good intro](http://buildnewgames.com/real-time-multiplayer/) > <article data-markdown> Could that be easy ? # tried with [easywebsocket](http://easywebsocket.org) * service which only echo packets up to the users to define protocols # above and beyond with [simplemmoserver](github.com/jeromeetienne/SimpleMMOServer) the brand new attempt :) less raw/more cooked </article> <article data-markdown> SimpleMMOServer # Feature handle userlist for you measure latency allow echo/broadcast broadcast = send to all others echo = send to everybody (even me)

  
# info mit license repo [here](github.com/jeromeetienne/SimpleMMOServer) </article> <article data-markdown> more cooked ? # not so cooked server: 60lines + node.js client: 130lines # Still rawish :) ## *very naive* tho :) </article> <article data-markdown> on the server ``` node server.js ``` </article> <article data-markdown> on the client # initialisation userinfo == info shared in the userlist

                  ```
                  var userInfo        = {
                          humanName        : "chater-"+Math.floor(Math.random()*100000)
                  };
                  var gameServer        = new SimpleMMOServer(userInfo);
                  ```
                  
  
# update user info ``` gameServer.userInfo(userInfo); ``` </article> <article data-markdown> on the client # send message format is up to you ``` gameServer.clientEcho('foo'); gameServer.clientBroadcast('bar'); ``` # measure latency ``` gameServer.latency() ``` </article> <!-- **************************************************************************** The End ******************************************************************************** --> <article data-markdown> # *Questions ?* Jerome Etienne </article> <!-- **************************************************************************** Admin Script ******************************************************************************** --> <script> // ==UserScript== // @name Use Markdown, sometimes, in your HTML. //
author: Paul Irish <paulirish.com/> // gray http://git.io/data-markdown // @match * // ==/UserScript== // If you're not using this as a userscript just delete from this line up. It's cool, homey. (function markdownSlideToHtml(){ if (!window.Showdown){ var scr = document.createElement('script'); scr.onload = markdownSlideToHtml; scr.src = 'vendor/showdown.js'; document.body.appendChild(scr); return; } [].forEach.call(document.querySelectorAll('[data-markdown]'), function fn(elem){ // strip leading whitespace so it isn't evaluated as code //var text = elem.textContent.replace(/\n\s*\n/g,'\n'); // jerome- to have better support of html within markdown var text = elem.innerHTML; //console.log("origin innerHTML", text.split('\n')); // remove all blanks lines //text = text.replace(/\n\s*\n/g,'\n'); //console.log("step text", text) // set indentation level so your markdown can be indented within your HTML var matches = text.match(/^\n([ \t]*)/); var leadingws = matches[1].length; //console.log("first line", matches) //console.log("leadingws", leadingws) var regex = new RegExp('\\n[ \\t]{' + leadingws + '}','g'); var md = text.replace(regex,'\n'); //console.log("pre md", md); html = (new Showdown.converter()).makeHtml(md); //console.log("post html", html); // to support prettyprint html = html.replace(/<code><br \/>/g,'<pre class="prettyprint">'); html = html.replace(/<br \/><\/code>/g,'</pre>'); // unescape [><] html = html.replace(/&amp;gt;/g,'>'); html = html.replace(/&amp;lt;/g,'<'); //console.log("escaped html", html); // here, have sum HTML elem.innerHTML = html; }); // callback prettyprint to highlight code found in markdown prettyPrint(); }()); </script> <script>
<h4>
//////////////////////////////////////////////////////////</h4>

// scan the whole webpage and replace url to their local location // - usefull to have local copy of the slides in conference when internet is unavailable // - and still have slides which works when internet is available //
open -a "/Applications/Google Chrome.app" --args --disable-web-security --allow-file-access-from-file setTimeout(function(){ location.href.match(/^file:/) && jQuery('a').add('iframe').each(function(index, element){ var attrNames = { 'A' : 'href', 'IFRAME': 'src' }; var attrName = attrNames[element.nodeName]; var url = jQuery(element).attr(attrName); url = url.replace(/^http:\/\/jeromeetienne.github.com\/tquery\// , 'file://localhost/Users/jerome/webwork/tquery/') url = url.replace(/^http:\/\/jeromeetienne.github.com\/augmentedgesture.js\// , 'file://localhost/Users/jerome/webwork/augmentedgesture.js/') url = url.replace(/^http:\/\/jeromeetienne.github.com\/webaudio.js\// , 'file://localhost/Users/jerome/webwork/webaudio.js/') url = url.replace(/^http:\/\/jeromeetienne.github.com\/pongGL\//, 'file://localhost/Users/jerome/webwork/pongGL/') url = url.replace(/^http:\/\/jeromeetienne.github.com\/threex\//, 'file://localhost/Users/jerome/webwork/threex/') url = url.replace(/^http:\/\/learningthreejs.com\//, 'file://localhost/Users/jerome/webwork/learningthreejs.com/') url = url.replace(/\//, '/index.html') jQuery(element).attr(attrName, url); }) }, 100); </script> </body> </html>


(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.
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript"> </script> <script type="text/javascript"> _uacct = "UA-2780434-1"; urchinTracker(); </script>