前一节: Hello Node,下一节: Hello Update Loop

本节教程中,我们将学习如何使用jME asset manager(jME资源管理器)向场景图加载3-D模型和文字,并将了解到如何使用正确的文件格式。

右键点击工程,选择“Properties”,选择“Libraries”,点击“Add Library”,将“jme3-test-data”库添加进去。这样,就可以在接下来的例子中使用其中的资源了。

样例代码

package jme3test.helloworld;

import com.jme3.app.SimpleApplication;

import com.jme3.font.BitmapText;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.math.Vector3f;

import com.jme3.scene.Geometry;

import com.jme3.scene.Spatial;

import com.jme3.scene.shape.Box;

/** Sample 3 - how to load an OBJ model, and OgreXML model,

* a material/texture, or text. */

public class HelloAssets extends SimpleApplication {

public static void main(String[] args) {

HelloAssets app = new HelloAssets();

app.start();

}

@Override

public void simpleInitApp() {

Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");

Material mat_default = new Material(

assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");

teapot.setMaterial(mat_default);

rootNode.attachChild(teapot);

// Create a wall with a simple texture from test_data

Box box = new Box(Vector3f.ZERO, 2.5f,2.5f,1.0f);

Spatial wall = new Geometry("Box", box );

Material mat_brick = new Material(

assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

mat_brick.setTexture("ColorMap",

assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"));

wall.setMaterial(mat_brick);

wall.setLocalTranslation(2.0f,-2.5f,0.0f);

rootNode.attachChild(wall);

// Display a line of text with a default font

guiNode.detachAllChildren();

guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");

BitmapText helloText = new BitmapText(guiFont, false);

helloText.setSize(guiFont.getCharSet().getRenderedSize());

helloText.setText("Hello World");

helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);

guiNode.attachChild(helloText);

// Load a model from test_data (OgreXML + material + texture)

Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");

ninja.scale(0.05f, 0.05f, 0.05f);

ninja.rotate(0.0f, -3.0f, 0.0f);

ninja.setLocalTranslation(0.0f, -5.0f, -2.0f);

rootNode.attachChild(ninja);

// You must add a light to make the model visible

DirectionalLight sun = new DirectionalLight();

sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));

rootNode.addLight(sun);

}

}

生成并运行样例代码。你将看到一个绿色的忍者和一个彩色的茶壶,忍者站在墙后。屏幕上的文字是“Hello World”。

Asset Manager资源管理器

JME3有一个很便捷的资源管理器,可以协助你结构化地组织游戏资源。项目中的资源是类似模型、材质、纹理、场景、着色器、声音和字体的媒体文件。资源管理器中的root存储了classpath,因此可以从当前classpath(工程的顶级目录)中加载任意文件。

除此之外,你还可以设置assetManager,在其root中添加任意路径,这样就可以从任意自定义路径中加载资源。在 jMonkeyPlatform工程中,jME3在工程中的assets目录下搜索模型。如下是推荐的一种存储资源的目录结构:

assets/Interface/

assets/MatDefs/

assets/Materials/

assets/Models/

assets/Scenes/

assets/Shaders/

assets/Sounds/

assets/Textures/

build.xml

src/...

dist/...

这只是一个最常见的例子,assets目录下的子目录名可以是任意的。

加载纹理

将纹理放在assets/Textures/的子目录下。先加载纹理,再设置材质。下面是simpleInitApp()方法中的示例代码:

        // Create a wall with a simple texture from test_data
        Box box = new Box(Vector3f.ZERO, 2.5f,2.5f,1.0f);
        Spatial wall = new Geometry("Box", box );
        Material mat_brick = new Material(
            assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        mat_brick.setTexture("ColorMap",
            assetManager.loadTexture("Textures/Terrain/BrickWall/BrickWall.jpg"));
        wall.setMaterial(mat_brick);
        wall.setLocalTranslation(2.0f,-2.5f,0.0f);
        rootNode.attachChild(wall);

大多数情况下,你可以像本例中一样使用类似“SimpleTextured.j3md”的默认材质。如果是高手,也可以创建自定义材质。

加载文字和字体

本例中以默认字体在窗口下方边缘处显示了“Hello Text”。guiNode是一个用于显示平面(正投影)元素的特殊结点,可以把文字附加到guiNode上,这样就能在屏幕上显示该文字。移除guiNode上的孩子结点可以将已存在的文本全部清除。下面是simpleInitApp()方法中的示例代码:

        // Display a line of text with a default font
        guiNode.detachAllChildren();
        guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
        BitmapText helloText = new BitmapText(guiFont, false);
        helloText.setSize(guiFont.getCharSet().getRenderedSize());
        helloText.setText("Hello World");
        helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
        guiNode.attachChild(helloText);

加载Ogre XML 模型

将模型导出为OgreXML格式(包含.mesh.xml,.scene,.material,.skeleton.xml)并将其放在assets/Models/的子目录下。下面是simpleInitApp()方法中的示例代码:

        // Load a model from test_data (OgreXML + material + texture)
        Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.mesh.xml");
        ninja.scale(0.05f, 0.05f, 0.05f);
        ninja.rotate(0.0f, -3.0f, 0.0f);
        ninja.setLocalTranslation(0.0f, -5.0f, -2.0f);
        rootNode.attachChild(ninja);
        // You must add a light to make the model visible
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));
        rootNode.addLight(sun);

如果使用的是 jMonkeyPlatform创建的build script,那么默认状态下,发布的游戏中将不会包含原始的OgreXML文件,加载时就会报错。

com.jme3.asset.DesktopAssetManager loadAsset
WARNING: Cannot locate resource: Scenes/town/main.scene
com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException

如果是release build,你只能使用.j3o文件。jMonkeyPlatform右键菜单中有“OgreXML模型转为.j3o格式”命令。

从自定义路径中加载资源

如果你的游戏依赖于用户提供的模型文件(显然你不可能在发布时把这些模型添加进去),那又该怎么办呢?如果文件不在默认路径下,你可以注册一个自定义Locator(定位器),这样就能从任意路径加载模型文件。

如下是使用ZipLocator的例子,这个ZipLocator已注册了工程顶级目录下的town.zip这个文件:

    assetManager.registerLocator("town.zip", ZipLocator.class.getName());
    Spatial scene = assetManager.loadModel("main.scene");
    rootNode.attachChild(scene);

如下是一个能够下载压缩模型的HttpZipLocator:

    assetManager.registerLocator("http://jmonkeyengine.googlecode.com/files/wildhouse.zip",
                                 HttpZipLocator.class.getName());
    Spatial scene = assetManager.loadModel("main.scene");
    rootNode.attachChild(scene);

JME3 还提供了 ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, 和 UrlLocator (参见com.jme3.asset.plugins)。

创建模型和场景

为了创建3D模型和场景,你需要一款安装了OgreXML Exporter插件的3D模型编辑器,比如Blender。创建模型时,请使用UV纹理。你可以使用jMonkeyPlatform来加载模型,并用这些模型创建场景。

将模型导出为带材质的Ogre XML模型格式。

  1. 打开菜单File > Export > OgreXML Exporter,弹出导出器(exporter)对话框。
  2. 在导出材质(Export Matertials)栏将材质命名为与模型同样的名称。例如,模型的名称为something.mesh.xml,那么材质的名称就应当是something.material,也许还有something.skeleton.xml以及一些JPG文件。
  3. 在导出模型(Export Meshes)栏,选择您assets/Models/目录下的一个子目录。例如,assets/Models/something/。
  4. 勾选下列导出选项:
  • § Copy Textures: YES
  • § Rendering Materials: YES
  • § Flip Axis: YES
  • § Require Materials: YES
  • § Skeleton name follows mesh: YES
  1. 点击导出(export)。

文件格式:JME3可以加载Ogre XML模型、材质、场景,还能有加载Wavefront OBJ+MTL格式的模型。发布游戏时,您应该把所有的模型转换为JME3的.j3o格式,这样才能优化模型加载过程。我们推荐您使用jMonkeyPlatform创建工程,它集成了一个.j3o转换器。

  1. 在jMonkeyplatform中打开您的JME3工程。
  2. 在Projects(或者Favorites)视图中右击一个.mesh.xml文件,然后选择“convert to JME3 binary”。
  3. .j3o文件将出现在.mesh.xml文件旁边,文件名保持相同。
  4. 如果您使用jMonkeyPlatform生成的build script,那么mesh.xml文件和obj文件将不会包含在可执行JAR文件中。如果您碰到了运行时异常,请确保您已经把所有的模型都转换成了.j3o格式。

加载模型和场景

任务?

解决方案!

加载有材质的模型

使用资源管理器的loadModel() 方法,将这一Spatial附加到rootNode。

Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.mesh.xml");
rootNode.attachChild(elephant);
Spatial elephant = assetManager.loadModel("Models/Elephant/Elephant.j3o");
rootNode.attachChild(elephant);

加载无材质的模型

如果您有无材质的模型,您应当添加一个默认的材质,以使模型可见。

Spatial teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
Material mat = new Material(assetManager, "Common/MatDefs/Misc/ShowNormals.j3md");
teapot.setMaterial(mat);
rootNode.attachChild(teapot);

