stephengold / jme-vehicles

A tech demo and library for simulating vehicles in jMonkeyEngine
BSD 3-Clause "New" or "Revised" License
16 stars 7 forks source link

AssertionError while calculating bounding box intersection #1

Closed stephengold closed 3 years ago

stephengold commented 3 years ago
Oct 23, 2020 12:25:58 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:53)

X Error of failed request:  BadWindow (invalid Window parameter)
  Major opcode of failed request:  20 (X_GetProperty)
  Resource id in failed request:  0x6200088
  Serial number of failed request:  1451
  Current serial number in output stream:  1451
stephengold commented 3 years ago

This doesn't happen every time; not sure how to trigger it.

stephengold commented 3 years ago

I managed to catch an incident in the debugger. In ShadowUtil.java line 428

bv.children[0] is a Geometry whose worldBound is a BoundingSphere with radius Infinity

stephengold commented 3 years ago

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?

stephengold commented 3 years ago

I loaded the sky and playground synchronously and still occasionally saw the AssertionError.

stephengold commented 3 years ago

Thus far, the crash has only happened while adding a vehicle to the scene.

stephengold commented 3 years ago

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.

stephengold commented 3 years ago

Not more incidents have occurred. Almost certainly solved.

stephengold commented 3 years ago

May have been related to the race condition resolved by 2ff7f2b .

stephengold commented 3 years ago

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)
stephengold commented 3 years ago

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.

stephengold commented 3 years ago

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.

stephengold commented 3 years ago

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

stephengold commented 3 years ago

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.

stephengold commented 3 years ago

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!

stephengold commented 3 years ago

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