3ds model loading - model looks awful

Hello,



I'm fairly new at java, so forgive me if I'm overlooking the obvious. I've looked about the forums and seen numerous topics on 3ds and textures but none turned the lightbul on in my brain.



I took the HelloModelLoading code and changed it to load a 3ds model. It works, but the model looks terrible. It's textures are marked up by large triangles where the colors were replaced with blue. It almost looks as if some of the textures are upside down.



I'm a complete noob, so I don't know if the model is loading in materials or textures. I got the model off of 3d cafe, and I've seen screenshots of it, so I know what it is suppose to look like, but my attempt at displaying it is falling short.




import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import com.jme.app.AbstractGame;
import com.jme.app.SimpleGame;
import com.jme.bounding.BoundingSphere;
import com.jme.scene.Node;
import com.jme.util.LoggingSystem;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.XMLparser.Converters.FormatConverter;
import com.jmex.model.XMLparser.Converters.ObjToJme;
import com.jmex.model.XMLparser.Converters.MaxToJme;
   

public class model extends SimpleGame
{
 
       public static void main(String[] args)
       {
   
        model app = new model();
        app.setDialogBehaviour(AbstractGame.ALWAYS_SHOW_PROPS_DIALOG);
        // Turn the logger off so we can see the XML later on
        LoggingSystem.getLogger().setLevel(Level.OFF);
        app.start();
        }

    protected void simpleInitGame() {
       
       
        // Point to a URL of my model
        URL model=model.class.getClassLoader().getResource("STARHAWK.3DS");
       

        // Create something to convert .obj format to .jme
         //FormatConverter converter=new ObjToJme();
       
        // Create something to convert .3ds format to .jme
            FormatConverter converter=new MaxToJme();

        // 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 to .jme
               converter.convert(model.openStream(), BO);

            Node starship=(Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
            // shrink this baby down some
            starship.setLocalScale(.03f);
            starship.setModelBound(new BoundingSphere());
            starship.updateModelBound();
            // Put it on the scene graph
            rootNode.attachChild(starship);
           
           }
           catch (IOException e)
              {   // Just in case anything happens
            System.out.println("Damn exceptions!" + e);
            e.printStackTrace();
            System.exit(0);
                 }
    }
   
       

}



