-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GodotPhysics] CharacterBody3D interaction with large StaticBody3D producing too many collisions #69683
Comments
Can you test this after switching the 3D physics engine to GodotPhysics in the Project Settings in 3.5? Godot 4.0 only features GodotPhysics, not Bullet. |
Update after more research and testing on the issue: It appears that on top of generating too many collisions between only two objects (player and terrain) almost always hitting the hard-coded maximum collision count of 6, the Normals calculated from collisions also stand to be wildly inaccurate occasionally at collision mesh edges, they are capable of returning perpendicular normal angles (parallel to the terrain surface) which all affect the resultant velocity causing some really... bad motion |
Just leaving this here. I believe it could be related to this function which is long. godot/servers/physics_3d/godot_space_3d.cpp Lines 646 to 1023 in 2f0d3d5
I would honestly really like to see an implementation of Jolt https://github.com/jrouwe/JoltPhysics |
Confirming that the normals can get very weird in Godot physics |
The worst glitches here are a result of the static body effectively being scaled Also be aware that getting stuck on an edge (after taking the above into account) can be due to the character body's It is an editor issue that we don't generate colliders for scaled meshes correctly at the moment. |
This comment was marked as duplicate.
This comment was marked as duplicate.
I usually double check to make sure all transforms are applied in Blender before exporting any meshes but I'll triple check that for the sake of the minimal reproduction project, however, it's very critical to note that the primary issue involves a dynamic run-time generated collision shape that does not undergo any import process and is not scaled, it is simply utilizing the HeightMapShape3D mesh shape. It is also worth noting that there are use-cases where the HeightMapShape3D MUST be scaled due to the fact it does not contain separate properties for size and index count, unfortunately they are directly linked through the only three properties of the shape that are exposed through the API. That said I've done extensive testing mostly ensuring a scale of 1:1 is maintained on the collision shape, and that this behavior seems to persist across different collision shapes, appearing to impact convex, concave, and heightmapshape collider shapes at the very least. I will update soon after some additional testing I thought about performing last night and even re-exporting the minimal reproduction project mesh from blender (which uses a concave collider on import I believe?) to provide any additional findings |
Wellp, after double checking my minimal projects, apparently when I re-exported the blender mesh after trimming it (it was originally too large in filesize for GIT) the scale was not applied anymore, so it WAS being imported scaled instead of fully normalized. This definitely can contribute to the results in the minimal projects making them unreliable for verification of the issue. That said, the actual issue is not from interaction from the imported mesh colliders, but with dynamically generated collision meshes of the HeightMapShape3D variety with no scaling applied, HOWEVER, this does give me more stuff to double check and verify to see if this is specifically a HeightMapShape3D difference... |
Thanks for checking. A reproduction project using a heightmap would be much appreciated (preferably including the cool debug drawing of the normals). |
As a quick update I've very painstaking rewritten and isolated much of the code to more closely replicate the actual issue initially suffered in 4.0 into 3.5 (backporting and chopping up code a lot, and backporting the debugger visualizers) and this is where things get weird: the run-time heightmap collider doesn't seem to be experiencing the same issues in 3.5 as in 4.0 even using Godot physics... so there's something extra weird going on here... even though the code is almost identical, minus a lot of the other parts that it doesn't need (the entire clipmap system for the visual mesh components)... For now I've removed the old minimal projects, and reuploaded the heightmap generated collision 3.5 project now, which can be switched between Godot and Bullet physics (but apparently both behave properly as of right now?) Gonna re-rewrite the same minimal project in 4.0 again, based on the 3.5 project... tediously annoying, but hoping to isolate when exactly the issue starts happening... |
I confirm the issue. The Now, from the capsule being on top of a relatively flat part of the heightmap, an expected type of collision is that of a point of the capsule with a face of the heightmap, and indeed these collisions are occurring with nice normals. Another type of collision is that of a point of the capsule with an edge of a face of the heightmap. These collisions are also occurring, and often with mostly vertical normals, but sometimes not! The problem is that even though the best separation axis is always mostly vertical, it can happen that the point is very close to the edge, and vertically closer than horizontally, which causes the normal to be more horizontal. That's what I've found so far anyway. I'm not sure how this should be fixed. |
That is interesting. I think there is another part too, Is there any findings as to why it generates so many collisions per tick? As mentioned earlier in 4.0 it generates 2-6 per tick vs 3.5's generating 1-2 depending on the situation. |
This sounds very much exactly to be what's happening, and explains almost all of the symptoms and why it's doing what it is doing. It is exclusively generating bad normal calculations along face edges, and far too often generating them at horizontal as opposed to vertical axis. This ALSO explains why it exhibits the same behavior using the HeightMapShape AND the auto-generated collisions that Godot creates when importing meshes for collision, which utilize Concave mesh shapes. This sounds like Concave collision in Godot (although concave is always the hardest) needs to be immediately flagged as unsupported and dysfunctional. Is it possible to implement any of the following:
Overall this is a very unfortunate situation, as this affects the entire 3D engine as a whole, and has far deeper reaching implications than it seems at surface value. This should be marked as highly critical for all 3D development on the engine. Thanks for your expedient follow-up rburing, I know it's some very very tedious source code to traverse (we already did some of our own) and a lot of it relatively unchanged from up to NINE (9) years ago, and I appreciate your help. Hopefully someone has a potential solution in mind, or this helps increase the prioritization of engine physics corrections and improvements. |
As I understand it, this approach has undesired side effects: #35945 (comment) |
The three suggestions above don't sound like the correct solution to this deeper issue. You can try the first and third idea by implementing your own character controller using I've posted the theoretical question arising from this issue on Game Development Stack Exchange: https://gamedev.stackexchange.com/questions/203635/collision-normal-for-sphere-near-edge-of-triangle-face |
I think you are 100% correct, I'm going to move forward writing my own custom raycast-centric player controller, however, everything I've suggested is a bandaid fix and will not be something I'd expect from 95% of the Godot developer community and is a critical issue for the current and future viability of Godot 4.0+ 3D development. I'm just a bit concerned that some of these issues have been brought up several times over the years and not fully addressed, as 4.0 was a major selling point for myself and other long-term experienced developers to consider Godot as a viable platform for 3D development, it's a bit disheartening to see such a core component in it's current state, as I've otherwise fallen in love with the engine. Thanks for taking this on Rburing, let me know if there is anything else that can be done to help troubleshoot and debug matters. |
AFAIK this algorithm should work properly even with trimesh, and even if there is a tiny separation normal. I think here it would be worth investigating where the values differ in 3.5 and 4.0 when feeding the same input, as it may just be a recently introduced bug. |
although above demonstrates the issue persists in 3.5 (GDPhysics) and in 4.0. It was just mentioned that it seemed to be worse in 4.0. I think something is just fundamentally broken in the code. Might just be me but everyone I know using 3.x chose bullet physics over GDPhysics. Finding and solving the issue will probably be quite an undertaking as one of the functions is 350+ lines of code. It will be a very necessary thing to tackle very soon though. |
Here is a more minimal reproduction project: |
In godot/servers/physics_3d/godot_space_3d.cpp Lines 927 to 929 in 0bb94df
and we generate collision normals from there. Now observe that if godot/servers/physics_3d/godot_space_3d.cpp Line 784 in 0bb94df
The use of (I've confirmed The strange thing is that a capsule with |
I believe I have encountered this same issue, but not through terrain. My steps: New project, new 3D scene. Run the scene. Use the directional keys to rub up against the box (slide) with the character. These issues occur: The character snags on the box corners (vertical edges of the box) when moving along/against the box wall and cannot pass the box corner without leaving the box and going around the corner manually. The character sometimes snags on the box and cannot be moved except by jumping or random movement after which they may break free and move again. The character sometimes snags permanently on the box and cannot be moved even by jumping. Issue remains after changing the character collision shape to a cylinder instead of a capsule, though the cylinder slides less well along the box (sometimes shuddering movement). I have logged the velocity, remainder and travel after the call to move_and_slide in the template. The travel is the zero vector when snagged, the remainder is a very small vector and the velocity is the zero vector unless you jump while snagged in which case the y component of the vector stays 4.5 per the template. If you break free from the snag, the y component is applied as expected, but remains 4.5 forever while snagged. While in the snagged state, y component either 0 or 4.5, on_wall is always false and on_floor is always true after calling move_and_slide. If you move directly toward the box while snagged, on_wall remains false after move_and_slide, even when you move toward the box, but it toggles between true/false as expected if not snagged. Logging and noting this is how I have come to recognise the "permanently snagged" state. |
Is my problem related, or should I create a new issue about this; convexpolygon.mp4 |
@Swarkin Oh hey I saw your project on Discord I think, love the aesthetic! It's hard to tell if this is exactly what's causing your issue, but know that there is a very large number of closely related collision solver issues tied to this issue. Fortunately they ARE working investigated and worked on by a few folk in the community, the best place to see recent progress in this regard is in this issue: I wouldn't be at all surprised if it's the same issue, I just haven't experienced it from the top like you are doing here in your video clip. |
To give an update on this:
I propose to implement section 4 of https://www.codercorner.com/MeshContacts.pdf, for which #72868 is a first step (for trimesh shapes), but it will take some work to fit the rest of the solution into the existing Godot Physics. |
Thanks for the update @rburing. I wish I could say I still had the same amount of time to dedicate to trouble-shooting this that I had before, but that hasn't been the case. Glad to see some progress has been made, but I really hope this is on the radar for everyone on the team as a major road-block for Godot4 in 3D. It was enough for me to abandon some mature projects in Godot and migrate them to Unreal for the time being, though I would prefer working in Godot if these things were ever resolved. |
I think the problem is with the value retrived by the Some of the functions related were implemented, but I'm not sure if they were used directly or indirectly within From
That's not to say that |
This could probably be the same problem I had in #79518. It's just the default values of @Dabnabbit When you can, try to set the In you script (test_collider.gd):
Normally, walls and floors need to have a collision_priority 10 or 100 times higher than other objects. This way you will have space to configure the priority of smaller and faster objects if you want. The faster and small the object's, the lower the priority needs to be. |
Godot version
4.0.beta7
System information
Windows 11, RTX 3070TI, Vulcan
Issue description
[UPDATE 3
After more specifically recreating the minimal reproduction projects to utilize a vertex shader displaced plane mesh, with run-time height-map sampled and generated HeightMapShape3D collision mesh data, it seems that the issue is much more specific to Godot4.0 than Godot Physics itself... I've reuploaded both 3.5 minimal reproduction (which seems to work fine in Bullet and Godot Physics) and the direct translation of that project to 4.0 (where the error occurs); Unfortunately this is a pretty major problem for ANY 3D game that intends to use Godot beyond basic planar/cube collision shapes in small indoor environments.
https://youtu.be/pU8mz7SlkzE
/UPDATE]
[UPDATE 2
I've uploaded a video demonstrating the issue a bit more clearly, although not fully demonstrating just how destructive the effect is, it at least demonstrates some of the incorrect calculations being performed.
https://youtu.be/Kw0ThRnUPDs
/UPDATE]
[UPDATE 1
Update after more research and testing on the issue:
It appears that on top of generating too many collisions between only two objects (player and terrain) almost always hitting the hard-coded maximum collision count of 6, the Normals calculated from collisions also stand to be wildly inaccurate occasionally at collision mesh edges, they are capable of returning perpendicular normal angles (parallel to the terrain surface) which all affect the resultant velocity causing some really... bad motion
/UPDATE]
In Godot 4.0.beta5, beta6, and beta7 (and likely all 4.0) CharecterBody3D collisions utilizing any collision shape (most extensively tested with capsule mesh/collider) is producing undesirable and incorrect physics interactions by triggering too numerous collision events per tic with the same object. This is most exaggerated in the example of large terrain colliders, it would appear that even soft/subtle terrain gradient changes can trigger extremely large numbers of collisions (though gdscript only seems to report a maximum of 6 collisions per move_and_slide()?) that are causing incorrect and undesirable outcomes.
The perceived effect is that the player object is "snagged" and appears to almost snap to vertex and mesh edges along the collider when moving, and can completely negate all velocity while moving across a relatively flat collision mesh, sometimes also causing a sling-shot effect when the player object escapes a snag.
In attempts to trouble-shoot this matter, I discovered that printing/producing the entire list of collisions while the player is moving indicates that any trouble-interactions are indicated by far more collisions with the StaticBody than normal.
In Godot 3.5, the KinematicBody and StaticBody interaction produces typically 1 collision per physics tic, which is the expected result, and occasionally produces 2 collisions when moving up steeper collisions, which is also to be expected and behaves correctly.
(Output of all instances where more than one collision occurs simultaneously per tic; notice the infrequency and collision count never exceeding two (index of 1))
In Godot 4.0.b7, the CharecterBody3D and StaticBody3D interaction produces between 2-6 collisions per physics tic, which is NOT the expected result between only two colliders, and does not appear to report on collision counts past 6 (index 5). This directly seems to affect the move_and_slide() behavior very negatively and incorrectly.
(Output of all instances where more than one collision occurs simultaneously per tic; notice the massive increase in frequency of occurrence, and the number/volume of collisions per tic is 6 (possibly more but not reported?)
I have produced two minimal projects to demonstrate this contrasting issue in 3.5 and 4.0.b7, however due to size of the terrain mesh object, the file-size exceeds GitHub upload limitations, so I'm trying to figure out how to upload/share them... They were produced using the exact same high resolution terrain mesh in GLB format automatically generating a collision mesh through Godot's import process, and the only thing added to the scene other than the terrain is a very basic player controller, utilizing a KinematicBody/CharecterBody3D with a Capsule CollisionShape and Capsule MeshInstance, with a child camera, and very basic identical (other than translation) input controls for movement and utilizing "move_and_slide"...
(Godot 4 snapshot of Terrainmesh+Collider)
(Godot 3.5 snapshot of Terrainmesh+Collider)
Steps to reproduce
Create large size terrain mesh in GLB format, automatically generating a collision mesh through Godot's import process, and add basic player controller, utilizing a KinematicBody/CharecterBody3D with a Capsule CollisionShape and Capsule MeshInstance, with a child camera, and very basic identical (other than translation) input controls for movement and utilizing "move_and_slide"
Minimal reproductio
HeightTest_3_5.zip
n project
HeightTest_3_5_to_4_0.zip
The text was updated successfully, but these errors were encountered: