Looking for a working .mesh/.xml/.scene Importer for jME

Hi all.

I have searched and read just about every posting I can find concerning importing into jME.

What I am using atm for Exporting Models from Maya is Ogre from OgreMax.com.

I can export out simple models into the .material/.mesh/.mesh.xml/.scene files.

Now my problem is which importer to use to get what I made into jME.

Sorry but I'm really confused and to top it off, most of the posts are from 2008.



Can someone please point me in the correct direction on an Importer that works.



I'm a game art & animation student at UAT and trying to get an internship with someone that is using jME.

Any and all help would be fantastic.



Thank you for reading this. And if this is in the wrong place, I am sorry - please relocate to the correct area.

Have a look at  jmetest.ogrexml.TestMeshLoading . There you can see how to load a ogre3d-xml-mesh.

In the same package you see a dotscene-loader as well!


It would be fantastic if there was a direct export/import for jME without jumping through several programs to do it.

I know that is wishful thinking though.

Don't know what you mean!?!  You said you use maya and it's ogre-exporter. jME have an ogre-importer so it is capable to load your exported model (well it should)… no need of any other programm(usually)!


Alight.

I got jME loaded and have tested it like it states in the tutorial.

I tell ya… that youtube video was fantastic using Java Eclipse.

I was able to load the jmetest.ogrexml TestMeshLoading.java and saw the ninja. And ran the TestDotScene.java



Now to figure out how to work it to see my .mesh.xml file.

experienced the same problem before… you just have to pay attention to these line of codes



private Spatial model;

URL meshURL = blendertojme.class.getResource(“mesh41_material0ID.mesh.xml”);

model = (Spatial) loader.loadModel(meshURL);



that does it… and pay attention to the materials also… sometimes it doesn’t load without the required materials…



although I’ve got myself a little problem of my own… could somone help me…







here’s a screenshot of the .mesh.xml that I loaded using ogre loader along with its materials… my question is…

its supposed to be red all the way… why is the texture a little jagged… or broken… can you tell me what I’m missing… here’s the whole of my code…



package mhelz;

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

import com.jme.app.SimpleGame;
import com.jme.image.Texture;
import com.jme.input.FirstPersonHandler;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.Spatial.LightCombineMode;
import com.jme.scene.Spatial.TextureCombineMode;
import com.jme.scene.shape.Box;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.resource.ClasspathResourceLocator;
import com.jme.util.resource.RelativeResourceLocator;
import com.jme.util.resource.ResourceLocator;
import com.jme.util.resource.ResourceLocatorTool;
import com.jmex.effects.particles.ParticleFactory;
import com.jmex.effects.particles.ParticleMesh;
import com.jmex.model.ModelFormatException;
import com.jmex.model.ogrexml.MaterialLoader;
import com.jmex.model.ogrexml.MeshCloner;
import com.jmex.model.ogrexml.OgreLoader;
import com.jmex.model.ogrexml.anim.Bone;
import com.jmex.model.ogrexml.anim.MeshAnimationController;

public class blendertojme extends SimpleGame {

    private static final Logger logger = Logger.getLogger(
            blendertojme.class.getName());

    private Spatial model;

    public static void main(String[] args){
       blendertojme app = new blendertojme();
        app.setConfigShowMode(ConfigShowMode.AlwaysShow);
        app.start();
    }

    protected void loadMeshModel(){
        OgreLoader loader = new OgreLoader();
        MaterialLoader matLoader = new MaterialLoader();
        //String matUrlString = "/jmetest/data/model/ogrexml/Example.material";
        //String ninjaMeshUrlString = "ID286.mesh.xml";

        try {
            URL meshURL = blendertojme.class.getResource("mesh41_material0ID.mesh.xml");
            URL matURL = blendertojme.class.getResource("new Scene.material");
            if (meshURL == null)
                throw new IllegalStateException(
                        "Required runtime resource missing: mesh "
                        );
            if (matURL == null)
                throw new IllegalStateException(
                        "Required runtime resource missing: meterial" );
            try {
                ResourceLocatorTool.addResourceLocator(
                        ResourceLocatorTool.TYPE_TEXTURE,
                        new RelativeResourceLocator(matURL));
                  // This causes relative references in the .material file to
                  // resolve to the same dir as the material file.
                  // Don't have to set up a relative locator for TYPE_MODEL
                  // here, because OgreLoader.loadModel() takes care of that.
            } catch (URISyntaxException use) {
                // Since we're generating the URI from a URL we know to be
                // good, we won't get here.  This is just to satisfy the
                // compiler.
                throw new RuntimeException(use);
            }
            matLoader.load(matURL.openStream());
            if (matLoader.getMaterials().size() > 0)
                loader.setMaterials(matLoader.getMaterials());

            model = (Spatial) loader.loadModel(meshURL);
        } catch (IOException ex) {
            logger.log(Level.SEVERE, null, ex);
        } catch (ModelFormatException mfe) {
            logger.log(Level.SEVERE, null, mfe);
        }
    }

    

