I really need to begin investigating the latest version of Gladius. But first, I would like to tackle two problems. One is switching between cameras and the other is targeting a moving object. I think the latter is the harder problem, but since I already started the former last night, I continue now.
I found last night that I could find all Gladius entities with a camera via:
space.findAllWith("Camera");Furthermore, I was able to remove a camera from an entity with:var camera = camera_entity.removeComponent("Camera");Removing a camera from an entity had the desirable side-effect of disabling the camera. Without doing so, multiple cameras would all display at the same time, in the same space. This makes for confusing viewing:
I also found that I could reactivate a camera by adding it back to it original "entity":
camera_entity.addComponent(camera);Tonight, I would like to take a page from CubicVR.js by adding a
setCamera() method to the Space class. I am not ready to add this directly to the Gladius source, so I opt instead for some JavaScript monkey-patching. I have a space object on which I am doing the bulk of the work in my game. So I grab that object's prototype so that I can add setCamera() to it:    var spacePrototype = Object.getPrototypeOf(space);
    spacePrototype.setCamera = function(camera_name) {
    }I start this method by disabling all active cameras:    spacePrototype.setCamera = function(camera_name) {
      this._deactivateAllCameras();
    }As mentioned, deactivating cameras is as simple as removing the component from its Gladius "entity". So that I can reactivate it later, when I remove each camera, I store it in a private _inactive_cameras instance variable:    spacePrototype._deactivateAllCameras = function() {
      if (typeof(this._inactive_cameras) == "undefined") {
        this._inactive_cameras = {};
      }
      var all_cameras = this.findAllWith("Camera");
      for (var i=0; i<all_cameras.length; i++) {
        var name = all_cameras[i].name;
        this._inactive_cameras[name] = all_cameras[i].removeComponent("Camera");
      }
    };In there, I use Space's findAllWith() method just like I did last night. Since I am working on the Space prototype, I am free to refer to the object as this.With all cameras inactive, I need to activate one of them back in
setCamera():    spacePrototype.setCamera = function(camera_name) {
      this._deactivateAllCameras();
      this.
        findNamed(camera_name).
        addComponent(this._inactive_cameras[camera_name]);
      delete this._inactive_cameras[camera_name];
    };With that, I can activate one camera with:space.setCamera("camera2");Resulting in a single camera view:And, if I want all of the functionality from the CubicVR.js example, I can switch between cameras ever 240 clock ticks:
    var task = new engine.FunctionTask( function() {
      if (space.clock.time % 240 == 0) {
        space.setCamera(space.camera.name == "camera1" ? "camera2" : "camera1");
      }
      // move the planets ...
    }That will suffice for now (until Gladius supports this more directly). Up tomorrow, I see if I can get a moving camera to target a moving object.
Day #431

Hey Chris,
ReplyDeleteThe current situation with cameras is that they are all associated with a single canvas element. Going forward, I want to change the API so that you can associate individual cameras with their own render outputs, either viewports on the canvas element or a texture. This will let you run multiple cameras concurrently in a way that doesn't superimpose the rendered output.
A