What was the Ray in those cases?
Sorry, forgot adding the ray. Did the experiment once more with ray coordinates.
Other than your triangles being relatively small for how far away they are from the ray’s origin… nothing jumps out immediately.
Last time I had to debug something like this I ended up setting up a test with a known-bad ray + known-bad geometry and then stepping through the collision code to see where things went wrong. (It’s how I found and fixed some 3.1 bounding box collision issues.)
Yes but I was assuming that single precision floating point arithmetics have 6-7 digits. So expecting a resolution of about 1m at a distcane of 10 km. My spaceship has a size of about 300 m so it is ok. And the most time (99,9 %) the hits are calculated correctly.
But you are right, Of course these triangles are pretty small…
Is there a possibility to perform translations/rotations/collisions on double precision floating point? This would be a great increase in positioning and transformation accuracy. I already tried this out for jre7 HotSpot: The runtime on x64 machines is nearly the same.
Short answer: no
Long answer: yes, if you reimplement it all yourself then anything is possible.
Also, you don’t even really know if that’s the issue…
You’d have to step through the collision code to see what is actually the problem. That is literally the only way forward from here: someone must step through that code. You are best positioned to do it.
To answer your question I am using an AppState which manages the coordinates of each spatial using FixedPoint128 Bit with 32 Bit binary point (for ensuring equal accuracy throughout the whole universe ). Dependent on these coordinates it determines the scene position of the spatial (with respect to the players reference coordinates).
But after all the collision detection takes place in scene coordinates far away from FixedPoint128 so I recognize two tasks for myself:
- interference between my “InfinitySceneState” and the scene objects must be proven to not happen.
- One other idea is to introduce a fall back condition: Go back to bounding volume collision if triangle based mesh collision fails. I will try this out.
I will let you know… Thank you
Regards, Harry
I mean, it could be just a yet-as-undiscovered bug in the collision code.
…but now you seem like you are going to architect around floating point just because we’ve speculated it might be the issue. Versus spending 15 minutes stepping through things in the debugger.
But I guess that’s your choice in the end.
I think theres a misunderstanding because I am planning to proceed double-tracked. One of course is to rework around the issue in order to solve the immediate problem (the points what I mentioned above) but this is only one aspect of my goal. In general: I don’t like making workarounds because I am striving for simplicity and clearness in my projects and workarounds usually lead to cumbersome code with potential runtime/clearness/bug issues (this is also my experience in ten years of embedded software development).
I already had a look into the code but I quickly realized that I failed to understand the collision detection algorithm properly. I simply didn’t understand where the infinity occurs in the lunch time break before I had to return to work. Thus in order to deepen the understanding it would be helpful if there were some books/documentation about ray-mesh or collision algorithms in general.
Regards,
Harry
Ill post a test case tomorrow. Im curious myself. It will either eliminate or uncover the issue. Its my sons birthday and he is hogging my work pc
That’s why I suggested stepping through it with the debugger. Step, step, step… “oh, those turned into infinity… let me post back to the forum.”
I generally don’t ever use the debugger… but there are times when it’s appropriate.
You may need his geometry to make it happen properly… unless you already have a case where it happens (and even still, it could be a different issue but I guess we’ll see).
I have spotted the place where the infinity occurs the first time. at Line Nbr. 408 inside the BIHNode.java. It happens here:
// a leaf
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);
t = t_world;
}
The first ray intersection at line 402 seems to succeed with
t = (float) 63.74776
but then the world matrix does the transformation on the triangle vertices:
worldMatrix = (com.jme3.math.Matrix4f) Matrix4f [ 42.2509 -19.02441. 107.99919 0.0
15.904092 56.847427. 30.440855. 0.0
-39.521152 2.5380936. 127.70876. 0.0
0.0 0.0 0.0 1.0
]
the transformed triangle vertices are
v1 = (com.jme3.math.Vector3f) (-69.03165, -63.077835, -56.384964)
v2 = (com.jme3.math.Vector3f) (-61.490913, -63.448433, -46.023514)
v3 = (com.jme3.math.Vector3f) (-58.02646, -64.74267, -48.644794)
After this the ray collision is repeated:
o = (com.jme3.math.Vector3f) (1655.2566, 4107.8115, 1836.2129)
d = (com.jme3.math.Vector3f) (-0.351738, -0.85287726, -0.38584113)
the local output of the triangle check leads to:
t_world = (float) Infinity
Strange: The check before the transformation passes while the check after the transformation fails.
Regards,
Harry
Yes. Sorry. Give me a short amount of time and I’ll write the test case.
By the way: How can I post pictures? Currently it seems to be impossible to do so (error message).
We all use imgur since it has the best features, but any external imagehost really. Im gonna have to fight that demon sooner or later.
Well. I proved us wrong. There’s nothing wrong with anything I can find. It fires a ray in the direction of the cursor, and another one inside the shape. The shape rotates around, and the ground is bumpy. Feel free to let me know if there’s anything else I can do to expose a bug.
https://gist.github.com/jayfella/2683d763b8aa19b4206048bc4d67f51a
-
The ray is fired to the target from a very distant point (with respect to the size of the geometry which is being hit). so the triangles seem to be very small from the rays origin.
-
It is quite difficult to reproduce the error for me because I often have to wait several minutes until it happens (randomly).
-
This happens only for about one frame so it is quite impossible to observe at high FPS with the “naked eye”.
-
It seems to happen more frequently when the edge of the geometry is being hit (if the geometry is just striped/slightliy touched by the ray).
-
Maybe this could be also imortant: I do not perform collision checks on node level. I do it only on geometry level. Before performing collision checks on a spacecraft or other object I filter out all non collideable geometries (thruster flames, etc…). Then I store all geometries for collision check within a Map<Spatial, List> where the keys are the spaceships and the lists contain the geometries for collision for each spaceships (The advantage: If the corresponding list is empty no checks are done on this object). Then I check on geometry level directly and store the results in a CollisionResults object.
public static void checkRayCollision(Ray ray, Map<Spatial, List<Geometry>> potentialTargetList, CollisionResults collisionAccumulator) { potentialTargetList.entrySet() .stream() .forEach(entry -> entry.getValue().forEach(geometry -> { geometry.collideWith(ray, collisionAccumulator); })); }
The method which is called by the gun inside the updateLoop:
/**
* This method updates the collision results.
*
* @param ray
* @return
*/
private void checkForRayCollisionsAndUpdateResults(Ray ray) {
results.clear();
Map<Spatial, List<Geometry>> colliderList = getPossibleVictims();
Collisions.checkRayCollision(ray, colliderList, results);
}
I will continues further investigations in my software components.
Except you have exactly all of the parameters you need to setup a test. Position the geometry where it was on the failure, set the ray to what it was on failure, etc… it will happen every time.