Away3D 4.1.4 中实现骨骼绑定

本文深入讲解了Away3D中骨骼绑定技术的实现原理与过程,包括如何创建绑定标签(BindingTag),并将其集成到Away3D中,以及如何确保绑定标签能够实时跟随骨骼更新。

骨骼的绑定归根结底就是将目标骨骼的位置以及旋转数据,同步给要绑定的显示对象。

先来看BindingTag.as

package away3d.entities
{
     import away3d.arcane;
     import away3d.animators.SkeletonAnimator;
     import away3d.animators.data.JointPose;
     import away3d.containers.ObjectContainer3D;
 
     use namespace arcane
    
     public class BindingTag extends ObjectContainer3D
     {
         private var _skeletonAnimator:SkeletonAnimator;
         private var _skeletonIndex: int ;
 
         /**
          *
          * @param skeletonAnimator
          * @param skeletonIndex 要绑定的骨骼索引
          *
          */    
         public function BindingTag(skeletonAnimator:SkeletonAnimator, skeletonIndex: int )
         {
             super ();
             _skeletonAnimator = skeletonAnimator;
             _skeletonIndex = skeletonIndex;
         }
 
         public function notifyBindingTransformChange(): void
         {
             invalidateTransform();
         }
 
         override protected function updateSceneTransform(): void
         {
             if (_parent)
             {
                 var jointPoses:Vector.<JointPose> = _skeletonAnimator.globalPose.jointPoses;
                 if (jointPoses && jointPoses.length)
                 {
                                         //取到骨骼数据并同步给当前对象
                     _sceneTransform.copyFrom( jointPoses[_skeletonIndex].toMatrix3D() );
                     _sceneTransform.append( _parent.sceneTransform );
                     _sceneTransform.prepend(transform);
                 }
             }
             _sceneTransformDirty = false ;
         }
 
         override public function dispose(): void
         {
             //TODO:
         }
     }
}
BindingTag即是绑定在指定骨骼上的容器,假如你想绑定武器或特效,
只要将他们addChild到该BindingTag就可以了。 
下面看怎样将BindingTag集成到Away3D里面。 
为AnimatorBase添加Exit_Frame事件,至于为什么要加这个Exit_Frame事件,后面再来解释。
分别在start()以及stop()方法里添加、移除Exit_Frame事件
?
1
2
3
4
5
6
7
8
9
10
if (!_broadcaster.hasEventListener(Event.EXIT_FRAME))
     _broadcaster.addEventListener(Event.ENTER_FRAME, onExitFrame);
 
if (_broadcaster.hasEventListener(Event.EXIT_FRAME))
     _broadcaster.removeEventListener(Event.EXIT_FRAME, onExitFrame);
 
protected function onExitFrame(event:Event): void
{
     //Override
}
为SkeletonAnimator添加addBindingTagByName,addBindingTagByIndex方法
以及复写onExitFrame
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
          * 绑定至通过名字指定的骨骼上
          * @param boneName
          * @return
          *
          */    
         public function addBindingTagByName(boneName: String ):BindingTag
         {
             var boneIndex : int = globalPose.jointPoseIndexFromName(boneName);
             if (boneIndex< 0 ) //骨骼不存在
                 return null ;
             return addBindingTagByIndex(boneIndex);
         }
 
         /**
          * 绑定至通过骨骼索引指定的骨骼上
          * @param boneIndex
          * @return
          *
          */    
         public function addBindingTagByIndex(boneIndex: int ):BindingTag
         {
             var bindingTag:BindingTag = new BindingTag( this , boneIndex);
 
             for ( var i: int = 0 ; i < _owners.length; i++)
             {
                 _owners[i].addChild(bindingTag); //将bindingTag添加至骨骼对应的Mesh
             }
 
             if (!_bindingTags)_bindingTags = new Vector.<BindingTag>();
             _bindingTags.push(bindingTag);         
             return bindingTag;
         }
 
         override protected function onExitFrame(event:Event): void
         {
             if (_bindingTags && _bindingTags.length)
             {
                 for ( var i: int = 0 ; i < _bindingTags.length; i++)
                 {
                     _bindingTags[i].notifyBindingTransformChange();
                 }
             }
         }
到这里就已经代码已经都修改添加完成了,下面来说下为什么要在Exit_Frame事件中通知
BindingTag更新.骨骼的更新是在skeletonAnimatior的updateGlobalProperties方法中
进行的,他的更新是在引擎执行完traverse后执行的,所以为了保证每次执行traverse时都能让
BindingTag根据骨骼更新,需在Exit_Frame时通知,否则BindingTag的更新总会延迟一帧,
从而导致跟随出现错位问题。
 

转载于:https://www.cnblogs.com/ch06src/p/3430951.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值