jolt-ruby 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.gitmodules +3 -0
  3. data/LICENSE.txt +21 -0
  4. data/README.md +228 -0
  5. data/Rakefile +180 -0
  6. data/examples/character_virtual.rb +35 -0
  7. data/examples/falling_sphere.rb +25 -0
  8. data/examples/stagecraft_binding.rb +29 -0
  9. data/ext/jolt_ruby/CMakeLists.txt +42 -0
  10. data/ext/jolt_ruby/character_helper.cpp +44 -0
  11. data/ext/jolt_ruby/constraint_helper.cpp +154 -0
  12. data/ext/jolt_ruby/extconf.rb +56 -0
  13. data/ext/jolt_ruby/helper.cpp +225 -0
  14. data/ext/jolt_ruby/helper.h +103 -0
  15. data/ext/joltc/.github/FUNDING.yml +1 -0
  16. data/ext/joltc/.github/workflows/build.yml +298 -0
  17. data/ext/joltc/.gitignore +272 -0
  18. data/ext/joltc/CMakeLists.txt +431 -0
  19. data/ext/joltc/LICENSE +21 -0
  20. data/ext/joltc/README.md +10 -0
  21. data/ext/joltc/build/cmake_vs2026_arm64.bat +3 -0
  22. data/ext/joltc/build/cmake_vs2026_clang.bat +10 -0
  23. data/ext/joltc/build/cmake_vs2026_x64.bat +3 -0
  24. data/ext/joltc/build/cmake_vs2026_x64_double.bat +3 -0
  25. data/ext/joltc/include/joltc.h +3166 -0
  26. data/ext/joltc/samples/01_HelloWorld/main.cpp +170 -0
  27. data/ext/joltc/samples/CMakeLists.txt +35 -0
  28. data/ext/joltc/src/joltc.c +4 -0
  29. data/ext/joltc/src/joltc.cpp +11812 -0
  30. data/ext/joltc/src/joltc_assert.cpp +271 -0
  31. data/ext/joltc/tests/CMakeLists.txt +77 -0
  32. data/ext/joltc/tests/test_character.cpp +149 -0
  33. data/ext/joltc/tests/test_collision.cpp +146 -0
  34. data/ext/joltc/tests/test_constraints.cpp +353 -0
  35. data/ext/joltc/tests/test_core.cpp +94 -0
  36. data/ext/joltc/tests/test_math.cpp +585 -0
  37. data/ext/joltc/tests/test_physics_system.cpp +465 -0
  38. data/ext/joltc/tests/test_shapes.cpp +789 -0
  39. data/ext/joltc/tests/test_skeleton.cpp +370 -0
  40. data/ext/joltc/tests/test_vehicle.cpp +319 -0
  41. data/generator/generate.rb +237 -0
  42. data/generator/layout_probe.cpp +489 -0
  43. data/generator/verify_layout.rb +32 -0
  44. data/lib/jolt/body.rb +147 -0
  45. data/lib/jolt/body_collection.rb +115 -0
  46. data/lib/jolt/body_dynamics.rb +93 -0
  47. data/lib/jolt/character_virtual.rb +162 -0
  48. data/lib/jolt/constraint.rb +136 -0
  49. data/lib/jolt/constraint_collection.rb +123 -0
  50. data/lib/jolt/contact_events.rb +19 -0
  51. data/lib/jolt/conversions.rb +76 -0
  52. data/lib/jolt/errors.rb +12 -0
  53. data/lib/jolt/fixed_stepper.rb +37 -0
  54. data/lib/jolt/hit.rb +5 -0
  55. data/lib/jolt/layers.rb +182 -0
  56. data/lib/jolt/native/character_functions.rb +16 -0
  57. data/lib/jolt/native/constraint_functions.rb +27 -0
  58. data/lib/jolt/native/core_functions.rb +17 -0
  59. data/lib/jolt/native/generated.rb +1995 -0
  60. data/lib/jolt/native/platform.rb +51 -0
  61. data/lib/jolt/native/query_functions.rb +43 -0
  62. data/lib/jolt/native/types.rb +28 -0
  63. data/lib/jolt/native.rb +94 -0
  64. data/lib/jolt/shape.rb +90 -0
  65. data/lib/jolt/shape_builders.rb +155 -0
  66. data/lib/jolt/system.rb +238 -0
  67. data/lib/jolt/system_characters.rb +25 -0
  68. data/lib/jolt/system_constraints.rb +36 -0
  69. data/lib/jolt/system_contacts.rb +57 -0
  70. data/lib/jolt/system_queries.rb +111 -0
  71. data/lib/jolt/transform.rb +5 -0
  72. data/lib/jolt/version.rb +5 -0
  73. data/lib/jolt.rb +83 -0
  74. data/script/smoke_gem.rb +29 -0
  75. data/script/verify_release.rb +36 -0
  76. metadata +147 -0
