Skip to content

Conversation

mihe
Copy link
Contributor

@mihe mihe commented Sep 27, 2025

This bumps Jolt Physics from jrouwe/JoltPhysics@0373ec0 (version 5.3.0) to jrouwe/JoltPhysics@036ea7b (version 5.4.0).

Several of the changes in this release have already been backported to our copy, so the release notes aren't going to be entirely applicable, but here they are anyway.

This brings in a few bug fixes that haven't been backported, and in general makes our copy more "proper" I guess, by not relying on backports anymore.

(Leaving this as draft until I've tested it a bit.)

CC @jrouwe.

@jrouwe
Copy link
Contributor

jrouwe commented Sep 27, 2025

That was fast!

@jrouwe
Copy link
Contributor

jrouwe commented Sep 27, 2025

I would say the most relevant changes for godot are:

  • Fixed bug in ConvexHullShape::CollideSoftBodyVertices where the wrong edge could be reported as the closest edge.
  • SoftBodySharedSettings::mVertexRadius was moved to SoftBodyCreationSettings::mVertexRadius

Where the 2nd one makes it possible to complete #106697

@mihe
Copy link
Contributor Author

mihe commented Sep 27, 2025

I was a bit curious about jrouwe/JoltPhysics#1758. Would you say that's something people are likely to run into, or notice at all?

@jrouwe
Copy link
Contributor

jrouwe commented Sep 27, 2025

I was a bit curious about jrouwe/JoltPhysics#1758. Would you say that's something people are likely to run into, or notice at all?

This only makes a difference on bad meshes and most likely doesn't have a huge impact. it won't do anything if enhanced edge detection is on.

@mihe
Copy link
Contributor Author

mihe commented Sep 27, 2025

It looks like the version check in RegisterTypesInternal is not playing nice with Godot's CI build cache, as the Jolt source files in thirdparty/jolt_physics are being recompiled with the new JPH_VERSION_ID but modules/jolt_physics/jolt_globals.cpp is still using the old one, leading to std::abort() being called.

None of the feature bits are causing problems, so I'm assuming it's because JPH_VERSION_MINOR is mixed into JPH_VERSION_ID. The mismatch mask is 0b11100000000, which I guess makes sense if the minor version went from 3 to 4.

There's probably some way of wiping the CI cache, but this will cause issues for anyone compiling with caching enabled downstream as well, so that surely can't be the fix.

EDIT: It turns out you don't need SCons caching enabled. The same thing happens when doing normal incremental builds as well.

I don't really understand how this can happen in the first place, short of SCons doing some sloppy caching, like not running source files through the preprocessor first. There's no way modules/jolt_physics/jolt_globals.cpp should not have been invalidated and recompiled, since it has to include Jolt/Core/Core.h, which has the new version number in it.

I would've thought this would invalidate all the modules/jolt_physics source files either way:

# Needed to force rebuilding the module files when the thirdparty library is updated.
env.Depends(module_obj, thirdparty_obj)

@mihe
Copy link
Contributor Author

mihe commented Sep 27, 2025

the Jolt source files in thirdparty/jolt_physics are being recompiled with the new JPH_VERSION_ID but modules/jolt_physics/jolt_globals.cpp is still using the old one

It seems it's actually the other way around, because Jolt/RegisterTypes.cpp isn't being recompiled for some reason. That's frankly just as weird though.

@mihe
Copy link
Contributor Author

mihe commented Sep 27, 2025

The SCons output with --tree=prune seems to suggest that unlike the files in modules/jolt_physics, the files in thirdparty/jolt_physics don't have any dependencies on any header files, or any files at all for that matter, which I guess explains why Jolt/RegisterTypes.cpp isn't being rebuilt.

This is unlike (for example) the integration of the Manifold library in modules/csg. Its SCSub file is pretty much identical with the Jolt one though, so that doesn't make much sense.

Someone more familiar with SCons probably needs to take a look at this.

@jrouwe
Copy link
Contributor

jrouwe commented Sep 28, 2025

It looks like in modules/jolt_physics/SCsub the following line needs to be changed from:

env_jolt.Prepend(CPPEXTPATH=[thirdparty_dir])

to

env_jolt.Prepend(CPPPATH=[thirdparty_dir])

For me this makes all the dependencies show up when running scons with --tree=prune:

  | | | +-bin\obj\modules\module_jolt_physics.windows.editor.x86_64.lib
  | | | | +-bin\obj\thirdparty\jolt_physics\Jolt\RegisterTypes.windows.editor.x86_64.obj
  | | | | | +-thirdparty\jolt_physics\Jolt\RegisterTypes.cpp
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\Factory.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\RTTI.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\TickCounter.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Jolt.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\CollisionDispatch.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\PhysicsMaterialSimple.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\BoxShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\CapsuleShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\ConvexHullShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\CylinderShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\EmptyShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\HeightFieldShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\MeshShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\MutableCompoundShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\OffsetCenterOfMassShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\PlaneShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\RotatedTranslatedShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\ScaledShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\SphereShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\StaticCompoundShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\TaperedCapsuleShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\TaperedCylinderShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\TriangleShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\SoftBody\SoftBodyShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\RegisterTypes.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\UnorderedMap.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\Reference.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\StaticArray.h
  | | | | | +-thirdparty\jolt_physics\Jolt\ObjectStream\SerializableAttribute.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\ARMNeon.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\Array.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\Core.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\IssueReporting.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\Memory.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Mat44.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Math.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Real.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Vec4.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\NarrowPhaseStats.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\Shape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\SubShapeID.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\ShapeCast.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\ShapeFilter.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\PhysicsMaterial.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\ConvexShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\PhysicsSettings.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Geometry\Plane.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Renderer\DebugRenderer.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\ByteBuffer.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Geometry\IndexedTriangle.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Geometry\Triangle.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\CompoundShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\DecoratedShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\Shape\ScaleHelpers.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\HalfFloat.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\SortReverseAndStore.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\HashTable.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\Atomics.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\HashCombine.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\STLAllocator.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Mat44.inl
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\MathTypes.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\DMat44.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\DVec3.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Vec4.inl
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Float4.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Swizzle.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\Color.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\NonCopyable.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\Result.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\StreamUtils.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\UnorderedSet.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Geometry\AABox.h
  | | | | | +-thirdparty\jolt_physics\Jolt\ObjectStream\SerializableObject.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Body\MassProperties.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\BackFaceMode.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\CollisionCollector.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\CollideShape.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Body\BodyID.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Float2.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\STLAlignedAllocator.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\FPException.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\BVec16.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Quat.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Vec3.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\DMat44.inl
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\DVec3.inl
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Double3.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Trigonometry.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\UVec4.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\StreamIn.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\StreamOut.h
  | | | | | +-thirdparty\jolt_physics\Jolt\ObjectStream\ObjectStream.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\ActiveEdgeMode.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Physics\Collision\CollectFacesMode.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Core\FPControlWord.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\BVec16.inl
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Quat.inl
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Vec3.inl
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\Float3.h
  | | | | | +-thirdparty\jolt_physics\Jolt\Math\UVec4.inl
  | | | | | +-C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.44.35207\bin\HostX64\x64\cl.EXE

However, on my machine it still doesn't rebuild.

@jrouwe
Copy link
Contributor

jrouwe commented Sep 28, 2025

I think I figured it out, I now added both lines:

env_jolt.Prepend(CPPEXTPATH=[thirdparty_dir])
env_jolt.Prepend(CPPPATH=[thirdparty_dir])

The first disables warnings in external headers, the 2nd makes scons search the correct path for dependencies.

The reason why it still isn't working is that I was passing dev_build=yes which has a special check here:

godot/SConstruct

Lines 536 to 538 in b4472f4

if methods.get_cmdline_bool("fast_unsafe", env.dev_build):
env.SetOption("implicit_cache", 1)
env.SetOption("max_drift", 60)

that enables the option implicit_cache. According to this means that any changes to CPPPATH are ignored.

I commented those 3 lines out locally and then it works. This should at least fix all the non dev_build's. I'm not sure what the build cache actually caches. If it only caches output files then we may get lucky, if it also caches scons state then it may still ignore the CPPPATH changes.

@mihe
Copy link
Contributor Author

mihe commented Sep 28, 2025

env_jolt.Prepend(CPPPATH=[thirdparty_dir]) was apparently changed to be env_jolt.Prepend(CPPEXTPATH=[thirdparty_dir]) in #104893.

Maybe @Repiteo or someone else in @godotengine/buildsystem can help us figure out why that seems to mess with SCons tracking of header dependencies in thirdparty/jolt_physics. Perhaps it's related to the nixpkgs issue mentioned in that PR?

@mihe
Copy link
Contributor Author

mihe commented Oct 5, 2025

Just to unblock this I've changed the Jolt SCsub file to use CPPPATH again, instead of CPPEXTPATH, which seems to still be a thing with a few other third-party integrations anyway (pending #108611). I've also added a single whitespace to ‎thirdparty/jolt_physics/Jolt/RegisterTypes.cpp in order to force that file to be compiled, which resolves the std::abort happening in Jolt's version check.

However, this of course does nothing for whatever other unchanged Jolt source files that might possibly need recompiling due to some header dependency having changed. It only addresses the std::abort crash that's preventing the CI tests from passing. Either way, the dangers of fast_unsafe won't be resolved in this PR.

Also, even with this hack, I believe this can still cause problems if the following happens:

  1. Somebody updates Jolt to a newer version by overwriting all the files in thirdparty/jolt_physics, effectively reverting this single whitespace in Jolt/RegisterTypes.cpp, assuming it hasn't changed in some other way by that point.
  2. Somebody then tries to bisect some bug, while having dev_build=yes enabled (and thus fast_unsafe=yes), and ends up jumping between two commits where this whitespace change never happened.

In such a case you will most likely std::abort in Jolt's version check and scratch your head for a while wondering why.

@mihe mihe marked this pull request as ready for review October 5, 2025 18:43
@mihe mihe requested review from a team as code owners October 5, 2025 18:43
@mihe
Copy link
Contributor Author

mihe commented Oct 5, 2025

The projects that I usually smoke test with all seem to behave as expected, so I've taken this out of draft.

@jrouwe
Copy link
Contributor

jrouwe commented Oct 5, 2025

Somebody updates Jolt to a newer version by overwriting all the files in thirdparty/jolt_physics, effectively reverting this single whitespace in Jolt/RegisterTypes.cpp, assuming it hasn't changed in some other way by that point.

I may have found a solution to that problem :)

