The .obj file in jmonkeyengine.com tutorial

Hi everyone :

    I am new to graphics , I have been trying load a object created in 3Dmax  8.0to Java3D,. I exported it  from 3Dmax as a .obj file ,but  I couldn't get the correct .mtl file which will

be needed .     Does anyone know how to get a correct .mtl file.  ?? The .mtl file I got is as below:


Max2Mtl Version 4.0 Mar 10th, 2001

#

EOF


which doesn't work.

I tried to use the Loader in jme.jar to load the .obj exported from 3D max  8.0, it doesn't work . But it works for the .obj in the example
from the jmonkeyengine.com tutorials . which is shown as below :

* Copyright (c) 2003-2006 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
*   notice, this list of conditions and the following disclaimer in the
*   documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
*   may be used to endorse or promote products derived from this software
*   without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package jmetest.TutorialGuide;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.jme.app.AbstractGame;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.scene.Node;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.FormatConverter;
import com.jmex.model.converters.ObjToJme;

/**
* Started Date: Jul 22, 2004


*
* Demonstrates loading formats.
*
* @author Jack Lindamood
*/
public class HelloModelLoading extends SimpleGame {
   private static final Logger logger = Logger
           .getLogger(HelloModelLoading.class.getName());
   
   public static void main(String[] args) {
       HelloModelLoading app = new HelloModelLoading();
       app.setDialogBehaviour(AbstractGame.ALWAYS_SHOW_PROPS_DIALOG);
       // Turn the logger off so we can see the XML later on
       app.start();
   }

   protected void simpleInitGame() {
       // Point to a URL of my model
       URL model=HelloModelLoading.class.getClassLoader().getResource("jmetest/data/model/maggie.obj");

       // Create something to convert .obj format to .jme
       FormatConverter converter=new ObjToJme();
       // Point the converter to where it will find the .mtl file from
       converter.setProperty("mtllib",model);

       // This byte array will hold my .jme file
       ByteArrayOutputStream BO=new ByteArrayOutputStream();
       try {
           // Use the format converter to convert .obj to .jme
           converter.convert(model.openStream(), BO);
           Node maggie=(Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
           // shrink this baby down some
           maggie.setLocalScale(.1f);
           maggie.setModelBound(new BoundingSphere());
           maggie.updateModelBound();
           // Put her on the scene graph
           rootNode.attachChild(maggie);
       } catch (IOException e) {   // Just in case anything happens
           logger.logp(Level.SEVERE, this.getClass().toString(),
                   "simpleInitGame()", "Exception", e);
           System.exit(0);
       }
   }
}


I changed "the jmetest/data/model/maggie.obj" to the .obj file exported from 3Dmax , it generates an error everytime I tried to run it.


Exception in game loop
java.lang.ClassCastException: com.jme.scene.TriMesh cannot be cast to com.jme.scene.Node
  at jmetest.TutorialGuide.HelloModelLoading.simpleInitGame(HelloModelLoading.java:82)
  at com.jme.app.BaseSimpleGame.initGame(BaseSimpleGame.java:503)
  at com.jme.app.BaseGame.start(BaseGame.java:69)
  at jmetest.TutorialGuide.HelloModelLoading.main(HelloModelLoading.java:65)
2007-3-16 11:24:29 com.jme.app.BaseSimpleGame cleanup


can anyone help?  ???Many thanks


:? :?

can u be more specific? like whats the error message?

Please create Topics, not Polls when you are not taking a Poll.

The error is shown as:



Exception in game loop

java.lang.ClassCastException: com.jme.scene.TriMesh cannot be cast to com.jme.scene.Node

  at jmetest.TutorialGuide.HelloModelLoading.simpleInitGame(HelloModelLoading.java:82)

  at com.jme.app.BaseSimpleGame.initGame(BaseSimpleGame.java:503)

  at com.jme.app.BaseGame.start(BaseGame.java:69)

  at jmetest.TutorialGuide.HelloModelLoading.main(HelloModelLoading.java:65)

2007-3-16 11:24:29 com.jme.app.BaseSimpleGame cleanup



Basically I create a model in 3D max 8.0 , and exported it as a .obj file . And then I try to use the loader in the jmonkeyengine.com tutorials to load the object , it won't work.  :? So I assume that i didn' get the right .obj file in 3D Max, because when 3D max export a model as a .obj file, it comes up with a .mtl  file which seems wrong. It works perfectly in the tutorial example HelloModelLoading .java.

In the example , it load a maggie.obj from the jmonkeyengine ,and I notice it has a correspanding maggie.mtl file which is different

from what I got from 3D max.  So my question is how can I got the right .obj file and can be loaded in this example? Many thanks

Easy answer: use Spatial not Node or TriMesh



Hard answer: depends on the number of individual meshes the model has (as well as the modeling program used)

Hi basixs :

          Thanks a lot for ur help although I still don't qiuite undersand. I only started expericeing JmonkeyEngine and 3D max two days ago , So still lots of things puzzles me a lot. 

Can I ask you something again please? Like what do you mean using Spatial?  And if I export some .obj file from 3D max, what kind of setting I need to do in order to get the right .mtl file contains the texture or Material information. (Sorry to ask this agian , I know lots of people ask this question  already, have to bother u again) .  How can I load those objects correctly with right texture?  Thanks a lot .

( I mean if I don't use the loader from JmonkeyEngine , use other loader like sun's standard Loader,how can I got the objects with colors and texture shown. I tried several loaders to load .obj, no texture and colors shown)





  DI

Well, to texture an object you need to one supply a texture and two use an UV image editor to describe how the texture is applied.



http://www.gamedev.net/reference/art/features/blender1/ Here’s a great beginner tutorial for blender.

I don’t use 3ds Max so I can’t help you much there…



As far as Spatial goes.  It is basically THE basic jME geometric construct;  a Spatial contains a TriMesh and a Node contains a Spatial.

(I believe thats the order)



So, try using

Spatial model = loadModel();



Not

Node model = loadModel();

the error occured coz when u pull the model out of binary importer, u casted it wrong.



i belive u r doing


Node node = (Node)BinaryImporter.getInstance().load(stream);



u should be doing


TriMesh mesh = (TriMesh)BinaryImporter.getInstance().load(stream);



if u really want it to be a node do this


Node node = new Node("MeshNode");
TriMesh mesh = (TriMesh)BinaryImporter.getInstance().load(stream);
node.attachChild(mesh);

Hi  neakor  and  basixs  , thanks both of ur help, I need have a try first, might still bother u guys later on. I am so sick of loading objects

without texture and have to fix that. The problem is i am running out of time, I really should programming now but still have to fix this first . God



                              Di

Neakor, won't your example fail if the model has multiple meshes??

basixs said:

Neakor, won't your example fail if the model has multiple meshes??


yes but i believe obj only supports single mesh. i could be wrong though since i dont really use obj format.

FYI, It does (thats what I am using) :slight_smile:

Hi All,



In order to get the mateial library correctly you should save the material to the library. And save the max file then export the obj file, it will generate the material library. But, you will have to edit it manually (notepad or similar) in order to put the correct path to your textures. :wink:



Hope this will be useful to you.

I ran into the same issue as the original poster when I loaded my own .obj, and this solved it.


TriMesh maggie = (TriMesh)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));