jME3的资产管理与文件系统

本文目标

经常有朋友问这么几个问题:

  • 怎么用jME3显示3D模型?
  • 怎么用jME3显示一张图片?
  • 为什么发生AssetNotFoundException异常?
  • 我的模型为什么是黑漆漆的?

回答这些问题,一般我会先问他/她使用的是什么开发工具,然后教他/她在自己的IDE中建立资产目录结构,把模型和纹理放到同一个文件夹。我还会再发一段用 AssetManager 来导入3D模型的代码,让他/她参考着来修改自己的代码。

不过这并没有什么鬼用,问的人实在太多了,我没有精力一一指导。因此,我打算写一套文章来详细分析解决方法。以后再有人问我这些问题,就可以让他们来这些文章中寻找答案。

问题分析

先引用《游戏引擎架构》一书中对“工具及资产管道”的论述:

游戏本质上是多媒体应用。游戏引擎的输入数据形式广泛,例如三角网格、纹理位图、动画数据、音频文件等。所有源数据皆由美术人员使用数字内容创作(digital content creation, DCC)应用软件制作。

DCC应用软件所使用的数据格式,鲜有适合直接用于游戏中的,主因有二。

  1. DCC软件在内存中的数据模型,通常比游戏所需的复杂得多。例如,Maya的场景节点,以有向非循环图(directed acyclic graph, DAG)储存,包含复杂的互相连接网络。Maya也储存了该文件的所有编辑历史记录。Maya场景中每个物体的位置、方向、比例,都以完整的三维变换表示,此变换又由平移(translation)、旋转(rotation)、缩放(scale)、切变(shear)所组成。游戏引擎通常只需要这些信息的一小部分就能在游戏中渲染模型。
  1. 在游戏中读取DCC软件格式的文件,其速度通常过慢。而有些格式更是不公开的专有格式。

因此,DCC软件制作的数据,通常要导出为容易读取的标准格式或自定义格式,以便在游戏中使用。

当数据自DCC软件导出后,有时必须再处理,才能放在游戏引擎里使用。若工作室要为游戏开发多个平台,这些中间文件必须按平台做不同处理。例如,三维网格(3D mesh)数据可能导出为某种中间文件格式,如XML或简单的二进制格式;之后,可能会合并相同材质的网格,或把太大的网格分割成引擎容许的大小;最后,为方便每个平台读取,用最合适的方式组织网格数据,并包装成内存影像。

从DCC到游戏引擎的管道,有时候称为资产调节管道(asset conditioning pipeline)。每个引擎都有某种形式的资产调节管道。

这些问题背后涉及到游戏引擎的资产管理文件系统。具体来说,就关于如何把美术人员制作的资源文件导入到游戏引擎中使用的问题。包括:

  • 把美术人员制作的源数据转化为游戏引擎的专有数据;
  • 在项目中建立标准资产目录结构,管理游戏资产;
  • 通过游戏引擎提供的API来导入游戏资产;
  • 游戏资产的打包、加密、发布;
  • 为美术人员开发专用工具,简化内容创作、文件转换等工作;
  • 等等

内容安排

这套文章,将由浅入深分析游戏资产在JME3中的使用方法、工作原理。

第一部分,资产管道。

这部分的内容比较偏向美术制作,介绍如何产生适用于JME3的游戏资产。

  • 从美术制作到程序使用的过程,了解游戏资产的来源;
  • JME3 的标准资产目录结构;
  • JME3 有哪些专有数据格式,支持哪些源数据格式;
  • 使用 jMonkeyEngine SDK 来转换游戏资产;
  • 使用 jMonkeyBuilder 来转换游戏资产;

第二部分,导入游戏资产。

这部分将讲解如何创建 JME3 资产目录结构,并使用 AssetManager 来导入不同类型的资产。

  • 在不同的IDE中创建资产目录结构;
  • 用 AssetManager 导入3D模型;
  • 用 AssetManager 导入材质;
  • 用 AssetManager 导入纹理位图;
  • 用 AssetManager 导入音频文件;
  • 用 AssetManager 导入字体;
  • 从自定义路径导入资产;
  • 加载资产时的常见异常;

第三部分:AssetManager工作原理。

这部分将分析 AssetManager 的工作原理,介绍资源定位、资源解析、资源缓存等概念。

  • 基础:Java文件读写
  • AssetManager工作流程分析
  • 用AssetLocator定位外部文件(classpath、file、zip、url等)
  • 用AssetLoader导入和解析文件
  • AssetManager的缓存机制

第四部分:导出和保存

这部分将介绍如何把JME3中的数据结构保存到磁盘,生成j3o文件,或者其他自定义文件格式。

  • Java序列化机制
  • Savable接口
  • BinaryImportor
  • BinaryExportor

第五部分:最佳实践

介绍在JME3中管理、加载游戏资产的一些最佳实践。

  • 工厂模式
  • 资源管理线程(异步加载)
  • 资产打包(zip、jar)
  • 纹理图集(TextureAtlas)

第六部分:案例

介绍一个实际的案例,用 jMonkeyEngine 的 AssetManager 来解析某游戏的加密数据包,加载并解析其中的3D模型。

目录

目前文章还在编写中,已写完的内容如下:

第一部分

第二部分

第三部分

第四部分