Ejemplo n.º 1
0
/**
 * Fix camera rotation on target.
 * uses _mat3_tmp, _mat3_tmp2
 */
function cam_rotate_to(quat, dir, dest) {
    // convenient to use 3x3 matrix
    var mat_dst = _mat3_tmp;

    var x_cam_world = mat_dst.subarray(0, 3);
    var y_cam_world = mat_dst.subarray(3, 6);
    var z_cam_world = mat_dst.subarray(6, 9);

    m_vec3.copy(dir, y_cam_world);
    m_vec3.negate(y_cam_world, y_cam_world);
    m_vec3.normalize(y_cam_world, y_cam_world);

    var up_down = Boolean(Math.abs(m_vec3.dot(dir, m_util.AXIS_Y)) > 0.999999);

    if (up_down) {
        var mat_src = m_mat3.fromQuat(m_quat.normalize(quat, dest), _mat3_tmp2);
        m_vec3.copy(mat_src.subarray(0, 3), x_cam_world);
    } else
        m_vec3.cross(m_util.AXIS_Y, y_cam_world, x_cam_world);

    m_vec3.normalize(x_cam_world, x_cam_world);

    m_vec3.cross(x_cam_world, y_cam_world, z_cam_world);
    m_vec3.normalize(z_cam_world, z_cam_world);

    m_quat.fromMat3(mat_dst, dest);
    m_quat.normalize(dest, dest);
}
Ejemplo n.º 2
0
function angle(pos, pos1, pos2) {
    var vec1 = [];
    var vec2 = [];
    m_vec3.subtract(pos1, pos, vec1);
    m_vec3.subtract(pos2, pos, vec2);

    m_vec3.normalize(vec1, vec1);
    m_vec3.normalize(vec2, vec2);

    return Math.acos(m_vec3.dot(vec1, vec2));
}
Ejemplo n.º 3
0
/**
 * Apply rotation to quat
 */
function rotate_to(trans, quat, target) {
    var dir_from = _vec3_tmp;
    m_util.quat_to_dir(quat, m_util.AXIS_MY, dir_from);
    m_vec3.normalize(dir_from, dir_from);

    var dir_to = _vec3_tmp_2;
    m_vec3.subtract(target, trans, dir_to);
    m_vec3.normalize(dir_to, dir_to);

    var rotation = _vec4_tmp;
    m_quat.rotationTo(dir_from, dir_to, rotation);

    m_quat.multiply(rotation, quat, quat);
}
Ejemplo n.º 4
0
function hor_rot(ev_track, cur_dir, elapsed, new_rot_q, new_hor_dir) {

    var cur_rot_q   = _quat4_tmp_2;
    var cur_hor_dir = _vec3_tmp_4;

    m_trans.get_rotation_quat(ev_track.collider, cur_rot_q);
    m_vec3.transformQuat(m_util.AXIS_Z, cur_rot_q, cur_dir);

    cur_hor_dir[0]  = cur_dir[0];
    cur_hor_dir[1]  = 0;
    cur_hor_dir[2]  = cur_dir[2];
    m_vec3.normalize(cur_hor_dir, cur_hor_dir);

    var vec_dot = m_vec3.dot(cur_hor_dir, new_hor_dir);

    var angle_to_turn = Math.acos(vec_dot);
    var angle_ratio   = Math.abs(angle_to_turn) / Math.PI;
    var slerp         = elapsed / angle_ratio * ev_track.rot_speed * ev_track.rotation_mult;

    m_quat.rotationTo(cur_hor_dir, new_hor_dir, new_rot_q);
    m_quat.rotationTo(m_util.AXIS_Z, cur_hor_dir, cur_rot_q);

    if (Math.abs(vec_dot) >= 1) {
        m_quat.copy(cur_rot_q, new_rot_q);
        return;
    }

    m_quat.multiply(new_rot_q, cur_rot_q, new_rot_q);
    m_quat.slerp(cur_rot_q, new_rot_q, Math.min(slerp, 1), new_rot_q);
}
Ejemplo n.º 5
0
function rotate_to_dest(golem_wrapper, elapsed) {

    var golem_empty = golem_wrapper.empty;
    var dest_pos = golem_wrapper.dest_pos;

    var trans       = _vec3_tmp;
    var cur_dir     = _vec3_tmp_2;
    var dir_to_dest = _vec3_tmp_3;
    var cur_rot_q   = _quat4_tmp;
    var new_rot_q   = _quat4_tmp2;

    m_trans.get_translation(golem_empty, trans);
    m_trans.get_rotation(golem_empty, cur_rot_q);
    m_vec3.transformQuat(m_util.AXIS_MY, cur_rot_q, cur_dir);

    m_vec3.subtract(dest_pos, trans, dir_to_dest);
    m_vec3.normalize(dir_to_dest, dir_to_dest);

    m_quat.rotationTo(cur_dir, dir_to_dest, new_rot_q);
    m_quat.multiply(new_rot_q, cur_rot_q, new_rot_q);

    var vec_dot = m_vec3.dot(cur_dir, dir_to_dest);
    vec_dot = vec_dot > 1? 1: vec_dot < -1? -1: vec_dot;

    var angle_to_turn = Math.acos(vec_dot);
    var angle_ratio   = Math.abs(angle_to_turn) / Math.PI;
    var slerp         = elapsed / angle_ratio * m_conf.GOLEM_ROT_SPEED;

    m_quat.slerp(cur_rot_q, new_rot_q, Math.min(slerp, 1), new_rot_q);
    m_trans.set_rotation_v(golem_empty, new_rot_q);

    return angle_to_turn
}
Ejemplo n.º 6
0
/**
 * Rotate camera to fix UP direction.
 * Uses _vec3_tmp, _vec3_tmp_2, _vec3_tmp_3
 */
function correct_up(camobj, y_axis) {
    var render = camobj._render;
    var quat = render.quat;

    var y_world = y_axis;

    // local camera Y in world space
    var y_cam_world = m_util.quat_to_dir(render.quat, m_util.AXIS_Y, _vec3_tmp)
    m_vec3.normalize(y_cam_world, y_cam_world);
    // handle extreme case (camera looks UP or DOWN)
    if (Math.abs(m_vec3.dot(y_world, y_cam_world)) > 0.999999)
        var rotation = m_quat.identity(_quat4_tmp);
    else {

        var x_cam_world_new = m_vec3.cross(y_world, y_cam_world, _vec3_tmp_2);

        m_vec3.normalize(x_cam_world_new, x_cam_world_new);

        if (render.move_style == m_cam.MS_TARGET_CONTROLS) {
            if (render.target_cam_upside_down)
                m_vec3.negate(x_cam_world_new, x_cam_world_new);
        } else {
            // Y coord of local camera Z axis in parent(!) space
            var z_cam_world = m_util.quat_to_dir(render.quat, m_util.AXIS_Z, _vec3_tmp_3);
            if (m_vec3.dot(z_cam_world, y_axis) > 0)
                m_vec3.negate(x_cam_world_new, x_cam_world_new);
        }

        var x_cam_world = m_util.quat_to_dir(render.quat, m_util.AXIS_X, _vec3_tmp_3);
        m_vec3.normalize(x_cam_world, x_cam_world);

        var cosine = m_util.clamp(m_vec3.dot(x_cam_world, x_cam_world_new), -1, 1);
        var angle = Math.acos(cosine);

        if (cosine <= -0.999999)
            var rotation = m_quat.setAxisAngle(y_cam_world, angle, _quat4_tmp);
        else
            var rotation = m_quat.rotationTo(x_cam_world, x_cam_world_new, _quat4_tmp);

        m_quat.normalize(rotation, rotation);
    }

    m_quat.multiply(rotation, quat, quat);
    m_cam.update_camera_upside_down(camobj);
}
Ejemplo n.º 7
0
/**
 * Apply rotation to quat only for limited angles
 */
