Skip to content

Instantly share code, notes, and snippets.

@mikebelanger
Created September 9, 2016 17:01
Show Gist options
  • Save mikebelanger/751a1aca2c62e9c0818fbc4da9c9e7a5 to your computer and use it in GitHub Desktop.
Save mikebelanger/751a1aca2c62e9c0818fbc4da9c9e7a5 to your computer and use it in GitHub Desktop.
"use strict"
// register the application module
b4w.register("marbleblast", function(exports, require) {
var m_app = require("app");
var m_cam = require("camera");
var m_cfg = require("config");
var m_cont = require("container");
var m_ctl = require("controls");
var m_data = require("data");
var m_scenes = require("scenes");
var m_time = require("time");
var m_trans = require("transform");
var m_vec3 = require("vec3");
var m_version = require("version");
/* export the method to initialize the app (called at the bottom of this file)
*/
exports.init = function() {
m_app.init({
canvas_container_id: "main_canvas_container",
callback: init_cb,
show_fps: true,
console_verbose: true,
autoresize: true
});
}
function init_cb(canvas_elem, success) {
if (!success) {
console.log("b4w init failure");
return;
}
load();
}
function load() {
m_data.load("marbleblast.json", load_cb);
}
function load_cb(data_id) {
m_app.enable_camera_controls();
var camobj = m_scenes.get_active_camera();
init_camera_animation(camobj);
var main_canvas = m_cont.get_canvas();
main_canvas.addEventListener("mouseup", main_canvas_up);
main_canvas.addEventListener("mousedown", main_canvas_down);
}
var DEBUG = (m_version.type() === "DEBUG");
var ANIM_TIME = 2;
var APP_ASSETS_PATH = m_cfg.get_std_assets_path() + "code_snippets/camera_animation/";
var _anim_stop = false;
var _delta_target = ANIM_TIME;
var _cam_anim = {
timeline: -ANIM_TIME,
starting_eye: new Float32Array(3),
starting_target: new Float32Array(3),
final_eye: new Float32Array(3),
final_target: new Float32Array(3),
current_eye: new Float32Array(3),
current_target: new Float32Array(3)
}
var _vec3_tmp = new Float32Array(3);
function main_canvas_up(e) {
if(e.button != 0)
return;
if(e.preventDefault)
e.preventDefault();
var obj = m_scenes.pick_object(e.clientX, e.clientY);
if (obj)
switch(m_scenes.get_object_name(obj)) {
case "Cube":
var target = m_scenes.get_object_by_name("Cube");
var eye = m_scenes.get_object_by_name("Camera");
break;
case "Cone":
var target = m_scenes.get_object_by_name("Cone");
var eye = m_scenes.get_object_by_name("Camera");
break;
default:
return;
}
if (eye && target) {
var camobj = m_scenes.get_active_camera();
var pos_view = m_trans.get_translation(eye);
var pos_target = m_trans.get_translation(target);
start_camera_animation(camobj, pos_view, pos_target);
}
}
function main_canvas_down(e) {
if (e.button != 0)
return;
var camobj = m_scenes.get_active_camera();
if (m_ctl.get_sensor_value(camobj, "CAMERA_MOVE", 0) - _cam_anim.timeline
< ANIM_TIME)
_anim_stop = true;
}
function start_camera_animation(camobj, pos_view, pos_target) {
// retrieve camera current position
m_cam.target_get_pivot(camobj, _cam_anim.current_target);
m_trans.get_translation(camobj, _cam_anim.current_eye);
// set camera starting position
m_vec3.copy(_cam_anim.current_target, _cam_anim.starting_target);
m_vec3.copy(_cam_anim.current_eye, _cam_anim.starting_eye);
// set camera final position
m_vec3.copy(pos_view, _cam_anim.final_eye);
m_vec3.copy(pos_target, _cam_anim.final_target);
// start animation
_delta_target = ANIM_TIME;
_cam_anim.timeline = m_time.get_timeline();
}
function init_camera_animation(camobj) {
var t_sensor = m_ctl.create_timeline_sensor();
var e_sensor = m_ctl.create_elapsed_sensor();
var logic_func = function(s) {
// s[0] = m_time.get_timeline() (t_sensor value)
return s[0] - _cam_anim.timeline < ANIM_TIME;
}
var cam_move_cb = function(camobj, id, pulse) {
if (pulse == 1) {
if (_anim_stop) {
_cam_anim.timeline = -ANIM_TIME;
return;
}
m_app.disable_camera_controls();
// elapsed = frame time (e_sensor value)
var elapsed = m_ctl.get_sensor_value(camobj, id, 1);
var delta = elapsed / ANIM_TIME;
m_vec3.subtract(_cam_anim.final_eye, _cam_anim.starting_eye, _vec3_tmp);
m_vec3.scaleAndAdd(_cam_anim.current_eye, _vec3_tmp, delta, _cam_anim.current_eye);
_delta_target -= elapsed;
delta = 1 - _delta_target * _delta_target / (ANIM_TIME * ANIM_TIME);
m_vec3.subtract(_cam_anim.final_target, _cam_anim.starting_target, _vec3_tmp);
m_vec3.scaleAndAdd(_cam_anim.starting_target, _vec3_tmp, delta, _cam_anim.current_target);
m_cam.target_set_trans_pivot(camobj, _cam_anim.current_eye, _cam_anim.current_target);
} else {
m_app.enable_camera_controls(false);
if (!_anim_stop)
m_cam.target_set_trans_pivot(camobj, _cam_anim.final_eye,
_cam_anim.final_target);
else
_anim_stop = false;
}
}
m_ctl.create_sensor_manifold(camobj, "CAMERA_MOVE", m_ctl.CT_CONTINUOUS,
[t_sensor, e_sensor], logic_func, cam_move_cb);
}
});
// import the app module and start the app by calling the init method
b4w.require("marbleblast").init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment