Blender ObjectHelper Bug

@Kaelthas

I think the last commit on com.jme3.scene.plugins.blender.objects.ObjectHelper broke the parenting handling.

*10867 02.11.13 16:14 1 Kaelthas_Spellsinger@o2.pl Refactoring: simplified method that loads the object's transformation.

I use parenting in Blender pretty extensively, mainly for animations. Now the objects are distributed all over the scene :smiley:

Okay, reverting that change didn’t solve it all. The object are then initially correctly placed but as an animation starts the object jumps to another location.
There must be another related change which also introduced a bug.

I’d be glad if you could have a look at that too :slight_smile:

@arpagaus could you send me a link to a test file where the problem occurs ? :slight_smile:

@Kaelthas

This is a test file which shows the bug:
https://dl.dropboxusercontent.com/u/14799295/test-parenting.blend

There is a perenting chain over 3 object and the last one has a rotation animation on it. If the animation is not started the two object are in completely different places. Once the animation start, the child object jumps to another location which still is not correct.

This still worked with SVN revision 10826. But I didn’t check which revision exactly introduced the bug.

@Kaelthas
Did you have a chance looking at this?

@arpagaus
Sorry, not yet :frowning:

I found one serious bug in bone animations loading and I focused on fixing that one first. But I will check out your problem soon.

1 Like

@arpagaus
I just commited the fix. Update and tell me if it works :slight_smile:

It turned out that blender does not always store the parent inverse matrix in the object’s structure ‘parentinv’ field.
So instead of reading this field I read the parent’s global matrix value and invert it myself.

And sorry it took me so long.

1 Like

@Kaelthas
Thanks for your efforts! Here is what I’ve found:

Since SVN Revision 10914 there seems to be something wrong with the mesh and its getIndicesAsList() & getTriangleCount(). When calling MeshCollisionShape.createCollisionMesh(…) I get the following stacktrace:

[java]
Caused by: java.lang.IndexOutOfBoundsException
at java.nio.Buffer.checkIndex(Buffer.java:532)
at java.nio.DirectShortBufferU.get(DirectShortBufferU.java:253)
at com.jme3.scene.mesh.IndexShortBuffer.get(IndexShortBuffer.java:53)
at com.jme3.bullet.collision.shapes.MeshCollisionShape.createCollisionMesh(MeshCollisionShape.java:148)
at com.jme3.bullet.collision.shapes.MeshCollisionShape.<init>(MeshCollisionShape.java:102)
at com.jme3.bullet.collision.shapes.MeshCollisionShape.<init>(MeshCollisionShape.java:81)
at com.jme3.bullet.util.CollisionShapeFactory.createSingleMeshShape(CollisionShapeFactory.java:214)
at com.jme3.bullet.util.CollisionShapeFactory.createCompoundShape(CollisionShapeFactory.java:112)
at com.jme3.bullet.util.CollisionShapeFactory.createCompoundShape(CollisionShapeFactory.java:134)
at com.jme3.bullet.util.CollisionShapeFactory.createMeshCompoundShape(CollisionShapeFactory.java:143)
at com.jme3.bullet.util.CollisionShapeFactory.createMeshShape(CollisionShapeFactory.java:173)
at app.scene.DesertScene.addRigidBodyControlMesh(DesertScene.java:374)
at app.scene.DesertScene.initTemple(DesertScene.java:108)
… 11 more
[/java]

I’m using native JME bullet, I haven’t tried it with JME JBullet yet. But there must be something wrong in the Blender import, because before that SVN commit, it was all fine.

Then back to the original issue: Since Revision 10922 some of the object in my scene are positioned correctly, but most of them are upside down (rotated 90° along x-axis). So, it got kinda worse. Sorry for the bad news.
If you can’t reproduce the issue, I’ll send you the scene.

@arpagaus
OK, send me the scene then because I never actually used collisions. And send me the blend file you use.

The fix I made did not do anything with the mesh so I am 100% sure it did not break it.
But several days ago I made changes to mesh loading and added line and point meshes loading support.
Maybe that is what caused problems.

1 Like

@Kaelthas

Thank you for your help. I saw your fix for the parenting and orientation, that looks good now :wink:

As for the Mesh-Buffers: I have uploaded the mesh I have trouble with to: https://dl.dropboxusercontent.com/u/14799295/void.jme.blend

If you call CollisionShapeFactory.createMeshShape(…) on the one Geometry, you should get the above Exception.

@arpagaus

The problem with the CollisionShapeFactory is that it treats the Line meshes as if they were triangles.
Not so long ago I added line and point loading to the blender importer and this is what causes troubles.

The question is simple: should the CollisionShapeFactory take Lines and Points into account ??
@normen it looks like you took part in creating the class. What do you think about it ?

1 Like
@Kaelthas said: @arpagaus

The problem with the CollisionShapeFactory is that it treats the Line meshes as if they were triangles.
Not so long ago I added line and point loading to the blender importer and this is what causes troubles.

The question is simple: should the CollisionShapeFactory take Lines and Points into account ??
@normen it looks like you took part in creating the class. What do you think about it ?

