[SOLVED] DAC Ragdoll passing through ground at high velocities

Thanks for providing the test case. I know simple tests aren’t easy to create.

Unfortunately, I seem to be missing some textures:

Libbulletjme version 16.3.0 initializing
Nov 09, 2022 2:08:02 PM com.jme3.app.LegacyApplication handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
com.jme3.asset.AssetNotFoundException: Textures/Terrain/PBR/Ground037_1K_Color.png (Flipped) (Mipmapped)
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:385)
	at com.jme3.asset.DesktopAssetManager.loadTexture(DesktopAssetManager.java:407)
	at com.jme3.asset.DesktopAssetManager.loadTexture(DesktopAssetManager.java:419)
	at jme3test.batching.Main.setUpTerrainMaterial(Main.java:192)
	at jme3test.batching.Main.simpleInitApp(Main.java:155)
	at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:240)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:139)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:221)
	at java.base/java.lang.Thread.run(Thread.java:833)

Since the textures probably aren’t relevant to the bug, I tried deleting the parts that use them, but then I ran into this:

Nov 09, 2022 2:14:00 PM com.jme3.app.LegacyApplication handleError
SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
com.jme3.asset.AssetNotFoundException: Scenes/LightProbes/quarry_Probe.j3o
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:385)
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:402)
	at jme3test.batching.Main.setUpLights(Main.java:309)
	at jme3test.batching.Main.simpleInitApp(Main.java:156)
	at com.jme3.app.SimpleApplication.initialize(SimpleApplication.java:240)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.initInThread(LwjglAbstractDisplay.java:139)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:221)
	at java.base/java.lang.Thread.run(Thread.java:833)

Could you add the missing assets to the DacCcdTestCase repo or point me to where I can download them?

2 Likes

All of the missing assets should be in the jme test data library, I should have mentioned that but I completely forgot I was importing and using assets from the test data library since I recycled this test case from another one that already had that dependency included in the build script.

In hindsight I also probably should’ve included the gradle build file to the repo to make it a proper gradle app, but if you add the 3.4 test data library then it should work:

    implementation "org.jmonkeyengine:jme3-testdata:3.4.0-stable"
2 Likes

I was using the 3.1.0-stable testdata. I switched to 3.4.0 and made some progress.
Now I’m getting:

Libbulletjme version 16.3.0 initializing
Nov 09, 2022 4:09:51 PM com.jme3.texture.Texture read
SEVERE: Cannot locate texture Models/darkElf_female/darkElf_female_basecolor_clothed_alt.png (Mipmapped)
Nov 09, 2022 4:09:51 PM class com.jme3.export.binary.BinaryImporter readObject(int id)
SEVERE: Exception
com.jme3.asset.AssetNotFoundException: MatDefs/shaders/AfflictedCreatures.j3md
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:385)
	at com.jme3.material.Material.read(Material.java:1137)
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:345)
	at com.jme3.export.binary.BinaryInputCapsule.readSavable(BinaryInputCapsule.java:483)
	at com.jme3.scene.Geometry.read(Geometry.java:741)
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:345)
	at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:510)
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:498)
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:616)
	at com.jme3.scene.Node.read(Node.java:768)
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:345)
	at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:510)
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:498)
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:616)
	at com.jme3.scene.Node.read(Node.java:768)
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:345)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:245)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:128)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:112)
	at com.jme3.export.binary.BinaryLoader.load(BinaryLoader.java:36)
	at com.jme3.asset.DesktopAssetManager.loadLocatedAsset(DesktopAssetManager.java:272)
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:388)
	at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:439)
	at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:444)
	at com.mygame.ElfCharacter.<init>(ElfCharacter.java:50)
	at com.mygame.Main.makeElfNpc(Main.java:124)
	at com.mygame.Main.access$000(Main.java:41)
	at com.mygame.Main$1.onAction(Main.java:106)
	at com.jme3.input.InputManager.invokeActions(InputManager.java:174)
	at com.jme3.input.InputManager.onKeyEventQueued(InputManager.java:474)
	at com.jme3.input.InputManager.processQueue(InputManager.java:871)
	at com.jme3.input.InputManager.update(InputManager.java:923)
	at com.jme3.app.LegacyApplication.update(LegacyApplication.java:777)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:248)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:160)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:201)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:242)
	at java.base/java.lang.Thread.run(Thread.java:833)

