如何加载《天龙八部》Skeleton

网络游戏《天龙八部》采用的是Ogre3d作为其客户端渲染引擎,他们对之做了许多自定义的修改,在这里作为学习只用,特别说明一下其自定义的Skeleton的格式,以及如何加载的办法。

天龙八部加入了这样一个区段:

SKELETON_ANIMATION_TRACK_MULTI_KEYFRAME  0x4120 (16672)
在加入了这个区段的内容之后,其格式大概就是这样一个样子:

 enum SkeletonChunkID {
        SKELETON_HEADER            = 0x1000,
            // char* version           : Version number check
        SKELETON_BONE              = 0x2000,
        // Repeating section defining each bone in the system. 
        // Bones are assigned indexes automatically based on their order of declaration
        // starting with 0.

            // char* name                       : name of the bone
            // unsigned short handle            : handle of the bone, should be contiguous & start at 0
            // Vector3 position                 : position of this bone relative to parent 
            // Quaternion orientation           : orientation of this bone relative to parent 
            // Vector3 scale                    : scale of this bone relative to parent 

        SKELETON_BONE_PARENT       = 0x3000,
        // Record of the parent of a single bone, used to build the node tree
        // Repeating section, listed in Bone Index order, one per Bone

            // unsigned short handle             : child bone
            // unsigned short parentHandle   : parent bone

        SKELETON_ANIMATION         = 0x4000,
        // A single animation for this skeleton

            // char* name                       : Name of the animation
            // float length                      : Length of the animation in seconds

            SKELETON_ANIMATION_TRACK = 0x4100,
            // A single animation track (relates to a single bone)
            // Repeating section (within SKELETON_ANIMATION)
                
                // unsigned short boneIndex     : Index of bone to apply to

                SKELETON_ANIMATION_TRACK_KEYFRAME = 0x4110,
                // A single keyframe within the track
                // Repeating section

                    // float time                    : The time position (seconds)
                    // Quaternion rotate            : Rotation to apply at this keyframe
                    // Vector3 translate            : Translation to apply at this keyframe
                    // Vector3 scale                : Scale to apply at this keyframe

                SKELETON_ANIMATION_TRACK_MULTI_KEYFRAME = 0x4120,
                // A multiple keyframe within the track
                // Repeating section

                    // float length                 : Length of the animation in seconds
                    // float flags                  : Length of the animation in seconds
                        // float time                   : The time position (seconds)
                        // Quaternion rotate            : Rotation to apply at this keyframe
                        // Vector3 translate            : Translation to apply at this keyframe
                
        SKELETON_ANIMATION_LINK         = 0x5000
        // Link to another skeleton, to re-use its animations

            // char* skeletonName                    : name of skeleton to get animations from
            // float scale                            : scale to apply to trans/scale keys

    };

然后我们打开OgreSkeletonSerializer.cpp找到SkeletonSerializer::readAnimationTrack的实现,然后替换为下面的代码:

void SkeletonSerializer::readAnimationTrack(DataStreamPtr& stream, Animation* anim, 
        Skeleton* pSkel)
    {
        // unsigned short boneIndex     : Index of bone to apply to
        unsigned short boneHandle;
        readShorts(stream, &boneHandle, 1);

        // Find bone
        Bone *targetBone = pSkel->getBone(boneHandle);

        // Create track
        NodeAnimationTrack* pTrack = anim->createNodeTrack(boneHandle, targetBone);

        // Keep looking for nested keyframes
        if (!stream->eof())
        {
            unsigned short streamID = readChunk(stream);
            while( (streamID == SKELETON_ANIMATION_TRACK_KEYFRAME || streamID == SKELETON_ANIMATION_TRACK_MULTI_KEYFRAME)
                && !stream->eof())
            {
                if (streamID == SKELETON_ANIMATION_TRACK_MULTI_KEYFRAME)
                {
                    // TLBB 新增了此部分
                    unsigned short len;
                    unsigned short flags;
                    readShorts(stream, &len, 1);
                    readShorts(stream, &flags, 1);

                    int count = (mCurrentstreamLen - 4 - 4) / 4;
                    if (len != count / 8)
                    {
                        len = len;
                    }
                    float time;
                    for (int i = 0; i < len; i += 1)
                    {
                        readFloats(stream, &time, 1);
                        TransformKeyFrame *kf = pTrack->createNodeKeyFrame(time);

                        Quaternion rot = Quaternion::IDENTITY;
                        if (flags & 1)
                        {
                            readObject(stream, rot);
                        }
                        kf->setRotation(rot);

                        Vector3 trans = Vector3::ZERO;
                        if (flags & 2)
                        {
                            readObject(stream, trans);
                        }
                        kf->setTranslate(trans);
                    }
                }
                else
                {
                    readKeyFrame(stream, pTrack, pSkel);
                }

                if (!stream->eof())
                {
                    // Get next stream
                    streamID = readChunk(stream);
                }
            }
           
            if (!stream->eof())
            {
                // Backpedal back to start of this stream if we've found a non-keyframe
                stream->skip(-STREAM_OVERHEAD_SIZE);
            }
        }
    }
