Leap Three Camera Controls

Have you ever used three.js? Have you ever wanted to see your work in 3D? Have you wondered how we got here, what the meaning of life is?

If your answer was yes to any of these questions, than you are in the right place! Here we are going to learn how to not only see things in 3D, but also make them move with just the flick of our wrist, the wave of our hands.

If you have never touched three.js before, your best bet is to check out one of the tutorials from someone who knows what they are doing ( which is most definitely not me ). Below are some good starting resources:

First we are going to quickly look at how to set up a three.js project with the camera controls, but if you are comfortable with three.js, feel free to skip to slide 8, where we will begin looking at LeapSpringControls

Please keep in mind that these controls are works in progress! If you have ideas on how they could be made better, have ideas of your own, or just want to tell me about typos / bugs, Check out the Repo or Hit me up on Twitter

DOWNLOADING THE EXAMPLE SOURCE

Including Scripts

Still with us? Good, than lets dive into some code right away!

The point of these Leap-Three-Camera-Controls is to make it as easy as possible to get something you've made to the point where it is using the Leap Motion Controller to make more magic. But before magic comes CODE!

The first thing we will do is to include all the files we need. For the purpose of this walkthrough, we will be defining the paths as we would in our examples, but keep in mind you will need to define your own paths:


<script src = "lib/three.min.js"                   ></script>
<script src = "lib/leap.js"                        ></script>
<script src = "controls/LeapTrackballControls.js"  ></script>
      

Next slide we'll get the camera set up, and initialize our controller!

DOWNLOAD THE EXAMPLE SOURCE

Global Variables

We will split the majority of our program into two parts: initialization, and animation. Animation will take care of updating and rendering things, and will be called every frame. Initialization will set up everything we need to use in the animation step. However, the first thing that we need to do is create things that we will share between the two steps:

Global Variables!


// our leap controller
var controller;

// our leap camera controls
var controls;

// our three.js variables
var scene , camera , renderer;
      

DOWNLOAD THE EXAMPLE SOURCE

Initialization

Now that we've got the global variables defined, we can initialize them. We will be going over the THREE.JS initialization pretty quickly, so if it doesn't make sense to you, make sure you check out Aerotwist's three.js tutorial.

All of our code will be inside an init function. This function can be called wherever you want, but for this slide we are more concerned about what's INSIDE the function call


function init(){

  // Setting up THREE.JS Scene / Camera / Renderer

  var w     = window.innerWidth;
  var h     = window.innerHeight;

  scene     = new THREE.Scene();
  camera    = new THREE.PerspectiveCamera( 50 , w / h , 1 , 1000 ); 
  renderer  = new THREE.WebGLRenderer();

  renderer.setSize( w , h );
  document.body.appendChild( renderer.domElement );

  // Adding something to the scene just so we can see if it works
  var geometry  = new THREE.IcosahedronGeometry( 5 , 2 );
  var material  = new THREE.MeshNormalMaterial();
  var mesh      = new THREE.Mesh( geometry , material );
  
  scene.add( mesh );

  // HERE IS WHERE WE WILL INITIALIZE OUR CONTROLS
  // IN THE NEXT SLIDE

}
      

DOWNLOAD THE EXAMPLE SOURCE

Leap Initialization

We've got the THREE.JS part of the initialization out of the way, but we've done NOTHING to include that sweet nectar of motion control. So lets get to work on including all of things we need to create a Leap-Three-Camera-Control!

Keep in mind that this is the example for only ONE of the many camera controls. In later slides, we will get to see how the different controls work. and play with their parameters, but for this first example, we'll keep rolling with the LeapTrackballControls


// AFTER OUR THREE.JS INITIALIZATION

// first off, create our leap controller to get data from
controller = new Leap.Controller();

// To get frames rolling! 
// Our Camera Controls, should do this on our own,
// but its good practice to say it outright!
controller.connect();

// THIS! is where the magic is.
// We pass in the camera ( what we are acting on )
// and the controller ( which gives us data )
controls = new THREE.LeapTrackballControls( camera , controller );

// Any defining of parameters, you can do here , like so:

controls.rotationSpeed = 20;

// but these parameters can also be updated anywhere else in the program!

// It is important to note that with other controls, 
// we may pass through our scene,
// to add markers, placeholders and other visual feedback.
// We will explore this more in later slides

      

DOWNLOAD THE EXAMPLE SOURCE

Animation

Now that we've got everything initialized, the only thing left to do is get frames rolling!


