Skip to content

[4.3] Add Jolt Physics as an alternative 3D physics engine #896

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

Open
wants to merge 25 commits into
base: 4.3
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d7ff8ab
Add aligned_static functions to Memory
darksylinc Dec 11, 2024
f41a494
Add Jolt Physics as an alternative 3D physics engine
mihe Dec 11, 2024
52d67c8
Jolt: Fix multiple definition LTO linking issue with mingw-gcc
akien-mga Dec 12, 2024
cb39174
SCons: Properly set SSE2 as baseline on x86_32
akien-mga Dec 12, 2024
daaea71
Make RID allocation thread-safe when using Jolt Physics
mihe Dec 12, 2024
b5c16c0
🐛 enforce bodies damping recomputation on mode switch at runtime
opsocket Dec 18, 2024
e14303e
Jolt: Update to commit f094082aa, adding RISC-V, PPC64 and LoongArch …
akien-mga Dec 21, 2024
d344c66
Improve performance with many static/sleeping bodies when using Jolt …
mihe Dec 30, 2024
53ef9e8
Cache value of Jolt Physics project setting `bounce_velocity_threshold`
mihe Jan 7, 2025
3319e25
Fix debug contact count not being initialized when using Jolt Physics
mihe Jan 7, 2025
10b2da3
Improve performance of changing compound shapes when using Jolt Physics
mihe Jan 6, 2025
088a118
Fix kinematic bodies not synchronizing state when using Jolt Physics
mihe Jan 19, 2025
5e7c8c0
Update Jolt Physics `BoxShape` to allow for zero-sized boxes
mihe Jan 22, 2025
2140b1f
Refactor post-step operations in Jolt module to be done as needed
mihe Jan 19, 2025
a738a47
Override mass properties for `Area3D` when using Jolt Physics
mihe Jan 25, 2025
ac697b6
Fix Jolt note in WorldBoundaryShape3D documentation
Calinou Jan 20, 2025
cffa765
No longer limiting max voided features/delayed results
jrouwe Feb 9, 2025
9c3366a
Skip `Object::to_string` when Jolt Physics is on separate thread
mihe Feb 11, 2025
a346ea0
Improve performance of certain physics queries when using Jolt Physics
mihe Jan 2, 2025
d0689f6
Improve Jolt module initialization style
metakunt Feb 17, 2025
baf46aa
Fix broken negative scaling when using Jolt Physics
mihe Mar 1, 2025
54ebc94
Fix `ConcavePolygonShape3D` always enabling `backface_collision` when…
mihe Mar 18, 2025
901c322
Jolt: Update to 5.3.0
mihe Mar 21, 2025
ed434eb
Fix `shape` always being zero with `get_rest_info` when using Jolt Ph…
mihe Mar 25, 2025
a90a5a5
Refactor Jolt-related project settings to only be loaded as needed
mihe Jan 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 12 additions & 0 deletions COPYRIGHT.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ Copyright: 2011, Ole Kniemeyer, MAXON, www.maxon.net
2007-2014, Juan Linietsky, Ariel Manzur
License: Expat and Zlib

Files: ./modules/jolt_physics/spaces/jolt_temp_allocator.cpp
Comment: Jolt Physics
Copyright: 2021, Jorrit Rouwe
2014-present, Godot Engine contributors
2007-2014, Juan Linietsky, Ariel Manzur
License: Expat

Files: ./modules/lightmapper_rd/lm_compute.glsl
Comment: Joint Non-Local Means (JNLM) denoiser
Copyright: 2020, Manuel Prandini
Expand Down Expand Up @@ -297,6 +304,11 @@ Comment: International Components for Unicode
Copyright: 2016-2024, Unicode, Inc.
License: Unicode

Files: ./thirdparty/jolt_physics/
Comment: Jolt Physics
Copyright: 2021, Jorrit Rouwe
License: Expat

Files: ./thirdparty/jpeg-compressor/
Comment: jpeg-compressor
Copyright: 2012, Rich Geldreich
Expand Down
7 changes: 7 additions & 0 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,13 @@ elif methods.using_clang(env):
print_warning("Clang < 10 doesn't support -ffile-prefix-map, disabling `debug_paths_relative` option.")
env["debug_paths_relative"] = False

# Default architecture flags.
if env["arch"] == "x86_32":
if env.msvc:
env.Append(CCFLAGS=["/arch:SSE2"])
else:
env.Append(CCFLAGS=["-msse2"])

# Set optimize and debug_symbols flags.
# "custom" means do nothing and let users set their own optimization flags.
# Needs to happen after configure to have `env.msvc` defined.
Expand Down
33 changes: 33 additions & 0 deletions core/os/memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void *operator new(size_t p_size, const char *p_description) {
return Memory::alloc_static(p_size, false);
Expand Down Expand Up @@ -67,6 +68,38 @@ SafeNumeric<uint64_t> Memory::max_usage;

SafeNumeric<uint64_t> Memory::alloc_count;

inline bool is_power_of_2(size_t x) { return x && ((x & (x - 1U)) == 0U); }

void *Memory::alloc_aligned_static(size_t p_bytes, size_t p_alignment) {
DEV_ASSERT(is_power_of_2(p_alignment));

void *p1, *p2;
if ((p1 = (void *)malloc(p_bytes + p_alignment - 1 + sizeof(uint32_t))) == nullptr) {
return nullptr;
}

p2 = (void *)(((uintptr_t)p1 + sizeof(uint32_t) + p_alignment - 1) & ~((p_alignment)-1));
*((uint32_t *)p2 - 1) = (uint32_t)((uintptr_t)p2 - (uintptr_t)p1);
return p2;
}

void *Memory::realloc_aligned_static(void *p_memory, size_t p_bytes, size_t p_prev_bytes, size_t p_alignment) {
if (p_memory == nullptr) {
return alloc_aligned_static(p_bytes, p_alignment);
}

void *ret = alloc_aligned_static(p_bytes, p_alignment);
memcpy(ret, p_memory, p_prev_bytes);
free_aligned_static(p_memory);
return ret;
}

void Memory::free_aligned_static(void *p_memory) {
uint32_t offset = *((uint32_t *)p_memory - 1);
void *p = (void *)((uint8_t *)p_memory - offset);
free(p);
}

void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
#ifdef DEBUG_ENABLED
bool prepad = true;
Expand Down
32 changes: 28 additions & 4 deletions core/os/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,30 @@ class Memory {
static void *realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align = false);
static void free_static(void *p_ptr, bool p_pad_align = false);

// ↓ return value of alloc_aligned_static
// ┌─────────────────┬─────────┬─────────┬──────────────────┐
// │ padding (up to │ uint32_t│ void* │ padding (up to │
// │ p_alignment - 1)│ offset │ p_bytes │ p_alignment - 1) │
// └─────────────────┴─────────┴─────────┴──────────────────┘
//
// alloc_aligned_static will allocate p_bytes + p_alignment - 1 + sizeof(uint32_t) and
// then offset the pointer until alignment is satisfied.
//
// This offset is stored before the start of the returned ptr so we can retrieve the original/real
// start of the ptr in order to free it.
//
// The rest is wasted as padding in the beginning and end of the ptr. The sum of padding at
// both start and end of the block must add exactly to p_alignment - 1.
//
// p_alignment MUST be a power of 2.
static void *alloc_aligned_static(size_t p_bytes, size_t p_alignment);
static void *realloc_aligned_static(void *p_memory, size_t p_bytes, size_t p_prev_bytes, size_t p_alignment);
// Pass the ptr returned by alloc_aligned_static to free it.
// e.g.
// void *data = realloc_aligned_static( bytes, 16 );
// free_aligned_static( data );
static void free_aligned_static(void *p_memory);

static uint64_t get_mem_available();
static uint64_t get_mem_usage();
static uint64_t get_mem_max_usage();
Expand Down Expand Up @@ -100,10 +124,10 @@ _ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
return p_obj;
}

#define memnew(m_class) _post_initialize(new ("") m_class)
#define memnew(m_class) _post_initialize(::new ("") m_class)

#define memnew_allocator(m_class, m_allocator) _post_initialize(new (m_allocator::alloc) m_class)
#define memnew_placement(m_placement, m_class) _post_initialize(new (m_placement) m_class)
#define memnew_allocator(m_class, m_allocator) _post_initialize(::new (m_allocator::alloc) m_class)
#define memnew_placement(m_placement, m_class) _post_initialize(::new (m_placement) m_class)

_ALWAYS_INLINE_ bool predelete_handler(void *) {
return true;
Expand Down Expand Up @@ -167,7 +191,7 @@ T *memnew_arr_template(size_t p_elements) {

/* call operator new */
for (size_t i = 0; i < p_elements; i++) {
new (&elems[i]) T;
::new (&elems[i]) T;
}
}

Expand Down
Loading
Loading