Пример #1
0
/**
 * Calculate pose data for given bone.
 * recursively calculate _tsr_channel_cache beginning from "root"
 * store _tsr_channel_cache_valid state in each pose bone
 */
function calc_pose_bone(pose_bone, dest_trans_scale, dest_quat) {
    var chain = pose_bone._chain;

    var pose_bone_root = chain[chain.length-1];
    var tsr_channel_parent = pose_bone_root._tsr_channel_cache;

    // reset "root" bone if not valid
    if (!pose_bone_root._tsr_channel_cache_valid)
        m_tsr.identity(tsr_channel_parent);

    // start from the last bone ("root" for chain)
    for (var i = chain.length - 1; i >= 0; i--) {
        var pose_bone = chain[i];

        var tsr_channel = pose_bone._tsr_channel_cache;

        // this can be already calculated because 
        // a bone can participate in other chains
        // else calculate channel TSR
        if (pose_bone._tsr_channel_cache_valid) {
            tsr_channel_parent = tsr_channel;
            continue;
        }

        // bone armature-relative TSR
        var tsr_local = pose_bone._tsr_local;
        // pose bone-relative TSR
        var tsr_basis = pose_bone._tsr_basis;
        
        // apply basis translation (delta) in armature space
        // go to bone space, apply pose, return back to armature space
        // tsr_local * (tsr_basis * tsr_locali)
        m_tsr.invert(tsr_local, _tsr8_tmp);
        m_tsr.multiply(tsr_basis, _tsr8_tmp, _tsr8_tmp);
        m_tsr.multiply(tsr_local, _tsr8_tmp, _tsr8_tmp);

        // apply hierarchy
        m_tsr.multiply(tsr_channel_parent, _tsr8_tmp, tsr_channel);
        
        // save
        tsr_channel_parent = tsr_channel;
        pose_bone._tsr_channel_cache_valid = true;
    }

    // split and store calculated TSR
    var tsr = pose_bone._tsr_channel_cache;

    dest_trans_scale[0] = tsr[0];
    dest_trans_scale[1] = tsr[1];
    dest_trans_scale[2] = tsr[2];
    dest_trans_scale[3] = tsr[3];
    dest_quat[0] = tsr[4];
    dest_quat[1] = tsr[5];
    dest_quat[2] = tsr[6];
    dest_quat[3] = tsr[7];
    m_quat.normalize(dest_quat, dest_quat);
}
Пример #2
0
exports.rotate_local = function(obj, quat) {
    var p_tsr = get_tsr_rel(obj, _tsr_tmp);
    var tsr = m_tsr.set_quat(quat, m_tsr.identity(_tsr_tmp2));

    m_tsr.multiply(p_tsr, tsr, tsr);
    set_tsr_rel(obj, tsr);
}
Пример #3
0
function update_bone_tsr_r(bone_pointer, use_bone_space, trans, quats) {

    var tsr_bone_pose = bone_pointer.tsr_bone_pose;
    var tsr_local_rest = bone_pointer.tsr_local_rest;
    var tsr_local_pose = bone_pointer.tsr_local_pose;

    var parent_bone_ptr = bone_pointer.parent_bone_ptr;
    if (parent_bone_ptr) {
        var tsr_par_local = parent_bone_ptr.tsr_local_pose;

        if (use_bone_space)
            m_tsr.multiply(tsr_par_local, tsr_bone_pose, tsr_local_pose);
        else {
            var inv_tsr_par_local = _tsr_tmp2;
            m_tsr.invert(tsr_par_local, inv_tsr_par_local);
            m_tsr.multiply(inv_tsr_par_local, tsr_local_pose, tsr_bone_pose);
        }
    } else
        if (use_bone_space)
            m_tsr.copy(tsr_bone_pose, tsr_local_pose);
        else
            m_tsr.copy(tsr_local_pose, tsr_bone_pose);

    var dest_tsr = _tsr_tmp;
    m_tsr.invert(tsr_local_rest, dest_tsr);
    m_tsr.multiply(tsr_local_pose, dest_tsr, dest_tsr);

    var index = bone_pointer.bone_index;

    trans[4*index]   = dest_tsr[0];
    trans[4*index+1] = dest_tsr[1];
    trans[4*index+2] = dest_tsr[2];
    trans[4*index+3] = dest_tsr[3];
    quats[4*index]   = dest_tsr[4];
    quats[4*index+1] = dest_tsr[5];
    quats[4*index+2] = dest_tsr[6];
    quats[4*index+3] = dest_tsr[7];

    var descend_ptrs = bone_pointer.descend_bones_ptrs;
    for (var i = 0; i < descend_ptrs.length; i++) {
        var desc_bone_ptr = descend_ptrs[i];
        // NOTE: temporary do not update child bones with constraints
        if (desc_bone_ptr.constraint)
            continue;
        update_bone_tsr_r(desc_bone_ptr, true, trans, quats)
    }
}
Пример #4
0
exports.set_tsr = function(obj, tsr) {
    m_tsr.copy(tsr, obj.render.world_tsr);

    if (m_cons.has_child_of(obj)) {
        var tsr_par = m_cons.get_child_of_parent_tsr(obj);
        var tsr_inv = m_tsr.invert(tsr_par, _tsr_tmp);
        var offset = m_cons.get_child_of_offset(obj);
        m_tsr.multiply(tsr_inv, obj.render.world_tsr, offset);
    }
}
Пример #5
0
exports.set_translation = function(obj, trans) {
    var render = obj.render;

    if (m_cons.has_child_of(obj)) {
        m_tsr.set_trans(trans, render.world_tsr);
        var tsr_par = m_cons.get_child_of_parent_tsr(obj);
        var tsr_inv = m_tsr.invert(tsr_par, _tsr_tmp);
        var offset = m_cons.get_child_of_offset(obj);
        m_tsr.multiply(tsr_inv, render.world_tsr, offset);
    } else
        m_tsr.set_trans(trans, render.world_tsr);
}
Пример #6
0
function set_rotation(obj, quat) {
    var render = obj.render;

    if (m_cons.has_child_of(obj)) {
        m_tsr.set_quat(quat, render.world_tsr);
        var tsr_par = m_cons.get_child_of_parent_tsr(obj);
        var tsr_inv = m_tsr.invert(tsr_par, _tsr_tmp);
        var offset = m_cons.get_child_of_offset(obj);
        m_tsr.multiply(tsr_inv, render.world_tsr, offset);
    } else
        m_tsr.set_quat(quat, render.world_tsr);
}
Пример #7
0
exports.set_bone_tsr = function(armobj, bone_name, tsr, use_bone_space) {
    var render = armobj.render;
    var bone_pointer = render.bone_pointers[bone_name];
    var trans_before = render.trans_before;
    var quats_before = render.quats_before;

    if (use_bone_space)
        m_tsr.multiply(bone_pointer.tsr_bone_rest, tsr,
                       bone_pointer.tsr_bone_pose);
    else
        m_tsr.copy(tsr, bone_pointer.tsr_local_pose);

    update_bone_tsr_r(bone_pointer, use_bone_space, trans_before, quats_before);
    render.frame_factor = 0;
    update_skinned_renders(armobj);
}
Пример #8
0
/**
 * Get armature bone pose data (animated or static)
 * NOTE: need to be somewhere else
 * uses _vec4_tmp, _quat4_tmp, _quat4_tmp2, _tsr8_tmp, _tsr8_tmp2
 */