@akien-mga
Copy link
Member

The CPPEXTPATH change was reverted in #111331 so you should be able to drop the custom changes to Jolt to fix CI.

@mihe
Copy link
Contributor Author

mihe commented Oct 7, 2025

so you should be able to drop the custom changes to Jolt to fix CI

I feel like this shouldn't be the case, since just changing CPPEXTPATH to CPPPATH was not enough previously, as seen above, but for whatever reason every single source file in thirdparty/jolt_physics is being recompiled when going from the parent commit of #111331 to this one.

Maybe some compilation flags changed or something, thus forcing a recompile? In any case, I'm glad to see it working.

@akien-mga
Copy link
Member

Maybe some compilation flags changed or something, thus forcing a recompile? In any case, I'm glad to see it working.

Well yes going from CPPEXTPATH to CPPPATH changes the compilation flags for all thirdparty code to not use -isystem etc.

@Repiteo
Copy link
Contributor

Repiteo commented Oct 7, 2025

Well yes going from CPPEXTPATH to CPPPATH changes the compilation flags for all thirdparty code to not use -isystem etc.

That's not quite true, as there's still a few stragglers that hardcoded that include style. Those cases are handled in #111346

Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally on several demo projects, it works as expected. Code looks good to me.

@Repiteo Repiteo merged commit 651d278 into godotengine:master Oct 7, 2025
20 checks passed
@Repiteo
Copy link
Contributor

Repiteo commented Oct 7, 2025

Thanks!

@mihe mihe deleted the jolt/v5.4.0 branch October 7, 2025 17:06
@mihe
Copy link
Contributor Author

mihe commented Oct 8, 2025

Well, I don't understand how, but we ended up having a report of this version check crash anyway, which was then resolved with a clean build.

Since this will likely keep being a problem when people go to bisect with dev_build=yes, I've put up a PR to cherrypick the recent change to Jolt/RegisterTypes.cpp, just to have some kind of change done to it: #111408

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants