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