function get_bone_pose(armobj, bone_name, get_pose_tail, dest_transscale,
        dest_quat) {

    var render = armobj._render;

    var frame_factor = render.frame_factor;
    var bone_pointer = render.bone_pointers[bone_name];
    var index = bone_pointer.deform_bone_index;
    var pose_bone_index = bone_pointer.pose_bone_index;
    var bone = armobj["pose"]["bones"][pose_bone_index];
    var tsr_local = bone._tsr_local;

    var transcale = _vec4_tmp;

    var trans_before = render.trans_before;
    var trans_after = render.trans_after;
    var quats_before = render.quats_before;
    var quats_after = render.quats_after;

    var x = trans_before[4*index];
    var y = trans_before[4*index+1];
    var z = trans_before[4*index+2];
    var s = trans_before[4*index+3];

    var xn = trans_after[4*index];
    var yn = trans_after[4*index+1];
    var zn = trans_after[4*index+2];
    var sn = trans_after[4*index+3];

    transcale[0] = (1-frame_factor) * x + frame_factor * xn;
    transcale[1] = (1-frame_factor) * y + frame_factor * yn;
    transcale[2] = (1-frame_factor) * z + frame_factor * zn;
    transcale[3] = (1-frame_factor) * s + frame_factor * sn;

    var quat = _quat4_tmp;
    var quatn = _quat4_tmp2;

    quat[0] = quats_before[4*index];
    quat[1] = quats_before[4*index+1];
    quat[2] = quats_before[4*index+2];
    quat[3] = quats_before[4*index+3];

    quatn[0] = quats_after[4*index];
    quatn[1] = quats_after[4*index+1];
    quatn[2] = quats_after[4*index+2];
    quatn[3] = quats_after[4*index+3];

    m_quat.slerp(quat, quatn, frame_factor, quat);

    var tsr_bone = _tsr8_tmp;
    m_tsr.set_transcale(transcale, tsr_bone);
    m_tsr.set_quat(quat, tsr_bone);

    if (get_pose_tail) {
        var tsr_local_tail = _tsr8_tmp2;
        m_tsr.translate(tsr_local, bone._tail, tsr_local_tail);
        m_tsr.multiply(tsr_bone, tsr_local_tail, tsr_bone);
    } else
        m_tsr.multiply(tsr_bone, tsr_local, tsr_bone);

    // from armature to world space
    m_tsr.multiply(render.tsr, tsr_bone, tsr_bone);

    dest_transscale[0] = tsr_bone[0];
    dest_transscale[1] = tsr_bone[1];
    dest_transscale[2] = tsr_bone[2];
    dest_transscale[3] = tsr_bone[3];

    if (dest_quat) {
        dest_quat[0] = tsr_bone[4];
        dest_quat[1] = tsr_bone[5];
        dest_quat[2] = tsr_bone[6];
        dest_quat[3] = tsr_bone[7];
    }
}
Пример #9
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;
    }
}
Пример #10
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);
    }
}
Пример #11
0
/**
 * Set object render world_matrix.
 * NOTE: do not try to update batched objects (buggy _dg_parent influence)
 * @methodOf transform
 * @param {Object} obj Object ID
 */
