Loading models

Hi, I'm very new to jme, and I'm doing some experimenting with things.



I downloaded a chess piece from 'The3dStudio.com', it downloaded as 'Knight.max'



But when I tried to use this model, using:


URL bikeFile = Lesson8.class.getClassLoader().getResource("jmetest/data/model/Knight.max");


It doesn't work, I don't know anything about file types with models and what is allowed,
can anyone advice me on the basics here?

Thanks

exactly what does not work?

Is the url null?



After you copy a new file into an eclipse project, you need to 'refresh' the folder, or eclipse won't see the new file.

Other than that, it should work.

Thanks, I just looked at the error in fact…



You probably guessed I'm just modifying the flagrush game, but the error is

a null pointer exception:



backwheel = ((Node)model).getChild("backwheel");



Well the knight model doesnt have a backwheel, so thats probably where its going wrong
Ill try just loading the knight in, and adding it to the scene if I can.

I'll let you know if it works.
Thanks

I don't get it, I added it to the scene , but it doesnt show up, I donno what its location is meant to be.

Doesnt seem to be any tutorial on loading models

Loading models is a weak-point tutorial wise.



Here's something from the User-Code section which loads all forms of models.


    public static Node loadModel (String modelFile){
            Node         loadedModel   = null;
            FormatConverter      formatConverter = null;      
            ByteArrayOutputStream    BO       = new ByteArrayOutputStream();
            String         modelFormat    = modelFile.substring(modelFile.lastIndexOf(".") + 1, modelFile.length());
            String         modelBinary   = modelFile.substring(0, modelFile.lastIndexOf(".") + 1) + "jbin";
            URL         modelURL   = Fyrestone.class.getClassLoader().getResource(modelBinary);

            //verify the presence of the jbin model
            if (modelURL == null){

                    modelURL      = ModelLoader.class.getClassLoader().getResource(modelFile);

                    //evaluate the format
                    if (modelFormat.equals("3ds")){
                            formatConverter = new MaxToJme();
                    } else if (modelFormat.equals("md2")){
                            formatConverter = new Md2ToJme();
                    } else if (modelFormat.equals("md3")){
                            formatConverter = new Md3ToJme();
                    } else if (modelFormat.equals("ms3d")){
                            formatConverter = new MilkToJme();
                    } else if (modelFormat.equals("ase")){
                            formatConverter = new AseToJme();
                    } else if (modelFormat.equals("obj")){
                            formatConverter = new ObjToJme();
                    }
                    formatConverter.setProperty("mtllib", modelURL);

                    try {
                            formatConverter.convert(modelURL.openStream(), BO);
                            loadedModel = (Node) BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));

                            //save the jbin format
                            BinaryExporter.getInstance().save((Savable)loadedModel, new File(modelBinary));
                    } catch (IOException e) {            
                            e.printStackTrace();
                            return null;
                    }
            }else{
                    try {
                            //load the jbin format
                            loadedModel = (Node) BinaryImporter.getInstance().load(modelURL.openStream());
                    } catch (IOException e) {
                            return null;
                    }
            }

            return loadedModel;
    }

I am not sure you can load a model using the .max file type. .max is the native format for 3DSMax files, so you must convert it in a compatible format for jME like .3ds, .obj or anything else. There are some tutorials about that.

pitchonel said:

I am not sure you can load a model using the .max file type.


Its not possible. The class MaxToJme is misleading because it loads .3ds models.

the onlything you can do is load teh .max model in 3D Studio Max and export it in e.g. .obj format (lightwave)

hi



@Trussell: I tried this code out, it did load my model, but absolutely no textures or even

colors were drawn. I created my model with Misfit Model 3D. I made a *.ms3d model and

attached some textures to it. But they were not found (the console said so). So I attached

just some colors to the model, but it just appeared white. Why does either work with

textures nor with colors?

take a look at the classes TextureKey and SimpleResourceLocator to get your textures working.

your have to apply a LightState to the model, then it wont be white anymore. (maybe black then?  ;)), however your model is most propably converted correctly anyhow, even withour a light in the converter.

Thanks for the answer. I added a LightState to it, now its indeed black :slight_smile:

But I still dont understand what you mean with TextureKey and SimpleResourceLocator

(which is no where in the jME API). I added the textures IN the modeleditor, so why

should I search them within my jME-code? Is it just not possible that the natively added

textures of a model are loaded into jME?

If your model is UV mapped you only have to apply a texture state… ResourceLocator is convenient but not necessary.


public static Node makeCharNodeModel()
    {
        Node toReturn = loadModel(ninjaDir);
        TextureState ts = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
        ts.setTexture(TextureManager.loadTexture(ninjaSkin, Texture.MM_LINEAR, Texture.FM_LINEAR));
        ts.setEnabled(true);
        toReturn.setRenderState(ts);
        toReturn.updateRenderState();
        return toReturn;
    }

Modellers do not (usually) actually add the texture data in to the model file. They just save the path to the texture and what it was applied to. So jME (and anything else) still needs to be able to find the texture file, aswell as the model file.



If your textures are in a place that jME can find them, then they will "just work" - as soon as you load the model they will be visible (certainly with MS3D).



Colors, if you used materials then they should work right out of the box also.

There is one thing I noticed missing from Trussel's code that also drove me mad last week when I was trying to load object files into my level editor.  Most obj exporters list their textures without path names, at least blender does.  You must specify the "texdir" property in converter.setProperty so that the model importer can create a texture key specifying where to find the texture.

If you have an OBJ file like "ninja.obj" put the materials in the same directory and name it the same thing (like "ninja.mtl") and the code I posted will automatically see it and load it.

But I did this before and it wasn't enough for me.  I had to specify the "texdir" in order for the textures to load.  Taking a look at the ObjToJme code it makes sense since it constructs a texture key directly and doesn't load the texture using the TextureManager.loadTexture method which uses the ResourceLocatorTool when a string parameter is passed as the file.  If the "texdir" property is not set, then it will only look in the application's main directory.  At least this is what I found.

Hmm… I use material libraries and that code worked fine for me. I'm not sure about the texkey, that may be something else that I'm not using at this point (I'm only using model loading for testing right now).

there you go: resourcelocator a.s.o: http://www.jmonkeyengine.com/jmeforum/index.php?topic=5707.0



Basically you are telling jME where to look for your textures and to ignore the paths in the .mtl file.