保存然后重新编译Ogre就OK了,理论上就是可以加载其骨骼动画了。

时间: 2024-12-29 10:24:50

如何加载《天龙八部》Skeleton的相关文章

Android Jni调用so库,加载库失败分析

现有一个项目,通过JNI接口调用底层库,例如:lib***.so 如下所示,总是加载不成功.调试发现,每次加载so库,会跳到catch异常处理部分,然后打印异常log信息. static{ try{ System.load("/data/data/com.***/lib/lib***.so"); } catch(UnsatisfiedLinkError ulink){ Log.i("HVnative====","Can not load library&q

Daemon Tools如何加载镜像

  首先在下载吧下虚拟光驱Daemon Tools 然后对Daemon Tools进行安装. 安装好后可以看到 右键点击该图标的DAEMON Tools Lite虚拟光驱工具. 如图 再点击装载和驱动管理. 点击出现如下图: 此时你就从这个对话框中,去找到你下载到的游戏的目录,就会发现所谓的映像文件! 游戏的映像文件格式很多种,不需要去记什么格式,只要用这个对话框去找游戏,去到下载到的游戏文件夹里, 你就会看见哪个是映像文件!若游戏只有1个映像文件,这就好办了!直接选中它,打开就是了! (强烈建

安卓viewpager加载问题

问题描述 安卓viewpager加载问题 在viewpager实现底部选项的时候,我首先进入的是首页,然后我直接点几最后一个个人中心的按钮,但是点进去的时候,他首先会想加载第二个和第三个的里面的数据,我想问下,怎么才能在点几最后一个按钮的时候,不加载第二个和第三个里面的东西,只有点击第几个就记载第几个里面的东西,这个怎么实现? 解决方案 首先先让我吐槽一下错别字,点几,还一错就错两个,是点击呀.你这个其实不应该使用viewPager而是直接使用四个fragment就行了,然后使用Fragment

给jsp页面加图片加载不出来

问题描述 给jsp页面加图片加载不出来 jsp页面在main里 图片在images里,我路径 .为啥jsp页面显示不出来呢? 解决方案 src='${request.pageContext.contextPath}/images/1.gif' 解决方案二: 解决方案三: 有木有大神 挺着急的 解决方案四: 1.先看看${request.pageContext.contextPath}对不对,一般这个不至于不正确 2.换个png等图片试试,可能是你的gif图片格式不支持,无法显示 解决方案五: 不

webview加载html,a标签超链接禁止跳转

问题描述 webview加载html,a标签超链接禁止跳转 webview加载html,a标签超链接禁止跳转 webview加载html,a标签超链接禁止跳转 webview加载html,a标签超链接禁止跳转 webview加载html,a标签超链接禁止跳转 webview加载html,a标签超链接禁止跳转 解决方案 shouldOverrideUrlLoading方法 return true 解决方案二: 简单,你在setWebViewClient()方法中把你的连接过滤掉就行了.

转圈圈定制加载中视图

// // HYCircleLoadingView.h // HYCircleLoadingViewExample // // Created by Shadow on 14-3-7. // Copyright (c) 2014年 Shadow. All rights reserved. // #import <UIKit/UIKit.h> /*! * @brief 圆形转圈圈加载等待视图 * @author huangyibiao */ @interface HYBCircleLoading

cortex a9 jtag-IMX6Q JTAG加载UBOOT失败原因

问题描述 IMX6Q JTAG加载UBOOT失败原因 UBoot加载问题点:用JTAG连接板卡,出现报错"Load Debugger fs3",截图如附件. 板卡最小系统参数: - CPU:Freescale IMX6Q Cortex-A9 - DDR3:Micorn 2Gb(32位) - Flash:Micron 256M(8位) 测试发现问题点: - 主晶振24M没有起振(更换16pF~36pF均如此---不振:测试晶振的电平XTALI/O均为457mV,NVCC_PLL_OUT电

Js表格万条数据瞬间加载实现代码

 一条数据创建一行,如果数量大的时候,一次性要加载完数据的话,浏览器就会卡上半天,下面有个不错的方法,大家可以参考下 Js表格,万条数据瞬间加载    在Ajax动态加载数据的实际应用中,大家都习惯了一种思维方式:一条数据创建一行.  于是如果数量大的时候,一次性要加载完数据的话,浏览器就会卡上半天    受Flex的DataGrid控件的启发,在Flex的DataGrid控件中,展示数据的方法并不是有多少条数据就创建多少行,它最多只创建你在界面上所看到的十几二十行(假设为n行),如果数据多的话

android上拉下拉加载更多数据

最近项目中用到了ListView的下拉刷新的功能,总结了一下前辈们的代码,单独抽取出来写了一个demo作为示例. 效果图 下拉刷新: 加载更多: CustomListView.java [java] view plaincopy package com.example.uitest.view;      import java.util.Date;   import com.example.uitest.R;   import android.content.Context;   import