    @Override
    protected void simpleInitGame() {
        ResourceLocator locator = new ClasspathResourceLocator();
        ResourceLocatorTool.addResourceLocator(
                ResourceLocatorTool.TYPE_MODEL, locator);
          // This is to find our *.mesh.xml file.
        ResourceLocatorTool.addResourceLocator(
                ResourceLocatorTool.TYPE_TEXTURE, locator);
          // This is to find our *.material file.

        Logger.getLogger("com.jme.scene.state.lwjgl").setLevel(Level.SEVERE);

        DisplaySystem.getDisplaySystem().setTitle("Test Mesh Instancing");
        display.getRenderer().setBackgroundColor(ColorRGBA.darkGray);
        cam.setFrustumFar(20000f);
        loadMeshModel();
        //MeshCloner.setVBO(model);
        logger.info("Loaded model node '" + model.getName() + ')');
        rootNode.attachChild(model);
        //model.setLocalRotation(new Quaternion().fromAngleAxis(45* FastMath.DEG_TO_RAD, Vector3f.UNIT_Y));
        rootNode.updateGeometricState(0, true);
        rootNode.updateRenderState();
    }


}

Can you please attach/post the mesh.xml and material files?



The importer was designed to work best with the Blender3D mesh exporter and may have some issues with other exporters.

ok here is the material and the mesh you were looking for… well as for what you were asking… my designer used google sketchup 6 in modeling the block and then I was able to import its Collada .dae to blender3d… where all are good including the color… then exported using Ogre Meshes… then import to JME using the aforementioned code… thanks for the quick reply…xD

bump

Hola,…can you attach the blend-file as well so I can give it a try with exporting. It might be a problem with the normals, but that is just a guess. (Try to select all veritces in blender -> ctrl-n -> Recalculate normals outside.)



With blend-file we could have a look as well…

just checked this mesh…

the diffuse material parameter has a more prominent red component but the ambient and specular are all at .5 grey…

hence the material issue…

the other thing is that the polygon winding seems incorrect…

when i added a cullstate many faces that should of been visible were culled…

i would recommend you check the face normals in blender before the next export…

Please tell me if my logic is incorrect.

I will be able to modify the TestDotScene.java / TestMeshLoading.java to get it to load my exported model file. Or do I need to rewrite it?



Thanks

What ncomp said is correct. The model you have has broken normals.

You need to check the normals in blender:

right click the model, press tab, press space, go to edit -> normals -> recalculate outside. That should fix the polygon winding as well.



You should also set the material colors properly, unless you specifically intend only the diffuse color to be red.

I imported you model again in blender and there were an error saying also something about normals (as we three thought about before). Two question, as it seems to be a static model, did you try to load the collada-file directly? Did you try the HottBJ-Exporter ( http://www.jmonkeyengine.com/wiki/doku.php?id=blenderjme_basics_tutorial ).



As I said I imported your mesh into blender and exported it with HottBJ and that seems to work (might be that the importer recalculated teh normales on its own).



Here is the result and the HottBJ-File:



[edit]: Exporting it with ogre-export didn't change the effect with that scrambled colors. Even recalculatin the normals didn't make any difference. Nevertheless there are this Wanings:"Error in normalize! Face of Mesh too small!" Actually I

tried to remove double vertices but that didn't fix the problem! Maybe momoko_fan knows how to solve that.

first, I didn't know if a collada importer into JME was available… so I wasn't able to directly import the .dae to jme… second, I find hottbj a little harder to understand than that of ogrexml… could you post the code you made for that screenshot of yours?.. I might reconsider using Hottbj instead of Ogre Meshes since you pulled it out perfectly…

first) jmetest.renderer.loader.TestColladaLoading (don't know how good the importer is)

second) yes, i know! lot's of text to read in the tutorial!  :stuck_out_tongue:



Here is the code.


package org.tomtro.test;

import java.io.IOException;



import com.jme.animation.AnimationController;
import com.jme.app.SimpleGame;
import com.jme.scene.ImportNode;
import com.jme.scene.Node;
import com.jme.util.export.xml.XMLImporter;

import test.TestGame;

public class TestStandard extends SimpleGame {

   public Node level;
   
   @Override
   protected void simpleInitGame() {
      level = getJMEXML("test/res/legomesh-jme.xml");
      level.setLocalScale(10f);
      rootNode.attachChild(level);
      System.out.println();
   }
   
    public static Node getJMEXML(String resource)
    {
       try {
          XMLImporter importer = new XMLImporter();
         Node result = (Node)importer.load(TestStandard.class.getClassLoader().getResource(resource));
         result.updateRenderState();
         return result;
      } catch (IOException e) {
         e.printStackTrace();
         return null;
      }       
    }
   
   public static void main(String args[])
   {
      new TestStandard().start();
   }

}

thanks for the quickie reply ttrocha… btw, I could change the invocation you made as Spatial instead of Node right?

Well yes,…you can but actually it is a node that comes from the import! Node extends Spatial so I doesnt make much difference here…but if you want you can…



Keep on rocking

Hi again… now that you've introduced me to Collada Importing, I am quite thinking now of what importer is to use into my project… since my models all are .dae… which came from Sketch-up where my modeler is more knowledgeable of… well, the initial plan was for him to model in sketch-up… save / export it as Collada .dae files, so that we could import it to blender and then export it again as .xml using an exporter such as Hottbj or Ogre Meshes… the thing is, since there is an existing Collada Importer, it would more likely, obviously, lighten my workload by simply importing the Collada files directly to JME… although, my problem is… I don't quite understand how this works… could someone explain me how this works… since I would only like to import simple Lego Blocks which have no skin or skeletons for animation whatsoever… the code should be simple… by the sample ttrocha had directed me with… its quite hard to understand… please help me… and sorry for being such a noob…



Here is the code in the jmetest.renderer.loader.TestColladaLoading.java

package jmetest.renderer.loader;

import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.logging.Logger;

import com.jme.animation.AnimationController;
import com.jme.animation.Bone;
import com.jme.animation.BoneAnimation;
import com.jme.animation.SkinNode;
import com.jme.app.SimpleGame;
import com.jme.input.FirstPersonHandler;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.light.PointLight;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Controller;
import com.jme.util.BoneDebugger;
import com.jme.util.resource.ResourceLocatorTool;
import com.jme.util.resource.SimpleResourceLocator;
import com.jmex.model.collada.ColladaImporter;

/**
 * Shows how to load a COLLADA file and apply an animation to it.
 * @author Mark Powell
 *
 */
public class TestColladaLoading extends SimpleGame {
    private static final Logger logger = Logger
            .getLogger(TestColladaLoading.class.getName());
    
    AnimationController ac;
    boolean boneOn = false;
    public static void main(String[] args) {
        TestColladaLoading app = new TestColladaLoading();
        app.setConfigShowMode(ConfigShowMode.AlwaysShow);
        app.start();
    }
    
    protected void simpleUpdate() {
        if( KeyBindingManager.getKeyBindingManager().isValidCommand( "bones", false ) ) {
            boneOn = !boneOn;
        }
    }

    protected void simpleRender() {
        //If we want to display the skeleton use the BoneDebugger.
        if(boneOn) {
            BoneDebugger.drawBones(rootNode, display.getRenderer(), true);
        }
    }