function rotate_to_limits(trans, quat, target, limit_angle) {
    var dir_from = _vec3_tmp;
    m_util.quat_to_dir(quat, m_util.AXIS_MY, dir_from);
    m_vec3.normalize(dir_from, dir_from);

    var dir_to = _vec3_tmp_2;
    m_vec3.subtract(target, trans, dir_to);
    m_vec3.normalize(dir_to, dir_to);

    if (m_vec3.dot(dir_from, dir_to) < Math.cos(limit_angle))
        return false;
    else {
        var rotation = _vec4_tmp;
        m_quat.rotationTo(dir_from, dir_to, rotation);
        m_quat.multiply(rotation, quat, quat);
        return true;
    }
}
Ejemplo n.º 8
0
function change_stereo(stereo) {
    deferred_close();

    if (_stereo_mode == stereo)
        return;

    switch (stereo) {
    case "NONE":
        m_storage.set("stereo", "NONE");
        if (_stereo_mode == "ANAGLYPH")
            reload_app()
        else {
            m_hmd.disable_hmd();
            _pick = m_scs.pick_object;
        }
        break;
    case "ANAGLYPH":
        m_storage.set("stereo", "ANAGLYPH");
        reload_app()
        break;
    case "HMD":
        m_storage.set("stereo", "NONE");
        if (_stereo_mode == "NONE") {
            if (m_input.can_use_device(m_input.DEVICE_HMD))
                m_hmd_conf.update();
            if (m_camera_anim.is_auto_rotate()) {
                stop_camera();
                update_auto_rotate_button();
            }

            var cam = m_scs.get_active_camera();
            var pos = m_trans.get_translation(cam, _vec3_tmp);
            var quat = m_trans.get_rotation(cam, _quat_tmp);
            var new_x = m_vec3.transformQuat(m_util.AXIS_X, quat, _vec3_tmp2);
            new_x[2] = 0;
            m_vec3.normalize(new_x, new_x);
            var offset_quat = m_quat.rotationTo(m_util.AXIS_X, new_x, _quat_tmp);
            m_hmd.set_position(pos);
            m_hmd.set_rotate_quat(offset_quat);

            m_hmd.enable_hmd(m_hmd.HMD_ALL_AXES_MOUSE_NONE);

            _pick = m_scs.pick_center;
            // Check if app is in fullscreen mode.
            var fullscreen_button = document.querySelector("#fullscreen_on_button");
            if (fullscreen_button)
                enter_fullscreen();
        } else {
            m_storage.set("stereo", "NONE");
            reload_app()
        }
        break;
    }

    _stereo_mode = stereo;
    set_stereo_button(stereo);
}
Ejemplo n.º 9
0
/**
 * Rotate camera to fix UP direction.
 * @methodOf constraints
 */
function correct_up(camobj, y_axis) {
    var quat = camobj._render.quat;

    // convenient to get 3x3 matrix
    var rmat = m_mat3.fromQuat(quat, _mat3_tmp);

    var y_world = y_axis;

    // local camera Y in world space
    var y_cam_world = _vec3_tmp;
    y_cam_world[0] = rmat[3];
    y_cam_world[1] = rmat[4];
    y_cam_world[2] = rmat[5];

    // handle extreme case (camera looks UP or DOWN)
    if (Math.abs(m_vec3.dot(y_world, y_cam_world)) > 0.999)
        return;

    var x_cam_world_new = m_vec3.cross(y_world, y_cam_world, y_cam_world);
    
    m_vec3.normalize(x_cam_world_new, x_cam_world_new);

    // Y coord of local camera Z axis in world space
    var z_cam_world_y = rmat[7];
    if (z_cam_world_y > 0) {
        x_cam_world_new[0] *= -1;
        x_cam_world_new[1] *= -1;
        x_cam_world_new[2] *= -1;
    }

    // _vec_3_tmp is available now
    var x_cam_world = _vec3_tmp_2;
    x_cam_world[0] = rmat[0];
    x_cam_world[1] = rmat[1];
    x_cam_world[2] = rmat[2];
    m_vec3.normalize(x_cam_world, x_cam_world);

    var rotation = _quat4_tmp;
    m_quat.rotationTo(x_cam_world, x_cam_world_new, rotation);

    m_quat.multiply(rotation, quat, quat);

}
Ejemplo n.º 10
0
function calc_normal_by_pos(pos0, pos1, pos2) {

    var vec1 = [], vec2 = [], normal = [];

    m_vec3.subtract(pos1, pos0, vec1);
    m_vec3.subtract(pos2, pos0, vec2);
    m_vec3.cross(vec1, vec2, normal);
    m_vec3.normalize(normal, normal); // required

    return normal;
}
Ejemplo n.º 11
0
 var collision_cb = function(obj, id, pulse) {
     if (pulse == 1) {
         var col_pt = m_ctl.get_sensor_payload(obj, id, 1);
         var trans = m_trans.get_translation(obj, _vec3_tmp);
         var delta = _vec3_tmp2;
         m_vec3.sub(trans, col_pt, delta);
         m_vec3.normalize(delta, delta);
         m_vec3.scale(delta, COLL_RESPONSE_NORMAL_FACTOR, delta);
         m_vec3.add(trans, delta, trans);
         m_trans.set_translation_v(obj, trans);
     }
 }