most models that are made for rendering (which most at 3dcafe are) need some tuning to be used in opengl apps. Maybe someone can tell you some more details if you post a link to the model/page. Additionally some could supply you with a working model including textures, so you can verify that your loading code is fine (I didn't look at your code, sorry).

Anyone?

3dscafe has their free section closed down so I can't point to the model I'm trying to use. So I swapped out the starhawk for a dc10 I found here:



http://www.free3dsmodels.com/modules/wfdownloads/viewcat.php?cid=1&start=5



My code is the same except now I load dc10.3ds and I changed the scale to .06f.



None of the textures load with the model, it's just grey with a few random light grey triangles over the mostly dark grey model. It kind of looks like someone has been throwing rocks at it.



Perhaps it is a problem with free models needing some tweeking before they can be used, but I suspect I'm doing something wrong.



Thanks.

I was able to run your code with jmetest/data/model/bike.3ds, so the loading code works fine.

bike has no textures, though - but at least the lighting/material of Blackclaws 3ds is broken, yes

I decided to just try loading a jpg texture on the model so I added this code:



//texture stuff

So I found a 3ds model that I know has textures and texture coordinates, modified my code, and tried again.


public class model extends SimpleGame
{
   

stupid question: did you triangulate your model before exporting?

Is that something you would do in a 3ds modeller program? I simply got the model from here:



http://www.meshfactory.com/free_model_06.htm

i took a look at the model and it is triangulated, so ignore my stupid question :slight_smile:

Sounds like you are almost there, you just need to use TextureKey.setOverridingLocation(URL) to point to where your textures really are.

I hate to have to ask this, but my attempts at using TextureKey.setOverridingLocation(URL) have only resulted in compiling errors, could you show me how? Once I see an example maybe I'll understand the syntax. And is there another import declaration I have to make to use TextureKey? (My compiling errors are usually Does not recognize symbol - TextureKey.)



My brain isnt working too well today.

I can't tell you the syntax from the top of my head, nor would I know the package for the import. But that does not really matter when you use an IDE -> you should use one! (have a look at e.g. www.eclipse.org)

com.jme.util.TextureKey

Thanks renanse, that solved my import problem.



However, I still can't get the textures to load. I'm not implementing something correctly. The closest I've gotten was getting the program to look for the textures in E:Jprojectjmebuildf5e_05.3dsTexture_Name, which doesn't exist. I can't figure out how to get the program to look inside the 3ds file to retrieve the textures.


public class model extends SimpleGame
{
   
       public static void main(String[] args)
       {
   
        model app = new model();
        app.setDialogBehaviour(AbstractGame.ALWAYS_SHOW_PROPS_DIALOG);
        // Turn the logger off so we can see the XML later on
        LoggingSystem.getLogger().setLevel(Level.OFF);
        app.start();
        }

    protected void simpleInitGame() {
       
        // Point to a URL of my model
        URL model=model.class.getClassLoader().getResource("f5e_05.3ds");
        URL texturedir = model.class.getClassLoader().getResource("f5e_05.3ds" + "/");

        // Create something to convert .obj format to .jme
         //FormatConverter converter=new ObjToJme();
       
        // Create something to convert .3ds format to .jme
           FormatConverter converter=new MaxToJme();
           
        // For OBJ: Point the converter to where it will find the .mtl file from
         // converter.setProperty("mtllib",model);
        
         //for 3ds
           
        // This byte array will hold my .jme file
        ByteArrayOutputStream BO=new ByteArrayOutputStream();
        try {
           
            // Use the format converter to convert to .jme
               TextureKey.setOverridingLocation(texturedir);
               //converter.setProperty("texurl", texturedir);
               converter.convert(model.openStream(), BO);
           
            Node starship=(Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
            // shrink this baby down some
            starship.setLocalScale(.06f);
            starship.setModelBound(new BoundingSphere());
            starship.updateModelBound();
            // Put it on the scene graph
            rootNode.attachChild(starship);
           
            //texture stuff
            //TextureState ts = display.getRenderer().createTextureState();
       //   ts.setEnabled(true);
       //   ts.setTexture(
          //    TextureManager.loadTexture(
         //   model.class.getClassLoader().getResource("skycloud.jpg"),
        //     Texture.MM_LINEAR_LINEAR,
         //   Texture.FM_LINEAR));

         //   rootNode.setRenderState(ts);
           
           }
           catch (IOException e)
              {   // Just in case anything happens
            System.out.println("Damn exceptions!" + e);
            e.printStackTrace();
            System.exit(0);
                 }
    }

   

Irrisor, I should look at using eclipse, but I really want to understand some of the fundamentals of jme first.

Well I discovered the wonders of "file:" so I added…


URL texturedir = model.class.getClassLoader().getResource("file:f5e_05.3ds");



under my initial url location and then have..

TextureKey.setOverridingLocation(texturedir);
 converter.setProperty("texurl", model);



before the converter startes converting. Now I'm getting a malformed URL error. At least it's a different error and the program is apparently looking in the file for the textures.

I think file urls take the form of "file://host/path".



If I remember correctly, that syntax is used for absolute paths… like: "file:///c|path/to/file/f5e_05.3ds"

The MalformedURLException you're getting is indicating that it can't parse the string you've passed in.



Sorry I can't be more help.

Blackclaw said:

I can't figure out how to get the program to look inside the 3ds file to retrieve the textures.

There are no textures inside a 3ds file!


Irrisor, I should look at using eclipse, but I really want to understand some of the fundamentals of jme first.

Believe me, the other way round would be much better - first learn java and using an IDE, then advance to the more complicated things (like 3D game development).

Well I have it working. I even managed to find a way to use a relative path.  :slight_smile:



I'm going to post the code so there's another working example on the discussion board for folks.



Thanks for everyone's patience and thank you all for helping me out.






public class model extends SimpleGame
{
   
       public static void main(String[] args)
       {
   
        model app = new model();
        app.setDialogBehaviour(AbstractGame.ALWAYS_SHOW_PROPS_DIALOG);
        // Turn the logger off so we can see the XML later on
        LoggingSystem.getLogger().setLevel(Level.OFF);
        app.start();
        }

    protected void simpleInitGame() {
       
       
        // Point to a URL of my model
        URL model=model.class.getClassLoader().getResource("f5e_05.3ds");
       
       
        // Create something to convert .3ds format to .jme
           FormatConverter converter=new MaxToJme();
           

        // 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 to .jme
           
             //for texture
            TextureKey.setOverridingLocation(new URL("file:f5tex\"));

            //TextureKey.setOverridingLocation (new URL ("file:/E:/Jproject/jme/build/f5tex/"));  
           
            //do conversion
            converter.convert(model.openStream(), BO);
           
            Node starship=(Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
            // shrink this baby down some
            starship.setLocalScale(.05f);
            starship.setModelBound(new BoundingSphere());
            starship.updateModelBound();
            // Put it on the scene graph
            rootNode.attachChild(starship);
           
           
           }
           catch (IOException e)
              {   // Just in case anything happens
            System.out.println("Damn exceptions!" + e);
            //System.out.println("Texture URL was" + texuredir);
            e.printStackTrace();
            System.exit(0);
                 }
    }    

}

irrisor said:
There are no textures inside a 3ds file!



I was thrown off because I'm getting IO errors regarding a file called 5ETPR_B.BMP. Is that a jme file?

So for a 3ds model to be textured, it would have to come with a file in addition to the 3ds file? The download I have only came with the 3ds file and I am unfamilar with how those files are packaged.


Believe me, the other way round would be much better - first learn java and using an IDE, then advance to the more complicated things (like 3D game development).


I can write java programs with swing gui's. I've just never done anything with graphics before. I'm currently using JCreatorV4LE.
Eclipse looks a lot more powerful, perhaps I was just a bit apprehensive about getting it setup.