// XXX: when non-uniform scale fix code is applied(r7291), this
// fails?:
// but it’s probably due to worldToLocal ?
// undo that fix to see this working fine
sphereToUse.setLocalTranslation(localContact);
// I believe the fix is good, though I think it needs to be applied
// also somewhere else too
}
}
}
[/java]
EDIT: Note: it works when sphereParent has no scale or uniform scale set, currently it’s non-uniform, if you want to see it work, with uniform scale, obviously change this line no.69 :
You’re right the worldToLocal method is returning incorrect results. To prove that, you can keep calling worldToLocal then localToWorld on the same vector and you will keep getting different results each time.
Not only did the actual transform concatenation did not follow convention, but the transform method and its inverse are using a completely different order of operations! In any case, I fixed this issue as well.
omg I’m so happy I figured this out by myself, but I cannot take credit(EDIT:I mean I cannot prove that I figured it out by myself lol) for it because you already did it, no matter I are happy looool monkey happy :))
You could now argue if the inverse doesn’t exist than you fucked up something else big. Since i’m not an quaternion expert i don’t now what it means that the inverse doesn’t exist or if it’s a bad thing. But the only thing i’m doing is using worldtoLocal.
the quaternion inverse method returns null when the norm of the quaternion is negative or zero.
From what I read, the Math rule is that a quaternion has an inverse only if it’s not 0,0,0,0.
I guess the norm computation in quaternion.inverse() is here to check this, but something bothers me :
The norm of a quaternion is sqrt(ww+xx+yy+zz).
The norm() function returns ww+xx+yy+zz. If you get over the fact that it’s wrong…this obviously can have a negative value (or am i wrong?) but sqrt(ww+xx+yy+zz) cannot. (square root is positive). So quaternions that have ww+xx+yy+zz negative will throw your exception when they shouldn’t.
So…maybe this is intended to not compute the square root which is expensive, but then the test should be if (norm==0.0f) return null; and not norm > 0.0f.
I’m not even sure what a sqrt() would be for a negative number. What multiplied by itself would be negative? Just not possible.
This function:
ww+xx+yy+zz
Will never return negative. Can you think of any numbers when multiplied by themselves that would produce a negative? Will adding them together make them go backwards?
I can’t say what may or may not be wrong with quaternion but those functions are always dealing in positive numbers.
@pspeed said: @nehon, you may need another cup of coffee. :)
I'm not even sure what a sqrt() would be for a negative number. What multiplied by itself would be negative? Just not possible.
This function:
w*w+x*x+y*y+z*z
Will never return negative. Can you think of any numbers when multiplied by themselves that would produce a negative? Will adding them together make them go backwards?
I can't say what may or may not be wrong with quaternion but those functions are always dealing in positive numbers.
hehehe true :D
I told you that the moment i was considered the math guy of the project we were doomed!
So @Lockhead this let you with the 0,0,0,0 rotation case...
@Lockhead said:
For some reasons the inverse doesn't exist for the quaternion
So maybe there should be a check for it?
You could now argue if the inverse doesn't exist than you fucked up something else big. Since i'm not an quaternion expert i don't now what it means that the inverse doesn't exist or if it's a bad thing. But the only thing i'm doing is using worldtoLocal.
My guess is that in these cases your Quaternion is somehow 0,0,0,0. If you are not specifically setting a bad quaternion then this is a sign that you are doing something really really bad somewhere. Something I can't even imagine at the moment.
Edit: a little bit of debugging (or dumping values to console) might show you what is happening.
Thanks for the responses. Will try to dig deeper after the weekend. For what i can say now the Quaternion is NaN at some point.
Maybe the physics has to do something with it since it’s the only part that is moving and rotating the node. I’m only applying forces and when i want to move the node than i’m using the RigidBodyControl (which i’m not doing at all when trying to produce this problem).
Will try to use native Bullet and see what happens. Unfortunately I’m stuck to jBullet because of the 64Bit Issues of native Bullet. It would be too much of a hassle to force 32JVM on my “cutomers”.
Long story short. I get and Infinity sometimes when colliding my Model with a Ray.
The problematic part is in BIHNode in the public final int intersectWhere(Ray r,Matrix4f worldMatrix, BIHTree tree, float sceneMin, float sceneMax, CollisionResults results) method (~:402).
[java]
for (int i = node.leftIndex; i <= node.rightIndex; i++) {
tree.getTriangle(i, v1, v2, v3);
float t = r.intersects(v1, v2, v3);
if (!Float.isInfinite(t)) {
if (worldMatrix != null) {
worldMatrix.mult(v1, v1);
worldMatrix.mult(v2, v2);
worldMatrix.mult(v3, v3);
float t_world = new Ray(o, d).intersects(v1, v2, v3);
Vector3f contactPoint = new Vector3f(d).multLocal(t).addLocal(o);
float worldSpaceDist = o.distance(contactPoint);
CollisionResult cr = new CollisionResult(contactPoint, worldSpaceDist);
cr.setContactNormal(contactNormal);
cr.setTriangleIndex(tree.getTriangleIndex(i));
results.addCollision(cr);
cols++;
}
}
[/java]
At the beginning we have our first intersection [java]float t = r.intersects(v1, v2, v3);[/java]. We check than for infinity [java]if (!Float.isInfinite(t)) {[/java]. So we don’t add any “bad” ContactPoints. After that we use the worldMatrix to change the vectors and intersect again with the changed vectors. But here i get sometimes and Infinity and because this one will not be checked it will be added as a ContactPoint. I checked the worldMatrix and it doesn’t contain any NaNs or Infs.
I checked the intersects Method of the Ray and it isn’t the parallel case but the last return. The Edge case? Or is it then outside of the triangle? If so then why is it then interpreted as an ContactPoint? And if it’s the edge then why and infinity as the ContactPoint? Shouldn’t it be possible to get the ContactPoint correctly?
Either way, too much math in the morning ;). Maybe someone could explain me how i should interpret infinite ContactPoints (Parrallel,Edge,Outside).
It doesn’t exactly make sense to me why the first collision would succeed and then the second will fail. Are you sure the world matrix is correct? NaN/Inf are not the only thing making a broken matrix