加载场景

您可以像加载模型一样加载场景:

Spatial scene = assetManager.loadModel("Scenes/house/main.scene");
rootNode.attachChild(scene);

练习 - 怎样加载资源

作为练习,不妨尝试一下用不同的方法加载场景。可以直接加载场景,也可以从zip文件中加载:

  1. 下载town.zip示例场景。
  2. (可选:)解压town.zip可以观察到其中的文档结构:您将看到一个名为town文件夹包含了main.scene、XML、纹理等文件。(这里仅仅是介绍一下,您不需要对模型文件做任何操作。)
  3. 将wildhouse.zip放在工程顶级目录,比如这样:

jMonkeyProjects/MyGameProject/assets/

jMonkeyProjects/MyGameProject/build.xml

jMonkeyProjects/MyGameProject/src/

jMonkeyProjects/MyGameProject/town.zip

...

用如下方法从zip文件中加载模型:

  1. 确保town.zip在工程目录中 。
  2. 我们把zip文件定位器注册到工程目录。loadModel() 方法将直接在zip文件中搜索需要加载的文件。
    (也就是说,不要写出town.zip/main.scene这样的路径
  3. simpleInitApp() 中添加如下代码
  4. 清理、生成并运行此工程。您将看到小镇里树立着一堵墙,上面有一个水壶,墙后是一个忍者。
assetManager.registerLocator("town.zip", ZipLocator.class.getName());
Spatial gameLevel = assetManager.loadModel("main.scene");
    gameLevel.setLocalTranslation(0, -5.2f, 0);
    gameLevel.setLocalScale(2);
    rootNode.attachChild(gameLevel);

如果你注册了一个新的定位器,请确保无文件名冲突:每个场景都有一个独一无二的名字。

在本教程的前面部分,您是从资源目录下加载的模型和场景。这是加载模型和场景的一般方法。如下是一个典型的过程:

  1. 删除前面练习中输入的代码。
  2. 将解压后的 town/ 目录拷贝到 您工程目录下的assets/Scenes/ 。
  3. simpleInitApp() 中添加如下代码
  4. 注意,这些路径都是相对于assets/…目录的
  5. 清理、生成并运行此工程。您将再次看到小镇里树立着一堵墙,上面有一个水壶,墙后是一个忍者。
    Spatial gameLevel = assetManager.loadModel("Scenes/town/main.scene");
    gameLevel.setLocalTranslation(0, -5.2f, 0);
    gameLevel.setLocalScale(2);
    rootNode.attachChild(gameLevel);

:如下这个方法您一定得知道。从.j3o文件加载场景或模型:

  1. 删除前面练习中输入的代码。
  2. 请打开jMonkeyPlatform,打开包含HelloAsset类的工程。
  3. 在工程窗口中,浏览 assets/Scenes/town目录。
  4. 右击main.scene 将其转换为二进制格式::jMoneyPlatform会生成一个main.j3o文件。
  5. simpleInitApp() 中添加如下代码:
  6. 再次提醒,这些路径都是相对于assets/…目录的。
  7. 清理、生成并运行此工程。您将再次看到小镇里树立着一堵墙,上面有一个水壶,墙后是一个忍者。
    Spatial gameLevel = assetManager.loadModel("Scenes/town/main.j3o");
    gameLevel.setLocalTranslation(0, -5.2f, 0);
    gameLevel.setLocalScale(2);
    rootNode.attachChild(gameLevel);

加载Scenes/town/main.j3o 和加载Scenes/town/main.scene有什么不同?

  • 在开发阶段你可以使用*.scene.xml文件:您的设计师会不断更新资源目录下的文件,在开发阶段您能够快速查看最新版本的资源目录。
  • 在测试和发布阶段,请创建和加载*.j3o 文件:.j3o是jME3应用程序的二进制格式,.j3o文件会自动包含在发布的JAR文件中。测试或者发布时,请使用jMonkeyPlatform把所有的.scene和.xml文件转换成.j3o文件,然后再加载。

小结

您已经知道在场景图中摆放静态形状和模型了,也知道如何创建场景了。您学习了如何使用assetManager来加载资源,知道资源在您工程目录下的存放路径。还有重要的一点就是,您学会了如何把模型转换为.j3o格式,使其包含在发布的JAR文件中。

让我们给场景增添一点“动静”,请继续学习Update Loop。


另请参阅:

  • 将Blender中的Ogre XML格式的场景导出到JME
  • 一个很棒的加载模型的截图
  • 欲了解如何加载声音,请参阅Hello Audio
  • 欲进一步了解纹理和材质,请参阅Hello Material

转载于:https://www.cnblogs.com/cybercser/archive/2012/02/03/2337212.html

JME 3 入门教程 3 - Hello Assets相关推荐

  1. ASP.NET Core 入门教程 2、使用ASP.NET Core MVC框架构建Web应用

    原文:ASP.NET Core 入门教程 2.使用ASP.NET Core MVC框架构建Web应用 一.前言 1.本文主要内容 使用dotnet cli创建基于解决方案(sln+csproj)的项目 ...

  2. TypeScript超详细入门教程(上)

    TypeScript超详细入门教程(上) 01 开篇词:Hello~TypeScript 01 开篇词:Hello~TypeScript 更新时间:2019-10-30 13:49:46 既然我已经踏 ...

  3. virtualxposed使用教程_Xposed 插件开发入门教程(一)

    其实网上已经有很多 Xposed 插件开发的入门教程了,我写的这篇与其说是教程,不如说是参考,为了防止以后忘了开发步骤,这里就写篇博客记录一下. 要使用 Xposed 插件,首先要 root 手机并安 ...

  4. Unity游戏开发官方入门教程:飞机大战(六)——创建子弹

    Unity版本:Unity 2018.2.14f1 原视频链接:https://unity3d.com/cn/learn/tutorials/s/space-shooter-tutorial 教程目录 ...

  5. kanzi安装和入门教程

    安装kanzi 系统要求 在 PC 上:64 位 Windows 7 SP1.8.1 和 10 Anniversary Update(1607 版)或更新版本 在 Mac 上:Boot Camp 中的 ...

  6. [转]【Unity3D入门教程】Unity3D简介、安装和程序发布

    <Unity3D入门教程>会带领零基础的初学者,一步步学会使用Unity3D来开发简单的应用程序,走近游戏开发的世界.本系列教程虽然不会面面俱到地深入到全部的知识点,但是会涉及到所有入门阶 ...

  7. Unity3D打砖块游戏入门教程

    今天来实现一个3D打砖块游戏,非常的简单,是正经的入门教程,但是学到的都是Unity游戏开发中重点的内容,下面一起来了解下吧. 新建3D游戏项目 打开Unity Hub软件,我们新建一个3D项目,新建 ...

  8. Hyperledger Fabric 官网翻译入门教程--之关键概念(Hyperledger Fabric 模型)

    英文地址:http://hyperledger-fabric.readthedocs.io/en/latest/fabric_model.html Hyperledger Fabric Model/ ...

  9. GitHub Actions入门教程

    GitHub Actions入门教程 GitHub Marketplace · Actions to improve your workflow · GitHub 概述 GitHub Actions ...

最新文章

  1. Oracle函数的定义
  2. 怎么判断有几个滴定突跃点_高中化学怎么学?先看近5年高考化学高频考点知识点分值分析...
  3. 2运行内存多大_电脑笔记本满血复活之内存升级篇
  4. NYOJ 10 skiing
  5. React开发(127):引入icon的方式
  6. js 用submit()方法提交表单,页面闪退问题以及解决方法
  7. 远程计算机关闭了怎么办,怎么远程关闭电脑 远程关闭电脑方法【详细步骤】...
  8. We change lives !
  9. 《设计的品格 探索×呈现×进化的InDesign美学》—第1课1.3节文字游戏
  10. SignalR 跨域解决方案全面
  11. 友盟ionic多渠道自动签名app
  12. 网络切片技术缺点_5G中网络切片研究的现状与挑战
  13. PHP 配置open_basedir,让各虚拟站点独立运行
  14. 想请问下PDF双面打印时(打印机自动双面打印)为什么反面那页的内容是倒过来的,应该怎么设置?...
  15. 《财富》推荐的75部必看书籍
  16. 网络宽带和实际下载速度单位换算详解:
  17. 爱奇艺APP的自动化录制回放系统 全云化处理新体验
  18. 日语基础复习 Day 16
  19. 使用echarts实现雷达图
  20. VIVADO调用MIG产生DDR3时实例化遇到的问题以及解决方法

热门文章

  1. Machine Learning – 第2周(Linear Regression with Multiple Variables、Octave/Matlab Tutorial)
  2. centos 7.5 安装桌面环境及报错
  3. WOW.js插件使用
  4. 位置在此计算机上运行程序灰色,Win10电脑中定位服务按钮灰色无法开启的2种解决方法...
  5. VLA的AIPS简单绘图
  6. Qt编写安防视频监控系统5-视频回放
  7. android 程序白屏,Android冷启动白屏问题
  8. JavaEE——作业管理系统期末总结
  9. su: warning: cannot change directory to : Permission denied ;-bash: bash_profile: Permission denied
  10. 支付宝云支付如何开通?