第三章:用jMonkeyEngine SDK转换j3o
jMonkeyEngine SDK,是jME3官方团队基于 NetBeans 制作的集成开发工具,下面简称 SDK 。在 SDK 中创建 jME3 工程,将会自动生成资产目录。
SDK 下载地址:https://github.com/jMonkeyEngine/sdk/releases
创建JME3工程
第一步:在菜单中选择 File -> New Project。
第二步:在弹出的对话框中,选择工程模板 JME3 -> BasicGame,然后点击 Next > 按钮。

第三步:在下一步窗口中,输入工程名(Project Name),并选择保存工程的位置(Project Location),然后点击 Finish 按钮。
例如,我在 F:\ 盘创建了一个名为 HelloGame 的jME3工程。

上述步骤完成后,将生成名为 HelloGame 的工程。SDK 会自动在工程的 Project Assets 目录中创建资产目录结构,并在 Source Packages 中创建 mygame.Main 类,按 F6 即可运行程序。

工程结构分析
SDK中的JME3工程结构如下:
- Project Assets 资产目录,用来存放游戏资产。
 - Source Packages 代码目录,用来存放 java 代码。
 - Libraries 项目依赖库,关联了 jme3-core.jar、jme3-desktop.jar 等库文件。
 - Important Files 项目的编译脚本。
 
打开 F:\HelloGame 文件夹,可以看到这个工程的实际结构。

SDK 中的 Project Assets 对应 F:\HelloGame\assets 目录,Source Packages 对应 F:\HelloGame\src 目录。
用SDK转换j3o模型
不管你习惯用什么IDE来开发Java/Android程序,SDK几乎都是必不可少的,因为需要用它来转换j3o模型。虽然你在了解 jME3 的转换原理后,可以自己写转换脚本,但至少目前来说 SDK 是最方便的。
下面我将介绍如何使用SDK来转换j3o。
在 Textures 目录下创建 Monkey 文件夹,把上一章制作的猴头模型和纹理都放进去。

鼠标右键点击 monkey.blend 文件,在弹出菜单中选择 “Convert to j3o Binary”。如果模型本身数据没有问题,那么就会生成一个 monkey.j3o 文件。

双击这个 j3o 文件,SDK 将会通过 Scene Composer 窗口来预览3D模型。看到的模型是一团漆黑,可能意味着需要“开灯”。

“开灯”后,看起来是这样的。

在 Models 目录下创建 Monkey 文件夹,把 monkey.j3o 文件拖进去。(这时 monkey.blend 文件已经不需要了。)

在程序中使用j3o
现在,可以在代码中通过 assetManager.loadModel("Models/Monkey/monkey.j3o") 来加载这个猴头模型。
package mygame;
import com.jme3.app.SimpleApplication;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
/**
 * 测试加载j3o模型
 * @author yanmaoyuan
 */
public class Main extends SimpleApplication {
    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }
    @Override
    public void simpleInitApp() {
        // 加载j3o模型
        Spatial model = assetManager.loadModel("Models/Monkey/monkey.j3o");
        rootNode.attachChild(model);
        // 添加灯光
        DirectionalLight sun = new DirectionalLight();
        sun.setColor(new ColorRGBA(0.7f, 0.7f, 0.7f, 1f));
        sun.setDirection(new Vector3f(-3, -4, -5).normalizeLocal());
        rootNode.addLight(sun);
        AmbientLight ambient = new AmbientLight();
        ambient.setColor(new ColorRGBA(0.2f, 0.2f, 0.2f, 1f));
        rootNode.addLight(ambient);
    }
}
运行结果如下:

性能比较比较
写一个简单的例子比较导入 blend 文件和 j3o 文件的性能。
package mygame;
import com.jme3.app.SimpleApplication;
/**
 * Test load j3o model.
 * @author yanmaoyuan
 */
public class Main extends SimpleApplication {
    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }
    @Override
    public void simpleInitApp() {
        // load j3o
        long start = System.currentTimeMillis();
        assetManager.loadModel("Models/Monkey/monkey.j3o");
        long time = System.currentTimeMillis() - start;
        System.out.println("j3o : " + time + "ms");
        // load blend
        start = System.currentTimeMillis();
        assetManager.loadModel("Textures/Monkey/monkey.blend");
        time = System.currentTimeMillis() - start;
        System.out.println("blend :" + time + "ms");
    }
}
运行结果:
j3o : 42 ms
blend :297 ms
根据实际使用经验,直接导入 .blend 文件的时间,是导入 .j3o 文件的5~8倍以上。随着文件规模的增大,这个比例会越来越大。所以最好不要在项目中直接使用 .blend 文件!