function animate(){

  requestAnimationFrame( animate );

  controls.update();
  renderer.render( scene , camera );

}

      

Easy enough, right?

DOWNLOAD THE EXAMPLE SOURCE

All Together Now!

We done all the coding we need to do, so lets view it all together!


<html>
  <body>    

    <script src = "lib/leap.min.js"                    ></script>
    <script src = "lib/three.js"                       ></script>
    <script src = "controls/LeapTrackballControls.js"  ></script>

    <script>

      var camera , scene, renderer;

      var controller , controls;

      init();
      animate();

      function init(){

        var w     = window.innerWidth;
        var h     = window.innerHeight;

        scene     = new THREE.Scene();
        camera    = new THREE.PerspectiveCamera( 50 , w / h , 1 , 1000 ); 
        renderer  = new THREE.WebGLRenderer();

        renderer.setSize( w , h );
        document.body.appendChild( renderer.domElement );

        var geometry  = new THREE.IcosahedronGeometry( 5 , 2 );
        var material  = new THREE.MeshNormalMaterial();
        var mesh      = new THREE.Mesh( geometry , material );
        
        scene.add( mesh );

        controller = new Leap.Controller();
        controller.connect();

        controls = new THREE.LeapTrackballControls( camera , controller );
        controls.rotationSpeed = 20;

      }


      function animate(){

        requestAnimationFrame( animate );
        
        controls.update();
        renderer.render( scene , camera );

      }

    </script>
  </body>
</html>
      

Hopefully this all makes sense to you. If not, please check out A TUTORIAL . Or reach out to me at icohen@leapmotion.com || @cabbibo

DOWNLOAD THE EXAMPLE SOURCE

Now For The Fun Stuff

Congrats! You are now a graphics programmer! And a Leap programmer! And super cool , and popular! And you understand how to use the controls, so we can move onto describing each one in detail.

Hopefully you don't look like this dude: but if you do, don't worry! now we get to actually start using the camera.

Whenever you are ready, head to the next slide to learn about LeapSpringControls

Spring Controls

Spring controls attatch a spring from your camera to a target, which it is always looking at. When you pinch, it places a new anchor that the target will tween to, always giving you a smooth movement, while the spring pulls the camera toward the target. To see exactly what this means, try adding markers to the anchor , hand , and target as described in the below code snippet

Pros:

Cons:

Pairings:

Called using:


<!-- Include Script -->
<script src="path/to/controls/LeapEyeLookControls.js"></script>

// Inside Init Function
controls = new THREE.LeapSpringControls( camera , controller , scene );

controls.dampening      = .75;
controls.size           = 120;
controls.springConstant =   1;
controls.mass           = 100;
controls.anchorSpeed    =  .1;
controls.staticLength   = 100;

// Adding meshes to the Anchor , Target and Hand
var geo = new THREE.IcosahedronGeometry( 5, 2 ); 
var mat = new THREE.MeshNormalMaterial(); 

var targetMesh  = new THREE.Mesh( geo , mat );
var anchorMesh  = new THREE.Mesh( geo , mat );
var handMesh    = new THREE.Mesh( geo , mat );

controls.addTargetMarker( targetMesh );
controls.addAnchorMarker( anchorMesh );
controls.addHandMarker(     handMesh );

// Inside Animate Function
controls.update();
      

Using the following parameters:

SEE SOURCE

Pointer Controls

The pointer controls always has the camera always pointing at a 'target', when you pinch, you begin moving the camera around the object, and when you release, the camera will stop moving.

Pros:

Cons:

Pairings:

Called using:


<!-- Include Script -->
<script src="path/to/controls/LeapPointerControls.js"></script>

// Inside Init Function
var controls = THREE.LeapPointerControls( camera , controller );

controls.size       = 100;
controls.speed      = .01;
controls.dampening  = .99;
controls.target     = new THREE.Vector3( 0 , 100 , 0 );

// Inside Animate Function
controls.update();
      

Using the following parameters:

SEE SOURCE

Leap Eye Look Controls

Eye Look Controls are very similar to the Pointer controls. Infact when you use your right hand, they are exactly the same. The biggest difference is that when you use your left hand, you dynamically move the target. This leads to the ability to easily move around a scene, but always have a specific point you are focused on. Also, all movements are relative, rather than absolute.

Pros:

Cons:

Pairings:

Called using:

<!-- Include Script -->
<script src="path/to/controls/LeapEyeLookControls.js"></script>

