Monday, July 9, 2012

Getting Started on a Gladius Avatar

‹prev | My Chain | next›

I think it best to temporarily give up on rotating my Gladius camera around an arbitrary axis. If I keep stumbling around, trying solutions from various sources, I think that I could actually get it working. The problem is that I would get it working without really understanding it.

So, while I dig through elementary 3D math books, I am going to get started on other aspect of my book: building a cute little avatar for games.

I start, as always, with the basic skeleton required by Gladius:
document.addEventListener( "DOMContentLoaded", function( e ) {
  require.config({
    baseUrl: "scripts"
  });

  require(
    [ "gladius-core", "gladius-cubicvr" ],
    function( Gladius, cubicvrExtension ) {
      // Game code here...
    }
  );
});
The actual game code starts with an engine, and ends with resuming (or starting) that engine:
    function( Gladius, cubicvrExtension ) {
      var engine = new Gladius();
      // Game code here...      
      engine.resume();
    }
Next comes attaching the engine to the CubicVR backend renderer, which needs a canvas document ID:
    function( Gladius, cubicvrExtension ) {
      var engine = new Gladius();

      // CubicVR rendering backend
      engine.registerExtension(cubicvrExtension, {
        renderer: {
          canvas: document.getElementById( "test-canvas" )
        }
      });

      // Game code here...

      engine.resume();
    }
So far, this is all very basic Gladius code. It could almost be a template or generated. The "real" work is not quite ready. First I need to load in the "resources" that will describe shapes and materials in my game.

I start with a simple procedural primitive mesh, which I save in assets/procedural-primitive-mesh.js. I think I would prefer some kind of inline factory function, but this external "proc" will do for now:
function proc(options) {
  options = options || {
    type: "sphere",
    radius: 1.0
  };

  return {
    primitive: options,
    compile: true
  };
}
I load this into the application with the usual Gladius engine.get():
    function( Gladius, cubicvrExtension ) {
      var engine = new Gladius();

      // CubicVR rendering backend...

      // Mesh and material resources
      var resources = {};
      engine.get(
        [
          {
            type: engine["gladius-cubicvr"].Mesh,
            url: 'assets/procedural-primitive-mesh.js?type=sphere',
            load: engine.loaders.procedural,
            onsuccess: function(mesh) {
              resources.sphere_mesh = mesh;
            },
            onfailure: function(error) {}
          },
          {
            type: engine["gladius-cubicvr"].Mesh,
            url: 'assets/procedural-primitive-mesh.js?type=cone',
            load: engine.loaders.procedural,
            onsuccess: function(mesh) {
              resources.cone_mesh = mesh;
            },
            onfailure: function(error) {}
          },
          // ...
        {
          oncomplete: game.bind(null, engine, resources)
        }
      );

      // Game code here...

      engine.resume();
    }
Finally, I add the game definition. For now, I just add the body (a cone), the head (a ball), and a camera:
    function( Gladius, cubicvrExtension ) {
      var engine = new Gladius();

      // CubicVR rendering backend...
      // Mesh and material resources
      var resources = {};
      engine.get(
        // Resources...
        {
          oncomplete: game.bind(null, engine, resources)
        }
      );

      function game(engine, resources) {
        var math = engine.math;
        var space = new engine.SimulationSpace();
        var cubicvr = engine.findExtension("gladius-cubicvr");

        space.add(new engine.Entity("body",
          [
            new engine.core.Transform(),
            new cubicvr.Model(resources.cone_mesh, resources.red_material)
          ],
          ["avatar"]
        ));

        space.add(new engine.Entity("head",
          [
            new engine.core.Transform([0, -1.25, 0]),
            new cubicvr.Model(resources.sphere_mesh, resources.blue_material)
          ],
          ["avatar"],
          space.findNamed("body")
        ));

        space.add(new engine.Entity("camera",
          [
            new engine.core.Transform([0,0,-23], [Math.PI, 0, 0]),
            new cubicvr.Camera()
          ]
        ));
      }

      engine.resume();
    }
With that, I get:

(I had originally not seen the cone because I omitted a comma inside the space.add() call).

I'll probably invert the code and add a picture for the face tomorrow. For now this is a good start.

Day #442

No comments:

Post a Comment