Ejemplo n.º 12
0
function rotate_to(trans, target, quat) {
    var dir_from = m_util.quat_to_dir(quat, m_util.AXIS_MZ, _vec3_tmp3);
    var dir_to   = m_vec3.subtract(target, trans, _vec3_tmp4);

    m_vec3.normalize(dir_to, dir_to);

    var rotation = m_quat.rotationTo(dir_from, dir_to, _vec4_tmp);

    m_quat.multiply(rotation, quat, quat);
    m_quat.normalize(quat, quat);

    return quat;
}
Ejemplo n.º 13
0
function normalize_normal(i, normals) {
    var normal = new Float32Array(NOR_NUM_COMP);

    for (var j = 0; j < NOR_NUM_COMP; j++) {
        var index = NOR_NUM_COMP * i + j;
        normal[j] = normals[index];
    }
    m_vec3.normalize(normal, normal);
    for (var j = 0; j < NOR_NUM_COMP; j++) {
        var index = NOR_NUM_COMP * i + j;
        normals[index] = normal[j];
    }
}
Ejemplo n.º 14
0
function translate(obj, target, elapsed, accurate) {
    var trans = _vec3_tmp;
    var cur_dir = _vec3_tmp2;
    var cur_rot_q = _vec4_tmp;
    var dist = _vec3_tmp3;

    m_trans.get_rotation(obj, cur_rot_q);
    m_trans.get_translation(obj, trans);
    m_vec3.subtract(target, trans, dist);

    var passed_dist = _gs.speed * elapsed;

    if (passed_dist * passed_dist < m_vec3.dot(dist, dist)) {
        if (accurate) {
            m_vec3.normalize(dist, cur_dir);
        } else {
            m_vec3.transformQuat(m_util.AXIS_MY, cur_rot_q, cur_dir);
            m_vec3.normalize(cur_dir, cur_dir);
        }
        m_vec3.scaleAndAdd(trans, cur_dir, passed_dist, trans);
    } else {
        trans = target;
    }
    // ray_test for projecting the position on the surface
    var ray_test_cb = function (id, hit_fract, obj_hit, hit_time, hit_pos, hit_norm) {
        trans[2] = hit_pos[2];
        m_trans.set_translation_v(obj, trans);
    };
    m_phy.append_ray_test_ext(obj, [0, 0, 0.5], [0, 0, -1], "raytest_floor",
        ray_test_cb, true, false, true, true);
    m_trans.set_translation_v(obj, trans);

    m_vec3.subtract(target, trans, dist);
    dist[2] = 0;
    return m_vec3.dot(dist, dist);
}
Ejemplo n.º 15
0
exports.lamp_to_light = function(lamp_obj) {

    var data = lamp_obj["data"];

    var light = init_light(data["type"]);

    light.name = lamp_obj["name"];

    light.use_diffuse = data["use_diffuse"];
    light.use_specular = data["use_specular"];

    var quat = lamp_obj._render.quat;
    var dir = m_util.quat_to_dir(quat, m_util.AXIS_Y, []);

    // though dir seems to be normalized, do it explicitely
    m_vec3.normalize(dir, dir);

    light.direction[0] = dir[0];
    light.direction[1] = dir[1];
    light.direction[2] = dir[2];

    light.color[0] = data["color"][0];
    light.color[1] = data["color"][1];
    light.color[2] = data["color"][2];

    light.energy = data["energy"];

    update_color_intensity(light);

    light.distance = data["distance"];

    if (light.type === "POINT" || light.type === "SPOT")
        light.distance = data["distance"];

    if (light.type === "SPOT") {
        light.spot_blend = data["spot_blend"];
        light.spot_size = data["spot_size"];
    } else if (light.type === "POINT")
        light.spot_size = Math.PI / 2;

    light.generate_shadows = data["b4w_generate_shadows"];
    light.dynamic_intensity = data["b4w_dynamic_intensity"];

    lamp_obj._light = light;
}
Ejemplo n.º 16
0
// using _quat_tmp, _vec3_tmp, _vec3_tmp2
function spawn_asteroid_random_pos(asteroid, cam_coord) {
    asteroid.active = true;
    // set target point
    var target_coord = m_vec3.copy(cam_coord, _vec3_tmp2);
    target_coord[0] += ASTEROID_DEFAULT_TARGET_OFFSET * (2 * Math.random() - 1);
    target_coord[1] += ASTEROID_DEFAULT_TARGET_OFFSET * (2 * Math.random() - 1);
    target_coord[2] = 0;

    // set spawn point
    var spawn_coord = m_vec3.copy(cam_coord, _vec3_tmp);
    spawn_coord[0] += ASTEROID_DEFAULT_SPAWN_OFFSET * (2 * Math.random() - 1);
    spawn_coord[1] += ASTEROID_DEFAULT_SPAWN_OFFSET * Math.random() / 2;
    spawn_coord[2] = -100;

    var ast_obj = asteroid.ast_obj;
    m_trans.set_translation_v(ast_obj, spawn_coord);

    var ast_copy_obj = asteroid.ast_copy_obj;
    if (ast_copy_obj)
        m_trans.set_translation_v(ast_copy_obj, spawn_coord);

    // set velosity
    var dir = m_vec3.subtract(target_coord, spawn_coord, _vec3_tmp2);
    m_vec3.normalize(dir, dir);
    var velocity = m_vec3.scale(dir, _asteroid_speed, dir);
    _asteroid_speed = _asteroid_speed < ASTEROID_MAX_SPEED?
            _asteroid_speed + 1: _asteroid_speed;

    var cockpit_mesh_obj = _cockpit.cockpit_mesh_obj;
    if (cockpit_mesh_obj)
        m_obj.set_nodemat_value(cockpit_mesh_obj, ["screen", "speed"],
                1 - 0.1 * ((_asteroid_speed - ASTEROID_DEFAULT_SPEED) /
                (ASTEROID_MAX_SPEED - ASTEROID_DEFAULT_SPEED) * 8 % 8));

    m_vec3.copy(velocity, asteroid.velosity);
    // apply torque
    var axis = m_vec3.set(2 * Math.random() - 1, 2 * Math.random() - 1, 2 * Math.random() - 1, _vec3_tmp);
    asteroid.angular_velosity = m_quat.setAxisAngle(axis,
            Math.PI * (2 * Math.random() - 1) * 10, asteroid.angular_velosity);

    // var element = document.getElementById("score");
    // element.innerHTML = _asteroid_speed - 20;
}
Ejemplo n.º 17
0
function init_light() {

    var light = {};

    light.direction = new Float32Array(3);
    m_vec3.normalize(light.direction, light.direction);

    light.color = new Float32Array(3);
    light.energy = 1.0;

    light.color_intensity = new Float32Array(3);
    update_color_intensity(light);

    light.distance = 25.0;
    
    light.generate_shadows = false;

    return light;
}
Ejemplo n.º 18
0
function move_destination_if_too_close(ev_track, dest, cur_loc) {

    var cur_rot_q = _quat4_tmp_2;
    var cur_hor_dir = _vec3_tmp_3;

    var speed = ev_track.speed;
    var rot_speed = ev_track.rot_speed;

    m_trans.get_rotation_quat(ev_track.collider, cur_rot_q);
    m_vec3.transformQuat(m_util.AXIS_Z, cur_rot_q, cur_hor_dir);
    cur_hor_dir[1] = 0;
    m_vec3.normalize(cur_hor_dir, cur_hor_dir);

    var sin_half_rot_angle = Math.sin(rot_speed/2);
    var walk_radius = 0.5 * speed / sin_half_rot_angle;

    var dist = m_vec3.dist(dest, cur_loc);
    if (dist < 2.0 * walk_radius)
        m_vec3.scaleAndAdd(dest, cur_hor_dir, (2.0 * walk_radius - dist), dest);
}
Ejemplo n.º 19
0
/** 
 * Generate array of particles'es linear and angular speed
 * vec4(linear_x, linear_y, linear_z, angular)
 */
