Material not getting set after importing 3ds model

Hi all,



I’ve created a simple 8x5x3 tile with bevelled edges in Blender, and exported to 3ds format. I load the model into my test app, and create a sphere as a test object as well. I set both objects to have a green emissive material, and put a red light in the scene. The sphere then looks correct – green, with red on top – but the tile is gray with white on top. What am I doing wrong?



Here is the original Blender file, and here is the exported 3ds file. I’ve placed the 3ds file in the test directory. And finally, here’s the complete source code for my test app:



(P.S. I am a N00B, so please be gentle. My application is going to be a Japanese language learning game!)



package test;

import com.jme.app.*;
import com.jme.util.*;
import com.jme.util.export.binary.*;
import com.jme.scene.shape.*;
import com.jme.scene.state.*;
import com.jme.scene.*;
import com.jme.math.*;
import com.jme.bounding.*;
import com.jme.renderer.*;
import com.jme.light.*;
import com.jme.image.*;
import com.jme.util.geom.*;
import com.jme.input.*;
import java.nio.*;
import java.net.*;
import java.io.*;
import com.jmex.model.XMLparser.Converters.*;
import com.jmex.model.XMLparser.*;

public class Test1 extends SimpleGame
{
   protected void simpleInitGame()
   {
      Node modelNode = null;

      try
      {
         MaxToJme converter = new MaxToJme();
         ByteArrayOutputStream BO = new ByteArrayOutputStream();

         URL file = Test1.class.getClassLoader()
               .getResource("test/tile.3ds");

         System.out.println("Starting to convert .3ds to .jme at " + file);

         converter.convert(file.openStream(), BO);

         // load as a TriMesh if single object, Node if multiple objects

         modelNode = (Node) BinaryImporter.getInstance().load(
               new ByteArrayInputStream(BO.toByteArray()));

         // modelNode.setLocalScale(0.5f);
         modelNode.setModelBound(new BoundingBox());
         modelNode.updateModelBound();

      }
      catch (IOException e)
      {
         e.printStackTrace();
      }

      Node n = new Node("My root node");

      // this is just a test object

      Sphere s = new Sphere("My sphere", 15, 15, 1);
      s.setLocalTranslation(-5, -5, 0);
      s.setModelBound(new BoundingSphere());
      s.updateModelBound();

      // Add green emission to sphere and tile
      
      MaterialState ms = display.getRenderer().createMaterialState();
      ms.setEmissive(new ColorRGBA(0, 0.2f, 0, 1));
      s.setRenderState(ms);
      modelNode.setRenderState(ms);

      // Add a red light
      
      PointLight pl = new PointLight();
      pl.setDiffuse(ColorRGBA.red);
      pl.setLocation(new Vector3f(0, 10, 5));
      pl.setEnabled(true);

      LightState ls = display.getRenderer().createLightState();
      ls.attach(pl);

      lightState.detachAll();
      n.setRenderState(ls);

      n.attachChild(s);
      n.attachChild(modelNode);
      rootNode.attachChild(n);

   }

   public static void main(String[] args)
   {
      Test1 app = new Test1();

      app.setDialogBehaviour(SimpleGame.ALWAYS_SHOW_PROPS_DIALOG);
      app.start();
   }
}

Hi. I'm also newbie.

But I had problems with looking of loaded 3ds models until I've added .updateRenderState();.

Maybe it'll work for you.

Nope, that didn't work :frowning:



–Rob

I have to wonder, is there something wrong with the model itself that makes it unusable with jME? Can anyone take a quick peek at the model (link in the original post)?



–Rob

The exported 3ds file (http://chuffyrodents.org/tile.obj) is a bad link. Can you put it back up?

Whoops, sorry – wrong filename. Here it is.



–Rob

Nothing? God, I hate begging.



I'd like to donate to jME, but if I can't get an answer to this seemingly simple problem… :confused:



–Rob

Don't get impatient. Realize that this engine is primarily user supported.  If you have a problem hopefully someone in the forum can help you, but if nobody is able to you're just going to have to undertake to figure it out yourself.

sigh Understood. But you're a "Hero Member", you should be able to heroically find the dumb thing I'm doing!  :wink:



–Rob

After trying random things, I discovered that iterating into the modelNode and finding all the non-Node leaves and setting their material state solved the problem. But why? I thought that setting a material state on a node overrode the material states of all the children?



–Rob

No it does not override the children's material state. The state of the parent is used only if the child does not have an own state.

Ahhhh… NOW I understand! This is the log4j paradigm as well. Thank you! Now I just need to figure out how to wrap a texture around this thing…



–Rob

Here's what I did in order to set the material for the model:



   private static void nodeIterator(Spatial n, int level, MaterialState ms)
   {
      ArrayList<Spatial> children = ((Node)n).getChildren();
      
      for (Spatial s:children)
      {
         for (int i=0; i<level; i++)
            System.out.print(" ");
         System.out.println("Child is a " + s.getClass());
         if (s instanceof Node)
            nodeIterator(s, level+2, ms);
         else
         {
            MaterialState old = (MaterialState)s.setRenderState(ms);
            System.out.println("Old emissive color: " + old.getEmissive());
            System.out.println("Old diffuse color: " + old.getDiffuse());
            System.out.println("Old specular color: " + old.getSpecular());
         }
      }
      
   }



Is there any more elegant way to do this? An API, perhaps?

Thanks,

--Rob

hmm, set it in your model file?

I need to change the material and texture many times, so I can't fix the material or texture in the model file.



–Rob