Friday, June 22, 2012

Dynamic Position in Gladius

‹prev | My Chain | next›

I do not know how to make a line in Gladius or CubicVR.js. If there is a drawLine() method to be found, it eludes me. This presents a problem because I would like to draw a line between the Earth and Mars in my very simple solar system simulation:



The nearest thing that I can think to do is add a line-like primitive shape to the drawing. I could do a very narrow plane, but that has the disadvantage of being thin to the point of invisibility when viewed horizontally. So I opt for a very thin cylinder instead. I define a "procedural" mesh (I really should figure out how to create a Galdius mesh without an external proc() function) as procedule-line-mesh.js:
function proc( options ) {
  options = options || {};
  options.size = options.size || 0.01;

  return {
    primitive: {
      type: "cylinder",
      radius: options.size
    },
    compile: true
  };
}
From the main script entry point, I then load this mesh, along with a yellow material, into the resources hash to be used in the "game":
  engine.get(
    [
      // ...
      // line between Earth and Mars
      {
        type: engine["gladius-cubicvr"].MaterialDefinition,
        url: '../assets/rgb-material.js?r=255&g=255',
        load: engine.loaders.procedural,
        onsuccess: function( material ) {
          resources.line_material = material;
        },
        onfailure: function( error ) {
        }
      },
      {
        type: engine["gladius-cubicvr"].Mesh,
        url: '../assets/procedural-line-mesh.js',
        load: engine.loaders.procedural,
        onsuccess: function( mesh ) {
          resources.line_mesh = mesh;
        },
        onfailure: function( error ) {
        }
      },
    ],
    {
      oncomplete: game.bind( null, engine, resources )
    }
  );
This may be something easier to do in the newer version 0.2 of Gladius, but, for now, I have to got through the ceremony of loading CubicVR Material and Mesh objects from external sources since Gladius does not grant direct access to these classes. As it is, I have nearly a dozen such definitions—each doing no more than defining a color or mesh.

Anyhow, with mesh (shape) and material in tow I can add my cylinder-line to the game space:
    space.add( new engine.simulation.Entity( "earth-mars-line-of-sight",
      [
        new engine.core.Transform( [0, 0, 0], [0,0,0], [1,1,1]),
        new cubicvr.Model( resources.line_mesh, resources.line_material )
      ]
    ));
Lastly, I shift it to the Earth's frame of reference and point it out to space (away from the Sun) by rotating it 90°:
    var line_of_sight = space.findNamed( "earth-mars-line-of-sight" );
    line_of_sight.setParent( space.findNamed( "earth" ) );
    line_of_sight.findComponent("Transform").setRotation([Math.PI/2, 0, 0]);
The result is:



I am also greeted by many warning to the effect that:
PERFORMANCE WARNING: Attribute 0 is disabled. This has signficant performance penalty 
I am unsure about this as it seems related to the mere presence of the cylinder independent of size, location or frame of reference. My machine is not impacted, so I ignore this for now.

Currently, the line that should point to Mars points straight out to space. To point to Mars, I need to know where Mars is in space and adjust the coordinates accordingly. Unfortunately, I cannot simply grab the x-y-z position of Mars:
      var marsPosition = new engine.math.Vector3( space.findNamed( "mars" ).findComponent( "Transform" ).position );
      console.log(marsPosition);
This results in [10,0,0] at every clock cycle. This is because the position of Mars does not change. Last night, I set the frame of reference in motion (individually for each planet) while everything else stayed fixed.

I am not going to solve this completely tonight, but I get started by computing the X-Y position by pulling the angle out of Mars' frame of reference and applying some simple trigonometry to determine the absolute position:
      var marsPosition = new engine.math.Vector3( space.findNamed( "mars" ).findComponent( "Transform" ).position );
      var marsDistance = Math.sqrt(marsPosition[0] * marsPosition[0] + marsPosition[1] * marsPosition[1]);

      console.log("X: " + Math.cos(marsRevolution[2]) * marsDistance);
      console.log("Y: " + Math.sin(marsRevolution[2]) * marsDistance);
I will pick back up tomorrow doing the same with Earth. Then the fun begins as I have to rotate the cylinder line as the planets orbit.

Day #425

No comments:

Post a Comment