function gen_velocities(pcount, vel_factor_rand, ang_vel_mode, ang_vel_factor, is_billboard)
{
    var varr = [];

    for (var i = 0; i < pcount; i++) {

        var vvec = [_rand() - 0.5, _rand() - 0.5, _rand() - 0.5];
        m_vec3.normalize(vvec, vvec);

        varr.push(vel_factor_rand * vvec[0]);
        varr.push(vel_factor_rand * vvec[1]);
        varr.push(vel_factor_rand * vvec[2]);

        switch(ang_vel_mode) {
        case "NONE":
            varr.push(0.0);
            break;
        // NOTE: "SPIN" renamed to "VELOCITY" in blender 2.63
        case "SPIN":
        case "VELOCITY":
            varr.push(ang_vel_factor);
            break;
        case "RAND":
            varr.push(ang_vel_factor*2*(_rand() - 0.5));
            break;
        default:
            throw("Undefined velocity factor");
        }
        
        if (is_billboard) {
            var last = varr.slice(-4);
            for (var j = 0; j < 12; j++) {
                varr.push(last[j % 4]);
            }
        }
    }
    
    var vels = new Float32Array(varr);
    return vels;

}
Ejemplo n.º 20
0
exports.calc_ray = function(camobj, xpix, ypix, dest) {

    if (!dest)
        var dest = new Float32Array(3);

    var cam = camobj._render.cameras[0];

    switch (cam.type) {
    case camera.TYPE_PERSP:
    case camera.TYPE_PERSP_ASPECT:
    case camera.TYPE_STEREO_LEFT:
    case camera.TYPE_STEREO_RIGHT:
        var top_1m = Math.tan(cam.fov * Math.PI / 360.0);
        var right_1m = top_1m * cam.aspect;

        var dir = _vec4_tmp;

        // in the camera's local space
        dir[0] = (2.0 * xpix / cam.width - 1.0) * right_1m;
        dir[1] = -1;
        dir[2] = (2.0 * ypix / cam.height - 1.0) * top_1m;
        dir[3] = 0;

        var wm = camobj._render.world_matrix;
        m_vec4.transformMat4(dir, wm, dir);

        dest[0] = dir[0];
        dest[1] = dir[1];
        dest[2] = dir[2];

        m_vec3.normalize(dest, dest);

        return dest;
    default:
        m_print.error("Non-compatible camera");
        return dest;
    }
}
Ejemplo n.º 21
0
function rotate_to_dir(obj, dir_to_dest, elapsed) {
    var cur_dir = _vec3_tmp1;
    var cur_rot_q = _vec4_tmp;
    var new_rot_q = _vec4_tmp2;

    m_trans.get_rotation(obj, cur_rot_q);
    m_vec3.transformQuat(m_util.AXIS_MY, cur_rot_q, cur_dir);

    dir_to_dest[2] = 0;
    m_vec3.normalize(dir_to_dest, dir_to_dest);
    m_quat.rotationTo(cur_dir, dir_to_dest, new_rot_q);
    m_quat.multiply(new_rot_q, cur_rot_q, new_rot_q);

    var vec_dot = m_vec3.dot(cur_dir, dir_to_dest);
    vec_dot = vec_dot > 1 ? 1 : vec_dot < -1 ? -1 : vec_dot;

    var angle_to_turn = Math.acos(vec_dot);
    var slerp = elapsed * (_gs.speed / _gs.dist_err) / Math.abs(angle_to_turn)*Math.PI/2;
    slerp = Math.min(slerp, 1);
    m_quat.slerp(cur_rot_q, new_rot_q, slerp, new_rot_q);
    m_trans.set_rotation_v(obj, new_rot_q);

    return angle_to_turn - angle_to_turn * slerp;
}
Ejemplo n.º 22
0
    var move_cam_cb = function(obj, id, pulse) {
        var cam_obj = m_scenes.get_active_camera();

        if (!cam_obj)
            return;

        if (pulse > 0) {
            // NOTE: init part
            if (!updated_eye_data) {
                var hmd_left_fov = get_fov("left", _vec4_tmp);
                var hmd_right_fov = get_fov("right", _vec4_tmp2);
                if (hmd_left_fov && hmd_left_fov)
                    m_cam.set_hmd_fov(cam_obj, hmd_left_fov, hmd_right_fov);

                var eye_distance = get_eye_distance();
                if (eye_distance)
                    m_cam.set_eye_distance(cam_obj, eye_distance);

                var hmd_params = {};
                if (_hmd_device.deviceName.toLowerCase().indexOf("oculus") !== -1)
                    var hmd_name = "oculus";
                else
                    var hmd_name = "default";

                hmd_params.distortion_coefs = [
                        _devices_params[hmd_name]["distortion_coefs"][0],
                        _devices_params[hmd_name]["distortion_coefs"][1]
                ];

                hmd_params.chromatic_aberration_coefs = [
                        _devices_params[hmd_name]["chromatic_aberration_coefs"][0],
                        _devices_params[hmd_name]["chromatic_aberration_coefs"][1],
                        _devices_params[hmd_name]["chromatic_aberration_coefs"][2],
                        _devices_params[hmd_name]["chromatic_aberration_coefs"][3]
                ];

                hmd_params.distortion_scale  = _devices_params[hmd_name]["distortion_scale"];
                // TODO: set distortion_offset
                hmd_params.distortion_offset = 0.0;
                hmd_params.enable_hmd_stereo = true;

                m_scenes.set_hmd_params(hmd_params);

                var canvas_container_elem = m_cont.get_container();
                var ccw = canvas_container_elem.clientWidth;
                var cch = canvas_container_elem.clientHeight;
                m_cont.resize(ccw, cch, true);

                updated_eye_data = true;

                _last_cam_quat = m_trans.get_rotation(cam_obj, _last_cam_quat);
                reset_hmd();
            }

            // NOTE: It is executed every frame.
            // uses _vec3_tmp, _vec3_tmp2, _vec3_tmp3, _quat_tmp, _quat_tmp2
            if (m_cam.is_eye_camera(cam_obj)) {
                if (control_type == HMD_ALL_AXES_MOUSE_NONE) {
                    var hmd_quat = get_sensor_orientation(_quat_tmp);

                    if (hmd_quat) {
                        var quat = m_quat.setAxisAngle(m_util.AXIS_X, Math.PI / 2, _quat_tmp2);
                        m_quat.normalize(quat, quat);
                        hmd_quat = m_quat.multiply(hmd_quat, quat, _quat_tmp);
                        var up_axis = m_vec3.transformQuat(m_util.AXIS_Z, hmd_quat, _vec3_tmp);
                        m_cam.set_vertical_axis(cam_obj, up_axis);
                        m_trans.set_rotation_v(cam_obj, hmd_quat);
                    }
                } else if (control_type == HMD_ROLL_PITCH_MOUSE_YAW ||
                        control_type == HMD_ALL_AXES_MOUSE_YAW) {
                    var hmd_quat = get_sensor_orientation(_quat_tmp);

                    if (hmd_quat) {
                        // NOTE: hmd_quat to WEBGL axis orientation
                        var quat = m_quat.setAxisAngle(m_util.AXIS_X, Math.PI / 2,
                                _quat_tmp2);
                        m_quat.normalize(quat, quat);
                        hmd_quat = m_quat.multiply(hmd_quat, quat, _quat_tmp);

                        var cam_quat = m_trans.get_rotation(cam_obj,
                                _quat_tmp2);
                        var inv_cam_quat = m_quat.invert(cam_quat,
                                _quat_tmp2);
                        var diff_cam_quat = m_quat.multiply(_last_cam_quat,
                                inv_cam_quat, _quat_tmp2);

                        var cur_vertical_axis = m_cam.get_vertical_axis(cam_obj,
                                _vec3_tmp);
                        if (Math.abs(cur_vertical_axis[2]) < Math.PI / 4)
                            var first_horiz_vec = m_vec3.cross(cur_vertical_axis,
                                    m_util.AXIS_Z, _vec3_tmp2);
                        else if (Math.abs(cur_vertical_axis[1]) < Math.PI / 4)
                            var first_horiz_vec = m_vec3.cross(cur_vertical_axis,
                                    m_util.AXIS_Y, _vec3_tmp2);

                        m_vec3.normalize(first_horiz_vec, first_horiz_vec);

                        var rotated_first_horiz_vec = m_vec3.transformQuat(
                                first_horiz_vec, diff_cam_quat, _vec3_tmp3);

                        var vertical_coef = m_vec3.dot(cur_vertical_axis,
                                rotated_first_horiz_vec);
                        var second_horiz_vec = m_vec3.scaleAndAdd(rotated_first_horiz_vec,
                                cur_vertical_axis, -vertical_coef, _vec3_tmp3);
                        m_vec3.normalize(second_horiz_vec, second_horiz_vec);

                        var sign_horiz_vec = m_vec3.cross(cur_vertical_axis,
                                first_horiz_vec, _vec3_tmp);
                        var abs_yaw_angle = Math.acos(m_util.clamp(
                                m_vec3.dot(first_horiz_vec, second_horiz_vec),
                                0, 1));
                        var sign_yaw_angle = m_util.sign(m_vec3.dot(
                                second_horiz_vec, sign_horiz_vec));
                        var diff_yaw_cam_angle = abs_yaw_angle * sign_yaw_angle;

                        _yaw_cam_angle += diff_yaw_cam_angle;
                        var yaw_cam_quat = m_quat.setAxisAngle(m_util.AXIS_Y,
                                -_yaw_cam_angle, _quat_tmp2);

                        if (control_type == HMD_ALL_AXES_MOUSE_YAW) {
                            var new_cam_quat = m_quat.multiply(yaw_cam_quat,
                                    hmd_quat, _quat_tmp);
                        } else {
                            var yaw_hmd_quat = m_util.quat_project(hmd_quat, m_util.AXIS_MY,
                                    m_util.AXIS_Y, m_util.AXIS_MZ, _quat_tmp3);
                            var yaw_hmd_inv_quat = m_quat.invert(yaw_hmd_quat, _quat_tmp3);
                            var vertical_hmd_quat = m_quat.multiply(
                                    yaw_hmd_inv_quat, hmd_quat, _quat_tmp3);

                            var new_cam_quat = m_quat.multiply(yaw_cam_quat,
                                    vertical_hmd_quat, _quat_tmp);
                        }
                        var up_axis = m_vec3.transformQuat(m_util.AXIS_Z,
                                new_cam_quat, _vec3_tmp);
                        m_cam.set_vertical_axis(cam_obj, up_axis);

                        m_trans.set_rotation_v(cam_obj, new_cam_quat);
                        m_quat.copy(new_cam_quat, _last_cam_quat)
                    }
                }
            }
        }
    }