function update_transform(obj) {
    var render = obj._render;

    // NOTE: need to update before constraints, because they rely on to this flag
    if (obj["type"] == "CAMERA")
        m_cam.update_camera_upside_down(obj);

    m_cons.update_constraint(obj, _elapsed);

    if (obj["type"] == "CAMERA")
        m_cam.update_camera(obj);

    // should not change after constraint update
    var trans = render.trans;
    var scale = render.scale;
    var quat = render.quat;

    m_tsr.set_sep(trans, scale, quat, render.tsr);

    var wm = render.world_matrix;

    m_mat4.identity(wm);
    m_mat4.fromQuat(quat, wm);

    // TODO: remove world matrix and move to tsr system
    if (obj["type"] != "CAMERA")
        m_util.scale_mat4(wm, scale, wm);

    wm[12] = trans[0];
    wm[13] = trans[1];
    wm[14] = trans[2];

    m_mat4.invert(wm, render.inv_world_matrix);

    if (obj._anim_slots.length && m_particles.has_anim_particles(obj))
        m_particles.update_emitter_transform(obj);

    // NOTE: available only after batch creation (really needed now?)
    if (render.bb_local && render.bb_world) {
        m_bounds.bounding_box_transform(render.bb_local, wm, render.bb_world);
        m_bounds.bounding_sphere_transform(render.bs_local, wm, render.bs_world);
        m_bounds.bounding_ellipsoid_transform(render.be_local, render.tsr,
                                             render.be_world)
        if (render.shadow_cast)
            m_scs.schedule_shadow_update(m_scs.get_active());
    }

    switch (obj["type"]) {
    case "SPEAKER":
        m_sfx.speaker_update_transform(obj, _elapsed);
        break;
    case "CAMERA":
        m_cam.update_camera_transform(obj);
        // listener only for active scene camera
        if (m_scs.check_active() && m_scs.get_camera(m_scs.get_active()) == obj)
            m_sfx.listener_update_transform(m_scs.get_active(), trans, quat, _elapsed);
        break;
    case "LAMP":
        m_lights.update_light_transform(obj);
        if (m_scs.check_active())
            m_scs.update_lamp_scene(obj, m_scs.get_active());
        break;
    case "EMPTY":
        if (obj["field"])
            m_scs.update_force(obj);
        break;
    }

    if (obj["type"] == "LAMP" || obj["type"] == "CAMERA") {
        if (m_scs.check_active()) {
            var active_scene = m_scs.get_active();
            m_scs.schedule_shadow_update(active_scene);
            m_scs.schedule_grass_map_update(active_scene);
        }
    }

    if (obj["type"] == "MESH") {
        var modifiers = obj["modifiers"];
        var armobj = null;
        for (var i = 0; i < modifiers.length; i++) {
            var modifier = modifiers[i];
            if (modifier["type"] == "ARMATURE")
                armobj = modifier["object"];
        }

        if (armobj) {
            var armobj_tsr = armobj._render.tsr;
            m_tsr.invert(armobj_tsr, _tsr_tmp);
            m_tsr.multiply(_tsr_tmp, render.tsr, _tsr_tmp);
            m_vec4.set(_tsr_tmp[0], _tsr_tmp[1], _tsr_tmp[2], _tsr_tmp[3],
                     render.arm_rel_trans);
            m_quat.set(_tsr_tmp[4], _tsr_tmp[5], _tsr_tmp[6], _tsr_tmp[7],
                     render.arm_rel_quat);
        }
    }

    var descends = obj._descends;

    for (var i = 0; i < descends.length; i++)
        update_transform(descends[i]);

    render.force_zsort = true;
}
Пример #12
0
/**
 * Set object render world_tsr.
 * NOTE: do not try to update batched objects (buggy _dg_parent influence)
 * @methodOf transform
 * @param {Object3D} obj Object 3D
 */
