Anterior: Hello Node pt, Próximo: Hello Update Loop pt
Neste tutorial nós aprenderemos a carregar modelos 3D e colcoar texto no grafo de cena, usando o Gerenciador de Ativo (Asset Manager) da JME. Você também aprenderá como determinar os caminhos corretos, e quais formatos de arquivo usar.

Problema no achar os arquivos para executar a amostra?`jme3-test-data.jar`“““““““
Amostra de Código
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);
}
}----
Compile e execute a amostra de código. Você deveria ver um ninja verde com um bule colorido permanecendo atrás de uma parede. O texto na tela deveria dizer “Hello World.
== O gerenciador de ativo
*Por ativos de jogo nós queremos dizer todos os arquivos multimídia, tais como modelos, materiais e texturas, cenas inteiras, shaders customizados, música e arquivos de som, e fontes customizadas.* JME3 vem com um objeto AssetManager prático que ajuda você a acessar seus ativos.
O AssetManager pode carregar arquivos de:
* O classpath atual (o nível do topo de seu diretório de projeto),
* O diretório `ativos` de seu projeto, e
* opcionalmente, caminhos persoanlizados que você registrar.
O seguinte é a estrutura de diretório recomendada em seu diretório de projeto:
[source]
MyGame/assets/Interface/ MyGame/assets/MatDefs/ MyGame/assets/Materials/ MyGame/assets/Models/ MyGame/assets/Scenes/ MyGame/assets/Shaders/ MyGame/assets/Sounds/ MyGame/assets/Textures/ MyGame/build.xml ←- Ant build script MyGame/src/… ←- Java sources go here MyGame/…
Isto é apenas um melhor prática sugerida, e é o que você consegue por padrão quando criando um novo projeto Java no <<sdk#,SDK>> da jMokeyEngine. Você pode criar um diretório de ativos e tecnicamente nomear os subdiretórios da maneira que você gostar. === Carregando Texturas Coloque suas texturas em um subdiretório de `assets/Textures/`. Carregue a textura em um material antes que você configure o Material. A seguinte amostra de código é do método `simpleInitApp()` e carrega um modelo de parede simples: [source,java]
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);
Neste caso, você <<hello_material#,cria seu próprio Material>> e aplica ele para a geometria (Geometry). Você baseia Materiais nas descrições de material padrão (por exemplo, “Unshaded.j3md), como mostrado neste exemplo. === Carregando Texto e Fontes Este exemplo exibe o texto “Hello World na fonte padrão na aresta do fundo da janela. Você anexa texto para o nó da +++<abbr title="Graphical User Interface">GUI</abbr>+++ (`guiNode`) – isto é um nó especial para elementos de exibição plana (ortogonal). Você exibe texto para mostrar a pontuação do jogo, a saúde do jogador, etc. A seguinte amostra de código vai no método `simpleInitApp()`. [source,java] ----// 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);
Dica: Limpe o texto existente no nó da GUI (guiNode) por retirar todas as suas crianças.
Carregando um modelo
Exporte seu modelo 3D no formato OgreXML (.mesh.xml, .scene, .material, .skeleton.xml) e coloque ele em um subdiretório de assets/Models/
. A seguinte amostra de código vai no método 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 directional light to make the model visible!
DirectionalLight sun = new DirectionalLight();
sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f).normalizeLocal());
rootNode.addLight(sun);
Note que você precisa criar um Material se você exportou o modelo com um material. Lembre-se de adicionar uma fonte de luz, como mostrado, de outra maneira o material (e o modelo inteiro) não estará visível!
Carregando Ativos de Caminhos Personalizados
E seu jogo dependen de arquivos de modelo fornecidos pelo usuário, que não estão inclusos na distribuição? Se um arquivo não é localizado no local padrão (e.g. diretório de ativos), você pode registrar um localizador (Locator) customizado e carregá-lo de qualquer caminho.
Aqui está um exemplo de uso de um ZipLocator que está registrado para um arquivo town.zip
no nível topo de seu diretório de projeto:
assetManager.registerLocator("town.zip", ZipLocator.class);
Spatial scene = assetManager.loadModel("main.scene");
rootNode.attachChild(scene);
Aque está um HttpZipLocator que pode baixar modelos zipados e carregá-los:
assetManager.registerLocator(
"http://jmonkeyengine.googlecode.com/files/wildhouse.zip",
HttpZipLocator.class);
Spatial scene = assetManager.loadModel("main.scene");
rootNode.attachChild(scene);
JME3 oferece ClasspathLocator, ZipLocator, FileLocator, HttpZipLocator, e UrlLocator (Veja com.jme3.asset.plugins
).
Criando Modelos e Cenas
Para criar modelos 3D e cenas, você precisa de um editor de malha 3D (3D Mesh Editor) com um plugin exportador (Exporter) OgreXML. Por exemplo, você pode criar modelos completamente texturizados com Blender.
Você pode usar o SDK para carregar modelos, converter modelos e criar cenas deles.
Se você usar Blender, exporte seus modelos como malhas Ogre XML com materiais como se segue:
-
Abra o menu Arquivo (File) > Exportar (Export) > Exportador OgreXML (OgreXML Exporter) para abrir o diálogo do exportador.
-
No campo Exportar Materiais (Export Materials): Dê ao material o mesmo nome que o modelo. Por exemplo, o modelo
something.mesh.xml
acompanhasomething.material
, mais (opcionalmente)something.skeleton.xml
e alguns arquivos de textura JPG. -
No campo Exportar Malhas (Export Meshes): Selecione um subdiretório de seu diretório
assets/Models/
directory. E.g.assets/Models/something/
. -
Ative as seguintes configurações do exportador:
-
Copiar Texturas (Copy Textures): YES
-
Renderizar materiais (Rendering Materials): YES
-
Virar Eixos (Flip Axis): YES
-
Requer Materiais (Require Materials): YES
-
Nome do Esqueleto segue o da malha (Skeleton name follows mesh): YES
-
-
Clique em exportar.
Formatos de Arquivo de Modelo
JME3 pode carregar modelos Ogre XML + materials, Ogre DotScenes, bem como modelos Wavefront OBJ+MTL models. O código loadModel() trabalha com estes arquivos quando você executa o código diretamente do SDK da jMonkeyEngine SDK.
Se você construir os executáveis usando o scrit de construção padrão, então os arquivos de modelo originais (XML, OBJ, etc) não são inclusos. Quando você executar o executável, você obetrá uma mensagem de erro se você tentar carregar quaisquer modelos diretamente:
----com.jme3.asset.DesktopAssetManager loadAsset
WARNING: Cannot locate resource: Models/Ninja/Ninja.mesh.xml
com.jme3.app.Application handleError
SEVERE: Uncaught exception thrown in Thread[LWJGL Renderer Thread,5,main]
java.lang.NullPointerException
----
Carregando os arquivos XML/OBJ diretamente é somente aceitável durante a fase de desenvolvimento. Se seus projetista gráfico coloca arquivos atualizados para o diretório de ativos, você pode rapidamente revisar a versão mais recente em seu ambiente de desenvolvimento.
Para teste e para a construção de liberação final, voc~e usa arquivos .j3o exclusivamente. J3o é um formato binário otimizado para aplicações jME3, e arquivos .j3o são automaticamente inclusos no arquivo JAR distribuível pelo script de construção. Quando você faz construções de teste de QA (Quality and Assurance - Averiguação da Qualidade) ou está pronto para liberar, use o SDK para converter todos os arquivos .obj/.scene/.xml/.blend para .j3o, e somente carregue as versões .j3o.
Abra seu Projeto JME3 no SDK da jMonkeyEngine.
-
Dê um clique com o botão direito em um arquivo .Blend, .OBJ, ou .mesh.xml file na janela Projetos (Projects), e escolha “converter para binário JME3 (“convert to JME3 binary)..
-
O arquivo .j3o aparece próximo ao arquivo .mesh.xml file e tem o mesmo nome.
-
Mude todas as linhas do seu loadModel() de acordo. Por exemplo:
----Spatial ninja = assetManager.loadModel("Models/Ninja/Ninja.j3o");----
Se seu executável dá uma exceção em tempo de execução, tenha certeza de que você converteu todos os modelos para .j3o!
Carregando Modelos e a Cena
tarefa? | Solução! |
---|---|
Carregar um modelo com materiais |
Use o método
|
carregar um modelo sem materiais |
Se você tiver um modelo sem materiais, você tem de dár a ele um material para fazê-lo visível.
|
Carregar uma cena |
Você carrega cenas da mesma forma que você carrega modelos:
|
Exercício - Como Carregar Ativos
Como um exercício, vamos tentar diferentes maneiras de carregar uma cena. Você aprenderá a como carregar a cena diretamente, ou de um arquivo zip.
-
(Opcional:) Dezipe o arquivo town.zip para ver a estrutura da Ogre dotScene contida: Você terá um diretório chamado
town
. Ele contém arquivos XML e textura, e o arquivo chamado main.scene. (Isto é apenas para sua informação, você não precisa fazer nada com ele.) -
Coloque o arquivo town.zip no diretório topo de nível de seu projeto JME3, assim:
----jMonkeyProjects/MyGameProject/assets/ jMonkeyProjects/MyGameProject/build.xml jMonkeyProjects/MyGameProject/src/ jMonkeyProjects/MyGameProject/town.zip ...
Use o seguinte método para carregar modelos de um arquivo zip: . Verifique se `town.zip` está no diretório do projeto. . Registre um localizador de arquivo zip para o diretório do projeto: Adicione o seguinte código sobre `simpleInitApp(){` [source,java] ---- assetManager.registerLocator("town.zip", ZipLocator.class); Spatial gameLevel = assetManager.loadModel("main.scene"); gameLevel.setLocalTranslation(0, -5.2f, 0); gameLevel.setLocalScale(2); rootNode.attachChild(gameLevel);---- O método loadModel() agora pesquisa pelo arquivo zip diretamente para carregar os arquivos (isto significa, não escreva `loadModel(town.zip/main.scene)` ou similar!) . Limpe, construa e execute o projeto. + Você deveria agora ver o Ninja+parede+bule permanecendo em uma cidade. *Dica:* se você registrar novos localizadores, tenha certeza de que você não tenha quaisquer conflitos de nome: Não nomeie todas as cenas `main.scene` mas dê a cada cena um nome único. Anteriormente neste tutorial, você carregou cenas e modelos do diretório de ativo. Isto é a maneira mais comum que você estará carregando cenas e modelos. Aqui está o procedimento típico: . Remova o código que você adicionou para o exercício anterior. . Mova o diretório dezipado `town/` no diretório `assets/Scenes/` de seu projeto. . Adicione o seguinte código sobre `simpleInitApp() {` [source,java] ---- Spatial gameLevel = assetManager.loadModel("Scenes/town/main.scene"); gameLevel.setLocalTranslation(0, -5.2f, 0); gameLevel.setLocalScale(2); rootNode.attachChild(gameLevel);---- Note que o caminho é relativo ao diretório `assets/…`. . Limpe, construa e execute o projeto. De novo, você deveria ver o Ninja+parede+bule em uma cidade. Aqui está um terceiro método que você deve conhecer, carregando uma cena/modelo de um arquivo .j3o: . Remova o código do exercício anterior. . Se você j´pa não fez, abra o <<sdk#,SDK>> e abra o projeto que contém a classe HelloAsset.. . Na janela de projetos, navegue para o diretório `assets/Scenes/town`. . Dê um clique com o botão direito em `main.scene` e converta a cena para binário: A jMonkeyPlatform gera um arquivo main.j3o. . Adicione o seguinte código em `simpleInitApp() {` [source,java] ---- Spatial gameLevel = assetManager.loadModel("Scenes/town/main.j3o"); gameLevel.setLocalTranslation(0, -5.2f, 0); gameLevel.setLocalScale(2); rootNode.attachChild(gameLevel);---- Novamente, note que o caminho é relativo ao diretório `assets/…` directory. . Limpe, construa e execute o projeto. + De novo, você deveria ver o Ninja+parede+bule em uma cidade. == Conclusão Agora você sabe como popular o grafo de cena com modelos e formas estáticas, e como construir cenas. Você aprendeu como carregar ativos usando o `gerenciador de ativos (assetManager)` e você viu que os caminhos iniciam relativos ao seu diretório de projeto. Uma outra coisa importante que você aprendeu é converter modelos para o formato .j3o para os JARs executáveis etc. Vamos adicionar alguma ação para a cena e continuar com o <<jme3/beginner/hello_main_event_loop-pt#, Loop de Atualização pt>>! ''' *See also:* * <<jme3/external/blender#,O tutorial de importação Blender definitivo>> * link:http://www.jmonkeyengine.com/forum/index.php?topic=14418.0[Instantâneos de um grande modelo carregado] * link:http://www.youtube.com/user/aramakara[Video tutoriais for obter OgreXML do 3DS Max usando OgreMax] * Se você quer aprender a como carregar sons, veja <<hello_audio_pt#,Hello Audio pt>> * Se você quer aprender mais sobre carregar materiais, veja <<hello_material_pt#,Hello Material pt>> <tags><tag target="beginner" /><tag target="intro" /><tag target="documentation" /><tag target="lightnode" /><tag target="material" /><tag target="model" /><tag target="node" /><tag target="gui" /><tag target="hud" /><tag target="texture" /></tags>