Ejemplo n.º 23
0
exports.track_to_target = function(cam_obj, target, rot_speed, zoom_mult,
                                    zoom_time, zoom_delay, callback, zoom_cb) {

    if (!cam_obj)
        return;

    if (!target)
        return;
    else if (m_util.is_vector(target))
        var obj_pos = target;
    else {
        var obj_pos = _vec3_tmp3;
        m_trans.get_object_center(target, false, obj_pos);
    }

    var rot_sp  = rot_speed  || 1;
    var zoom_m  = zoom_mult  || 2;
    var zoom_t  = zoom_time  || 1;
    var zoom_d  = zoom_delay || 1;

    var def_dir    = _vec3_tmp2;
    def_dir[0]     = 0;
    def_dir[1]     = -1;
    def_dir[2]     = 0;

    var cam_quat   = m_trans.get_rotation_quat(cam_obj);
    var cam_dir    = m_util.quat_to_dir(cam_quat, def_dir);
    var cam_angles = m_cam.get_angles(cam_obj);

    // direction vector to the target
    var dir_to_obj = _vec3_tmp;
    var cam_pos    = m_trans.get_translation(cam_obj);
    m_vec3.subtract(obj_pos, cam_pos, dir_to_obj);
    m_vec3.normalize(dir_to_obj, dir_to_obj);

    // quaternion between current camera vector and new camera vector
    var rot_quat = m_quat.rotationTo(cam_dir, dir_to_obj, m_quat.create());

    // final quaternion for the camera
    var quat = _quat4_tmp;
    m_quat.multiply(rot_quat, cam_quat, quat);

    m_util.correct_cam_quat_up(quat, false);

    // distance to zoom point
    var sub_vec = _vec3_tmp2;
    m_vec3.subtract(obj_pos, cam_pos, sub_vec);
    var zoom_distance = m_vec3.length(sub_vec) * (1 - 1 / zoom_m);

    // destination angles
    var angle_to_obj_y = Math.asin(dir_to_obj[1]);
    var angle_to_obj_x =
                 Math.acos(-dir_to_obj[2] / Math.abs(Math.cos(angle_to_obj_y)));

    if (dir_to_obj[0] > 0)
        angle_to_obj_x = 2 * Math.PI - angle_to_obj_x;

    // delta rotate angles
    var angle_x = angle_to_obj_x - cam_angles[0];
    var angle_y = angle_to_obj_y - cam_angles[1];

    var cam_dir_z = _vec3_tmp3;
    cam_dir_z[0]  = 0;
    cam_dir_z[1]  = 0;
    cam_dir_z[2]  = -1;

    var cam_rot_quat = m_trans.get_rotation_quat(cam_obj);
    var cam_rot_dir  = m_util.quat_to_dir(cam_rot_quat, cam_dir_z);

    if (cam_rot_dir[1] < 0) {
        if (cam_dir[1] > 0)
            angle_y = angle_to_obj_y - Math.PI + cam_angles[1];
        else
            angle_y = angle_to_obj_y + Math.PI + cam_angles[1];

        if (angle_x > 0)
            angle_x = -Math.PI + angle_x;
        else
            angle_x = Math.PI + angle_x;

    } else {
        if(Math.abs(angle_x) > Math.PI)
            if (angle_x > 0)
                angle_x = angle_x - 2 * Math.PI;
            else
                angle_x = angle_x + 2 * Math.PI;
    }

    angle_y = -angle_y;

    // action conditions
    var cur_time       = 0;
    var elapsed        = m_ctl.create_elapsed_sensor();
    var rot_end_time_x = Math.abs(angle_x / rot_sp);
    var rot_end_time_y = Math.abs(angle_y / rot_sp);
    var rot_end_time   =
        rot_end_time_x > rot_end_time_y ? rot_end_time_x : rot_end_time_y;
    var zoom_end_time  = rot_end_time + zoom_t;
    var zoom_end_delay = zoom_end_time + zoom_d;
    var finish_time    = zoom_end_delay + zoom_t;

    var dest_ang_x   = angle_x;
    var dest_ang_y   = angle_y;
    var dest_trans_x = zoom_distance;

    var smooth_function = function(x) {
        var f = 6 * x * (1 - x);
        return f;
    }

    var track_cb = function(obj, id, pulse) {

        if (pulse) {
            var value = m_ctl.get_sensor_value(obj, id, 0);
            cur_time += value;

            if (cur_time < rot_end_time) {

                var delta_x = angle_x / rot_end_time * value;
                var delta_y = angle_y / rot_end_time * value;

                // smoothing
                var time_ratio = cur_time / rot_end_time;
                var slerp      = smooth_function(time_ratio);

                delta_x *= slerp;
                delta_y *= slerp;

                dest_ang_x -= delta_x;
                dest_ang_y -= delta_y;

                m_cam.rotate(obj, delta_x, delta_y);

            } else if (cur_time < zoom_end_time) {

                if (dest_ang_x) {
                    m_cam.rotate(obj, dest_ang_x, dest_ang_y);
                    dest_ang_x = 0;

                    if (zoom_cb)
                        zoom_cb();
                }

                var time_ratio = (cur_time - rot_end_time)/ zoom_t;
                var delta      = -zoom_distance * value / zoom_t;
                dest_trans_x  -= delta_x;

                delta *= smooth_function(time_ratio);
                m_trans.move_local(obj, 0, delta, 0);

            } else if (cur_time < zoom_end_delay) {
                if (dest_trans_x) {
                    m_trans.move_local(obj, 0, dest_trans_x, 0);
                    dest_trans_x = 0;
                }
                // waiting for zoom delay

            } else if (cur_time < finish_time) {
                var time_ratio = (cur_time - zoom_end_delay)/ zoom_t;
                var delta      = zoom_distance * value / zoom_t;

                delta *= smooth_function(time_ratio);
                m_trans.move_local(obj, 0, delta, 0);

            } else {
                m_trans.set_translation_v(obj, cam_pos);
                m_ctl.remove_sensor_manifold(obj, id);

                if (callback)
                    callback();
            }
        }
    }

    m_ctl.create_sensor_manifold(cam_obj,
                                "TRACK_TO_TARGET",
                                m_ctl.CT_CONTINUOUS,
                                [elapsed],
                                null,
                                track_cb);
}
Ejemplo n.º 24
0
exports.clamp_vertical_limits = function(obj) {
    var render = obj._render;

    if (render.vertical_limits !== null) {

        var angles = get_angles(obj, _vec2_tmp);
        var phi = angles[0];
        var theta = angles[1];

        var z_world_cam = m_util.quat_to_dir(render.quat, m_util.AXIS_Z, _vec3_tmp);
        var camera_upside_down = m_util.sign(z_world_cam[1]);

        // NOTE: overshoot case
        if (Math.abs(theta) > Math.PI / 4)
            if (camera_upside_down == 1)
                phi += Math.PI;

        // NOTE: clamping theta - [0, Pi]
        var clamping_theta = theta;        
        if (camera_upside_down == 1)
            clamping_theta = m_util.sign(theta) * Math.PI - theta;

        
        // NOTE: clamping
        var is_clamped = false;
        if (clamping_theta < -render.vertical_limits.down) {
            var new_theta = -render.vertical_limits.down;
            if (new_theta < -Math.PI / 2)
                new_theta = -Math.PI - new_theta;

            var return_rotation = -camera_upside_down * (new_theta - theta);

            // fix camera overshooting for limits smaller than PI/2
            if (camera_upside_down == 1 && render.vertical_limits.down < Math.PI / 2) {
                phi += Math.PI;
                return_rotation += Math.PI - 2 * render.vertical_limits.down;
            }
            is_clamped = true;

        }
        if (clamping_theta > render.vertical_limits.up) {
            var new_theta = render.vertical_limits.up;
            if (new_theta > Math.PI / 2)
                new_theta = Math.PI - new_theta;

            var return_rotation = -camera_upside_down * (new_theta - theta);

            // fix camera overshooting for limits smaller than PI/2
            if (camera_upside_down == 1 && render.vertical_limits.up < Math.PI / 2) {
                phi += Math.PI;
                return_rotation -= Math.PI - 2 * render.vertical_limits.up;
            }
            is_clamped = true;
        }   

        if (is_clamped) {
            // NOTE: if camera has TARGET move style, then change translation 
            // vector related to theta angle
            if (render.move_style == exports.MS_TARGET_CONTROLS) {
                
                var sin_phi = Math.sin(phi);
                var cos_phi = Math.cos(phi);

                var sin_theta = Math.sin(new_theta);
                var cos_theta = Math.cos(new_theta);

                // camera trans relative to target location
                render.trans[0] -= obj._constraint.target[0];
                render.trans[1] -= obj._constraint.target[1];
                render.trans[2] -= obj._constraint.target[2];

                var len = m_vec3.length(render.trans);
                render.trans[0] = cos_theta * sin_phi;
                render.trans[1] = -sin_theta;
                render.trans[2] = cos_theta * cos_phi;

                m_vec3.scale(render.trans, len / m_vec3.length(render.trans), render.trans);
                
                // returning into world coordinate system
                render.trans[0] += obj._constraint.target[0];
                render.trans[1] += obj._constraint.target[1];
                render.trans[2] += obj._constraint.target[2];
            }

            // NOTE: change camera quaternion 
            var axis = m_vec3.transformQuat(m_util.AXIS_X, render.quat, _vec3_tmp);
            // NOTE: avoid accumulating accuracy errors
            m_vec3.normalize(axis, axis);
            
            var clamp_rotation = m_quat.setAxisAngle(axis, return_rotation, 
                    _quat4_tmp);
            m_quat.multiply(clamp_rotation, render.quat, render.quat);
        }
    }
}
Ejemplo n.º 25
0
function animate_planets(timeline) {
    if (_focusing) {
        _activated_rotation = false;
    }

    for (var i = 0; i < _planets.length; i++) {
        var planet = _planets[i];

        var duration = timeline - planet.start_time;
        if (duration <= ANIMATION_DURATION) {

            // procedural animation
            var new_scale;
            var new_trans;
            var new_trans_length;

            if (_focusing) {
                if (planet.focused) {
                    new_scale = m_math.ease_out_bounce(duration,
                            planet.start_scale,
                            FOCUSED_SCALE /
                            (PLANET_ORIGIN_SCALES[planet.name] * PLANET_PROC_SCALES[planet.name]),
                            ANIMATION_DURATION);
                    new_trans_length = m_math.ease_out_expo(duration,
                            planet.start_trans_length, -planet.start_trans_length,
                            ANIMATION_DURATION);
                } else {
                    new_scale = m_math.ease_in_circ(duration,
                            planet.start_scale, -planet.start_scale,
                            ANIMATION_DURATION);
                    new_trans_length = m_math.ease_in_expo(duration,
                            planet.start_trans_length, 500,
                            ANIMATION_DURATION);
                }

                var original_trans_dir = m_vec3.normalize(planet.original_trans, _vec3_tmp);
                new_trans = m_vec3.scale(original_trans_dir, new_trans_length,
                        _vec3_tmp);
                m_anim.stop(planet.empty);
            } else {
                // procedural scale
                new_scale = m_math.ease_out_expo(duration,
                        planet.start_scale,
                        PLANET_PROC_SCALES[planet.name] - planet.start_scale,
                        ANIMATION_DURATION);

                // procedural translation
                var original_trans_dir = m_vec3.normalize(planet.original_trans, _vec3_tmp);
                var original_trans_length = m_vec3.length(planet.original_trans);
                new_trans_length = m_math.ease_out_expo(duration,
                        planet.start_trans_length,
                        original_trans_length - planet.start_trans_length,
                        ANIMATION_DURATION);
                new_trans = m_vec3.scale(original_trans_dir, new_trans_length,
                        _vec3_tmp);
            }
            m_trans.set_translation_rel_v(planet.armature, new_trans);
            m_trans.set_scale(planet.armature, new_scale);
        } else {
            if (!_focusing) {
                if (!_activated_rotation) {
                    for (var i = 0; i < _planets.length; i++) {
                        var planet = _planets[i];
                        m_trans.set_translation_rel_v(planet.armature,
                                planet.original_trans);
                        m_anim.play(planet.empty);
                        _activated_rotation = true;
                    }
                }
            } else {
                for (var i = 0; i < _planets.length; i++) {
                    var planet = _planets[i];

                    if (!planet.focused) {
                        m_trans.set_scale(planet.armature, 0);
                    }
                }
            }
        }
    }
}
Ejemplo n.º 26
0
/**
 * Only trans/quat affected by constraint here
 */
