Argh! setScale collisions!

Started by mystara, May 16, 2008, 08:52:29 PM

Previous topic - Next topic

mystara

Hurray!

I added a calcNormals() to level and it works correctly. I possibly should have said that I'm doing the scaling dynamically. A long time after the structure is actually loaded.

I'm sorry, this perhaps should have been painfully obvious to me. But my 3D skill is limited. I more or less understand concepts like using triangles and UV coordinates. I also understand pure maths like how to manipulate a matrix and what a normal is. But beyond that, I understand nothing.

One quick side request actually.
Might it be possible for the XML format to contain the name associated with a light source? It seems that once a light source is stored in XML format, there is no way to refer to it so that it can be later modified. Unlike, for example, models which can be searched by name with World.getModelbyName(String)?

EgonOlsen

That's not caused by lack of skills on your side, but by a mistake on mine. I'll correct this silly normal scaling in the next version. It's just wrong the way it is now.

About the lights: You can't get a Light-instance for them, but you should be able to reference them directly via World. The order they have in the XML should be the order in which they are stored in World, i.e. the first number should be 0, the second 1...with that information, it should be possible to manipulate a light after loading it via the xml.

mystara

The problem is that I cannot tell in advance what order they'll be stored in the XML :)

With regards to the bug, when this is fixed, will the calcNormals line no longer be needed?

EgonOlsen

The order is the same in which you've added them to the world.

When the bug is fixed, the calcNormals() is no longer needed, but it doesn't hurt anyway (well, it costs some time to execute of course, but that shouldn't be a problem in most cases).

mystara

Excellent. Thanks for your help!

mystara

hm.
I'm sure you're getting fed up of this by now. But I believe there is still another bug regarding scaling (or possibly my code).

My main rendering loop looks like this:

while (true)
{
   buffer.clear();
   theWorld.renderScene(buffer);
   theWorld.draw(buffer);
   buffer.update();
   buffer.displayGLOnly();
}

I have a Java GUI which can set the scale of an object via the functions:

getLevel().disableLazyTransformations();
getLevel().setScale(Float.parseFloat(scale));
getLevel().rotateMesh();
getLevel().setScale(1.0f);
getLevel().calcNormals();
rebuildOctree(getLevel());

Occasionally, seemingly randomly, when I set the scale of a loaded object, I get the following exception:

Exception in thread "main" java.lang.NullPointerException
at com.threed.jpct.Object3D.render(Unknown Source)
at com.threed.jpct.World.renderScene(Unknown Source)
at MainWindow.mainLoop(MainWindow.java:217)

Where line 217 of MainWindow refers to the line theWorld.renderScene(buffer); (above).
Now the weird bit here is that if theWorld was null, the exception stack wouldn't show entries for Object3D.render and World.renderScene (I believe) and buffer cannot be null, because the previous line uses the buffer object.

My previous investigations suggested that *something* to do with scaling caused buffer to be set to null, but I couldn't for the life of me manage to narrow it down.

Any ideas? It seems non deterministic, so I can only assume it's some kind of synchronisation error between my Java GUI affecting an item and perhaps messing up the buffer as the buffer is being accessed by that function but immediately after the clear() function?



mystara

Through trial and error (yeah, scientific), I suggest that the following code is somehow responsible:

level.createTriangleStrips(2);
level.setCollisionMode(Object3D.COLLISION_CHECK_OTHERS);
level.setCollisionOptimization(Object3D.COLLISION_DETECTION_OPTIMIZED);

OcTree oc = new OcTree(level, 100, OcTree.MODE_OPTIMIZED);
oc.setCollisionUse(OcTree.COLLISION_USE);
level.setOcTree(oc);

level.enableLazyTransformations();
level.setOrigin(new SimpleVector(0,0,0));

Which is my rebuildOctree() method mentioned above.
Whenever I disable this function, I cannot cause the above exception to occur.

Is there any reason why I shouldn't be able to call this code? Or any reason why it should cause buffer to become null? (even briefly?)

EgonOlsen

#22
jPCT isn't thread safe. You shouldn't call jPCT related methods from within other threads (which is where GUI events run in) without synchronizing the calls. Or, and even better IMHO, let the GUI set a flag only or queue the events and execute the actual code in the render loop.

Edit: More references can be found when searching the forum for "thread safe".