File Converter

Hey all,



I was just messing around with the file converters listed in the utilities section of the website. One of them is broken, and the other two don't seem to work. After reading the forums for a while I'm guessing that they're just old.



Just wondering if anybody has made an app for converting 3ds files to jme that works for the current version of jme, and if that section of the website should be updated.



Thanks,



~Peregrinati

Use my ModelLoader class in jmex, it will handle that for you.

It doesn't seem to work with .3ds files, but thanks for the reply none the less.



So, is there a class (or application) already made that will take a 3ds file and save it as a .jme file, which could then be loaded directly without having to run it through a converter?

…you're right. :o  I can't remember how to import a .3ds file without converting it to a .jme file first now either…if someone can point me to where an example of that is I'll get ModelLoader updated to load other formats besides .jme and Collada.

Wait… converting a 3ds file to a .jme file is exactly what I'm trying to do, but I then want to write that jme file out to the disc. I figured a program to do this for you would be pretty useful.



I might be doing this whole model loading thing the wrong way… I'm pretty new at this. I just figured it would be faster to save a .jme file and load that, than having to convert the 3ds every time. I know next to nothing about Collada… is there a tutorial or article I could read? Does blender save collada files? That's where most of my models will come from.

Most 3D modeling apps have a third-party exporter/importer for Collada (including Blender and 3DS Max).



ModelLoader doesn't just do the file conversion, it imports it into the scene directly from the file you choose and if it loads properly then it goes to the next step and exports it back out as a .jme file.  The jME binary file is significantly faster to load than any of the XML formats.

Ahhh… cool. Alright, I guess I'll check that out. Thanks for your help.

Hey, I got tired of waiting for my modeling friend to get that exporter up and running, so I took a look at ModelLoader and made it load 3ds and obj files. I make no claims about this being the best way to do it (I'm a newbish noob), but here it is… if you want to update the class with it, that would make me feel special :P, but I think I did something wrong, either that or there's something wrong with the models I'm converting.



The 3ds model I converted looks pretty crappy after conversion. :frowning: All jaggy and sharp, my friend says the normals aren't being smoothed, and there's some strangeness with the lighting not affecting parts of it. I think maybe the normals of a couple of the faces are inverted.



The obj I converted also seems a little jagged, and faces just pop in and out of shadow for some reason. It's like they're being lit, or not, and nothing in between. Also, they're not being affected properly by the directional light I have… it doesn't matter what color I set the light to, the object is always bright white, unless I put a texture on it. Any help?



I updated the following two methods:



public static final Node loadModel(File file) {
      String filename = file.getName().toUpperCase();
      Node model = null;
      try {
         if (filename.endsWith(".DAE")) {
            ColladaImporter.load(file.toURL().openStream(), file.getAbsoluteFile().getParentFile().toURL(), "Model");
            model = ColladaImporter.getModel();
         } else if (filename.endsWith(".JME")) {
            model = (Node)BinaryImporter.getInstance().load(file);
         } else if (filename.endsWith(".3DS")) {
            MaxToJme converter = new MaxToJme();
              ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
               converter.convert(new BufferedInputStream(file.toURL().openStream()), byteArrayOutputStream);
               model = (Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
         } else if (filename.endsWith(".OBJ")) {
            ObjToJme converter = new ObjToJme();
              ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
               converter.convert(new BufferedInputStream(file.toURL().openStream()), byteArrayOutputStream);
               model = new Node();
               model.attachChild((TriMesh)BinaryImporter.getInstance().load(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())));
         }
      } catch(IOException exc) {
         exc.printStackTrace();
      }
      return model;
   }
   
   public static final boolean isValidModelFile(File file) {
      String filename = file.getName().toUpperCase();
      if (filename.endsWith(".DAE")) return true;
      else if (filename.endsWith(".JME")) return true;
      else if (filename.endsWith(".3DS")) return true;
      else if (filename.endsWith(".OBJ")) return true;
      return false;
   }

That's great unless it's a really massive file. :wink:



I was hoping there was some way to simply import the 3DS file into the scene (like with Collada files) before I export it back out as a file, does jME not support this?

Ummm… I was the noob asking questions :P, but it should already let you load the node into any scene (that bit of code, not the class). If you look at the model variable it's actually a Node, as seen here:

 model = (Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));


so, that should be drawable... just attach it to your root node or whatever.

Actually, this is confusing me a lot. Ummm... let me explain:

I'm making a simple little Space Flight Sim as my very firstest game ever, and the first thing I did was create a starfield skybox, and create an asteroid class that let's me spawn a whole lot of tumbling space rocks. I didn't have a model of an asteroid, but I found a .3ds that was apparently made from a NASA map of one. Using the code I posted earlier, I loaded it in, applied a texture to it, set a slightly yellow directional light, and sent it tumbling around... it looked great and I was very happy with everything but the extremely long load time (it's a really detailed mesh... too detailed for a game methinks). Anyways... I figured the conversion was probably taking a noticable amount of time so I started this thread to figure out how to save it as a .jme file. The code I posted works, but after converting the .3ds it looks pretty horrible.

My question is... how can that be? Both the saved version and the "directly imported" version are made from the same original input stream (the .3ds file), run through the same converter (MaxToJme), and both come out as a byteArrayOutputStream. The only difference is that the former is written to disk and then loaded directly next time without the use of a MaxToJme converter, and the latter is never written to disk. But both should be using the same byte array generated from the converter, so... why did it change my model at all?

Hope that made sense, and I'm not missing something obvious.

Also, as I mentioned before, the converted .obj file has some weird lighting issues. If anyone else has experienced this and has a solution, that would be much appreciated.

I would suggest posting screenshots…even if it doesn't help it's always fun to see pictures. :slight_smile:



Can someone else commit this code for me (Renanse, you know you want to!!!), I'm absorbed in my own personal issues at the moment and barely have the time to check messages here.

Ok… I'll post some shots sometime tommorrow (when I get home).



I'd recommmend someone try that code first… if it's producing garbled models (particularly the .3ds bit), then it might need some fixing.

doh

I can't really be the one to put that in because I have nothing to test it with. :confused:

I'm not sure if this is the problem for you, but I noticed that some OBJ models I imported were getting a default material applied that was very shiny.  At first, it looked like the lighting (or normals I thought) were screwed up.  When I took the camera inside the model though, the lighting looked ok.  Then I realized it was the material…  it was very shiny and only applied to the front faces.



As for ambient…  there is a global ambient value in LightState, try setting that also to black.



For the light intensity, afaik OpenGL uses vertex normals, the lighting colors (ambient, diffuse, specular and emissive,) materials, and a few lighting params (attenuation for example) to determine surface color.  There's not really a one value concept of light power… like say 60 watts and 120 watts or something.  You'll need to use attenuation and the other color values in conjunction to setup such a model.

Hey, thanks for your help. I moved the camera inside the asteroid and yeah, it was being correctly lit in there. I messed with the material and still couldn't get a change though. Then I flipped it inside out (set the scale to negative) and it looked better, but there were still some weird lighting issues. Then I got my friend to flip the model inside out in Blender and I imported the inside out version, and now it looks perfect. Strange but true.



I'll be messing with lights more whenever I get the time (which doesn't seem soon :frowning: ), but thanks for the info.

I'm guessing still that it is the material state.  If flipping it inside out comes back to haunt you later, go back to the original model and when you load it, recursively traverse the loaded model scene, clearing out all MaterialStates.  Just setting a new material at the top of the model will not override any that the converter added further down the scene.

Will do, thanks.