function update_cons(obj, cons, elapsed) {
    switch (cons.type) {
    case CONS_TYPE_STIFF_OBJ:

        var quat = obj._render.quat;

        var p_world_matrix = cons.obj_parent._render.world_matrix;
        var p_quat = cons.obj_parent._render.quat;

        if (cons.rotation_offset) {
            m_quat.copy(cons.rotation_offset, quat);
            m_quat.multiply(p_quat, quat, quat);
        } else
            m_quat.copy(p_quat, quat);

        m_vec3.transformMat4(cons.offset, p_world_matrix, obj._render.trans);
        obj._render.scale = cons.scale_offset * cons.obj_parent._render.scale;

        break;
    case CONS_TYPE_SEMI_STIFF_OBJ:

        var trans = obj._render.trans;
        var quat = obj._render.quat;

        var p_world_matrix = cons.obj_parent._render.world_matrix;
        var p_quat = cons.obj_parent._render.quat;

        // Qp * Qp_prev_inv * Q
        m_quat.multiply(
                m_quat.invert(cons.parent_prev_rotation, cons.parent_prev_rotation),
                quat, quat);
        m_quat.multiply(p_quat, quat, quat);

        m_vec3.transformMat4(cons.offset, p_world_matrix, trans);
        m_quat.copy(p_quat, cons.parent_prev_rotation);

        break;
    case CONS_TYPE_SEMI_STIFF_CAM_OBJ:

        var trans = obj._render.trans;
        var quat = obj._render.quat;

        var p_world_matrix = cons.obj_parent._render.world_matrix;
        var p_quat = cons.obj_parent._render.quat;

        // Qp * Qp_prev_inv * Q
        m_quat.multiply(
                m_quat.invert(cons.parent_prev_rotation, cons.parent_prev_rotation),
                quat, quat);
        m_quat.multiply(p_quat, quat, quat);

        m_vec3.transformMat4(cons.offset, p_world_matrix, trans);
        m_quat.copy(p_quat, cons.parent_prev_rotation)

        clamp_orientation(obj, cons);

        break;
    case CONS_TYPE_SEMI_SOFT_CAM_OBJ:

        var trans          = obj._render.trans;
        var quat           = obj._render.quat;
        var p_world_matrix = cons.obj_parent._render.world_matrix;
        var p_trans        = cons.obj_parent._render.trans;
        var softness       = cons.softness;
        var trans_pivot    = _vec3_tmp;
        var quat_pivot     = _quat4_tmp;
        var softness_ratio = 0.16;

        m_vec3.transformMat4(cons.offset, p_world_matrix, trans_pivot);

        m_util.smooth_v(trans_pivot, trans, elapsed, softness, trans);

        var dir_to_obj = _vec3_tmp;
        m_vec3.sub(p_trans, trans, dir_to_obj);
        m_vec3.normalize(dir_to_obj, dir_to_obj);
        cam_rotate_to(quat, dir_to_obj, quat_pivot);
        m_util.smooth_q(quat_pivot, quat, elapsed, softness * softness_ratio, quat);

        break;
    case CONS_TYPE_STIFF_BONE:
        var quat = obj._render.quat;

        var p_transscale = _vec4_tmp;
        var p_quat = _quat4_tmp;

        get_bone_pose(cons.obj_parent, cons.bone_name, true, p_transscale, 
                p_quat);

        if (cons.rotation_offset) {
            m_quat.copy(cons.rotation_offset, quat);
            m_quat.multiply(p_quat, quat, quat);
        } else
            m_quat.copy(p_quat, quat);

        obj._render.scale = cons.scale_offset * p_transscale[3];

        m_util.transform_vec3(cons.offset, p_transscale[3], p_quat, p_transscale, 
                obj._render.trans);

        break;
    case CONS_TYPE_TRACK_OBJ:
        var trans = obj._render.trans;
        var quat = obj._render.quat;
        var t_trans = cons.obj_parent._render.trans;

        rotate_to(trans, quat, t_trans);
        break;
    case CONS_TYPE_TRACK_POINT:
        var trans = obj._render.trans;
        var quat = obj._render.quat;
        var t_trans = cons.target;

        rotate_to(trans, quat, t_trans);
        break;

    case CONS_TYPE_FOLLOW_OBJ:
        var trans = obj._render.trans;
        var quat = obj._render.quat;
        var t_trans = cons.obj_parent._render.trans;

        rotate_to(trans, quat, t_trans);

        // shrink distance
        var dist = m_vec3.dist(trans, t_trans);

        // passing target location
        if (dist > cons.offset_max)
            var delta = dist - cons.offset_max;
        else if (dist < cons.offset_min)
            var delta = dist - cons.offset_min;
        else
            var delta = 0.0;

        if (delta) {
            // NOTE: from trans to t_trans
            m_vec3.sub(t_trans, trans, _vec3_tmp);
            m_vec3.normalize(_vec3_tmp, _vec3_tmp);
            m_vec3.scale(_vec3_tmp, delta, _vec3_tmp);
            m_vec3.add(trans, _vec3_tmp, trans);
        }

        break;
    case CONS_TYPE_FOLLOW_POINT:
        var trans = obj._render.trans;
        var quat = obj._render.quat;
        var t_trans = cons.target;

        rotate_to(trans, quat, t_trans);

        // shrink distance
        var dist = m_vec3.dist(trans, t_trans);

        // passing target location
        if (dist > cons.offset_max)
            var delta = dist - cons.offset_max;
        else if (dist < cons.offset_min)
            var delta = dist - cons.offset_min;
        else
            var delta = 0.0;

        if (delta) {
            // NOTE: from trans to t_trans
            m_vec3.sub(t_trans, trans, _vec3_tmp);
            m_vec3.normalize(_vec3_tmp, _vec3_tmp);
            m_vec3.scale(_vec3_tmp, delta, _vec3_tmp);
            m_vec3.add(trans, _vec3_tmp, trans);
        }

        break;
    case CONS_TYPE_STIFF_TRANS_OBJ:
        var p_world_matrix = cons.obj_parent._render.world_matrix;
        m_vec3.transformMat4(cons.offset, p_world_matrix, obj._render.trans);
        break;
    case CONS_TYPE_COPY_TRANS_OBJ:
        var p_trans = cons.obj_parent._render.trans;
        var trans = obj._render.trans;
        m_vec3.add(p_trans, cons.offset, trans);
        break;
    case CONS_TYPE_STIFF_TRANS_ROT_OBJ:

        var quat = obj._render.quat;

        var p_world_matrix = cons.obj_parent._render.world_matrix;
        var p_quat = cons.obj_parent._render.quat;

        if (cons.rotation_offset) {
            m_quat.copy(cons.rotation_offset, quat);
            m_quat.multiply(p_quat, quat, quat);
        } else
            m_quat.copy(p_quat, quat);

        m_vec3.transformMat4(cons.offset, p_world_matrix, obj._render.trans);
        break;
    case CONS_TYPE_CHILD_OF:
        var prender = cons.obj_parent._render;
        var ptsr = m_tsr.create_sep(prender.trans, prender.scale, prender.quat,
                _tsr8_tmp);
        var tsr_offset = cons.tsr_offset;

        m_tsr.multiply(ptsr, tsr_offset, ptsr);

        var trans = obj._render.trans;
        trans[0] = ptsr[0];
        trans[1] = ptsr[1];
        trans[2] = ptsr[2];

        obj._render.scale = ptsr[3];

        var quat = obj._render.quat;
        quat[0] = ptsr[4];
        quat[1] = ptsr[5];
        quat[2] = ptsr[6];
        quat[3] = ptsr[7];

        break;
    case CONS_TYPE_STIFF_VIEWPORT:
        var camobj = cons.obj_parent;
        var cam = m_cam.get_first_cam(camobj);

        var trans = obj._render.trans;

        var top = m_cam.get_edge(cam, "TOP");
        var bottom = m_cam.get_edge(cam, "BOTTOM");
        var height = top - bottom;

        if (cons.left_edge) {
            var left = m_cam.get_edge(cam, "LEFT");
            trans[0] = left + height * cons.left_right_dist;
        } else {
            var right = m_cam.get_edge(cam, "RIGHT");
            trans[0] = right - height * cons.left_right_dist;
        }

        // in the camera's local space (not view space)
        if (cons.top_edge)
            trans[2] = -(top - height * cons.top_bottom_dist);
        else
            trans[2] = -(bottom + height * cons.top_bottom_dist);

        // NOTE: ortho cameras have scaling problems
        if (m_cam.is_ortho(cam)) {
            trans[1] = -cons.distance;
        } else {
            trans[1] = -1;
            m_vec3.normalize(trans, trans);
            var scale = cons.distance/Math.abs(trans[1]);
            m_vec3.scale(trans, scale, trans);
        }

        m_tsr.transform_dir_vec3(trans, camobj._render.tsr, trans);
        m_vec3.add(camobj._render.trans, trans, trans);

        var quat = obj._render.quat;

        if (cons.rotation_offset) {
            m_quat.copy(cons.rotation_offset, quat);
            m_quat.multiply(camobj._render.quat, quat, quat);
        } else
            m_quat.copy(camobj._render.quat, quat);

        break;
    default:
        break;
    }

    if (obj._render.type == "CAMERA") {
        var corr_axis = m_util.AXIS_Y;
        if (cons.type == CONS_TYPE_SEMI_STIFF_CAM_OBJ) {
            var p_quat = cons.obj_parent._render.quat;
            corr_axis = m_vec3.transformQuat(corr_axis, p_quat, _parent_y_axis);
        }

        m_cam.update_camera_upside_down(obj);
        correct_up(obj, corr_axis);
    }
}
Ejemplo n.º 27
0
/**
 * Only trans/quat affected by constraint here
 */