function update_transform(obj) {
    var render = obj.render;
    var scenes_data = obj.scenes_data;

    var obj_type = obj.type;

    // NOTE: need to update before constraints, because they rely on to this flag
    if (obj_type == "CAMERA")
        m_cam.update_camera_upside_down(obj);

    m_cons.update_constraint(obj, _elapsed);

    if (obj_type == "CAMERA")
        m_cam.update_camera(obj);

    // should not change after constraint update
    var trans = m_tsr.get_trans_value(render.world_tsr, _vec3_tmp);
    var quat = m_tsr.get_quat_value(render.world_tsr, _quat4_tmp);

    // NOTE: available only after batch creation (really needed now?)
    if (render.bb_local && render.bb_world) {
        m_bounds.bounding_box_transform(render.bb_local, render.world_tsr, render.bb_world);
        m_bounds.bounding_sphere_transform(render.bs_local, render.world_tsr, render.bs_world);
        m_bounds.bounding_ellipsoid_transform(render.be_local, render.world_tsr,
                                             render.be_world)
    }

    switch (obj_type) {
    case "SPEAKER":
        m_sfx.speaker_update_transform(obj, _elapsed);
        break;
    case "MESH":
        var armobj = obj.armobj;
        if (armobj) {
            var armobj_tsr = armobj.render.world_tsr;
            m_tsr.invert(armobj_tsr, _tsr_tmp);
            m_tsr.multiply(_tsr_tmp, render.world_tsr, _tsr_tmp);
            m_vec4.set(_tsr_tmp[0], _tsr_tmp[1], _tsr_tmp[2], _tsr_tmp[3],
                     render.arm_rel_trans);
            m_quat.set(_tsr_tmp[4], _tsr_tmp[5], _tsr_tmp[6], _tsr_tmp[7],
                     render.arm_rel_quat);
        }
        break;
    case "CAMERA":
        m_cam.update_camera_transform(obj);
        // listener only for active scene camera
        if (m_scs.check_active()) {
            var active_scene = m_scs.get_active();
            if (m_scs.get_camera(active_scene) == obj)
                m_sfx.listener_update_transform(active_scene, trans, quat,
                                                _elapsed);
        }
        break;
    case "LAMP":
        m_lights.update_light_transform(obj);
        break;
    }

    for (var i = 0; i < scenes_data.length; i++) {
        var sc_data = scenes_data[i];
        if (sc_data.is_active) {
            var scene = sc_data.scene;
            var sc_render = scene._render;
            var batches = sc_data.batches;

            switch (obj_type) {
            case "LAMP":
                m_scs.update_lamp_scene(obj, scene);
                break;
            case "CAMERA":
                m_scs.schedule_grass_map_update(scene);
                if (sc_render.shadow_params) {
                    // camera movement only influence csm shadows
                    if (sc_render.shadow_params.enable_csm)
                        m_scs.schedule_shadow_update(scene);
                    m_scs.update_shadow_billboard_view(obj, sc_render.graph);
                }
                   
                break;
            case "MESH":
                if (render.bb_local && render.bb_world) {
                    if (render.shadow_cast)
                        m_scs.schedule_shadow_update(scene);

                    var cube_refl_subs = sc_data.cube_refl_subs;
                    if (render.cube_reflection_id != null && cube_refl_subs) {
                        m_scs.update_cube_reflect_subs(cube_refl_subs, trans);
                    }
                }
                break;
            case "EMPTY":
                m_obj.update_force(obj);
                break;
            }

            var plane_refl_subs = sc_data.plane_refl_subs;
            var refl_objs = obj.reflective_objs;
            if (refl_objs.length) {
                for (var j = 0; j < plane_refl_subs.length; j++) {
                    var cam = plane_refl_subs[j].camera;
                    m_scs.update_plane_reflect_subs(plane_refl_subs[j], trans, quat);
                    m_obj_util.update_refl_objects(refl_objs, cam.reflection_plane);
                    m_cam.set_view(cam, m_scs.get_camera(scene));
                    m_util.extract_frustum_planes(cam.view_proj_matrix, cam.frustum_planes);
                }
            }
        }
    }

    var cons_descends = obj.cons_descends;
    for (var i = 0; i < cons_descends.length; i++)
        update_transform(cons_descends[i]);

    var cons_armat_bone_descends = obj.cons_armat_bone_descends;
    for (var i = 0; i < cons_armat_bone_descends.length; i++) {
        var cons_armat_desc = cons_armat_bone_descends[i];
        var armobj = cons_armat_desc[0];
        var bone_name = cons_armat_desc[1];
        m_cons.update_bone_constraint(armobj, bone_name);
    }

    render.force_zsort = true;
}
Пример #13
0
function update_object(bpy_armobj, armobj) {
    var arm_bones = bpy_armobj["data"]["bones"];
    var pose_bones = bpy_armobj["pose"]["bones"];

    var bone_pointers = {};

    for (var i = 0; i < pose_bones.length; i++) {
        var pose_bone = pose_bones[i];
        var arm_bone = pose_bone["bone"];

        var bone_name = arm_bone["name"];
        var bpointer = bone_pointers[bone_name] = init_bone_pointer();

        var mat_loc = new Float32Array(arm_bone["matrix_local"]);
        var mat_loc_inv = new Float32Array(16);
        m_mat4.invert(mat_loc, mat_loc_inv);

        var mat_bas = new Float32Array(pose_bone["matrix_basis"]);

        var tail = bpointer.tail;
        m_vec3.subtract(arm_bone["tail_local"], arm_bone["head_local"], tail);
        // translate tail offset from armature to bone space
        m_util.vecdir_multiply_matrix(tail, mat_loc_inv, tail);

        m_tsr.from_mat4(mat_loc, bpointer.tsr_local_rest);
        m_tsr.from_mat4(mat_bas, bpointer.tsr_basis);
        m_tsr.copy(bpointer.tsr_local_rest, bpointer.tsr_local_pose);
    }

    for (var i = 0; i < arm_bones.length; i++) {
        var bone = arm_bones[i];
        var bone_name = bone["name"];
        var pose_bone = m_util.keysearch("name", bone_name, pose_bones);

        var bpointer = bone_pointers[bone_name];
        var parent_pose_bones = pose_bone["parent_recursive"];

        // include current bone to chain with its parents
        bpointer.chain.push(bpointer);
        for (var j = 0; j < parent_pose_bones.length; j++) {
            var parent_bone = parent_pose_bones[j];
            var parent_bone_name = parent_bone["name"];
            var parent_bone_ptr = bone_pointers[parent_bone_name];
            bpointer.chain.push(parent_bone_ptr);
        }

        if (parent_pose_bones.length) {
            var parent_bone = parent_pose_bones[0];
            var parent_bone_name = parent_bone["name"];
            var parent_bone_ptr = bone_pointers[parent_bone_name];
            bpointer.parent_bone_ptr = parent_bone_ptr;

            m_tsr.invert(parent_bone_ptr.tsr_local_rest, _tsr_tmp);
            m_tsr.multiply(_tsr_tmp, bpointer.tsr_local_rest,
                           bpointer.tsr_bone_rest);

            // store only direct bone's descendants
            parent_bone_ptr.descend_bones_ptrs.push(bpointer);
        } else
            m_tsr.copy(bpointer.tsr_local_rest, bpointer.tsr_bone_rest);

        bpointer.bone_index = i;
        bpointer.name = bone_name;

        m_tsr.multiply(bpointer.tsr_bone_rest, bpointer.tsr_basis,
                       bpointer.tsr_bone_pose);

    }
    armobj.render.bone_pointers = bone_pointers;
}
Пример #14
0
exports.get_bone_tsr = function(armobj, bone_name, get_pose_tail,
                                use_bone_space, dest_tsr) {
    var render = armobj.render;

    var frame_factor = render.frame_factor;
    var bone_pointer = render.bone_pointers[bone_name];
    var index = bone_pointer.bone_index;
    var tsr_local = bone_pointer.tsr_local_rest;

    var transcale = _vec4_tmp;

    var trans_before = render.trans_before;
    var trans_after = render.trans_after;
    var quats_before = render.quats_before;
    var quats_after = render.quats_after;

    var x = trans_before[4*index];
    var y = trans_before[4*index+1];
    var z = trans_before[4*index+2];
    var s = trans_before[4*index+3];

    var xn = trans_after[4*index];
    var yn = trans_after[4*index+1];
    var zn = trans_after[4*index+2];
    var sn = trans_after[4*index+3];

    transcale[0] = (1-frame_factor) * x + frame_factor * xn;
    transcale[1] = (1-frame_factor) * y + frame_factor * yn;
    transcale[2] = (1-frame_factor) * z + frame_factor * zn;
    transcale[3] = (1-frame_factor) * s + frame_factor * sn;

    var quat = _quat4_tmp;
    var quatn = _quat4_tmp2;

    quat[0] = quats_before[4*index];
    quat[1] = quats_before[4*index+1];
    quat[2] = quats_before[4*index+2];
    quat[3] = quats_before[4*index+3];

    quatn[0] = quats_after[4*index];
    quatn[1] = quats_after[4*index+1];
    quatn[2] = quats_after[4*index+2];
    quatn[3] = quats_after[4*index+3];

    m_quat.slerp(quat, quatn, frame_factor, quat);

    var tsr_bone = _tsr_tmp;
    m_tsr.set_transcale(transcale, tsr_bone);
    m_tsr.set_quat(quat, tsr_bone);

    if (get_pose_tail) {
        var tsr_local_tail = _tsr_tmp2;
        m_tsr.translate(tsr_local, bone_pointer.tail, tsr_local_tail);
        m_tsr.multiply(tsr_bone, tsr_local_tail, tsr_bone);
    } else
        m_tsr.multiply(tsr_bone, tsr_local, tsr_bone);

    if (use_bone_space) {
        var parent_bone_ptr = bone_pointer.parent_bone_ptr;
        if (parent_bone_ptr) {
            // move to bone space
            var tsr_par_local = parent_bone_ptr.tsr_local_pose;
            var inv_tsr_par_local = _tsr_tmp2;
            m_tsr.invert(tsr_par_local, inv_tsr_par_local);
            m_tsr.multiply(inv_tsr_par_local, tsr_bone, tsr_bone);
        }
        // calculate difference with rest pose tsr
        var tsr_bone_rest = bone_pointer.tsr_bone_rest;
        var inv_tsr_bone_rest = _tsr_tmp2;
        m_tsr.invert(tsr_bone_rest, inv_tsr_bone_rest);
        m_tsr.multiply(inv_tsr_bone_rest, tsr_bone, tsr_bone);
    }

    m_tsr.copy(tsr_bone, dest_tsr);
}