// Inside Init Function
var controls = THREE.LeapEyeLookControls( camera , controller , scene );

controls.lookSize       = 10;
controls.lookMass       = 10;
controls.lookSpeed      = 10;
controls.lookDampening  = .9;

controls.eyeSize        = 10;
controls.eyeMass        = 10;
controls.eyeSpeed       = 10;
controls.eyeDampening   = .9;

// If you want to have a marker for your eye
// Which you probably do...

var geo   = new THREE.CubeGeometry( 1 , 1 , 1 );
var mat   = new THREE.MeshNormalMaterial();
var mesh  = new THREE.Mesh( geo , mat );

controls.addLookMarker( mesh );


// Inside Animate Function
controls.update();
      

Using the following parameters:

SEE SOURCE

Two Hand Controls

Two Hand controls let you translate around a scene by pinching with a single hand, and rotate scene when you pinch with two hands

Pros:

Cons:

Pairings:

Called using:


<!-- Include Script -->
<script src="path/to/controls/LeapEyeLookControls.js"></script>

// Inside Init Function
controls = new THREE.LeapTwoHandControls( camera , controller , scene );

controls.translationSpeed   = 20;
controls.translationDecay   = 0.3;
controls.scaleDecay         = 0.5;
controls.rotationSlerp      = 0.8;
controls.rotationSpeed      = 4;
controls.pinchThreshold     = 0.5;
controls.transSmoothing     = 0.5;
controls.rotationSmoothing  = 0.2;

// Inside Animate Function
controls.update();
      

SEE SOURCE

Pinch Rotate Controls

Pinch Rotate Controls are nearly Identical to the Trackball controls, ( described next slide ) , except that they use pinch in order to move the camera. As well, they have the ability to zoom in and out, by simply pinching and moving inwards or outwards. In order to define when this happens, it looks at the movement in Z vs the movement in X and Y, and compares the two to see if there is more movement in Z than XY or vice versa

Pros:

Cons:

Pairings:

Called using:


<!-- Include Script -->
<script src="path/to/controls/LeapPinchRotateControls.js"></script>

// Inside Init Function
var controls = THREE.LeapPinchRotateControls( camera , controller );

controls.rotationSpeed            =   10;
controls.rotationLowDampening     =  .98;
controls.rotationHighDampening    =   .7;
controls.zoom                     =   40;
controls.zoomDampening            =   .6;
controls.zoomSpeedRatio           =   10;
controls.zoomCutoff               =   .9;
controls.zoomEnabled              = true;
controls.zoomVsRotate             =    1;
controls.minZoom                  =   20;
controls.maxZoom                  =   80;

// Inside Animate Function
controls.update();
      

Using the following parameters:

SEE SOURCE

Leap Trackball Controls

Trackball Controls let you swipe the camera around a target, as if you were pushing a giant bowling ball around ( your hand is always behind the ball ) Also , if you turn your hand straight up, and zoom is enabled, you will stop spinning and start zooming, based on moving your hand forward and backwards

Pros:

Cons:

Pairings:

Called using:


<!-- Include Script -->
<script src="path/to/controls/LeapTrackballControls.js"></script>

// Inside Init Function
var controls = THREE.LeapTrackballControls( camera , controller );

controls.rotationSpeed            = 10;
controls.rotationDampening        = .98;
controls.zoom                     = 40;
controls.zoomDampening            = .6;
controls.zoomCutoff               = .9;

controls.minZoom                  = 20;
controls.maxZoom                  = 80;

// Inside Animate Function
controls.update();
      

Using the following parameters:

SEE SOURCE

Paddle Controls

Paddle Controls Let you 'paddle' Around a scene, the way that you would paddle through water. Pretty cool huh?

Pros:

Cons:

Pairings:

Called using:


      <!-- Include Script -->
      <script src="path/to/controls/LeapPaddleControls.js"></script>

      // Inside Init Function
      var controls = THREE.LeapPaddleControls( camera , controller );

      controls.weakDampening        = .99;
      controls.strongDampening      = .9;
      controls.fingerMatchCutoff    = .5;
      controls.velocityMatchCutoff  =.5;
      controls.fingerMatchPower     = 5;
      controls.velocityMatchPower   = 5;
      controls.movementSpeed        = 1;
      controls.maxSpeed             = 10; 

      // Inside Animate Function
      controls.update();
      

Using the following parameters:

SEE SOURCE