Away3D-3 含有动画的模型的加载与设置
1 package 2 { 3 import away3d.textures.*; 4 import away3d.tools.helpers.*; 5 import away3d.animators.data.*; 6 import away3d.animators.nodes.*; 7 import away3d.animators.*; 8 import away3d.materials.lightpickers.*; 9 import away3d.materials.methods.*; 10 import away3d.*; 11 import away3d.entities.*; 12 import away3d.materials.*; 13 import away3d.materials.methods.*; 14 import away3d.primitives.*; 15 import away3d.utils.*; 16 import away3d.containers.*; 17 import away3d.tools.commands.*; 18 import away3d.events.*; 19 import away3d.loaders.*; 20 import away3d.loaders.parsers.*; 21 import away3d.lights.*; 22 import away3d.core.base.*; 23 import away3d.cameras.*; 24 import away3d.controllers.*; 25 import away3d.controllers.*; 26 import away3d.primitives.*; 27 import away3d.tools.helpers.*; 28 import away3d.library.*; 29 import away3d.library.assets.*; 30 import away3d.animators.data.*; 31 import flash.net.*; 32 import flash.text.*; 33 34 import flash.display.*; 35 import flash.events.*; 36 import flash.ui.*; 37 import flash.display.*; 38 import flash.geom.*; 39 import flash.utils.*; 40 import flash.filters.*; 41 42 /** 43 * ... 44 * @author HonmaMeiko 45 */ 46 [SWF(width="600",height="400",backgroundColor="#FFFFFF", frameRate="60")] 47 public class Main extends Sprite 48 { 49 //3D视图 50 private var view:View3D; 51 //3D加载器,用于加载模型 52 private var loader:Loader3D; 53 //骨骼动画集合 54 private var animationSet:SkeletonAnimationSet; 55 //骨骼动画 56 private var animator:SkeletonAnimator; 57 //模型网格 58 private var modelMesh:Mesh; 59 //模型纹理 60 private var tex:TextureMaterial; 61 62 public function Main() 63 { 64 view = new View3D(); 65 //AssetLibrary.enableParser(AWD2Parser); //可以采用这种方式使加载器可以加载AWD2类型的模型文件 66 67 //本次模型以及纹理的加载都使用动态加载,动态加载可缩小生成的swf文件的大小 68 //首先进行模型的动态加载 69 var data:URLLoader = new URLLoader(); 70 data.dataFormat = URLLoaderDataFormat.BINARY; 71 //模型数据加载完成的时候调用监听函数 72 data.addEventListener(Event.COMPLETE,OnDownloadComplete);//实际使用的时候第五个参数设置为true以使用弱引用,可以使得监听器在不被使用的时候被GC回收 73 data.load(new URLRequest("ceshiyong.awd")); 74 //设置camera,指向坐标原点 75 view.camera.x = -50; 76 view.camera.y = 50; 77 view.camera.z = -50; 78 view.camera.lookAt(new Vector3D(0,0,0)); 79 80 81 stage.addChild(view); 82 stage.addEventListener(Event.ENTER_FRAME,OnFrame); 83 } 84 private function OnDownloadComplete(e:Event):void 85 { 86 //模型数据动态加载完成的时候为二进制数据,还无法直接使用 87 var target:URLLoader = e.target as URLLoader; 88 //创建3D加载器 89 loader = new Loader3D(false); 90 //监听ASSET_COMPLETE事件可以对模型加载的每一步都进行处理,如加载骨骼,加载骨骼位置,加载Mesh等. 91 loader.addEventListener(AssetEvent.ASSET_COMPLETE, OnAssetComplete); 92 //完全加载完成的时候调用OnAllComplete 93 loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE, OnAllComplete); 94 //不采用全局解析器的时候可以针对单个3D加载器设置相应的模型解析器 95 loader.loadData(target.data, null, null, new AWD2Parser()); 96 //移除监听器 97 target.removeEventListener(Event.COMPLETE, OnDownloadComplete); 98 } 99 private function OnAssetComplete(event:AssetEvent):void 100 { 101 //一个模型可以分为多个部分,主要处理的有:骨骼,动画帧节点,网格等. 102 if (event.asset.assetType == AssetType.SKELETON) { 103 //创建骨骼设置,这里设置的3代表的是网格中的每个顶点都受到3块骨骼的影响. 104 animationSet = new SkeletonAnimationSet(3); 105 //根据骨骼动画集合创建骨骼动画,而event.asset则包含了骨骼信息 106 animator = new SkeletonAnimator(animationSet, event.asset as Skeleton, true); 107 } else if (event.asset.assetType == AssetType.ANIMATION_NODE) { 108 //获得骨骼动画帧节点 109 var animationNode:SkeletonClipNode = event.asset as SkeletonClipNode; 110 //将骨骼动画帧节点添加到骨骼动画集中去 111 animationSet.addAnimation(animationNode); 112 } else if (event.asset.assetType == AssetType.MESH) { 113 //获取网格 114 var mesh:Mesh = event.asset as Mesh; 115 if (mesh) { 116 //判断网格的名字以取得网格,这个名字在建模工具中可以看到 117 if (mesh.name == "ONKBA-Corps-lnew") { 118 modelMesh = mesh; 119 } 120 } 121 } 122 } 123 private function OnAllComplete(e:Event):void 124 { 125 //模型文件完全加载完成以后,移除监听器 126 loader.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, OnAllComplete); 127 loader.removeEventListener(AssetEvent.ASSET_COMPLETE, OnAssetComplete); 128 //设置网格的动画,位置,缩放等属性 129 modelMesh.animator = animator; 130 modelMesh.x = 0; 131 modelMesh.y = 0; 132 modelMesh.z = 0; 133 modelMesh.scale(0.6); 134 //加载完成模型之后开始加载模型的纹理,依旧是动态加载 135 var texData:URLLoader = new URLLoader(); 136 texData.dataFormat = URLLoaderDataFormat.BINARY; 137 texData.addEventListener(Event.COMPLETE, OnDownloadTexComplete); 138 texData.load(new URLRequest("onkba_N.jpg")); 139 } 140 private function OnDownloadTexComplete(e:Event):void 141 { 142 //纹理数据加载完成之后为二进制数据 143 var target:URLLoader = e.target as URLLoader; 144 //创建加载器,这里是加载纹理图像,因此不是使用Loader3D而是使用Loader 145 var texLoader:Loader = new Loader(); 146 //注意添加的是contentLoaderInfo的监听器 147 texLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onBitmapComplete); 148 //二进制数据在target.data中,使用loadBytes()函数 149 texLoader.loadBytes(target.data); 150 target.removeEventListener(Event.COMPLETE, OnDownloadTexComplete); 151 } 152 private function onBitmapComplete(e:Event):void 153 { 154 //移除监听器 155 var target:Loader = LoaderInfo(e.target).loader; 156 target.contentLoaderInfo.removeEventListener(Event.COMPLETE, onBitmapComplete); 157 //将图像数据转换成纹理材质 158 tex = new TextureMaterial(Cast.bitmapTexture(target.content)); 159 //设置模型网格的材质 160 modelMesh.material = tex; 161 //设置动画播放速度 162 animator.playbackSpeed = 1; 163 //开始播放"Run"动画 164 animator.play("Run"); 165 //将网格添加场景中去 166 view.scene.addChild(modelMesh); 167 //卸载加载器 168 target.unload(); 169 } 170 private function OnFrame(e:Event):void 171 { 172 //渲染 173 view.render(); 174 } 175 } 176 }
AssetLibrary.enableParser(AWD2Parser); //可以采用这种方式使所有加载器都可以加载AWD2类型的模型文件
loader.loadData(target.data, null, null, new AWD2Parser());
以上是两种使用3D模型解析器的方式.动态加载文件主要是两步:
1.使用URLLoader加载文件,在监听事件中监听Event.COMPLETE事件
2.在完成事件函数中,使用Loader3D或Loader完成数据的加载(其实是对二进制数据的解析).
在模型和纹理都加载完成之后即可添加到场景中.
骨骼动画说明:
从3DSMAX中导出AWD模型需要使用插件,可到Away3D下载.
导出时选项设置:
1.General栏
Compression 设置成GZIP,压缩可使模型更小.
Export custom attribute 去掉勾选状态,不用设置
2.Scene&geometry栏
全部勾选
并注意最下面的Joints per vertex,这里设置成3表示每个顶点受到3块骨骼的影响.这个值不一定要设置成3(这里只是个例子).
注意,这里填的数值就是创建骨骼动画集的时候设置的参数!两处一定要设置成一样的.
animationSet = new SkeletonAnimationSet(3);
3.Material栏
勾选Include Material,表示包含材质.
(1).绝对路径,最好不要使用
(2).相对路径,可以勾选复制纹理到模型保存的目录(我测试的时候貌似没有效果,所以我没有勾选)
(3).将纹理包含到模型文件中,含义就是纹理图片包含在模型里面了(我没注意这个怎么使用)
4.Animation栏
(1).包含骨骼,骨骼动画模型必备
(2.)包含动画序列
就是按帧数分割动画,本例中使用的sequences.txt如下:
Breathe 0 60
Walk 70 130
Run 140 157
格式:
动画名 起始帧数 终止帧数
sequences.txt文件需要在导出之前就保存在导出目录中
模型导入后动画的使用方法:
animator.play("Run");
5.Flash viewer栏
导出后自动生成swf和html文件,用以预览模型(我测试时看到模型但看不到贴图)