Reusing Meshes and Colors

Started by fendres, August 08, 2005, 05:08:07 PM

Previous topic - Next topic

fendres

Hi there,

I stumbled on two Problems while coding an Applet based on JPCT:
When I try to reuse a mesh by assigning it to an Object3D a nullPointerException is thrown.
Object3D retVal = new Object3D(0);
retVal.setMesh(((Object3D)usedModels.get(name)).getMesh());

The Error is:
Quotejava.lang.NullPointerException
   at com.threed.jpct.Object3D.setMesh(Unknown Source)
   at org.twofivesixbit.felix.mintec.RessourcePool.getModel(RessourcePool.java:140)
   at org.twofivesixbit.felix.mintec.SceneFromXMLBuilder.addModel(SceneFromXMLBuilder.java:81)
   at org.twofivesixbit.felix.mintec.SceneFromXMLBuilder.startElement(SceneFromXMLBuilder.java:40)
   at qdxml.QDParser.parse(QDParser.java:195)
   at org.twofivesixbit.felix.mintec.SceneFromXMLBuilder.buildOnReader(SceneFromXMLBuilder.java:190)
   at org.twofivesixbit.felix.mintec.Mintec3DScene.buildFromXML(Mintec3DScene.java:61)
   at org.twofivesixbit.felix.mintec.Mintec3DScene.<init>(Mintec3DScene.java:43)
   at org.twofivesixbit.felix.mintec.InteractiveMintec3DScene.<init>(InteractiveMintec3DScene.java:12)
   at org.twofivesixbit.felix.mintec.Mintec3DEngineApplet.init(Mintec3DEngineApplet.java:21)
   at sun.applet.AppletPanel.run(AppletPanel.java:353)
   at java.lang.Thread.run(Thread.java:534)
However as a workaround I currently use this:
Object3D retVal = ((Object3D)usedModels.get(name)).cloneObject();
So I am pretty sure, that the Object from the HashTable "usedModels" is correct. I would rather do it in the former way, because doing it like this I have to reset translation and additional color and do waste time copying those attributes.

The second Issue is a minor one:
It would be nice if there was a way to retrieve the additional color from an Object3D. (I would like to set a "team-color" which shall be replaced by red, when an object is selected and reapplied when another object is selected). Otherwise I would have to code a subclass of Object3D, which seems rather inelegant.

Finally I'd like to thank you for your great work! Programming with jPCT is really comfortable.

Felix

EgonOlsen

The null pointer exception is caused by the fact that an Object3D with 0 triangles doesn't have a mesh. If it's intentionally to create such objects in your code (i suggest to use createDummyObj() instead which does exactly this, but anyway), it shouldn't be needed to share the mesh instance (even if there were one, it would be emtpy...).
However, i've added some code that should fix this albeit i don't see the point in this operation... :?:
Be aware that you can't use setMesh(<Mesh>) to use the same object with completely different meshes. setMesh() sets vertex and triangle data. It doesn't set the texturing data for example.
About the getter for the color: I've added it. Both changes can be found in this pre-release jar: http://www.jpct.net/download/jpct_108a1.jar

fendres

Thanks for the quick reaction. The getAdditionalColor() works for me :-)

Unfortunately the problem with the shared mesh still exists. The nullPointerException is gone, but the Models that should reuse the existing Mesh are not displayed at all. I think I better clarify my goal:
My intention is to load a mesh from a 3DS file and use it for several Objects without reloading and reparsing the 3DS file. My Applet is displaying something similar to a chessboard. I have objects without Animation and these can occur several times.  So what I want when creating the objects one by one is to read the mesh data only for the first occurence of a type of counter (e.g a pawn). The second, third, etc pawn should then share the mesh of the first one. Thus in pseudocode:
pawn1 = Loader.load3ds("pawn.3ds");
pawn2 =new Object(0); //needs no mesh as it should share one with a previously loaded Object
pawn2.setMesh(pawn1.getMesh());
pawn3 =new Object(0);
pawn3.setMesh(pawn1.getMesh());
etc

Wouldn't this be the fastest method to instanciate several similar objects?
Maybe I missunderstood some of the concepts? However createDummyObj() didn't work either:

Object3D obj2 = Object3D.createDummyObj();
obj2.setMesh(obj1.getMesh());

[/code]

EgonOlsen

Quote from: "fendres"
Wouldn't this be the fastest method to instanciate several similar objects?
No, it just won't work (as you have noticed). The Mesh is only one part of an Object3D. By creating a (0)-sized object, you are creating an empty object. That doesn't change when setting a mesh. To copy an object, just use the corresponding contructor in Object3D (new Object3D(oldObj)) followed by a setMesh, i.e.:

Object3D obj=<your 3ds object>;
Object3D clone=new Object3D(obj);
clone.setMesh(obj.getMesh());


or, without the constructor:

Object3D clone=obj.cloneObject();


The Object3D created by cloneObject() will already share the mesh of the cloned object.

fendres

Ok, so there is something else in an Object that would have to be set beneath the mesh, and the translation matrix, which I can not set manually. Unfortunately this means I need to copy the Object, i.e. have many properties of the original cloned, just to throw them away.

Anyway I (believe I do) now understand the problem and since premature optimization is the root of all evil (paul graham, isn't it?) I'll use cloning and won't care anymore. There sure are plenty of worse performance issues in my code :oops: .

Thanks for the explanation (and for getAdditionalColor()).

EgonOlsen

Quote from: "fendres"i.e. have many properties of the original cloned, just to throw them away.
What do you mean by "throw them away"? You are using the objects, aren't you? As mentioned, the mesh is only a part of an Object3D. It doesn't contain texture coordinates, color information etc. There's no way to render a textured, lit object without them! If you worry about memory usage, you are save to set Config.saveMemory to true before creating Worlds and Object3Ds. It may help to reduce memory usage in some cases.

fendres

Oh, I didn't notice yet that you wrote another post, sorry.

I write "throw away", because I would like to have an Object3D with standard properties (Matrices, Color etc) except the mesh. So I would rather create an Object3D instance with the default constructor and set the mesh, instead of cloning an Object3D which has special properties set and resetting all the properties to defaults.
So it looks like I am setting specialized properties during cloning and "throw away" the customized properties when replacing them afterwards with default ones.