As arpagaus indocated the issue is not why you cannot create a collision mesh from lines or points, the question is why does it get this data to work on.

When I load an object from blender it often happens that I need to split the mesh into several jme geometries and put them in a single node.
I split the mesh in two cases:

  1. when a mesh has several materials: this is because jme does not support multiple materials for a geometry
  2. when a mesh have single lines or points: a mesh cannot be both on triangle, line and point modes

The lines and points are being loaded because they will be used to properly compute the constraint target if a user sets it to be a vertex group instead of the whole object. So I need to have all vertices computed and stored in a single node.

That is why the line and point data get into the CollisionShapeFactory.
So I guess there are two solutions. Either we tell developers to be careful what they put inside the CollisionShapeFactory (but that would not be very nice because they would need to iterate through all the meshes and check their mode). Or we could simply ignore meshes of non triangle type in CollisionShapeFactory and log a warning or an info.

1 Like

@Kaelthas
Thank you for analysing and clarifying. So it’s pretty nice lines and unconnected vertices are supported now :slight_smile:
But when modelling the mesh I wasn’t intentionally creating a line without a face and looking at the model now, I’m not able to actually find it. For example the first two vertices in the list are (4.700002, 7.2000003, -4.7000003) & (4.700002, 7.2000003, -5.0). Wherase the second is really a vertex there is none at the first location in my mesh. And there is definitly no edge between those. Is this something invisible which originates from my “strange” model or do you know what’s going on there? :smiley:

@normen
Could you add a filter in the MeshCollisionShape.createCollisionMesh(…) methods which only treats the Meshes with the right Mesh.Mode? Or is there something I could help with? Thanks!

Okay, I’ve found workarounds for most issues. I’m using setUserData(UserData.JME_PHYSICSIGNORE, true) for non-triangle meshes for now.

@Kaelthas
Most of it looks fine now, the only issue that remains are Ipo animations and parenting. This used to work fine before SVN revision 10867
I guess the fixes you did on the ObjectHelper would need to be applied to IpoHelper as well?
I’ve uploaded a new blender model which shows the issue here: https://dl.dropboxusercontent.com/u/14799295/test-parenting.blend
If you create an animation channel and start a cycle animation on it, you can clearly see the difference to the version in Blender.
By the way, this feature makes using the blender importer really great :slight_smile: keep up the good work!

1 Like

@Kaelthas
A bit off topic, but I had an exception on MeshHelper:206 because I’ve used a Lighting material as default material in the BlenderKey. So I’ve added an additional in my local git repository:

[java]
if(geometry.getMesh().getBuffer(Type.Color) != null && defaultMaterial.getMaterialDef().getName().equals(“Unshaded”)) {
defaultMaterial = defaultMaterial.clone();
defaultMaterial.setBoolean(“VertexColor”, true);
}
[/java]

There are definitely more elegant solutions, but that’s all I need for now.
Would you mind adding it?

Seems like in the case of Lighting you’d want to us “UseVertexColor” or your vertex colors will be ignored.

Why we have two separately named uniforms for the same thing in this case will just have to go down in history.

@pspeed
Yes, that’s right. But I omitted that because the case covered by that piece of code is rather rare. It’s only entered if the object has no material assigned but uses vertex colors. Very convenient for beginners or simple cases. But if someone actually changes the default material, they’ve got to know what they’re doing anyway.
That’s why I suggest that simple solution.

@Kaelthas
Okay, it took me a while but I’ve found the bug. :slight_smile: As I’ve suspected it was the Ipo class. On commit 10585 you’ve implemented a bugfix, but forgot to negate the Y-axis values on fixUpAxis. I’ve simply compared it with the previous version. Now my animations look fine again!

Could you please include the following patch:
[java]
diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java b/engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java
index 9922a14…8e07684 100644
— a/engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java
+++ b/engine/src/blender/com/jme3/scene/plugins/blender/animations/Ipo.java
@@ -168,7 +168,12 @@ public class Ipo {
translation[0] = (float) value;
break;
case AC_LOC_Y:

  •                        translation[yIndex] = (float) value;
    
  •                        if (fixUpAxis) {
    
  •                           translation[yIndex] = value == 0.0f ? 0 : (float) -value;
    
  •                        }
    
  •                        else {
    
  •                           translation[yIndex] = (float) value;
    
  •                        }
                           break;
                       case AC_LOC_Z:
                           translation[zIndex] = (float) value;
    

@@ -208,7 +213,12 @@ public class Ipo {
quaternionRotation[0] = (float) value;
break;
case AC_QUAT_Y:

  •                        quaternionRotation[fixUpAxis ? 1 : 2] = (float) value;
    
  •                        if (fixUpAxis) {
    
  •                           quaternionRotation[1] = value == 0.0f ? 0 : (float) -value;
    
  •                        }
    
  •                        else {
    
  •                           quaternionRotation[2] = (float) value;
    
  •                        }
                           break;
                       case AC_QUAT_Z:
                           quaternionRotation[fixUpAxis ? 2 : 1] = (float) value;
    

[/java]

Thank you!

2 Likes

@arpagaus

Thank for finding it.
The fix is now in the svn :slight_smile:

1 Like