function update_cons(obj, cons, elapsed) {
    switch (cons.type) {
    case CONS_TYPE_STIFF_OBJ:

        var trans = obj._render.trans;
        var quat = obj._render.quat;

        var p_world_matrix = cons.obj_parent._render.world_matrix; 
        var p_trans = cons.obj_parent._render.trans; 
        var p_quat = cons.obj_parent._render.quat; 

        if (cons.rotation_offset) {
            m_quat.copy(cons.rotation_offset, quat);
            m_quat.multiply(p_quat, quat, quat);
        } else
            m_quat.copy(p_quat, quat);

        m_vec3.transformMat4(cons.offset, p_world_matrix, obj._render.trans);
        obj._render.scale = cons.scale_offset * cons.obj_parent._render.scale;

        break;
    case CONS_TYPE_SEMI_STIFF_OBJ:

        var trans = obj._render.trans;
        var quat = obj._render.quat;
        
        var p_world_matrix = cons.obj_parent._render.world_matrix; 
        var p_quat = cons.obj_parent._render.quat; 

        // Qp * Qp_prev_inv * Q
        m_quat.multiply(
                m_quat.invert(cons.parent_prev_rotation, cons.parent_prev_rotation),
                quat, quat);
        m_quat.multiply(p_quat, quat, quat);

        m_vec3.transformMat4(cons.offset, p_world_matrix, trans);
        m_quat.copy(p_quat, cons.parent_prev_rotation);

        break;
    case CONS_TYPE_SEMI_STIFF_CAM_OBJ:

        var trans = obj._render.trans;
        var quat = obj._render.quat;
        
        var p_world_matrix = cons.obj_parent._render.world_matrix; 
        var p_quat = cons.obj_parent._render.quat; 

        // Qp * Qp_prev_inv * Q
        m_quat.multiply(
                m_quat.invert(cons.parent_prev_rotation, cons.parent_prev_rotation),
                quat, quat);
        m_quat.multiply(p_quat, quat, quat);

        m_vec3.transformMat4(cons.offset, p_world_matrix, trans);
        m_quat.copy(p_quat, cons.parent_prev_rotation)

        clamp_angles(obj, cons);
        if (obj._render.type == "CAMERA") {
            var p_y_axis = m_vec3.transformQuat(m_util.AXIS_Y, p_quat, _vec3_tmp_2);
            correct_up(obj, p_y_axis);
        }

        break;
    case CONS_TYPE_SEMI_SOFT_CAM_OBJ:

        var trans          = obj._render.trans;
        var quat           = obj._render.quat;
        var p_world_matrix = cons.obj_parent._render.world_matrix;
        var p_trans        = cons.obj_parent._render.trans;
        var trans_pivot    = _vec3_tmp;
        var quat_pivot     = _quat4_tmp;

        m_vec3.transformMat4(cons.offset, p_world_matrix, trans_pivot);

        m_util.smooth_v(trans_pivot, trans, elapsed, 0.3, trans);

        var dir_to_obj = _vec3_tmp;
        m_vec3.sub(p_trans, trans, dir_to_obj);
        m_vec3.normalize(dir_to_obj, dir_to_obj);
        cam_rotate_to(quat, dir_to_obj, quat_pivot);
        m_util.smooth_q(quat_pivot, quat, elapsed, 0.1, quat);

        break;
    case CONS_TYPE_STIFF_BONE:
        var trans = obj._render.trans;
        var quat = obj._render.quat;

        var p_trans = _vec4_tmp;
        var p_quat = _quat4_tmp;

        get_bone_pose(cons.obj_parent, cons.bone_name, true, p_trans, p_quat);

        if (cons.rotation_offset) {
            m_quat.copy(cons.rotation_offset, quat);
            m_quat.multiply(p_quat, quat, quat);
        } else
            m_quat.copy(p_quat, quat);

        m_util.transform_vec3(cons.offset, 1, p_quat, p_trans, obj._render.trans);

        break;
    case CONS_TYPE_TRACK_OBJ:
        var trans = obj._render.trans;
        var quat = obj._render.quat;
        var t_trans = cons.obj_parent._render.trans; 

        rotate_to(trans, quat, t_trans);
        if (obj._render.type == "CAMERA")
            correct_up(obj, m_util.AXIS_Y);
        break;
    case CONS_TYPE_TRACK_POINT:
        var trans = obj._render.trans;
        var quat = obj._render.quat;
        var t_trans = cons.target; 

        rotate_to(trans, quat, t_trans);
        if (obj._render.type == "CAMERA")
            correct_up(obj, m_util.AXIS_Y);
        break;

    case CONS_TYPE_FOLLOW_OBJ:
        var trans = obj._render.trans;
        var quat = obj._render.quat;
        var t_trans = cons.obj_parent._render.trans; 

        var is_rotated = rotate_to_limits(trans, quat, t_trans, CONS_ROTATE_LIMIT);
        
        // shrink distance
        var dist = m_vec3.dist(trans, t_trans);

        // passing target location
        if (!is_rotated)
            delta = dist + cons.offset_min;
        else {
            if (dist > cons.offset_max)
                var delta = dist - cons.offset_max;
            else if (dist < cons.offset_min)
                var delta = dist - cons.offset_min;
            else
                var delta = 0.0;
        }

        if (delta) {
            // NOTE: from trans to t_trans
            m_vec3.sub(t_trans, trans, _vec3_tmp);
            m_vec3.normalize(_vec3_tmp, _vec3_tmp);
            m_vec3.scale(_vec3_tmp, delta, _vec3_tmp);
            m_vec3.add(trans, _vec3_tmp, trans);
        }
        
        if (obj._render.type == "CAMERA")
            correct_up(obj, m_util.AXIS_Y);

        break;
    case CONS_TYPE_FOLLOW_POINT:
        var trans = obj._render.trans;
        var quat = obj._render.quat;
        var t_trans = cons.target; 

        var is_rotated = rotate_to_limits(trans, quat, t_trans, CONS_ROTATE_LIMIT);

        // shrink distance
        var dist = m_vec3.dist(trans, t_trans);

        // passing target location
        if (!is_rotated)
            delta = dist + cons.offset_min;
        else {
            if (dist > cons.offset_max)
                var delta = dist - cons.offset_max;
            else if (dist < cons.offset_min)
                var delta = dist - cons.offset_min;
            else
                var delta = 0.0;
        }

        if (delta) {
            // NOTE: from trans to t_trans
            m_vec3.sub(t_trans, trans, _vec3_tmp);
            m_vec3.normalize(_vec3_tmp, _vec3_tmp);
            m_vec3.scale(_vec3_tmp, delta, _vec3_tmp);
            m_vec3.add(trans, _vec3_tmp, trans);
        }
        
        if (obj._render.type == "CAMERA")
            correct_up(obj, m_util.AXIS_Y);
        break;
    case CONS_TYPE_STIFF_TRANS_OBJ:
        var p_world_matrix = cons.obj_parent._render.world_matrix; 
        m_vec3.transformMat4(cons.offset, p_world_matrix, obj._render.trans);
        break;
    case CONS_TYPE_COPY_TRANS_OBJ:
        var p_trans = cons.obj_parent._render.trans; 
        var trans = obj._render.trans;
        m_vec3.add(p_trans, cons.offset, trans);
        break;
    case CONS_TYPE_STIFF_TRANS_ROT_OBJ:

        var trans = obj._render.trans;
        var quat = obj._render.quat;

        var p_world_matrix = cons.obj_parent._render.world_matrix;
        var p_trans = cons.obj_parent._render.trans;
        var p_quat = cons.obj_parent._render.quat;

        if (cons.rotation_offset) {
            m_quat.copy(cons.rotation_offset, quat);
            m_quat.multiply(p_quat, quat, quat);
        } else
            m_quat.copy(p_quat, quat);

        m_vec3.transformMat4(cons.offset, p_world_matrix, obj._render.trans);
        break;
    case CONS_TYPE_CHILD_OF:
        var prender = cons.obj_parent._render; 
        var ptsr = m_tsr.create_sep(prender.trans, prender.scale, prender.quat,
                _tsr8_tmp);
        var tsr_offset = cons.tsr_offset;

        m_tsr.multiply(ptsr, tsr_offset, ptsr);
        
        var trans = obj._render.trans;
        trans[0] = ptsr[0];
        trans[1] = ptsr[1];
        trans[2] = ptsr[2];

        obj._render.scale = ptsr[3];

        var quat = obj._render.quat;
        quat[0] = ptsr[4];
        quat[1] = ptsr[5];
        quat[2] = ptsr[6];
        quat[3] = ptsr[7];

        break;
    default:
        break;
    }
}