Wednesday, July 4, 2012

Input Actors in Gladius

‹prev | My Chain | next›

I made a good start of adding gladius-input controls to my solar system simulation yesterday. The controls were not quite right though, because I copied-and-pasted them from one of the Gladius core examples. Tonight I would like to get them right and, hopefully in the process, learn a bit more about the logic "Actor" in Gladius.

The camera entity with which I am working is declared as:
    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 )
      ]
    ));
In the array argument, I move the camera 23 "space units" away from the origin and rotate 180° (Math.PI) around the x-axis so that I am looking down on the Solar System. To make the entity a real camera, I add a Camera object to it. Then comes the fun input stuff.

The inputController maps keyboard inputs to different states. The resources.cameraControls that I defined yesterday includes the "PanUp" and "PanDown" states. Last up in the camera entity definition is the Actor which manipulates the camera entity depending on the states currently represented in the input controller.

The cameraLogic argument to the Actor constructor contains the mapping between state and action and looks something like:
    var cameraLogic = {
      "Update": function(event) {
        if (!this.owner.hasComponent("Controller")) return;

        var controller = this.owner.findComponent("Controller")
          , transform = this.owner.findComponent("Transform");

        if (controller.states["PanUp"]) {
          console.log(this.owner.id, "Pan Up!");
          // ...
        }

        if (controller.states["PanDown"]) {
          console.log(this.owner.id, "Pan Down!");
          // ...
        }
      }
    };
The Actor constructor needs a function to Update in response to an event. Interestingly, the event argument to the Update function is never used (it only contains "{"type":"Update","data":false,"queue":true}"). Instead, I grab the input controller so that I can determine the current state—and act accordingly.

Acting involves transforming the camera. A "transform" can move the object, scale it or rotate it. In this case I only want to rotate the camera:
        // ...
        if (controller.states["PanUp"]) {
          console.log(this.owner.id, "Pan Up!");
          var rotation = [space.clock.delta * 0.0005, 0, 0];
          transform.setRotation(math.vector3.add(rotation, transform.rotation));
        }
        // ...
With that, I can take my camera:


And rotate it:


And rotate it some more:


Up tomorrow, I think that I will add that ability to rotate left and right as well. I may even add the ability to move forward and backwards.

Day #437

No comments:

Post a Comment