Tuesday, July 3, 2012

Getting Started with Gladius-Input

‹prev | My Chain | next›

Now that I am on the most recent version of Gladius for my solar system example, I would like to play about with some of the new features available in 0.2. Tonight I start with gladius-input, an extension that should make working with user input better.

There does not seem to be much documentation yet for gladius-input, but there is an example: the tank simulation makes use of gladius-input.

First up, I need to require the extension:
  require(
    [ "gladius-core",
      "gladius-cubicvr",
      "gladius-input" ],
    function( Gladius, cubicvrExtension, inputExtension ) {
      // ...
    });
As with the rendering extension, I must register the input extension. I copy the configuration object from the tank example to do so:
  // ...
  var inputOptions = {
    dispatcher: {
      element: document
    }
  };
  engine.registerExtension( inputExtension, inputOptions );
  // ...
It seems that there will be an event dispatcher listening for events on the pages's document element.

Next up, I need to load in a "control map". This is not done with require.js, but rather with the Gladius engine's get() which I have mostly used for mesh and material loading until now:
  engine.get(
    [
      // ...

      // input extension
      {
        type: engine.findExtension( "gladius-input" ).Map,
        url: "camera-controls.json",
        onsuccess: function( inputMap ) {
          resources.cameraControls = inputMap;
        },
        onfailure: function( error ) {
        }
      }

    ],
    {
      oncomplete: game.bind( null, engine, resources )
    }
  );
I adapt camera-controls.json from the tank example to allow for panning up and down with the camera:
{
  "States": {
    "PanUp": [ "J" ],
    "PanDown": [ "K" ],
  }
}
That is a nice, semantic mapping of keyboard input to controls, but I still need to map the PanUp and PanDown "states" into actual changes.

For that, I add a controller and an actor to my existing camera definition:
  function game( engine, resources ) {
    var space = new engine.SimulationSpace();
    var cubicvr = engine.findExtension( "gladius-cubicvr" );
    var input = engine.findExtension( "gladius-input" );
    // ...
    space.add( new engine.Entity( "camera1",
      [
        new engine.core.Transform([0,0,-23], [Math.PI, 0, 0]),
        new cubicvr.Camera(),
        new input.Controller( resources.cameraControls ),
        new engine.logic.Actor( cameraLogic )
      ]
    ));
    // ...
  }
The resources.cameraControls are what just got loaded from the camera-controls.json file. What is that "Actor" thingy? The actor is what maps the camera controls into actual action:
    var cameraLogic = {
      "Update": function( event ) {
        if( this.owner.hasComponent( "Controller" ) ) {
          var controller = this.owner.findComponent( "Controller" );
          var transform = space.findNamed( "camera1" ).findComponent( "Transform" );
          if( controller.states["PanUp"] ) {
            console.log( this.owner.id, "Pan Up!" );
            var direction = math.transform.translate( [space.clock.delta * 0.001, 0, 0] );
            var rotation = math.transform.rotate( transform.rotation );
            direction = math.matrix4.multiply( [direction, rotation] );
            direction = [direction[12], direction[13], direction[14]];
            transform.setPosition( math.vector3.add( direction, transform.position ) );
          }
          if( controller.states["PanDown"] ) {
            console.log( this.owner.id, "Pan Down!" );
            var direction = math.transform.translate( [space.clock.delta * -0.001, 0, 0] );
            var rotation = math.transform.rotate( transform.rotation );
            direction = math.matrix4.multiply( [direction, rotation] );
            direction = [direction[12], direction[13], direction[14]];
            transform.setPosition( math.vector3.add( direction, transform.position ) );
          }
        }
      }
    };
I need to adapt those controls to setRotation() instead of the setPostion() that I copied from the tank example. Even so, this works as I see the camera move back and forth when I press "J" and "K". Additionally, I see the logging in the JavaScript console:
21BCB0FC5-DBA1-42BA-B930-33703CF37592 Pan Down! retrograde.js:267
75 retrograde.js:387
21BCB0FC5-DBA1-42BA-B930-33703CF37592 Pan Down! retrograde.js:267
75 retrograde.js:387
21BCB0FC5-DBA1-42BA-B930-33703CF37592 Pan Down! retrograde.js:267
75 retrograde.js:387
1BCB0FC5-DBA1-42BA-B930-33703CF37592 Pan Down! retrograde.js:267
218 
That will serve as a good stopping point for tonight. I will continue exploring gladius-input tomorrow, but this is a promising start.


Day #436

No comments:

Post a Comment