@@ -0,0 +1,271 @@
1
+ // Copyright (c) Amer Koleci and Contributors.
2
+ // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
3
+
4
+ #include "joltc.h"
5
+
6
+ #ifdef _MSC_VER
7
+ __pragma(warning(push, 0))
8
+ #endif
9
+
10
+ #include "Jolt/Jolt.h"
11
+ #include "Jolt/RegisterTypes.h"
12
+ #include "Jolt/Core/Factory.h"
13
+ #include "Jolt/Core/TempAllocator.h"
14
+ #include "Jolt/Core/JobSystemThreadPool.h"
15
+ #include "Jolt/Physics/PhysicsSettings.h"
16
+ #include "Jolt/Physics/PhysicsSystem.h"
17
+ #include "Jolt/Physics/Collision/CollideShape.h"
18
+ #include "Jolt/Physics/Collision/Shape/BoxShape.h"
19
+ #include "Jolt/Physics/Collision/Shape/SphereShape.h"
20
+ #include "Jolt/Physics/Collision/Shape/TriangleShape.h"
21
+ #include "Jolt/Physics/Collision/Shape/CapsuleShape.h"
22
+ #include "Jolt/Physics/Collision/Shape/TaperedCapsuleShape.h"
23
+ #include "Jolt/Physics/Collision/Shape/CylinderShape.h"
24
+ #include "Jolt/Physics/Collision/Shape/ConvexHullShape.h"
25
+ #include "Jolt/Physics/Collision/CastResult.h"
26
+ #include "Jolt/Physics/Body/BodyCreationSettings.h"
27
+ #include "Jolt/Physics/Body/BodyActivationListener.h"
28
+ #include "Jolt/Physics/Body/AllowedDOFs.h"
29
+ #include <Jolt/Physics/SoftBody/SoftBodySharedSettings.h>
30
+ #include <Jolt/Physics/SoftBody/SoftBodyCreationSettings.h>
31
+ #include "Jolt/Physics/Constraints/SixDOFConstraint.h"
32
+ #include "Jolt/Physics/Character/CharacterBase.h"
33
+ #include "Jolt/Physics/Character/CharacterID.h"
34
+ #include "Jolt/Physics/Collision/Shape/MeshShape.h"
35
+ #include "Jolt/Physics/Vehicle/VehicleTransmission.h"
36
+
37
+ #ifdef JPH_DEBUG_RENDERER
38
+ #include <Jolt/Renderer/DebugRendererSimple.h>
39
+ #endif // JPH_DEBUG_RENDERER
40
+
41
+ #ifdef _MSC_VER
42
+ __pragma(warning(pop))
43
+ #endif
44
+
45
+ #define ENSURE_SIZE_ALIGN(type0, type1) \
46
+ static_assert(sizeof(type0) == sizeof(type1)); \
47
+ static_assert(alignof(type0) == alignof(type1))
48
+
49
+ // Ensure that we use 32-bit object layers
50
+ static_assert(sizeof(JPH::ObjectLayer) == 4);
51
+
52
+ static_assert(sizeof(JPH::ObjectLayer) == sizeof(JPH_ObjectLayer));
53
+ static_assert(sizeof(JPH::BroadPhaseLayer) == sizeof(JPH_BroadPhaseLayer));
54
+ static_assert(sizeof(JPH::BodyID) == sizeof(JPH_BodyID));
55
+ static_assert(sizeof(JPH::SubShapeID) == sizeof(JPH_SubShapeID));
56
+ static_assert(sizeof(JPH::CharacterID) == sizeof(JPH_CharacterID));
57
+ static_assert(sizeof(JPH::CollisionGroup::GroupID) == sizeof(JPH_CollisionGroupID));
58
+ static_assert(sizeof(JPH::CollisionGroup::SubGroupID) == sizeof(JPH_CollisionSubGroupID));
59
+
60
+ static_assert(JPH_INVALID_COLLISION_GROUP_ID == (int)JPH::CollisionGroup::cInvalidGroup);
61
+ static_assert(JPH_INVALID_COLLISION_SUBGROUP_ID == (int)JPH::CollisionGroup::cInvalidSubGroup);
62
+
63
+ static_assert(sizeof(JPH::Mat44) == sizeof(JPH_Mat4));
64
+
65
+ // EPhysicsUpdateError
66
+ static_assert(sizeof(JPH_PhysicsUpdateError) == sizeof(JPH::EPhysicsUpdateError));
67
+ static_assert(JPH_PhysicsUpdateError_None == (int)JPH::EPhysicsUpdateError::None);
68
+ static_assert(JPH_PhysicsUpdateError_ManifoldCacheFull == (int)JPH::EPhysicsUpdateError::ManifoldCacheFull);
69
+ static_assert(JPH_PhysicsUpdateError_BodyPairCacheFull == (int)JPH::EPhysicsUpdateError::BodyPairCacheFull);
70
+ static_assert(JPH_PhysicsUpdateError_ContactConstraintsFull == (int)JPH::EPhysicsUpdateError::ContactConstraintsFull);
71
+
72
+ // EBodyType
73
+ static_assert(JPH_BodyType_Rigid == (int)JPH::EBodyType::RigidBody);
74
+ static_assert(JPH_BodyType_Soft == (int)JPH::EBodyType::SoftBody);
75
+
76
+ // EMotionType
77
+ static_assert(JPH_MotionType_Static == (int)JPH::EMotionType::Static);
78
+ static_assert(JPH_MotionType_Kinematic == (int)JPH::EMotionType::Kinematic);
79
+ static_assert(JPH_MotionType_Dynamic == (int)JPH::EMotionType::Dynamic);
80
+
81
+ // EActivation
82
+ static_assert(sizeof(JPH::EActivation) == sizeof(JPH_Activation));
83
+ static_assert(JPH_Activation_Activate == (int)JPH::EActivation::Activate);
84
+ static_assert(JPH_Activation_DontActivate == (int)JPH::EActivation::DontActivate);
85
+
86
+ // EActivation
87
+ static_assert(sizeof(JPH::ValidateResult) == sizeof(JPH_ValidateResult));
88
+ static_assert(JPH_ValidateResult_AcceptAllContactsForThisBodyPair == (int)JPH::ValidateResult::AcceptAllContactsForThisBodyPair);
89
+ static_assert(JPH_ValidateResult_AcceptContact == (int)JPH::ValidateResult::AcceptContact);
90
+ static_assert(JPH_ValidateResult_RejectContact == (int)JPH::ValidateResult::RejectContact);
91
+ static_assert(JPH_ValidateResult_RejectAllContactsForThisBodyPair == (int)JPH::ValidateResult::RejectAllContactsForThisBodyPair);
92
+
93
+ // EShapeType
94
+ static_assert(JPH_ShapeType_Convex == (int)JPH::EShapeType::Convex);
95
+ static_assert(JPH_ShapeType_Compound == (int)JPH::EShapeType::Compound);
96
+ static_assert(JPH_ShapeType_Decorated == (int)JPH::EShapeType::Decorated);
97
+ static_assert(JPH_ShapeType_Mesh == (int)JPH::EShapeType::Mesh);
98
+ static_assert(JPH_ShapeType_HeightField == (int)JPH::EShapeType::HeightField);
99
+ static_assert(JPH_ShapeType_SoftBody == (int)JPH::EShapeType::SoftBody);
100
+ static_assert(JPH_ShapeType_User1 == (int)JPH::EShapeType::User1);
101
+ static_assert(JPH_ShapeType_User2 == (int)JPH::EShapeType::User2);
102
+ static_assert(JPH_ShapeType_User3 == (int)JPH::EShapeType::User3);
103
+ static_assert(JPH_ShapeType_User4 == (int)JPH::EShapeType::User4);
104
+
105
+ // EShapeSubType
106
+ static_assert(JPH_ShapeSubType_Sphere == (int)JPH::EShapeSubType::Sphere);
107
+ static_assert(JPH_ShapeSubType_Box == (int)JPH::EShapeSubType::Box);
108
+ static_assert(JPH_ShapeSubType_Triangle == (int)JPH::EShapeSubType::Triangle);
109
+ static_assert(JPH_ShapeSubType_Capsule == (int)JPH::EShapeSubType::Capsule);
110
+ static_assert(JPH_ShapeSubType_TaperedCapsule == (int)JPH::EShapeSubType::TaperedCapsule);
111
+ static_assert(JPH_ShapeSubType_Cylinder == (int)JPH::EShapeSubType::Cylinder);
112
+ static_assert(JPH_ShapeSubType_ConvexHull == (int)JPH::EShapeSubType::ConvexHull);
113
+ static_assert(JPH_ShapeSubType_StaticCompound == (int)JPH::EShapeSubType::StaticCompound);
114
+ static_assert(JPH_ShapeSubType_MutableCompound == (int)JPH::EShapeSubType::MutableCompound);
115
+ static_assert(JPH_ShapeSubType_RotatedTranslated == (int)JPH::EShapeSubType::RotatedTranslated);
116
+ static_assert(JPH_ShapeSubType_Scaled == (int)JPH::EShapeSubType::Scaled);
117
+ static_assert(JPH_ShapeSubType_OffsetCenterOfMass == (int)JPH::EShapeSubType::OffsetCenterOfMass);
118
+ static_assert(JPH_ShapeSubType_Mesh == (int)JPH::EShapeSubType::Mesh);
119
+ static_assert(JPH_ShapeSubType_HeightField == (int)JPH::EShapeSubType::HeightField);
120
+ static_assert(JPH_ShapeSubType_SoftBody == (int)JPH::EShapeSubType::SoftBody);
121
+
122
+ // EConstraintType
123
+ static_assert(JPH_ConstraintType_Constraint == (int)JPH::EConstraintType::Constraint);
124
+ static_assert(JPH_ConstraintType_TwoBodyConstraint == (int)JPH::EConstraintType::TwoBodyConstraint);
125
+
126
+ // EConstraintSubType
127
+ static_assert(JPH_ConstraintSubType_Fixed == (int)JPH::EConstraintSubType::Fixed);
128
+ static_assert(JPH_ConstraintSubType_Point == (int)JPH::EConstraintSubType::Point);
129
+ static_assert(JPH_ConstraintSubType_Hinge == (int)JPH::EConstraintSubType::Hinge);
130
+ static_assert(JPH_ConstraintSubType_Slider == (int)JPH::EConstraintSubType::Slider);
131
+ static_assert(JPH_ConstraintSubType_Distance == (int)JPH::EConstraintSubType::Distance);
132
+ static_assert(JPH_ConstraintSubType_Cone == (int)JPH::EConstraintSubType::Cone);
133
+ static_assert(JPH_ConstraintSubType_SwingTwist == (int)JPH::EConstraintSubType::SwingTwist);
134
+ static_assert(JPH_ConstraintSubType_SixDOF == (int)JPH::EConstraintSubType::SixDOF);
135
+ static_assert(JPH_ConstraintSubType_Path == (int)JPH::EConstraintSubType::Path);
136
+ static_assert(JPH_ConstraintSubType_Vehicle == (int)JPH::EConstraintSubType::Vehicle);
137
+ static_assert(JPH_ConstraintSubType_RackAndPinion == (int)JPH::EConstraintSubType::RackAndPinion);
138
+ static_assert(JPH_ConstraintSubType_Gear == (int)JPH::EConstraintSubType::Gear);
139
+ static_assert(JPH_ConstraintSubType_Pulley == (int)JPH::EConstraintSubType::Pulley);
140
+
141
+ static_assert(JPH_ConstraintSubType_User1 == (int)JPH::EConstraintSubType::User1);
142
+ static_assert(JPH_ConstraintSubType_User2 == (int)JPH::EConstraintSubType::User2);
143
+ static_assert(JPH_ConstraintSubType_User3 == (int)JPH::EConstraintSubType::User3);
144
+ static_assert(JPH_ConstraintSubType_User4 == (int)JPH::EConstraintSubType::User4);
145
+
146
+ // EActivation
147
+ static_assert(sizeof(JPH::EConstraintSpace) == sizeof(JPH_ConstraintSpace));
148
+ static_assert(JPH_ConstraintSpace_LocalToBodyCOM == (int)JPH::EConstraintSpace::LocalToBodyCOM);
149
+ static_assert(JPH_ConstraintSpace_WorldSpace == (int)JPH::EConstraintSpace::WorldSpace);
150
+
151
+ // EMotionQuality
152
+ static_assert(JPH_MotionQuality_Discrete == (int)JPH::EMotionQuality::Discrete);
153
+ static_assert(JPH_MotionQuality_LinearCast == (int)JPH::EMotionQuality::LinearCast);
154
+
155
+ // EOverrideMassProperties
156
+ static_assert(sizeof(JPH_OverrideMassProperties) == sizeof(uint32_t));
157
+ static_assert(sizeof(JPH::EOverrideMassProperties) == sizeof(uint8_t));
158
+ static_assert(JPH_OverrideMassProperties_CalculateMassAndInertia == (int)JPH::EOverrideMassProperties::CalculateMassAndInertia);
159
+ static_assert(JPH_OverrideMassProperties_CalculateInertia == (int)JPH::EOverrideMassProperties::CalculateInertia);
160
+ static_assert(JPH_OverrideMassProperties_MassAndInertiaProvided == (int)JPH::EOverrideMassProperties::MassAndInertiaProvided);
161
+
162
+ // EAllowedDOFs
163
+ static_assert(sizeof(JPH_AllowedDOFs) == sizeof(uint32_t));
164
+ static_assert(JPH_AllowedDOFs_All == (int)JPH::EAllowedDOFs::All);
165
+ static_assert(JPH_AllowedDOFs_TranslationX == (int)JPH::EAllowedDOFs::TranslationX);
166
+ static_assert(JPH_AllowedDOFs_TranslationY == (int)JPH::EAllowedDOFs::TranslationY);
167
+ static_assert(JPH_AllowedDOFs_TranslationZ == (int)JPH::EAllowedDOFs::TranslationZ);
168
+ static_assert(JPH_AllowedDOFs_RotationX == (int)JPH::EAllowedDOFs::RotationX);
169
+ static_assert(JPH_AllowedDOFs_RotationY == (int)JPH::EAllowedDOFs::RotationY);
170
+ static_assert(JPH_AllowedDOFs_RotationZ == (int)JPH::EAllowedDOFs::RotationZ);
171
+ static_assert(JPH_AllowedDOFs_Plane2D == (int)JPH::EAllowedDOFs::Plane2D);
172
+
173
+ // JPH_MotorState
174
+ static_assert(sizeof(JPH_MotorState) == sizeof(uint32_t));
175
+ static_assert(JPH_MotorState_Off == (int)JPH::EMotorState::Off);
176
+ static_assert(JPH_MotorState_Velocity == (int)JPH::EMotorState::Velocity);
177
+ static_assert(JPH_MotorState_Position == (int)JPH::EMotorState::Position);
178
+
179
+ // JPH_SwingType
180
+ static_assert(sizeof(JPH_SwingType) == sizeof(uint32_t));
181
+ static_assert(JPH_SwingType_Cone == (int)JPH::ESwingType::Cone);
182
+ static_assert(JPH_SwingType_Pyramid == (int)JPH::ESwingType::Pyramid);
183
+
184
+ // JPH_SixDOFConstraintAxis
185
+ static_assert(sizeof(JPH_SixDOFConstraintAxis) == sizeof(uint32_t));
186
+ static_assert(JPH_SixDOFConstraintAxis_TranslationX == (int)JPH::SixDOFConstraintSettings::EAxis::TranslationX);
187
+ static_assert(JPH_SixDOFConstraintAxis_TranslationY == (int)JPH::SixDOFConstraintSettings::EAxis::TranslationY);
188
+ static_assert(JPH_SixDOFConstraintAxis_TranslationZ == (int)JPH::SixDOFConstraintSettings::EAxis::TranslationZ);
189
+ static_assert(JPH_SixDOFConstraintAxis_RotationX == (int)JPH::SixDOFConstraintSettings::EAxis::RotationX);
190
+ static_assert(JPH_SixDOFConstraintAxis_RotationY == (int)JPH::SixDOFConstraintSettings::EAxis::RotationY);
191
+ static_assert(JPH_SixDOFConstraintAxis_RotationZ == (int)JPH::SixDOFConstraintSettings::EAxis::RotationZ);
192
+
193
+ // JPH_SpringMode
194
+ static_assert(sizeof(JPH_SpringMode) == sizeof(uint32_t));
195
+ static_assert(JPH_SpringMode_FrequencyAndDamping == (int)JPH::ESpringMode::FrequencyAndDamping);
196
+ static_assert(JPH_SpringMode_StiffnessAndDamping == (int)JPH::ESpringMode::StiffnessAndDamping);
197
+
198
+ // EGroundState
199
+ static_assert(sizeof(JPH::CharacterBase::EGroundState) == sizeof(JPH_GroundState));
200
+ static_assert(JPH_GroundState_OnGround == (int)JPH::CharacterBase::EGroundState::OnGround);
201
+ static_assert(JPH_GroundState_OnSteepGround == (int)JPH::CharacterBase::EGroundState::OnSteepGround);
202
+ static_assert(JPH_GroundState_NotSupported == (int)JPH::CharacterBase::EGroundState::NotSupported);
203
+ static_assert(JPH_GroundState_InAir == (int)JPH::CharacterBase::EGroundState::InAir);
204
+
205
+ // EBackFaceMode
206
+ static_assert(JPH_BackFaceMode_IgnoreBackFaces == (int)JPH::EBackFaceMode::IgnoreBackFaces);
207
+ static_assert(JPH_BackFaceMode_CollideWithBackFaces == (int)JPH::EBackFaceMode::CollideWithBackFaces);
208
+
209
+ // EActiveEdgeMode
210
+ static_assert(JPH_ActiveEdgeMode_CollideOnlyWithActive == (int)JPH::EActiveEdgeMode::CollideOnlyWithActive);
211
+ static_assert(JPH_ActiveEdgeMode_CollideWithAll == (int)JPH::EActiveEdgeMode::CollideWithAll);
212
+
213
+ // ECollectFacesMode
214
+ static_assert(JPH_CollectFacesMode_CollectFaces == (int)JPH::ECollectFacesMode::CollectFaces);
215
+ static_assert(JPH_CollectFacesMode_NoFaces == (int)JPH::ECollectFacesMode::NoFaces);
216
+
217
+ static_assert(sizeof(JPH::SubShapeIDPair) == sizeof(JPH_SubShapeIDPair));
218
+ static_assert(alignof(JPH::SubShapeIDPair) == alignof(JPH_SubShapeIDPair));
219
+
220
+ // EBendType
221
+ static_assert((int)JPH_SoftBodyBendType_None == (int)JPH::SoftBodySharedSettings::EBendType::None);
222
+ static_assert((int)JPH_SoftBodyBendType_Distance == (int)JPH::SoftBodySharedSettings::EBendType::Distance);
223
+ static_assert((int)JPH_SoftBodyBendType_Dihedral == (int)JPH::SoftBodySharedSettings::EBendType::Dihedral);
224
+
225
+
226
+ #if defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__)
227
+ // 64-bit Platform Sizes
228
+ static_assert(
229
+ sizeof(JPH::BodyCreationSettings) == 288 ||
230
+ sizeof(JPH::BodyCreationSettings) == 256
231
+ );
232
+ static_assert(
233
+ sizeof(JPH::SoftBodyCreationSettings) == 160 ||
234
+ sizeof(JPH::SoftBodyCreationSettings) == 144 ||
235
+ sizeof(JPH::SoftBodyCreationSettings) == 128
236
+ );
237
+ #endif
238
+
239
+ #ifdef JPH_DEBUG_RENDERER
240
+
241
+ // ESoftBodyConstraintColor
242
+ static_assert(JPH_SoftBodyConstraintColor_ConstraintType == (int)JPH::ESoftBodyConstraintColor::ConstraintType);
243
+ static_assert(JPH_SoftBodyConstraintColor_ConstraintGroup == (int)JPH::ESoftBodyConstraintColor::ConstraintGroup);
244
+ static_assert(JPH_SoftBodyConstraintColor_ConstraintOrder == (int)JPH::ESoftBodyConstraintColor::ConstraintOrder);
245
+
246
+ // BodyManager::EShapeColor
247
+ static_assert(JPH_BodyManager_ShapeColor_InstanceColor == (int)JPH::BodyManager::EShapeColor::InstanceColor);
248
+ static_assert(JPH_BodyManager_ShapeColor_ShapeTypeColor == (int)JPH::BodyManager::EShapeColor::ShapeTypeColor);
249
+ static_assert(JPH_BodyManager_ShapeColor_MotionTypeColor == (int)JPH::BodyManager::EShapeColor::MotionTypeColor);
250
+ static_assert(JPH_BodyManager_ShapeColor_SleepColor == (int)JPH::BodyManager::EShapeColor::SleepColor);
251
+ static_assert(JPH_BodyManager_ShapeColor_IslandColor == (int)JPH::BodyManager::EShapeColor::IslandColor);
252
+ static_assert(JPH_BodyManager_ShapeColor_MaterialColor == (int)JPH::BodyManager::EShapeColor::MaterialColor);
253
+
254
+ // DebugRenderer::ECastShadow
255
+ static_assert(JPH_DebugRenderer_CastShadow_On == (int)JPH::DebugRenderer::ECastShadow::On);
256
+ static_assert(JPH_DebugRenderer_CastShadow_Off == (int)JPH::DebugRenderer::ECastShadow::Off);
257
+
258
+ // DebugRenderer::EDrawMode
259
+ static_assert(JPH_DebugRenderer_DrawMode_Solid == (int)JPH::DebugRenderer::EDrawMode::Solid);
260
+ static_assert(JPH_DebugRenderer_DrawMode_Wireframe == (int)JPH::DebugRenderer::EDrawMode::Wireframe);
261
+
262
+ // MeshShapeSettings::EBuildQuality
263
+ static_assert(JPH_Mesh_Shape_BuildQuality_FavorRuntimePerformance == (int)JPH::MeshShapeSettings::EBuildQuality::FavorRuntimePerformance);
264
+ static_assert(JPH_Mesh_Shape_BuildQuality_FavorBuildSpeed == (int)JPH::MeshShapeSettings::EBuildQuality::FavorBuildSpeed);
265
+
266
+ // MeshShapeSettings::EBuildQuality
267
+ static_assert(JPH_TransmissionMode_Auto == (int)JPH::ETransmissionMode::Auto);
268
+ static_assert(JPH_TransmissionMode_Manual == (int)JPH::ETransmissionMode::Manual);
269
+
270
+
271
+ #endif
@@ -0,0 +1,77 @@
1
+ # Tests CMakeLists.txt
2
+
3
+ include(FetchContent)
4
+
5
+ # Fetch GoogleTest
6
+ FetchContent_Declare(
7
+ googletest
8
+ GIT_REPOSITORY https://github.com/google/googletest.git
9
+ GIT_TAG v1.14.0
10
+ )
11
+
12
+ # For Windows: Prevent overriding the parent project's compiler/linker settings
13
+ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
14
+ FetchContent_MakeAvailable(googletest)
15
+
16
+ # Enable testing
17
+ enable_testing()
18
+
19
+ # Collect all test source files
20
+ set(TEST_SOURCES
21
+ test_math.cpp
22
+ test_core.cpp
23
+ test_shapes.cpp
24
+ test_physics_system.cpp
25
+ test_collision.cpp
26
+ test_constraints.cpp
27
+ test_character.cpp
28
+ test_vehicle.cpp
29
+ test_skeleton.cpp
30
+ )
31
+
32
+ # Create test executable
33
+ add_executable(joltc_tests ${TEST_SOURCES})
34
+
35
+ # Ensure console subsystem on Windows (required for gtest_main)
36
+ if(MSVC)
37
+ target_link_options(joltc_tests PRIVATE /SUBSYSTEM:CONSOLE)
38
+ endif()
39
+
40
+ target_link_libraries(joltc_tests
41
+ PRIVATE
42
+ ${TARGET_NAME}
43
+ GTest::gtest
44
+ GTest::gtest_main
45
+ )
46
+
47
+ target_include_directories(joltc_tests
48
+ PRIVATE
49
+ ${CMAKE_SOURCE_DIR}/include
50
+ )
51
+
52
+ set_property(TARGET gmock PROPERTY FOLDER "tests")
53
+ set_property(TARGET gmock_main PROPERTY FOLDER "tests")
54
+ set_property(TARGET gtest PROPERTY FOLDER "tests")
55
+ set_property(TARGET gtest_main PROPERTY FOLDER "tests")
56
+ set_property(TARGET joltc_tests PROPERTY FOLDER "tests")
57
+
58
+ # Add tests to CTest (skip discovery for cross-compilation or when target arch differs from host)
59
+ include(GoogleTest)
60
+
61
+ # Detect cross-compilation scenarios where test discovery won't work
62
+ set(SKIP_TEST_DISCOVERY FALSE)
63
+ if(CMAKE_CROSSCOMPILING)
64
+ set(SKIP_TEST_DISCOVERY TRUE)
65
+ elseif(MSVC AND CMAKE_GENERATOR_PLATFORM)
66
+ # Visual Studio: check if target platform differs from host
67
+ if(CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64" OR CMAKE_GENERATOR_PLATFORM STREQUAL "ARM")
68
+ set(SKIP_TEST_DISCOVERY TRUE)
69
+ endif()
70
+ endif()
71
+
72
+ if(SKIP_TEST_DISCOVERY)
73
+ # For cross-compilation, just add the test executable without discovery
74
+ add_test(NAME joltc_tests COMMAND joltc_tests)
75
+ else()
76
+ gtest_discover_tests(joltc_tests)
77
+ endif()
@@ -0,0 +1,149 @@
1
+ // Copyright (c) Amer Koleci and Contributors.
2
+ // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
3
+
4
+ #include <gtest/gtest.h>
5
+ #include "joltc.h"
6
+
7
+ namespace BroadPhaseLayers {
8
+ static constexpr JPH_BroadPhaseLayer NON_MOVING = 0;
9
+ static constexpr JPH_BroadPhaseLayer MOVING = 1;
10
+ static constexpr uint32_t NUM_LAYERS = 2;
11
+ }
12
+
13
+ namespace ObjectLayers {
14
+ static constexpr JPH_ObjectLayer NON_MOVING = 0;
15
+ static constexpr JPH_ObjectLayer MOVING = 1;
16
+ static constexpr uint32_t NUM_LAYERS = 2;
17
+ }
18
+
19
+ class CharacterTest : public ::testing::Test {
20
+ protected:
21
+ JPH_PhysicsSystem* physicsSystem = nullptr;
22
+ JPH_BroadPhaseLayerInterface* bpLayer = nullptr;
23
+ JPH_ObjectLayerPairFilter* objPairFilter = nullptr;
24
+ JPH_ObjectVsBroadPhaseLayerFilter* objVsBpFilter = nullptr;
25
+
26
+ void SetUp() override {
27
+ ASSERT_TRUE(JPH_Init());
28
+
29
+ bpLayer = JPH_BroadPhaseLayerInterfaceTable_Create(ObjectLayers::NUM_LAYERS, BroadPhaseLayers::NUM_LAYERS);
30
+ JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(bpLayer, ObjectLayers::NON_MOVING, BroadPhaseLayers::NON_MOVING);
31
+ JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(bpLayer, ObjectLayers::MOVING, BroadPhaseLayers::MOVING);
32
+
33
+ objPairFilter = JPH_ObjectLayerPairFilterTable_Create(ObjectLayers::NUM_LAYERS);
34
+ JPH_ObjectLayerPairFilterTable_EnableCollision(objPairFilter, ObjectLayers::NON_MOVING, ObjectLayers::MOVING);
35
+ JPH_ObjectLayerPairFilterTable_EnableCollision(objPairFilter, ObjectLayers::MOVING, ObjectLayers::MOVING);
36
+
37
+ objVsBpFilter = JPH_ObjectVsBroadPhaseLayerFilterTable_Create(
38
+ bpLayer, BroadPhaseLayers::NUM_LAYERS,
39
+ objPairFilter, ObjectLayers::NUM_LAYERS);
40
+
41
+ JPH_PhysicsSystemSettings settings = {};
42
+ settings.maxBodies = 1024;
43
+ settings.maxBodyPairs = 1024;
44
+ settings.maxContactConstraints = 1024;
45
+ settings.broadPhaseLayerInterface = bpLayer;
46
+ settings.objectVsBroadPhaseLayerFilter = objVsBpFilter;
47
+ settings.objectLayerPairFilter = objPairFilter;
48
+
49
+ physicsSystem = JPH_PhysicsSystem_Create(&settings);
50
+ }
51
+
52
+ void TearDown() override {
53
+ if (physicsSystem) JPH_PhysicsSystem_Destroy(physicsSystem);
54
+ JPH_Shutdown();
55
+ }
56
+ };
57
+
58
+ TEST_F(CharacterTest, CharacterSettings_Init) {
59
+ JPH_CharacterSettings settings;
60
+ JPH_CharacterSettings_Init(&settings);
61
+ EXPECT_NE(settings.base.up.y, 0.0f);
62
+ }
63
+
64
+ TEST_F(CharacterTest, Character_Create) {
65
+ JPH_CapsuleShape* shape = JPH_CapsuleShape_Create(0.5f, 0.3f);
66
+ ASSERT_NE(shape, nullptr);
67
+
68
+ JPH_CharacterSettings settings;
69
+ JPH_CharacterSettings_Init(&settings);
70
+ settings.base.shape = (JPH_Shape*)shape;
71
+
72
+ JPH_RVec3 position = {0.0f, 1.0f, 0.0f};
73
+ JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
74
+
75
+ JPH_Character* character = JPH_Character_Create(&settings, &position, &rotation, 0, physicsSystem);
76
+ ASSERT_NE(character, nullptr);
77
+
78
+ JPH_Character_AddToPhysicsSystem(character, JPH_Activation_Activate, true);
79
+
80
+ JPH_BodyID bodyId = JPH_Character_GetBodyID(character);
81
+ EXPECT_NE(bodyId, 0xFFFFFFFF);
82
+
83
+ JPH_Character_RemoveFromPhysicsSystem(character, true);
84
+ JPH_CharacterBase_Destroy((JPH_CharacterBase*)character);
85
+ JPH_Shape_Destroy((JPH_Shape*)shape);
86
+ }
87
+
88
+ TEST_F(CharacterTest, Character_PositionAndRotation) {
89
+ JPH_CapsuleShape* shape = JPH_CapsuleShape_Create(0.5f, 0.3f);
90
+ JPH_CharacterSettings settings;
91
+ JPH_CharacterSettings_Init(&settings);
92
+ settings.base.shape = (JPH_Shape*)shape;
93
+
94
+ JPH_RVec3 position = {1.0f, 2.0f, 3.0f};
95
+ JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
96
+
97
+ JPH_Character* character = JPH_Character_Create(&settings, &position, &rotation, 0, physicsSystem);
98
+ JPH_Character_AddToPhysicsSystem(character, JPH_Activation_Activate, true);
99
+
100
+ JPH_RVec3 resultPos;
101
+ JPH_Character_GetPosition(character, &resultPos, true);
102
+ EXPECT_FLOAT_EQ(resultPos.x, 1.0f);
103
+ EXPECT_FLOAT_EQ(resultPos.y, 2.0f);
104
+ EXPECT_FLOAT_EQ(resultPos.z, 3.0f);
105
+
106
+ JPH_RVec3 newPos = {5.0f, 6.0f, 7.0f};
107
+ JPH_Character_SetPosition(character, &newPos, JPH_Activation_Activate, true);
108
+ JPH_Character_GetPosition(character, &resultPos, true);
109
+ EXPECT_FLOAT_EQ(resultPos.x, 5.0f);
110
+ EXPECT_FLOAT_EQ(resultPos.y, 6.0f);
111
+ EXPECT_FLOAT_EQ(resultPos.z, 7.0f);
112
+
113
+ JPH_Character_RemoveFromPhysicsSystem(character, true);
114
+ JPH_CharacterBase_Destroy((JPH_CharacterBase*)character);
115
+ JPH_Shape_Destroy((JPH_Shape*)shape);
116
+ }
117
+
118
+ TEST_F(CharacterTest, Character_Velocity) {
119
+ JPH_CapsuleShape* shape = JPH_CapsuleShape_Create(0.5f, 0.3f);
120
+ JPH_CharacterSettings settings;
121
+ JPH_CharacterSettings_Init(&settings);
122
+ settings.base.shape = (JPH_Shape*)shape;
123
+
124
+ JPH_RVec3 position = {0.0f, 1.0f, 0.0f};
125
+ JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
126
+
127
+ JPH_Character* character = JPH_Character_Create(&settings, &position, &rotation, 0, physicsSystem);
128
+ JPH_Character_AddToPhysicsSystem(character, JPH_Activation_Activate, true);
129
+
130
+ JPH_Vec3 velocity = {1.0f, 0.0f, 0.0f};
131
+ JPH_Character_SetLinearVelocity(character, &velocity, true);
132
+
133
+ JPH_Vec3 resultVel;
134
+ JPH_Character_GetLinearVelocity(character, &resultVel);
135
+ EXPECT_FLOAT_EQ(resultVel.x, 1.0f);
136
+
137
+ JPH_Character_RemoveFromPhysicsSystem(character, true);
138
+ JPH_CharacterBase_Destroy((JPH_CharacterBase*)character);
139
+ JPH_Shape_Destroy((JPH_Shape*)shape);
140
+ }
141
+
142
+ TEST_F(CharacterTest, CharacterVirtualSettings_Init) {
143
+ JPH_CharacterVirtualSettings settings;
144
+ JPH_CharacterVirtualSettings_Init(&settings);
145
+ EXPECT_GT(settings.mass, 0.0f);
146
+ }
147
+
148
+ // Note: CharacterVirtual tests are disabled due to crashes in JPH_CharacterVirtual_Create
149
+ // This appears to be a bug in the joltc library that needs investigation
@@ -0,0 +1,146 @@
1
+ // Copyright (c) Amer Koleci and Contributors.
2
+ // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
3
+
4
+ #include <gtest/gtest.h>
5
+ #include "joltc.h"
6
+
7
+ namespace BroadPhaseLayers {
8
+ static constexpr JPH_BroadPhaseLayer NON_MOVING = 0;
9
+ static constexpr JPH_BroadPhaseLayer MOVING = 1;
10
+ static constexpr uint32_t NUM_LAYERS = 2;
11
+ }
12
+
13
+ namespace ObjectLayers {
14
+ static constexpr JPH_ObjectLayer NON_MOVING = 0;
15
+ static constexpr JPH_ObjectLayer MOVING = 1;
16
+ static constexpr uint32_t NUM_LAYERS = 2;
17
+ }
18
+
19
+ class CollisionTest : public ::testing::Test {
20
+ protected:
21
+ JPH_PhysicsSystem* physicsSystem = nullptr;
22
+ JPH_BodyInterface* bodyInterface = nullptr;
23
+ JPH_BroadPhaseLayerInterface* bpLayer = nullptr;
24
+ JPH_ObjectLayerPairFilter* objPairFilter = nullptr;
25
+ JPH_ObjectVsBroadPhaseLayerFilter* objVsBpFilter = nullptr;
26
+
27
+ void SetUp() override {
28
+ ASSERT_TRUE(JPH_Init());
29
+
30
+ bpLayer = JPH_BroadPhaseLayerInterfaceTable_Create(ObjectLayers::NUM_LAYERS, BroadPhaseLayers::NUM_LAYERS);
31
+ JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(bpLayer, ObjectLayers::NON_MOVING, BroadPhaseLayers::NON_MOVING);
32
+ JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(bpLayer, ObjectLayers::MOVING, BroadPhaseLayers::MOVING);
33
+
34
+ objPairFilter = JPH_ObjectLayerPairFilterTable_Create(ObjectLayers::NUM_LAYERS);
35
+ JPH_ObjectLayerPairFilterTable_EnableCollision(objPairFilter, ObjectLayers::NON_MOVING, ObjectLayers::MOVING);
36
+ JPH_ObjectLayerPairFilterTable_EnableCollision(objPairFilter, ObjectLayers::MOVING, ObjectLayers::MOVING);
37
+
38
+ objVsBpFilter = JPH_ObjectVsBroadPhaseLayerFilterTable_Create(
39
+ bpLayer, BroadPhaseLayers::NUM_LAYERS,
40
+ objPairFilter, ObjectLayers::NUM_LAYERS);
41
+
42
+ JPH_PhysicsSystemSettings settings = {};
43
+ settings.maxBodies = 1024;
44
+ settings.maxBodyPairs = 1024;
45
+ settings.maxContactConstraints = 1024;
46
+ settings.broadPhaseLayerInterface = bpLayer;
47
+ settings.objectVsBroadPhaseLayerFilter = objVsBpFilter;
48
+ settings.objectLayerPairFilter = objPairFilter;
49
+
50
+ physicsSystem = JPH_PhysicsSystem_Create(&settings);
51
+ bodyInterface = JPH_PhysicsSystem_GetBodyInterface(physicsSystem);
52
+ }
53
+
54
+ void TearDown() override {
55
+ if (physicsSystem) JPH_PhysicsSystem_Destroy(physicsSystem);
56
+ JPH_Shutdown();
57
+ }
58
+
59
+ JPH_BodyID CreateSphereBody(float x, float y, float z, float radius, JPH_MotionType motionType, JPH_ObjectLayer layer) {
60
+ JPH_SphereShape* shape = JPH_SphereShape_Create(radius);
61
+ JPH_Vec3 position = {x, y, z};
62
+ JPH_Quat rotation = {0.0f, 0.0f, 0.0f, 1.0f};
63
+
64
+ JPH_BodyCreationSettings* bs = JPH_BodyCreationSettings_Create3((JPH_Shape*)shape, &position, &rotation, motionType, layer);
65
+ JPH_Body* body = JPH_BodyInterface_CreateBody(bodyInterface, bs);
66
+ JPH_BodyID bodyId = JPH_Body_GetID(body);
67
+ JPH_BodyInterface_AddBody(bodyInterface, bodyId, JPH_Activation_Activate);
68
+
69
+ JPH_BodyCreationSettings_Destroy(bs);
70
+ JPH_Shape_Destroy((JPH_Shape*)shape);
71
+ return bodyId;
72
+ }
73
+
74
+ void RemoveAndDestroyBody(JPH_BodyID bodyId) {
75
+ JPH_BodyInterface_RemoveBody(bodyInterface, bodyId);
76
+ JPH_BodyInterface_DestroyBody(bodyInterface, bodyId);
77
+ }
78
+ };
79
+
80
+ TEST_F(CollisionTest, GetNarrowPhaseQuery) {
81
+ const JPH_NarrowPhaseQuery* query = JPH_PhysicsSystem_GetNarrowPhaseQuery(physicsSystem);
82
+ EXPECT_NE(query, nullptr);
83
+ }
84
+
85
+ TEST_F(CollisionTest, GetNarrowPhaseQueryNoLock) {
86
+ const JPH_NarrowPhaseQuery* query = JPH_PhysicsSystem_GetNarrowPhaseQueryNoLock(physicsSystem);
87
+ EXPECT_NE(query, nullptr);
88
+ }
89
+
90
+ TEST_F(CollisionTest, RayCast_Hit) {
91
+ JPH_BodyID sphereId = CreateSphereBody(0.0f, 0.0f, 0.0f, 1.0f, JPH_MotionType_Static, ObjectLayers::NON_MOVING);
92
+ JPH_PhysicsSystem_OptimizeBroadPhase(physicsSystem);
93
+
94
+ const JPH_NarrowPhaseQuery* query = JPH_PhysicsSystem_GetNarrowPhaseQuery(physicsSystem);
95
+
96
+ JPH_RVec3 origin = {-5.0f, 0.0f, 0.0f};
97
+ JPH_Vec3 direction = {10.0f, 0.0f, 0.0f};
98
+ JPH_RayCastResult hit;
99
+
100
+ bool hasHit = JPH_NarrowPhaseQuery_CastRay(query, &origin, &direction, &hit, nullptr, nullptr, nullptr);
101
+ EXPECT_TRUE(hasHit);
102
+ EXPECT_NEAR(hit.fraction, 0.4f, 0.01f);
103
+ EXPECT_EQ(hit.bodyID, sphereId);
104
+
105
+ RemoveAndDestroyBody(sphereId);
106
+ }
107
+
108
+ TEST_F(CollisionTest, RayCast_Miss) {
109
+ JPH_BodyID sphereId = CreateSphereBody(0.0f, 0.0f, 0.0f, 1.0f, JPH_MotionType_Static, ObjectLayers::NON_MOVING);
110
+ JPH_PhysicsSystem_OptimizeBroadPhase(physicsSystem);
111
+
112
+ const JPH_NarrowPhaseQuery* query = JPH_PhysicsSystem_GetNarrowPhaseQuery(physicsSystem);
113
+
114
+ JPH_RVec3 origin = {0.0f, 10.0f, 0.0f};
115
+ JPH_Vec3 direction = {10.0f, 0.0f, 0.0f};
116
+ JPH_RayCastResult hit;
117
+
118
+ bool hasHit = JPH_NarrowPhaseQuery_CastRay(query, &origin, &direction, &hit, nullptr, nullptr, nullptr);
119
+ EXPECT_FALSE(hasHit);
120
+
121
+ RemoveAndDestroyBody(sphereId);
122
+ }
123
+
124
+ TEST_F(CollisionTest, RayCast_ClosestHit) {
125
+ JPH_BodyID sphere1Id = CreateSphereBody(-3.0f, 0.0f, 0.0f, 1.0f, JPH_MotionType_Static, ObjectLayers::NON_MOVING);
126
+ JPH_BodyID sphere2Id = CreateSphereBody(3.0f, 0.0f, 0.0f, 1.0f, JPH_MotionType_Dynamic, ObjectLayers::MOVING);
127
+ JPH_PhysicsSystem_OptimizeBroadPhase(physicsSystem);
128
+
129
+ const JPH_NarrowPhaseQuery* query = JPH_PhysicsSystem_GetNarrowPhaseQuery(physicsSystem);
130
+
131
+ JPH_RVec3 origin = {-10.0f, 0.0f, 0.0f};
132
+ JPH_Vec3 direction = {20.0f, 0.0f, 0.0f};
133
+ JPH_RayCastResult hit;
134
+
135
+ bool hasHit = JPH_NarrowPhaseQuery_CastRay(query, &origin, &direction, &hit, nullptr, nullptr, nullptr);
136
+ EXPECT_TRUE(hasHit);
137
+ EXPECT_EQ(hit.bodyID, sphere1Id);
138
+
139
+ RemoveAndDestroyBody(sphere1Id);
140
+ RemoveAndDestroyBody(sphere2Id);
141
+ }
142
+
143
+ TEST_F(CollisionTest, GetBroadPhaseQuery) {
144
+ const JPH_BroadPhaseQuery* query = JPH_PhysicsSystem_GetBroadPhaseQuery(physicsSystem);
145
+ EXPECT_NE(query, nullptr);
146
+ }