DJ's WebGL Tutorial 007--骨骼动画

本文档介绍了如何在WebGL中实现骨骼动画,通过JavaScript处理CPU骨骼更新,并利用GPU进行顶点蒙皮。动画数据从Unity3D导出,包括骨架、动画曲线和顶点的骨骼权重信息。
摘要由CSDN通过智能技术生成

骨骼动画是目前最常用的模型动画,
这一节将增加对骨骼动画的支持,
使用javascript进行基于cpu的骨骼更新,
使用vertex shader进行基于gpu的顶点蒙皮。
所用模型和动画数据都导出自Unity3D。


动画数据加载

读取了骨架、动画clip(包含动画曲线关键帧)、模型的bindpose、顶点的骨骼索引和权重:

function on_mesh_data_load(data, mesh) {
   
    var offset = [0];
    read_string(data, offset);

    var bone_count = DataLoader.ReadInt32(data, offset);
    var bone_array = [];
    var bone_map = {};
    for(var i=0; i<bone_count; i++) {
        var b_name = read_string(data, offset);
        var b_pos = read_vector3(data, offset);
        var b_rot = read_quaternion(data, offset);
        var b_sca = read_vector3(data, offset);
        var parent = DataLoader.ReadInt32(data, offset);

        var b = {
            name:b_name,
            pos_loc:b_pos,
            rot_loc:new Quaternion().set(b_rot),
            sca_loc:b_sca,
            children:{}
        };
        if(parent >= 0) {
            b['parent'] = bone_array[parent];
            b['parent']['children'][b_name] = b;
        } else {
            b['parent'] = null;
        }

        bone_array[i] = b;
        bone_map[b_name] = b;
    }
    mesh.bone_array = bone_array;
    mesh.bone_map = bone_map;

    var clip_count = DataLoader.ReadInt32(data, offset);
    var clips = {};
    for(var i=0; i<clip_count; i++) {
        var c_name = read_string(data, offset);
        c_name = c_name.substr(0, c_name.indexOf('_'));

        var fps = DataLoader.ReadFloat32(data, offset);
        var len = DataLoader.ReadFloat32(data, offset);
        var mode = DataLoader.ReadUint8(data, offset);

        var curve_count = DataLoader.ReadInt32(data, offset);
        var curves = [];
        for(var j=0; j<curve_count; j++) {
            var path = read_string(data, offset);
            var property = read_string(data, offset);

            var key_count = DataLoader.ReadInt32(data, offset);
            var keys = [];
            for(var k=0; k<key_count; k++) {
                var tan_in = DataLoader.ReadFloat32(data, offset);
                var tan_out = DataLoader.ReadFloat32(data, offset);
                var tan_mode = DataLoader.ReadInt32(data, offset);
                var time = DataLoader.ReadFloat32(data, offset);
                var value = DataLoader.ReadFloat32(data, offset);

                keys[k] = {
                    tan_in:tan_in,
                    tan_out:tan_out,
                    tan_mode:tan_mode,
                    time:time,
                    value:value
                };
            }

            curves[j] = {
                path:path,
                property:property,
                keys:keys
            };
        }

        clips[c_name] = {
            name:c_name,
            fps:fps,
            len:len,
            mode:mode,
            curves:curves
        };
    }
    mesh.clips = clips;

    var renderer_count = DataLoader.ReadInt32(data, offset);
    for(var i=0; i<renderer_count; i++) {
        var r_name = read_string(data, offset);
        var r_pos = read_vector3(data, offset);
        var r_rot = read_quaternion(data, offset);
        var r_sca = read_vector3(data, offset);

        var r_bone_count = DataLoader.ReadInt32(data, offset);
        var r_bones = [];
        for(var i=0; i<r_bone_count; i++) {
            var index = DataLoader.ReadInt32(data, offset);
            if(index >= 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值