Nov 09, 2022 4:09:51 PM com.jme3.texture.Texture read
SEVERE: Cannot locate texture Models/CharacterBuilder/CharacterModels/woodElf_female/lightblue_eye.png
Nov 09, 2022 4:09:51 PM com.jme3.texture.Texture read
SEVERE: Cannot locate texture Models/CharacterBuilder/CharacterModels/woodElf_female/eyelashes02.png
Nov 09, 2022 4:09:51 PM com.jme3.texture.Texture read
SEVERE: Cannot locate texture Models/CharacterBuilder/CharacterModels/woodElf_female/eyebrow005.png (Mipmapped)
Nov 09, 2022 4:09:51 PM com.jme3.texture.Texture read
SEVERE: Cannot locate texture Models/tiffany/gltf/fancyFabric_Albedo.png.jpg (Mipmapped)
Nov 09, 2022 4:09:51 PM com.jme3.texture.Texture read
SEVERE: Cannot locate texture Models/CharacterBuilder/Hair/Female/frenchBraid0/braid01_rough.jpg (Mipmapped)
Nov 09, 2022 4:09:51 PM com.jme3.texture.Texture read
SEVERE: Cannot locate texture Models/CharacterBuilder/Hair/Female/frenchBraid0/braid01_nrml.png (Mipmapped)
Nov 09, 2022 4:09:51 PM com.jme3.texture.Texture read
SEVERE: Cannot locate texture Models/CharacterBuilder/Hair/Female/frenchBraid0/braid01_baseColor_solid.png (Mipmapped)
Nov 09, 2022 4:09:51 PM class com.jme3.export.binary.BinaryImporter readObject(int id)
SEVERE: Exception
com.jme3.asset.AssetNotFoundException: MatDefs/shaders/AfflictedCreatures.j3md
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:385)
	at com.jme3.material.Material.read(Material.java:1137)
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:345)
	at com.jme3.export.binary.BinaryInputCapsule.readSavable(BinaryInputCapsule.java:483)
	at com.jme3.scene.Geometry.read(Geometry.java:741)
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:345)
	at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:510)
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:498)
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:616)
	at com.jme3.scene.Node.read(Node.java:768)
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:345)
	at com.jme3.export.binary.BinaryInputCapsule.resolveIDs(BinaryInputCapsule.java:510)
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArray(BinaryInputCapsule.java:498)
	at com.jme3.export.binary.BinaryInputCapsule.readSavableArrayList(BinaryInputCapsule.java:616)
	at com.jme3.scene.Node.read(Node.java:768)
	at com.jme3.export.binary.BinaryImporter.readObject(BinaryImporter.java:345)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:245)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:128)
	at com.jme3.export.binary.BinaryImporter.load(BinaryImporter.java:112)
	at com.jme3.export.binary.BinaryLoader.load(BinaryLoader.java:36)
	at com.jme3.asset.DesktopAssetManager.loadLocatedAsset(DesktopAssetManager.java:272)
	at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:388)
	at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:439)
	at com.jme3.asset.DesktopAssetManager.loadModel(DesktopAssetManager.java:444)
	at com.mygame.ElfCharacter.<init>(ElfCharacter.java:50)
	at com.mygame.Main.makeElfNpc(Main.java:124)
	at com.mygame.Main.access$000(Main.java:41)
	at com.mygame.Main$1.onAction(Main.java:106)
	at com.jme3.input.InputManager.invokeActions(InputManager.java:174)
	at com.jme3.input.InputManager.onKeyEventQueued(InputManager.java:474)
	at com.jme3.input.InputManager.processQueue(InputManager.java:871)
	at com.jme3.input.InputManager.update(InputManager.java:923)
	at com.jme3.app.LegacyApplication.update(LegacyApplication.java:777)
	at com.jme3.app.SimpleApplication.update(SimpleApplication.java:248)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.runLoop(LwjglAbstractDisplay.java:160)
	at com.jme3.system.lwjgl.LwjglDisplay.runLoop(LwjglDisplay.java:201)
	at com.jme3.system.lwjgl.LwjglAbstractDisplay.run(LwjglAbstractDisplay.java:242)
	at java.base/java.lang.Thread.run(Thread.java:833)
2 Likes

Oops, I thought that I had adjusted that model so I wouldn’t need to include all the materials and textures, that way the model would just default to using the yellow “missing” texture and I could keep the size of the test case as small as possible.

But it looks like I still needed to include the shader files for the custom shaders that some of the materials are using.

Ideally I would’ve liked to change the materials to use the basic PBR shader, but since the model is made up of 8 geometries with unique materials and textures saved disorderly across many folders in my local project that would’ve taken a while to sort out.

But I just uploaded my entire Assets/MatDefs folder to the test case since its only 6mb and that is quicker than reverting a handful of embedded materials back to the stock PBR shader. So I think it should run now as long as the MatDefs directory is included, but let me know if you still have any trouble. Sorry for the mistake.

2 Likes

Using the code and assets you uploaded, I’ve reproduced the issue. I trust some lessons were learned in the process!

I am working to simplify the code and turn it into a reproducible test case. If I discover anything interesting, I’ll report back here.

Update #1:

The strange contortions that happen when the elf hurtles through mid-air are due to collisions between different physics links in the same ragdoll. I know this because disabling such collisions with dynamicAnimControl.setIgnoredHops(8) prevents those contortions.

It makes sense that enabling CCD on a fast-moving ragdoll results in Bullet detecting more collisions between physics links. In general, disabling intra-ragdoll collisions is not good idea. For instance, having a ragdoll’s arm pass through its torso might detract from the verisimilitude of the effect.

Please try the workaround described above. If it isn’t satisfactory, I’ll implement a mechanism to disable CCD collisions without disabling ordinary collisions.

Update #2:

Another workaround to consider: don’t setIgnoredHops() but instead apply setCcdSweptSphereRadius(0.04f) to each rigid body in the ragdoll. Physics links will penetrate the terrain only slightly, and this greatly reduces the chances of mid-air, intra-ragdoll, CCD collisions.

2 Likes

Yes I notice this a lot when setting ignored hops to 8, it does stop the ccd bugginess, but the results look unnatural and are very noticeable when an arm folds inward and overlaps the torso or another limbs in the model, so I don’t think this would be an optimal solution.

This does reduce the severity of the issue, but I’m finding that it is still causing some bugginess with the limbs stretching out when i launch the model directly at the terrain, specifically when the model is skidding along the terrain and slowing down. And on occassion it still gets the issue with the limbs being pinned in mid air. It is less frequent than when I had the sweptSphereRadius set higher, but is still much less clean than whenever I completely disable CCD

At the current state of things, I think I would probably choose to just go without using any CCD and just let the character phase through the ground consistently. This still isn’t an optimal solution, but the results without CCD cause consistent clipping through the ground so it at least feels like that’s what’s supposed to happen. But trying to get it to work using CCD with a low swept sphere radius only seems to make the results less consistent (on rare occasion it still gets pinned on itself in mid-air, sometimes it still clips the ground, and most of the time it still looks buggy and much less natural floating in mid air when compared to not using any CCD) and this inconsistency means that players will be unable to accurately speculate where they will end up when they get hit by a knockback effect that they have experienced before and thus expect to work in a similar way.

I think something like this would be the best solution. With CCD enabled, the limbs intersect cleanly with the terrain, but very buggy against other limbs in the DAC. And with CCD disabled the DAC operates very well in mid-air but still clips the terrain.
So if the CCD could be ignored between physics links in the same DAC but still used against the terrain, then I think that would solve all of the issues as best as possible.

1 Like

So if the CCD could be ignored between physics links in the same DAC but still used against the terrain, then I think that would solve all of the issues as best as possible.

I’ll get started on this.

2 Likes

Pawing through the Bullet sourcecode, I discovered some code that’s disabled at build time (using the PREDICTIVE_CONTACT_USE_STATIC_ONLY and USE_STATIC_ONLY #defines). It appears to disable CCD between dynamic bodies, so that CCD only detects static-vs-dynamic collisions.

If this feature works the way I think it should, it’ll be just the ticket. I’m building a test right now.

Update: working toward a new release of Minie to incorporate the feature

4 Likes

Isn’t there a risk to break existing apps by enabling that ? I wonder why this code is disabled by default… Shouldn’t it be an dynamic option instead ? Or maybe I’m missing something here…

2 Likes

Good question. For Minie, I created my own fork of Bullet. In that fork, I’ve converted the disabled code into a dynamic option. The option defaults to the old behavior.

3 Likes

Okay, that took a bit longer than I expected.
Please try Minie v6.2.0 with physicsSpace.setCcdWithStaticOnly(true).

3 Likes

I upgraded to the new version and that fixed the problem. Now the ragdoll physics are just as clean with CCD enabled and there’s no clipping through the ground :grinning:

I greatly appreciate all of your help troubleshooting and resolving this issue!

5 Likes

I’m glad to be of service. Thank you for persevering.

6 Likes

as i understand, setting setCcdWithStaticOnly as true will just disable CCD dynamic vs dynamic, but dynamic vs dynamic collisions will still generally appear. Thats fine then.

IMO it would be really nice, if this would work only for “single armature internal CS Collisions” and not “armature vs armature CS collisions”

lets say for example @yaRnMcDonuts would want to make 2 characters, where they fight with swords with Minie DAC physics, CCD would not apply in this case, because both are dynamic right?

Anyway good work here.

2 Likes

setting setCcdWithStaticOnly as true will just disable CCD dynamic vs dynamic, but dynamic vs dynamic collisions will still generally appear

That’s right.

it would be really nice, if this would work only for “single armature internal CS Collisions” and not “armature vs armature CS collisions”

I’m sure some developer will want more fine-grained control over CCD. My original plan was to dynamically filter CCD collisions based on (new) ignore lists. However, the new mechanism is simpler, easier to implement, and more efficient.

3 Likes