I got a pretty sweet walking Gladius-based avatar put together last night. Tonight, I'd like to work with the camera so that it rotates nicely around the avatar.
I start by doing my new favorite thing in Gladius: adding another frame of reference to make subsequent movement and positioning easier. In this case, I add a frame of reference that is tied to the body of the avatar and then position the camera relative to this:
function game(engine, resources) {
var math = engine.math;
var space = new engine.SimulationSpace();
var cubicvr = engine.findExtension("gladius-cubicvr");
// add avatar bits and pieces...
space.add(new engine.Entity("camera-frame",
[
new engine.core.Transform()
],
[],
space.findNamed("body")
));
space.add(new engine.Entity("camera",
[
new engine.core.Transform([0, 10, 23], [-Math.PI/8, 0, 0]),
new cubicvr.Camera()
],
["avatar"],
space.findNamed("camera-frame")
));
// Game tasks here...
}
Next, I add the gladius-input extension to my required modules so that I can use it to manipulate the camera: require(
[ "gladius-core", "gladius-cubicvr", "gladius-input" ],
function( Gladius, cubicvrExtension, inputExtension ) {
var engine = new Gladius();
// Set up mesh and materials
function game(engine, resources) {
// Game code here...
}
});
When I register the extension as listening to the web page's document
element, however, I start seeing already completed
errors. Oddly, this is resolved by defining the logic controllers in the game()
core function. It is a bit frustrating not knowing if these errors are due to a missing input definition or because I have broken something else. I probably need to investigate this closer another day.To define the controls, I first need to define the various input states in which my camera can be. For now, this will include "PanLeft" and "PanRight":
require( [ "gladius-core", "gladius-cubicvr", "gladius-input" ], function( Gladius, cubicvrExtension, inputExtension ) { var engine = new Gladius(); // Set up mesh and materials... // Input states var cameraControls = new engine["gladius-input"].Map({ "States": { "PanLeft": [ "J" ], "PanRight": [ "K" ] } }); resources['camera_controls'] = cameraControls; function game(engine, resources) { // Game code here... } });All that remains now is to add the input controller (based on the states defined above) and an actor to effect changes in the game based on these states:
function game(engine, resources) {
var math = engine.math;
var space = new engine.SimulationSpace();
var cubicvr = engine.findExtension("gladius-cubicvr");
var input = engine.findExtension( "gladius-input" );
// Add other bits and pieces to the game...
// Camera input logic
var cameraLogic = {
"Update": function(event) {
if (!this.owner.hasComponent("Controller")) return;
var controller = this.owner.findComponent("Controller")
, transform = this.owner.findComponent("Transform");
var rotation;
if (controller.states["PanLeft"]) {
rotation = [0, -space.clock.delta * 0.001, 0];
}
if (controller.states["PanRight"])
rotation = [0, space.clock.delta * 0.001, 0];
if (rotation)
transform.setRotation(math.vector3.add(rotation, transform.rotation));
}
};
space.add(new engine.Entity("camera-frame",
[
new engine.core.Transform(),
new input.Controller( resources.camera_controls ),
new engine.logic.Actor( cameraLogic )
],
[],
space.findNamed("body")
));
// The rest of the game here ...
}
The result is that I watch the avatar from the side:And rotate around to view from the front as well:
As I found yesterday when I got the avatar limbs swinging in unison, intermediate frames of reference come in extremely handy. There is a downside of additional code for these extra frames of reference. It is manageable, but I may need some higher level code for kids — at least when introducing these concepts.
Day #449
No comments:
Post a Comment