示例#1
0
function animate(obj, elapsed) {

    // not animatable
    if (!obj._anim) 
        return; 
    // update paused animation only if elapsed == 0
    if (!(obj._anim.play || elapsed == 0))
        return

    var render = obj._render;
    
    var cff = obj._anim.current_frame_float;
    var start = obj._anim.start;
    var length = obj._anim.length;

    var finish_callback;

    cff += elapsed * cfg_ani.framerate;

    if (cff >= start + length) {

        finish_callback = obj._anim.finish_callback;

        switch(obj._anim.behavior) {
        case AB_CYCLIC:
            cff = ((cff-start) % length) + start;
            break;
        case AB_FINISH_RESET:
            cff = start;
            stop(obj);
            break;
        case AB_FINISH_STOP:
            cff = start + length - 0.000001;
            stop(obj);
            break;
        }
    }
    obj._anim.current_frame_float = cff;
    obj._render.time = (cff - start) / cfg_ani.framerate;

    var anim_type = obj._anim.type;

    switch (anim_type) {
    case OBJ_ANIM_TYPE_ARMATURE:
    case OBJ_ANIM_TYPE_SKELETAL:

        var finfo = action_anim_finfo(obj._anim, cff, _frame_info_tmp);

        var frame = finfo[0];
        var frame_next = finfo[1];
        var frame_factor = finfo[2];

        var trans = obj._anim.trans;
        var quats = obj._anim.quats;

        render.quats_before = quats[frame];
        render.quats_after  = quats[frame_next];
        render.trans_before = trans[frame];
        render.trans_after  = trans[frame_next];
        render.frame_factor = frame_factor;

        if (anim_type === OBJ_ANIM_TYPE_ARMATURE)
            m_trans.update_transform(obj);

        break;

    case OBJ_ANIM_TYPE_OBJECT:
        var finfo = action_anim_finfo(obj._anim, cff, _frame_info_tmp);

        var trans = get_anim_translation(obj, 0, finfo, _vec3_tmp);
        var quat = get_anim_rotation(obj, 0, finfo, _quat4_tmp);
        var scale = get_anim_scale(obj, 0, finfo);

        if (obj._anim.trans_smooth_period) {
            var trans_old = _vec3_tmp2;
            m_trans.get_translation(obj, trans_old);
            m_util.smooth_v(trans, trans_old, elapsed,
                    obj._anim.trans_smooth_period, trans);
        }

        if (obj._anim.quat_smooth_period) {
            var quat_old = _quat4_tmp2;
            m_trans.get_rotation(obj, quat_old);
            m_util.smooth_q(quat, quat_old, elapsed,
                    obj._anim.quat_smooth_period, quat);
        }

        m_trans.set_translation(obj, trans);
        m_trans.set_rotation(obj, quat);
        m_trans.set_scale(obj, scale);

        m_trans.update_transform(obj);
        m_phy.sync_transform(obj);
        break;

    case OBJ_ANIM_TYPE_VERTEX:
        vertex_anim_finfo(obj._anim, cff, _frame_info_tmp);
        var finfo = _frame_info_tmp;

        render.va_frame = finfo[0];
        render.va_frame_factor = finfo[2];
        break;

    case OBJ_ANIM_TYPE_SOUND:
        var finfo = action_anim_finfo(obj._anim, cff, _frame_info_tmp);
        var fc = finfo[0];
        var fn = finfo[1];
        var ff = finfo[2];

        if (obj._anim.volume) {
            var volume = (1-ff) * obj._anim.volume[fc] + ff * obj._anim.volume[fn];
            m_sfx.set_volume(obj, volume);
        }
        
        if (obj._anim.pitch) {
            var pitch = (1-ff) * obj._anim.pitch[fc] + ff * obj._anim.pitch[fn];
            m_sfx.playrate(obj, pitch);
        }
        break;
    case OBJ_ANIM_TYPE_STATIC:
        // do nothing
        break;

    default:
        throw("Unknown animation type:" + anim_type);
        break;
    }
    
    if (finish_callback)
        finish_callback(obj);
    
}
示例#2
0
function update_object(obj) {
    var is_dynamic = obj_is_dynamic(obj);
    obj._is_dynamic = is_dynamic;

    if (obj["type"] === "MESH")
        var render_type = is_dynamic ? "DYNAMIC" : "STATIC";
    else
        var render_type = obj["type"];
    obj._render = create_render(render_type);

    obj._constraint = null;
    obj._descends = [];
    if (!obj._dg_parent)
        obj._dg_parent = null;

    var render = obj._render;

    var pos = obj["location"];
    var scale = obj["scale"][0];
    var rot = _quat4_tmp;
    m_util.quat_bpy_b4w(obj["rotation_quaternion"], rot);

    m_trans.set_translation(obj, pos);
    m_trans.set_rotation(obj, rot);
    m_trans.set_scale(obj, scale);

    switch (obj["type"]) {
    case "ARMATURE":

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

            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 = new Float32Array(3);
            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);

            pose_bone._tail = tail;

            // include current bone to chain with its parents 
            pose_bone._chain = [pose_bone].concat(pose_bone["parent_recursive"]);

            pose_bone._tsr_local = m_tsr.from_mat4(mat_loc, m_tsr.create());
            pose_bone._tsr_basis = m_tsr.from_mat4(mat_bas, m_tsr.create());
            pose_bone._tsr_channel_cache = m_tsr.create();
            pose_bone._tsr_channel_cache_valid = false;
        }

        var bone_pointers = m_anim.calc_armature_bone_pointers(obj);
        render.bone_pointers = bone_pointers;

        var pose_data = m_anim.calc_pose_data(obj, bone_pointers);

        render.quats_before = pose_data.quats;
        render.quats_after  = pose_data.quats;
        render.trans_before = pose_data.trans;
        render.trans_after  = pose_data.trans;
        render.frame_factor = 0;

        break;
    case "MESH":
        render.selectable = cfg_def.all_objs_selectable || obj["b4w_selectable"];
        render.origin_selectable = obj["b4w_selectable"];
        render.glow_anim_settings = {
            glow_duration: obj["b4w_glow_settings"]["glow_duration"],
            glow_period: obj["b4w_glow_settings"]["glow_period"],
            glow_relapses: obj["b4w_glow_settings"]["glow_relapses"]
        };

        if (render.selectable) {
            // assign color id
            obj._color_id = m_util.gen_color_id(_color_id_counter);
            _color_id_counter++;
        }

        prepare_skinning_info(obj);
        prepare_vertex_anim(obj);

        // apply pose if any
        var armobj = m_anim.get_first_armature_object(obj);
        if (armobj) {
            var bone_pointers = obj._render.bone_pointers;
            var pose_data = m_anim.calc_pose_data(armobj, bone_pointers);

            render.quats_before = pose_data.quats;
            render.quats_after  = pose_data.quats;
            render.trans_before = pose_data.trans;
            render.trans_after  = pose_data.trans;
            render.frame_factor = 0;
        }

        obj._batches = [];

        render.shadow_cast = obj["b4w_shadow_cast"];
        render.shadow_receive = obj["b4w_shadow_receive"];
        render.shadow_cast_only = obj["b4w_shadow_cast_only"] 
                && render.shadow_cast;

        render.reflexible = obj["b4w_reflexible"];
        render.reflexible_only = obj["b4w_reflexible_only"] 
                && render.reflexible;
        render.reflective = obj["b4w_reflective"];
        render.caustics   = obj["b4w_caustics"];

        render.wind_bending = obj["b4w_wind_bending"];
        render.wind_bending_angle = obj["b4w_wind_bending_angle"];
        var amp = m_batch.wb_angle_to_amp(obj["b4w_wind_bending_angle"], 
                m_batch.bb_bpy_to_b4w(obj["data"]["b4w_bounding_box"]), obj["scale"][0]);
        render.wind_bending_amp = amp;
        render.wind_bending_freq   = obj["b4w_wind_bending_freq"];
        render.detail_bending_freq = obj["b4w_detail_bending_freq"];
        render.detail_bending_amp  = obj["b4w_detail_bending_amp"];
        render.branch_bending_amp  = obj["b4w_branch_bending_amp"];
        render.hide = false;

        render.main_bend_col = obj["b4w_main_bend_stiffness_col"];
        var bnd_st = obj["b4w_detail_bend_colors"];
        render.detail_bend_col = {};
        render.detail_bend_col.leaves_stiffness = bnd_st["leaves_stiffness_col"];
        render.detail_bend_col.leaves_phase = bnd_st["leaves_phase_col"];
        render.detail_bend_col.overall_stiffness = bnd_st["overall_stiffness_col"];

        render.do_not_cull = obj["b4w_do_not_cull"];
        render.disable_fogging = obj["b4w_disable_fogging"];
        render.dynamic_geometry = obj["b4w_dynamic_geometry"];

        // assign params for object (bounding) physics simulation
        // it seams BGE uses first material to get physics param
        var first_mat = first_mesh_material(obj);
        render.friction = first_mat["physics"]["friction"];
        render.elasticity = first_mat["physics"]["elasticity"];

        render.lod_dist_min = 0;
        render.lod_dist_max = 10000;
        render.lod_transition_ratio = obj["b4w_lod_transition"];
        render.last_lod = true;

        break;
    case "CAMERA":
        m_cam.camera_object_to_camera(obj);
        m_cam.assign_boundings(obj);
        break;

    case "LAMP":
        m_lights.lamp_to_light(obj);
        break;

    case "CURVE":
        var spline = m_curve.create_spline(obj);
        if (spline)
            obj._spline = spline;
        break;
    case "SPEAKER":
        break;
    case "EMPTY":
        // NOTE: center = 1/2 height
        var bb = m_bounds.zero_bounding_box();
        render.bb_local = bb;

        var bs = m_bounds.zero_bounding_sphere();
        render.bs_local = bs;
        break;
    default:
        break;
    }

    // NOTE: temporary disable armature parenting
    if (obj["parent"] && obj["parent_type"] == "OBJECT" && obj["parent"]["type"] != "ARMATURE") {
        var trans = render.trans;
        var quat = render.quat;
        var scale = render.scale;
        m_cons.append_stiff_obj(obj, obj["parent"], trans, quat, scale);
    } else if (obj["parent"] && obj["parent_type"] == "BONE" &&
            obj["parent"]["type"] == "ARMATURE") {
        var trans = render.trans;
        var quat = render.quat;
        m_cons.append_stiff_bone(obj, obj["parent"], obj["parent_bone"], trans, quat);
    } else if (obj._dg_parent && obj._dg_parent["b4w_group_relative"]) {
        // get offset from render before child-of constraint being applied
        var offset = m_tsr.create_sep(render.trans, render.scale, render.quat);
        m_cons.append_child_of(obj, obj._dg_parent, offset);
    } else if (obj._dg_parent && !obj._dg_parent["b4w_group_relative"]) {
        m_trans.update_transform(obj);    // to get world matrix
        var wm = render.world_matrix;
        m_mat4.multiply(obj._dg_parent._render.world_matrix, wm, wm);

        var trans = m_util.matrix_to_trans(wm);
        var scale = m_util.matrix_to_scale(wm);
        var quat = m_util.matrix_to_quat(wm);

        m_trans.set_translation(obj, trans);
        m_trans.set_rotation(obj, quat);
        m_trans.set_scale(obj, scale);
    }

    // store force field
    if (obj["field"]) {
        render.force_strength = obj["field"]["strength"];
        m_scenes.update_force(obj);
    }

    // make links from group objects to their parent
    var dupli_group = obj["dupli_group"];
    if (dupli_group) {
        var dg_objects = dupli_group["objects"];
        for (var i = 0; i < dg_objects.length; i++) {
            var dg_obj = dg_objects[i];
            dg_obj._dg_parent = obj;
        }
    }

    render.use_collision_compound = obj["game"]["use_collision_compound"];
    render.physics_type = obj["game"]["physics_type"];

    m_trans.update_transform(obj);
}