Ray collision results in infinite distances

Hello guys,

I have encountered a problem while playing around with Jme3 3.2 ray collision.
In some rare cases the collision distance results in Infinity.
I would like to figure out wether someone has also encountered such problems and what is the most likely cause.

I get output like this:
CollisionResults[CollisionResult[geometry=Forward (Math2D), contactPoint=(26.958435, 20.854736, 164.37305), contactNormal=(-0.4416181, -0.14222594, -0.8858584), distance=4897.3433, triangleIndex=209], CollisionResult[geometry=Forward (Math2D), contactPoint=(26.958435, 20.854736, 164.37305), contactNormal=(0.4416181, 0.14222594, 0.8858584), distance=4897.3433, triangleIndex=211], CollisionResult[geometry=Cylinder1 (Geometry), contactPoint=(-4.265259, -3.2994995, -26.009277), contactNormal=(-0.1985307, 0.2964904, 0.9341729), distance=5091.7754, triangleIndex=63], CollisionResult[geometry=Cylinder1 (Geometry), contactPoint=(-8.673401, -6.7095947, -52.887207), contactNormal=(-0.38953823, 0.073161595, -0.9180998), distance=5119.225, triangleIndex=35], CollisionResult[geometry=Cube1 (Geometry), contactPoint=(-19.889221, -15.385986, -121.273926), contactNormal=(-0.10184377, -0.11908125, -0.9876475), distance=5189.0664, triangleIndex=28], CollisionResult[geometry=Rear (Math2D), contactPoint=(-26.957642, -20.854065, -164.37305), contactNormal=(-0.4416183, -0.14222696, -0.8858583), distance=5233.082, triangleIndex=1482], CollisionResult[geometry=Rear (Math2D), contactPoint=(-26.957642, -20.854065, -164.37305), contactNormal=(0.4416183, 0.14222705, 0.8858583), distance=5233.082, triangleIndex=1480], CollisionResult[geometry=Cube1 (Geometry), contactPoint=(-Infinity, -Infinity, -Infinity), contactNormal=(0.10184595, 0.11908179, 0.9876472), distance=Infinity, triangleIndex=623]]

I have already checked the meshes involved here and I am pretty sure that there is no problem. It occurs on Blender exported meshes as well as on procedural meshes.

Regards,
Harry

You should also print other things out like the ray values… the world transforms of the geometry you collide with, etc…

Yes of course:

The code:
System.out.println(farthestResult);
System.out.println("Transformation matrix of the lucky victim: " + farthestResult.getGeometry().getWorldTransform());
System.out.println("Transformation matrix bad guy with gun: " + getSpatial().getWorldTransform());
System.out.println("the laser beam: " + ray);

Example 1:
The collision result: CollisionResult[geometry=Left (Math2D), contactPoint=(-Infinity, -Infinity, -Infinity), contactNormal=(-0.48193124, 0.52758485, 0.6995688), distance=Infinity, triangleIndex=93]
Transformation matrix of the lucky victim: Transform[ 0.0, 0.0, 0.0]
[ -0.12959768, 0.5060236, 0.13397495, 0.84213823]
[ 60.0 , 60.0, 170.0]
Transformation matrix bad guy with gun: Transform[ 332.25955, 3580.25, 4975.102]
[ 0.73381263, -0.60560995, 0.17316027, 0.2545055]
[ 1.0 , 1.0, 1.0]
the laser beam: Ray [Origin: (332.25955, 3580.25, 4975.102), Direction: (-0.054127663, -0.58325326, -0.81048703)]

Example 2:
CollisionResult[geometry=Cylinder1 (Geometry), contactPoint=(-Infinity, -Infinity, -Infinity), contactNormal=(-0.57303023, -0.44715807, -0.68679404), distance=Infinity, triangleIndex=100]
Transformation matrix of the lucky victim: Transform[ -28.313505, -19.648045, -21.649353]
[ -0.12693931, 0.8718491, -0.15565002, -0.44670093]
[ 10.0 , 10.0, 10.0]
Transformation matrix bad guy with gun: Transform[ 4523.7607, 3480.082, 4924.293]
[ 0.68082273, 0.6025885, -0.41540194, -0.028617091]
[ 1.0 , 1.0, 1.0]
the laser beam: Ray [Origin: (4523.7607, 3480.082, 4924.293), Direction: (-0.6001158, -0.46166414, -0.65325654)]

Regards, Harry

Currently I have a workaround: I check all collision results of a ray collision check for infinite results and skip the whole collision detection for beam length update and damage supply.
This seems to be sufficient because the probability is quite low that a collision check fails (e.g. 1/1000).

But not understanding the issue doesn’t let me sleep quietly :slight_smile:

This is how I found it (just to show the relevance to me):
I am flying a heavily damaged spaceship (Hitpoint=1) with an enemy ship putting me under beam weapon fire. The beam weapon hits are estimated by ray collisions. My ship is entirely surrounded by a shield (geometry) capable of protecting me from a couple of beam rounds. The closest collision of the beam weapon is the point where the damage is being delivered. Because my ship is entirely surrounded by the shield the damage shall be taken by the shield first. Only on shield failure the protective cheese dome is removed.
If the shield collision detection fails (distance is infinite) the shield is assumed to be infinitely far away then closest collision will then be the hull of the ship => 1HP → 0HP → BOOM. :slight_smile:

For the transform, it’s probably more interesting to see the values as JME will use them. Mostly I was interested in the Quaternion since a degenerate quaternion can produce strange results.

You might also choose to print out the information about the triangle that was hit.

I have experienced the same and can confirm your line of thought @pspeed. It occurs for me mostly when i’m placing objects on spherical surfaces. I can provide a video. Not certain about a test case. I havent delved any further than thought on it. Thanks for the heads up :stuck_out_tongue:

Now I have some quaternions: WorldRotation and triangle vectors of three infinity cases. Nothing unusual to me (no NaNs, no ±Infs and no E±50 etc…)

#1
Lucky victim name: Cube1 (Geometry)
Lucky victim location: (0.0, 0.0, 0.0)
Lucky victim hit location: (-Infinity, -Infinity, -Infinity)
Lucky victim rotation quaternion: (-0.1930057, 0.9121568, -0.15380746, -0.32720608)
Lucky victim triangle:
(1.0273232, -0.028530452, -10.33968)
(1.0025762, 0.12567475, -10.33968)
(1.0084343, 0.10884176, -10.33968)
Ray: Ray [Origin: (3070.324, 1146.0314, 4956.8965), Direction: (-0.5174651, -0.1892948, -0.8345032)]

#2
Lucky victim name: Left (Math2D)
Lucky victim location: (0.0, 0.0, 0.0)
Lucky victim hit location: (-Infinity, -Infinity, -Infinity)
Lucky victim rotation quaternion: (-0.15379186, 0.3271978, 0.19300283, 0.912163)
Lucky victim triangle:
(0.8627299, 0.07547908, -0.5)
(0.816035, 0.0713938, -0.57357645)
(0.8528685, 0.15038373, -0.5)
Ray: Ray [Origin: (815.85016, 893.9591, 4970.653), Direction: (-0.15942243, -0.17480308, -0.97161126)]

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 :slight_smile: ). 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:

  1. interference between my “InfinitySceneState” and the scene objects must be proven to not happen.
  2. 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 :slight_smile:

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 :confused:

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).