Closed stephengold closed 3 years ago
This doesn't happen every time; not sure how to trigger it.
I managed to catch an incident in the debugger. In ShadowUtil.java line 428
bv
has radius NaN and center (NaN, NaN, NaN)nodeOcc
points to a Node
with 6 children and null parentbv.children[0]
is a Geometry
whose worldBound
is a BoundingSphere
with radius Infinity
Since the sky is loaded asynchronously with respect to shadow filter creation, perhaps it gets added to the scene graph in the middle of an update?
I loaded the sky and playground synchronously and still occasionally saw the AssertionError
.
Thus far, the crash has only happened while adding a vehicle to the scene.
Assertions have been enabled since 6218360a (21 November), and I don't recall any incidents since a55ea38 (22 November). Perhaps this issue has also been solved.
Not more incidents have occurred. Almost certainly solved.
May have been related to the race condition resolved by 2ff7f2b .
It's back. Here's the most recent stack trace:
Jan 12, 2021 1:17:37 PM com.jme3.app.LegacyApplication handleError
SEVERE: Uncaught exception thrown in Thread[main,5,main]
java.lang.AssertionError
at com.jme3.bounding.Intersection.intersect(Intersection.java:67)
at com.jme3.bounding.BoundingSphere.intersectsBoundingBox(BoundingSphere.java:683)
at com.jme3.bounding.BoundingBox.intersects(BoundingBox.java:595)
at com.jme3.shadow.ShadowUtil$OccludersExtractor.process(ShadowUtil.java:428)
at com.jme3.shadow.ShadowUtil$OccludersExtractor.addOccluders(ShadowUtil.java:368)
at com.jme3.shadow.ShadowUtil.updateShadowCamera(ShadowUtil.java:501)
at com.jme3.shadow.DirectionalLightShadowRenderer.getOccludersToRender(DirectionalLightShadowRenderer.java:194)
at com.jme3.shadow.AbstractShadowRenderer.renderShadowMap(AbstractShadowRenderer.java:427)
at com.jme3.shadow.AbstractShadowRenderer.postQueue(AbstractShadowRenderer.java:412)
at com.jme3.shadow.AbstractShadowFilter.postQueue(AbstractShadowFilter.java:116)
at com.jme3.post.FilterPostProcessor.postQueue(FilterPostProcessor.java:241)
at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1103)
at com.jme3.renderer.RenderManager.render(RenderManager.java:1158)
at com.jme3.app.SimpleApplication.update(SimpleApplication.java:272)
at com.jme3.system.lwjgl.LwjglWindow.runLoop(LwjglWindow.java:530)
at com.jme3.system.lwjgl.LwjglWindow.run(LwjglWindow.java:632)
at com.jme3.system.lwjgl.LwjglWindow.create(LwjglWindow.java:466)
at com.jme3.app.LegacyApplication.start(LegacyApplication.java:463)
at com.jme3.app.LegacyApplication.start(LegacyApplication.java:424)
at com.jme3.app.SimpleApplication.start(SimpleApplication.java:127)
at com.jayfella.jme.vehicle.Main.main(Main.java:214)
By modifying jme3-core, I showed that center
is (NaN, NaN, NaN) in intersectsBoundingBox()
.
From there, I traced it back to BoundingSphere.merge(float, Vector3f, BoundingSphere)
. this.center
was okay just prior to rCenter.set(center.addLocal(diff.multLocal(coeff)));
but afterward it is all NaNs. There's a lot of numeric junk at this point, since diff
, coeff
and radiusDiff
were also NaNs.
In the failing situation, not only is this.radius
equal to +Infinity, but we also have rVal == this
(!)
Consequently, radiusDiff
is NaN and length
is +Infinity, making the coeff
calculation entirely pointless.
Taking a step back ... there's no point in calculating a new center location if either this
or rVal
has radius +Infinity.
So I changed the test from:
if (length > RADIUS_EPSILON) {
to
if (length > RADIUS_EPSILON && Float.isFinite(length)) {
I've tested this fix, and so far it seems to work.
It'll take awhile to release a jme3-core with the fix. For this project, there's a simple workaround: make the sky's bounding volume finite!
Fixed in "master" branch at f4589028a62617f36f24cc3580eb98b3a0822814
I had some trouble creating a simple test to reproduce the issue, so I revisited it. Here's a code fragment to reproduce it:
BoundingBox box = new BoundingBox(new Vector3f(-92f, 3.3194322e29f, 674.89886f), 1.0685959f, 3.3194322e29f, 2.705017f);
BoundingSphere sphere = new BoundingSphere(Float.POSITIVE_INFINITY, new Vector3f(0f, 0f, 0f));
sphere.mergeLocal(box);
Not sure why the box has that strange center; that may indicate an unrelated issue.
Pursuing the box-center clue, I encountered a Geometry
named "wheel1_bodyMAT_0.001" that has worldTransform.translation.y=1.6995493E32 . Its parent Node
(named "wheel") has worldTransform.translation.y=1.6995493E32 . And the grandparent Node
(named "WheelNode") has localTransform.translation.y=1.6995493E32 . Far out!
Not surprisingly, the huge wheel offset comes from Bullet: VehicleWheel.getWheelLocation()
setting wheelWorldLocation
to (-92.85, 1.6931809E27, 673.4). Probably some uninitialized data in the native code...