如何加载《天龙八部》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了,理论上就是可以加载其骨骼动画了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值