    protected void simpleInitGame() {
        try {
            ResourceLocatorTool.addResourceLocator(
                    ResourceLocatorTool.TYPE_TEXTURE,
                    new SimpleResourceLocator(TestColladaLoading.class
                            .getClassLoader().getResource(
                                    "jmetest/data/model/collada/")));
        } catch (URISyntaxException e1) {
            logger.warning("Unable to add texture directory to RLT: "
                    + e1.toString());
        }

        KeyBindingManager.getKeyBindingManager().set( "bones", KeyInput.KEY_SPACE );
        
        //Our model is Z up so orient the camera properly.
        cam.setAxes(new Vector3f(-1,0,0), new Vector3f(0,0,1), new Vector3f(0,1,0));
        cam.setLocation(new Vector3f(0,-100,20));
        input = new FirstPersonHandler( cam, 80,
                1 );
        
        //this stream points to the model itself.
        InputStream mobboss = TestColladaLoading.class.getClassLoader()
                .getResourceAsStream("jmetest/data/model/collada/man.dae");
        //this stream points to the animation file. Note: You don't necessarily
        //have to split animations out into seperate files, this just helps.
        InputStream animation = TestColladaLoading.class.getClassLoader()
        .getResourceAsStream("jmetest/data/model/collada/man_walk.dae");
        if (mobboss == null) {
            logger.info("Unable to find file, did you include jme-test.jar in classpath?");
            System.exit(0);
        }
        //tell the importer to load the mob boss
        ColladaImporter.load(mobboss, "model");
        //we can then retrieve the skin from the importer as well as the skeleton
        SkinNode sn = ColladaImporter.getSkinNode(ColladaImporter.getSkinNodeNames().get(0));
        Bone skel = ColladaImporter.getSkeleton(ColladaImporter.getSkeletonNames().get(0));
        //clean up the importer as we are about to use it again.
        ColladaImporter.cleanUp();
        
        //load the animation file.
        ColladaImporter.load(animation, "anim");
        //this file might contain multiple animations, (in our case it's one)
        ArrayList<String> animations = ColladaImporter.getControllerNames();
        if(animations != null) {
           logger.info("Number of animations: " + animations.size());
           for(int i = 0; i < animations.size(); i++) {
               logger.info(animations.get(i));
           }
           //Obtain the animation from the file by name
           BoneAnimation anim1 = ColladaImporter.getAnimationController(animations.get(0));
           
           //set up a new animation controller with our BoneAnimation
           ac = new AnimationController();
           ac.addAnimation(anim1);
           ac.setRepeatType(Controller.RT_WRAP);
           ac.setActive(true);
           ac.setActiveAnimation(anim1);
           
           //assign the animation controller to our skeleton
           skel.addController(ac);
        }
        
        //attach the skeleton and the skin to the rootnode. Skeletons could possibly
        //be used to update multiple skins, so they are seperate objects.
        rootNode.attachChild(sn);
        rootNode.attachChild(skel);
        
        rootNode.updateGeometricState(0, true);
        //all done clean up.
        ColladaImporter.cleanUp();
        
        lightState.detachAll();
        
        PointLight pl = new PointLight();
        pl.setAmbient(new ColorRGBA(0.5f,0.5f,0.5f,1));
        pl.setDiffuse(new ColorRGBA(1,1,1,1));
        pl.setLocation(new Vector3f(10,-50,20));
        pl.setEnabled(true);
        lightState.attach(pl);
    }
}

 

Here's my trial...


package mhelz;

import java.io.InputStream;

import jmetest.renderer.loader.TestColladaLoading;

import com.jme.animation.Bone;
import com.jme.animation.SkinNode;
import com.jme.app.SimpleGame;
import com.jmex.model.collada.ColladaImporter;


public class MyTestCollada extends SimpleGame
{
   public static void main(String args[]){
      MyTestCollada app = new MyTestCollada();
      app.setConfigShowMode(ConfigShowMode.AlwaysShow);
      app.start();
   }
   
   protected void simpleInitGame(){
      InputStream mobboss = MyTestCollada.class.getResourceAsStream("Green.dae");
       ColladaImporter.load(mobboss, "model");
       ColladaImporter.cleanUp();
       if (mobboss == null) {
               System.out.println("Unable to find file, did you include jme-test.jar in classpath?");
               System.exit(0);
           }
       SkinNode sn = ColladaImporter.getSkinNode(ColladaImporter.getSkinNodeNames().get(0));
           rootNode.attachChild(sn);
           
           rootNode.updateGeometricState(0, true);
           //all done clean up.
   }
}



btw... here is the brick im trying to import...

http://www.easy-share.com/1908027481/Green.dae

bump