作者:Jens Chr Brynildsen
随着Away3d 4.0的发布,我们准备了一系列关于工作流程的教程。这个教程将会演示如何从3ds Max中导出带骨骼动画的模型,并且在Away3d中加入互动元素。
使用方向键,E键,Shift键个空格键控制角色,点击此处打开更高分辨率的版本
教程环境需求
1.Windows电脑
2.Autodesk3ds Max 2012 ()
3.最新版本的Away3D 4
4.AWD Max插件
确保你已经安装3dsMax,并从官网的下载中心或者GitHub下载最新版本的Away3D,另外你需要一个Flash开发工具,譬如FlashBuilder。
载入AWD plugin
AWD格式由Away3D团队制定,用来解决其他文件不适合网络应用的问题。目标是创建一种紧凑,可扩展的三维格式,可以自主选择是否加载材质,动画及其他资源。支撑多个模型,甚至可以导出整个场景。
这是一种标准的,免费的格式,提供开源的C++和Python SDK以便得到更好的编译,这些优点使之成为一个很有吸引力的格式。
AWD团队计划为Blender, Maya 和 3ds Max这次流行的3D软件创建插件。其中3ds Max插件可以在下载部分得到。在教程发布时,Maya和Blender依然在代码阶段,很快就会发布。下载合适的插件,并且按照安装示例正确安装后,打开3ds Max就可以在导出对话框中AWD选项。如下图。
在3ds Max中准备模型。
这次使用的模型和代码是的作者是法国设计师,它是有一个模型为基础,并在Character Studio和Biped中创建了骨骼和角色动画。
你可以在下载包含3ds Max 工程,材质,Biped打包文件,以及包含src文件的ActionScript源代码文件和以后将会用到的一个”sequence”文件。
当你打开onkba.max文件时,软件或许会弹出一些提示,忽视他们。你可以使用磨砂滑块观察包括静止,行走以及奔跑的三个动画,如果你打开Graph Editors -> Motion Mixer,可以观察到骨骼动画。同时,你可以在时间线加快或减慢动画速率,以及各个动作的次序。
打开管理图层面板,观察骨骼动画。隐藏骨骼层和打开蒙皮层。这些骨骼将会在之后被导出到AWD文件中,你也可以用actionScript控制它们。而仅仅导出标记为可渲染图层的设置也将在不久之后实现。
当你导出AWD文件时,你应该清楚,AWD现在只支持几何体,多边形(包含instancing),包含容器和父子关系的动画,包含基本颜色和贴图的材质,骨骼和骨骼动画。除此之外其他任何东西都会被忽略。
从Max中导出
当模型工作完成后,我们需要决定哪些部分需要导出,同时建立一个导出文件夹。并在这个文件夹中建立一个叫做”sequence.txt”的文件。文件将记录我们导出动画的名字和帧的范围,并在之后的代码中用到。到这个Wiki page中了解更多。
在这个实例中,我们将写入以下内容。
- Breathe 0 60
- Walk 70 130
- Run 140 157
它仅仅在导出AWD文件时做标记用途,为了获得其他的导出效果你可以修改这个文件。同时导出插件自带的预览器将会预览第一个动画。点击主菜单下的导出命令,选择合适的文件夹,在下拉菜单中选择AWD文件。AWD导出设置提供丰富的参数,当然默认的就足够好了。在最后导出之前,请再次确保设置文本文件没有问题。
在导出之后,导出插件会默认预览文件。如果你想在本地预览的话,请选择"Export for local preview"
也可以选择"Exportfor deployment"在线分享给其他人。因为Flash Player安全沙箱的问题,但这种设置导出后不会有预览。
插件会导出整个场景,现在和不能单独导出骨骼。在这个例子中,我们选择在本地预览,确认导出会,会得到以下结果。
在导出文件中看到骨骼也无妨,我们可以在Flash中设置它。
如果预览是一片空白的话,那可能是"sequences.txt"文件的设置有问题,确认下文件名和内容是否和你的项目匹配,真不行的话可以参考Wiki页面
在Flash中使用模型
这个教程并不会注重于基本的场景搭建,你可以在官网的教程部分找到基本的摄像机,灯光,材质以及的模型的帮助。这个教程将会向你展示加载AWD文件和控制动画部分的操作。
在这个部分中,我们将使用Adobe推出的FlashBuilder编写代码,你也可以选择其他IDE,这里有如何在AdobeFlash,Flash Builder 以及免费开源的Flashdevelop中开发的教程,以及如何在这些工具中使用Actionscript项目
首先建立一个叫做"MaxAWDWorkflow"的ActionScript项目。
把下载的示例文件解压到项目文件夹中,并覆盖原来空的"MaxAWDWorkflow.as"。在设置Away3D源文件路径之后,我们将会用到这些文件。
前面已经提到过,你可以从Github下载ZIP格式的源文件,并将它解压的合适的文件夹中。之后到属性面板的"Actionscript Build Path"菜单中设置源文件路径。
你的项目窗口中应该有如下图所示的一些文件。
点击绿色的运行之后,你可以看到一个红色的圆球。如果在运行时出现"Error #2044",那么需要在HTML template中加入其它一些参数。下面一节将会处理这个问题。如果你一切顺利,请跳过下一章。
Stage3D 标记
很遗憾,刚刚导出的文件不能在stage3D中运行,通常会得到一个错误提示:"Error #2044: Unhandled ErrorEvent:.text=Error #3702: Context3D not available."其中Context3D是Stage3D的一个核心类,我们可以通过添加一下代码到HTML中解决这个问题。
params.wmode="direct";
点击放大此图,查看添加的具体位置。
如果你使用adobeair 可能还要添加一下内容到application.xml。
<renderMode>direct</renderMode>
如果还有问题,并且是正在使用老版本的SDK开发,可能还要添加下面的编译参数。强制使用Flash Player 11.x
-swf-version=13
运行实例文件。
运行AWDViewerLoth.as作为运行文件,检验我们导出的.awd文件。在不同的IDE中,有不同的方法,在FlashBuilder中,我们可以右击"AWDViewerLoth.as"选择"Set as Default application"。同时打开"AWDViewerLoth.as",他将在后面被用到。点击运行按钮后,你将看到我们导出的动画角色,使用WASD控制,使用Shift奔跑。
如果提示"SecurityError:Error #2148",并不能运行,你需要添加编译器参数-use-network=false到项目中,详情请看 。
我会在下面的代码中解释模型是如何工作的,在构造函数中有initEngine, initText 和 initLights三个方法,它们建立了这个场景的基础:视口,摄像机以及其他。initLoading是最后一个方法,负责使用AssetLibrary类加载各种资源。
AssetLibrary类
它是一个Away3D 4新添加的一个加载类,可以加载多边形,几何体,位图贴图等各种资源
首先要告诉格式解析器你要导入的格式,应该是Away3D支持的OBJ,AC3D,DAE,3DS,MD2,MD5以及AWD1,AWD2中的一种。如果嫌麻烦,也可以这么做加载所有解析器:
- Parsers.enableAllBundled();
当然导入更多的解析器意味着更大的swf体积,在这个项目中,我们只导入AWD2解析器,这样可以省下82kb的体积。
- AssetLibrary.enableParser( AWD2Parser );
通过Flash中的事件机制,我们可以侦听AssetLibrary加载过程中的的各种事件。
- AssetLibrary.addEventListener(AssetEvent.ASSET_COMPLETE, onAssetComplete );AssetLibrary.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete );AssetLibrary.addEventListener(LoaderEvent.LOAD_ERROR, onLoadError );
下面是我们经常侦听的3种事件:
- AssetEvent.ASSET_COMPLETE
很多情况下,导入Away3D的模型不仅仅包含多边形,在我们这个案例中,我们的模型包含一个带有各种动作的骨骼动画,以及嵌入的材质。模型自身包含多边形以及几何体。使用这个事件我们可以检查模型加载情况,并且使用它们。
在这个教程中,AssetLibrary类将会自己完成加载,而我们只会用它来纠错。通过tarce()函数,检查加载资源的名字和类型。你可以观察的到。这些加载资源和"sequencences.txt"具有相同的名字,如果名字有重复的话,AssetLibrary会自己处理。但请在命名文件时注意。
你也可以通过侦听Away3d类库中的AssetLibraryBundle侦听每个成员的加载。
- LoaderEvent.LOAD_ERROR
我们必须处理这个提示某些资源没有被加载的事件。在这个教程中,我们只是在控制台trace()错误,但是在更大的项目中,向用户显示这些错误信息会更好一点。
如果你不处理这个事件,那么在屏幕上只是一片空白。除非是在程序员使用的调试版本的Flash Player中才会显示错误:Error#2032: Stream Error。一定要侦听并处理这些事件,否则你的用户只会看到一个空白的屏幕。
- LoaderEvent.RESOURCE_COMPLETE
一旦加载完成,就会触发这个时间。因为我们的AWD不包含材质,所以我们需要两个申请。
- AssetLibrary.load( new URLRequest(TEXTURE_URL ) );AssetLibrary.load( new URLRequest(MESH_URL ) );
AWD2也可以将材质嵌入到模型中,这在大文件中有很大的价值。
在网络中,所有资源不太可能按照我们申请的顺序加载完成,而onResourceComplete方法的工作就是在我们进行下面的工作之前确认所有资源都已经加载完成,一旦模型和材质加载完成,我们就可以在setupScene方法中显示我们的模型。
渲染最终结果
在away3d中,只有加入到场景的对才会被渲染。在initEngine方法中,地面以及其他一些对象已经被加入,setupScene方法中为我们的hero角色加载了材质,并且将它缩放了合适的尺度。现在大部分三维软件都在不统一的单位内工作,所以缩放是很必须的。
- hero.scale( 8 );
如果你明白摄像机的工作原理,那么也可以通过摄像机设置来抵消这一种差别,两种方式是相对的。在大项目中,应该设定一个全局标准,用来统一各个模型的设置。
当设置好模型之后,我们将它添加到场景中。
- scene.addChild( hero );
现在模型已经可以被渲染了,但他还在默认位置上,我们下一步为它添加动作。我们使用一个动画数据容器,并将之前ASSET_COMPLETE事件中的数据添加进去。
- animationSet = newSkeletonAnimationSet(3);animationSet.addState(breatheState.name,breatheState);animationSet.addState(walkState.name,walkState);animationSet.addState(runState.name,runState);
在我们得到了动画设定之后,我们将在动画数据和模型之间建立关联,并创建控制机制。我们通过一个动画对象联系我们从ASSET_COMPLETE事件中获得的骨骼和新建立的动画设定。我们何以禁用经常在骨骼动画中使用的位置更新(position update),防止角色远离摄像机。
- animator = newSkeletonAnimatior(animationSet, skeleton);animator.updateRootPosition = false;hero.animator = animator;
最后,为我们的动画定义一个状态转换器,它可以在我们几个动画间切换。现在我们将会使用默认的crossfade转换对象
- crossfadeTransition = newCrossfadeStateTransition(XFade_TIME);
XFADE_TIME是定义在类文件上方的一个常量,它定义了两个动画之间的动画过渡时间,如果设置为0的话,就会瞬间切换。这样看上去不太好,通常像我们这样进行一些顶点混合会比较好。
我们可以通过animationSet.hasState测试每个动画都被成功加载,避免一些不必要的错误,当然这不是必须的。这些都完成之后,可以开始渲染和添加用户交互。
根据用户的不同操作,updateMovement方法负责执行不同的动画,如果没有任何操作,那么将会执行,goToPauseState方法。在这两个方法中,我们设置动画状态名字并且激活他们。
- animator.play(currentAnim,crossfadeTransition);
总结
感谢AWD文件和AWD插件,我们可以轻松地从3ds Max导出带有动画和材质的模型到Away3D中。新的AssetLibrary类简化了各种资源的加载。ActionScript可以轻松的创建网络和移动平台的交互应用。紧凑的AWD格式优化了网络传输和加载