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.
- checksums.yaml +7 -0
- data/.gitmodules +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +228 -0
- data/Rakefile +180 -0
- data/examples/character_virtual.rb +35 -0
- data/examples/falling_sphere.rb +25 -0
- data/examples/stagecraft_binding.rb +29 -0
- data/ext/jolt_ruby/CMakeLists.txt +42 -0
- data/ext/jolt_ruby/character_helper.cpp +44 -0
- data/ext/jolt_ruby/constraint_helper.cpp +154 -0
- data/ext/jolt_ruby/extconf.rb +56 -0
- data/ext/jolt_ruby/helper.cpp +225 -0
- data/ext/jolt_ruby/helper.h +103 -0
- data/ext/joltc/.github/FUNDING.yml +1 -0
- data/ext/joltc/.github/workflows/build.yml +298 -0
- data/ext/joltc/.gitignore +272 -0
- data/ext/joltc/CMakeLists.txt +431 -0
- data/ext/joltc/LICENSE +21 -0
- data/ext/joltc/README.md +10 -0
- data/ext/joltc/build/cmake_vs2026_arm64.bat +3 -0
- data/ext/joltc/build/cmake_vs2026_clang.bat +10 -0
- data/ext/joltc/build/cmake_vs2026_x64.bat +3 -0
- data/ext/joltc/build/cmake_vs2026_x64_double.bat +3 -0
- data/ext/joltc/include/joltc.h +3166 -0
- data/ext/joltc/samples/01_HelloWorld/main.cpp +170 -0
- data/ext/joltc/samples/CMakeLists.txt +35 -0
- data/ext/joltc/src/joltc.c +4 -0
- data/ext/joltc/src/joltc.cpp +11812 -0
- data/ext/joltc/src/joltc_assert.cpp +271 -0
- data/ext/joltc/tests/CMakeLists.txt +77 -0
- data/ext/joltc/tests/test_character.cpp +149 -0
- data/ext/joltc/tests/test_collision.cpp +146 -0
- data/ext/joltc/tests/test_constraints.cpp +353 -0
- data/ext/joltc/tests/test_core.cpp +94 -0
- data/ext/joltc/tests/test_math.cpp +585 -0
- data/ext/joltc/tests/test_physics_system.cpp +465 -0
- data/ext/joltc/tests/test_shapes.cpp +789 -0
- data/ext/joltc/tests/test_skeleton.cpp +370 -0
- data/ext/joltc/tests/test_vehicle.cpp +319 -0
- data/generator/generate.rb +237 -0
- data/generator/layout_probe.cpp +489 -0
- data/generator/verify_layout.rb +32 -0
- data/lib/jolt/body.rb +147 -0
- data/lib/jolt/body_collection.rb +115 -0
- data/lib/jolt/body_dynamics.rb +93 -0
- data/lib/jolt/character_virtual.rb +162 -0
- data/lib/jolt/constraint.rb +136 -0
- data/lib/jolt/constraint_collection.rb +123 -0
- data/lib/jolt/contact_events.rb +19 -0
- data/lib/jolt/conversions.rb +76 -0
- data/lib/jolt/errors.rb +12 -0
- data/lib/jolt/fixed_stepper.rb +37 -0
- data/lib/jolt/hit.rb +5 -0
- data/lib/jolt/layers.rb +182 -0
- data/lib/jolt/native/character_functions.rb +16 -0
- data/lib/jolt/native/constraint_functions.rb +27 -0
- data/lib/jolt/native/core_functions.rb +17 -0
- data/lib/jolt/native/generated.rb +1995 -0
- data/lib/jolt/native/platform.rb +51 -0
- data/lib/jolt/native/query_functions.rb +43 -0
- data/lib/jolt/native/types.rb +28 -0
- data/lib/jolt/native.rb +94 -0
- data/lib/jolt/shape.rb +90 -0
- data/lib/jolt/shape_builders.rb +155 -0
- data/lib/jolt/system.rb +238 -0
- data/lib/jolt/system_characters.rb +25 -0
- data/lib/jolt/system_constraints.rb +36 -0
- data/lib/jolt/system_contacts.rb +57 -0
- data/lib/jolt/system_queries.rb +111 -0
- data/lib/jolt/transform.rb +5 -0
- data/lib/jolt/version.rb +5 -0
- data/lib/jolt.rb +83 -0
- data/script/smoke_gem.rb +29 -0
- data/script/verify_release.rb +36 -0
- metadata +147 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// Copyright (c) Amer Koleci and Contributors.
|
|
2
|
+
// Distributed under the MIT license. See the LICENSE file in the project root for more information.
|
|
3
|
+
|
|
4
|
+
#include "joltc.h"
|
|
5
|
+
#include <stdbool.h>
|
|
6
|
+
#include <stdlib.h> // malloc, free
|
|
7
|
+
#include <string.h> // memset
|
|
8
|
+
// STL includes
|
|
9
|
+
#include <iostream>
|
|
10
|
+
|
|
11
|
+
static void TraceImpl(const char* message)
|
|
12
|
+
{
|
|
13
|
+
// Print to the TTY
|
|
14
|
+
std::cout << message << std::endl;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
namespace Layers
|
|
18
|
+
{
|
|
19
|
+
static constexpr JPH_ObjectLayer NON_MOVING = 0;
|
|
20
|
+
static constexpr JPH_ObjectLayer MOVING = 1;
|
|
21
|
+
static constexpr JPH_ObjectLayer NUM_LAYERS = 2;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
namespace BroadPhaseLayers
|
|
25
|
+
{
|
|
26
|
+
static constexpr JPH_BroadPhaseLayer NON_MOVING(0);
|
|
27
|
+
static constexpr JPH_BroadPhaseLayer MOVING(1);
|
|
28
|
+
static constexpr uint32_t NUM_LAYERS(2);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
int main(void)
|
|
32
|
+
{
|
|
33
|
+
if (!JPH_Init())
|
|
34
|
+
return 1;
|
|
35
|
+
|
|
36
|
+
JPH_SetTraceHandler(TraceImpl);
|
|
37
|
+
//JPH_SetAssertFailureHandler(JPH_AssertFailureFunc handler);
|
|
38
|
+
|
|
39
|
+
JPH_JobSystem* jobSystem = JPH_JobSystemThreadPool_Create(nullptr);
|
|
40
|
+
|
|
41
|
+
// We use only 2 layers: one for non-moving objects and one for moving objects
|
|
42
|
+
JPH_ObjectLayerPairFilter* objectLayerPairFilterTable = JPH_ObjectLayerPairFilterTable_Create(2);
|
|
43
|
+
JPH_ObjectLayerPairFilterTable_EnableCollision(objectLayerPairFilterTable, Layers::NON_MOVING, Layers::MOVING);
|
|
44
|
+
JPH_ObjectLayerPairFilterTable_EnableCollision(objectLayerPairFilterTable, Layers::MOVING, Layers::NON_MOVING);
|
|
45
|
+
|
|
46
|
+
// We use a 1-to-1 mapping between object layers and broadphase layers
|
|
47
|
+
JPH_BroadPhaseLayerInterface* broadPhaseLayerInterfaceTable = JPH_BroadPhaseLayerInterfaceTable_Create(2, 2);
|
|
48
|
+
JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(broadPhaseLayerInterfaceTable, Layers::NON_MOVING, BroadPhaseLayers::NON_MOVING);
|
|
49
|
+
JPH_BroadPhaseLayerInterfaceTable_MapObjectToBroadPhaseLayer(broadPhaseLayerInterfaceTable, Layers::MOVING, BroadPhaseLayers::MOVING);
|
|
50
|
+
|
|
51
|
+
JPH_ObjectVsBroadPhaseLayerFilter* objectVsBroadPhaseLayerFilter = JPH_ObjectVsBroadPhaseLayerFilterTable_Create(broadPhaseLayerInterfaceTable, 2, objectLayerPairFilterTable, 2);
|
|
52
|
+
|
|
53
|
+
JPH_PhysicsSystemSettings settings = {};
|
|
54
|
+
settings.maxBodies = 65536;
|
|
55
|
+
settings.numBodyMutexes = 0;
|
|
56
|
+
settings.maxBodyPairs = 65536;
|
|
57
|
+
settings.maxContactConstraints = 65536;
|
|
58
|
+
settings.broadPhaseLayerInterface = broadPhaseLayerInterfaceTable;
|
|
59
|
+
settings.objectLayerPairFilter = objectLayerPairFilterTable;
|
|
60
|
+
settings.objectVsBroadPhaseLayerFilter = objectVsBroadPhaseLayerFilter;
|
|
61
|
+
JPH_PhysicsSystem* system = JPH_PhysicsSystem_Create(&settings);
|
|
62
|
+
JPH_BodyInterface* bodyInterface = JPH_PhysicsSystem_GetBodyInterface(system);
|
|
63
|
+
|
|
64
|
+
JPH_BodyID floorId = {};
|
|
65
|
+
{
|
|
66
|
+
// Next we can create a rigid body to serve as the floor, we make a large box
|
|
67
|
+
// Create the settings for the collision volume (the shape).
|
|
68
|
+
// Note that for simple shapes (like boxes) you can also directly construct a BoxShape.
|
|
69
|
+
JPH_Vec3 boxHalfExtents = { 100.0f, 1.0f, 100.0f };
|
|
70
|
+
JPH_BoxShape* floorShape = JPH_BoxShape_Create(&boxHalfExtents, JPH_DEFAULT_CONVEX_RADIUS);
|
|
71
|
+
|
|
72
|
+
JPH_Vec3 floorPosition = { 0.0f, -1.0f, 0.0f };
|
|
73
|
+
JPH_BodyCreationSettings* floorSettings = JPH_BodyCreationSettings_Create3(
|
|
74
|
+
(const JPH_Shape*)floorShape,
|
|
75
|
+
&floorPosition,
|
|
76
|
+
nullptr, // Identity,
|
|
77
|
+
JPH_MotionType_Static,
|
|
78
|
+
Layers::NON_MOVING);
|
|
79
|
+
|
|
80
|
+
// Create the actual rigid body
|
|
81
|
+
floorId = JPH_BodyInterface_CreateAndAddBody(bodyInterface, floorSettings, JPH_Activation_DontActivate);
|
|
82
|
+
JPH_BodyCreationSettings_Destroy(floorSettings);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Sphere
|
|
86
|
+
JPH_BodyID sphereId = {};
|
|
87
|
+
{
|
|
88
|
+
JPH_SphereShape* sphereShape = JPH_SphereShape_Create(50.0f);
|
|
89
|
+
JPH_Vec3 spherePosition = { 0.0f, 2.0f, 0.0f };
|
|
90
|
+
JPH_BodyCreationSettings* sphereSettings = JPH_BodyCreationSettings_Create3(
|
|
91
|
+
(const JPH_Shape*)sphereShape,
|
|
92
|
+
&spherePosition,
|
|
93
|
+
nullptr, // Identity,
|
|
94
|
+
JPH_MotionType_Dynamic,
|
|
95
|
+
Layers::MOVING);
|
|
96
|
+
|
|
97
|
+
sphereId = JPH_BodyInterface_CreateAndAddBody(bodyInterface, sphereSettings, JPH_Activation_Activate);
|
|
98
|
+
JPH_BodyCreationSettings_Destroy(sphereSettings);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Now you can interact with the dynamic body, in this case we're going to give it a velocity.
|
|
102
|
+
// (note that if we had used CreateBody then we could have set the velocity straight on the body before adding it to the physics system)
|
|
103
|
+
JPH_Vec3 sphereLinearVelocity = { 0.0f, -5.0f, 0.0f };
|
|
104
|
+
JPH_BodyInterface_SetLinearVelocity(bodyInterface, sphereId, &sphereLinearVelocity);
|
|
105
|
+
|
|
106
|
+
{
|
|
107
|
+
static constexpr float cCharacterHeightStanding = 1.35f;
|
|
108
|
+
static constexpr float cCharacterRadiusStanding = 0.3f;
|
|
109
|
+
static constexpr float cCharacterHeightCrouching = 0.8f;
|
|
110
|
+
static constexpr float cCharacterRadiusCrouching = 0.3f;
|
|
111
|
+
static constexpr float cInnerShapeFraction = 0.9f;
|
|
112
|
+
|
|
113
|
+
JPH_CapsuleShape* capsuleShape = JPH_CapsuleShape_Create(0.5f * cCharacterHeightStanding, cCharacterRadiusStanding);
|
|
114
|
+
JPH_Vec3 position = { 0, 0.5f * cCharacterHeightStanding + cCharacterRadiusStanding, 0 };
|
|
115
|
+
auto mStandingShape = JPH_RotatedTranslatedShape_Create(&position, nullptr, (JPH_Shape*)capsuleShape);
|
|
116
|
+
|
|
117
|
+
JPH_CharacterVirtualSettings characterSettings{};
|
|
118
|
+
JPH_CharacterVirtualSettings_Init(&characterSettings);
|
|
119
|
+
characterSettings.base.shape = (const JPH_Shape*)mStandingShape;
|
|
120
|
+
characterSettings.base.supportingVolume = { {0, 1, 0}, -cCharacterRadiusStanding }; // Accept contacts that touch the lower sphere of the capsule
|
|
121
|
+
static const JPH_RVec3 characterVirtualPosition = { -5.0f, 0, 3.0f };
|
|
122
|
+
|
|
123
|
+
auto mAnimatedCharacterVirtual = JPH_CharacterVirtual_Create(&characterSettings, &characterVirtualPosition, nullptr, 0, system);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
JPH_SixDOFConstraintSettings jointSettings;
|
|
127
|
+
JPH_SixDOFConstraintSettings_Init(&jointSettings);
|
|
128
|
+
|
|
129
|
+
// We simulate the physics world in discrete time steps. 60 Hz is a good rate to update the physics system.
|
|
130
|
+
const float cDeltaTime = 1.0f / 60.0f;
|
|
131
|
+
|
|
132
|
+
// Optional step: Before starting the physics simulation you can optimize the broad phase. This improves collision detection performance (it's pointless here because we only have 2 bodies).
|
|
133
|
+
// You should definitely not call this every frame or when e.g. streaming in a new level section as it is an expensive operation.
|
|
134
|
+
// Instead insert all new objects in batches instead of 1 at a time to keep the broad phase efficient.
|
|
135
|
+
JPH_PhysicsSystem_OptimizeBroadPhase(system);
|
|
136
|
+
|
|
137
|
+
// Now we're ready to simulate the body, keep simulating until it goes to sleep
|
|
138
|
+
uint32_t step = 0;
|
|
139
|
+
while (JPH_BodyInterface_IsActive(bodyInterface, sphereId))
|
|
140
|
+
{
|
|
141
|
+
// Next step
|
|
142
|
+
++step;
|
|
143
|
+
|
|
144
|
+
// Output current position and velocity of the sphere
|
|
145
|
+
JPH_RVec3 position;
|
|
146
|
+
JPH_Vec3 velocity;
|
|
147
|
+
|
|
148
|
+
JPH_BodyInterface_GetCenterOfMassPosition(bodyInterface, sphereId, &position);
|
|
149
|
+
JPH_BodyInterface_GetLinearVelocity(bodyInterface, sphereId, &velocity);
|
|
150
|
+
std::cout << "Step " << step << ": Position = (" << position.x << ", " << position.y << ", " << position.z << "), Velocity = (" << velocity.x << ", " << velocity.y << ", " << velocity.z << ")" << std::endl;
|
|
151
|
+
|
|
152
|
+
// If you take larger steps than 1 / 60th of a second you need to do multiple collision steps in order to keep the simulation stable. Do 1 collision step per 1 / 60th of a second (round up).
|
|
153
|
+
const int cCollisionSteps = 1;
|
|
154
|
+
|
|
155
|
+
// Step the world
|
|
156
|
+
JPH_PhysicsSystem_Update(system, cDeltaTime, cCollisionSteps, jobSystem);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Remove the destroy sphere from the physics system. Note that the sphere itself keeps all of its state and can be re-added at any time.
|
|
160
|
+
JPH_BodyInterface_RemoveAndDestroyBody(bodyInterface, sphereId);
|
|
161
|
+
|
|
162
|
+
// Remove and destroy the floor
|
|
163
|
+
JPH_BodyInterface_RemoveAndDestroyBody(bodyInterface, floorId);
|
|
164
|
+
|
|
165
|
+
JPH_JobSystem_Destroy(jobSystem);
|
|
166
|
+
|
|
167
|
+
JPH_PhysicsSystem_Destroy(system);
|
|
168
|
+
JPH_Shutdown();
|
|
169
|
+
return 0;
|
|
170
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
if (NOT JPH_SAMPLES)
|
|
2
|
+
return ()
|
|
3
|
+
endif ()
|
|
4
|
+
|
|
5
|
+
function(add_sample SAMPLE_NAME)
|
|
6
|
+
file(GLOB SOURCE_FILES
|
|
7
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/${SAMPLE_NAME}/*.h"
|
|
8
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/${SAMPLE_NAME}/*.c"
|
|
9
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/${SAMPLE_NAME}/*.cpp"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
if (ANDROID)
|
|
13
|
+
add_library(${SAMPLE_NAME} SHARED ${SOURCE_FILES})
|
|
14
|
+
else ()
|
|
15
|
+
add_executable(${SAMPLE_NAME} ${SOURCE_FILES})
|
|
16
|
+
endif ()
|
|
17
|
+
|
|
18
|
+
if (DOUBLE_PRECISION)
|
|
19
|
+
target_link_libraries(${SAMPLE_NAME} LINK_PUBLIC joltc_double)
|
|
20
|
+
else()
|
|
21
|
+
target_link_libraries(${SAMPLE_NAME} LINK_PUBLIC joltc)
|
|
22
|
+
endif ()
|
|
23
|
+
|
|
24
|
+
if (MSVC)
|
|
25
|
+
target_link_options(${SAMPLE_NAME} PUBLIC "/SUBSYSTEM:CONSOLE")
|
|
26
|
+
endif()
|
|
27
|
+
|
|
28
|
+
set_target_properties(${SAMPLE_NAME} PROPERTIES
|
|
29
|
+
VS_DEBUGGER_WORKING_DIRECTORY "$<TARGET_FILE_DIR:${SAMPLE_NAME}>"
|
|
30
|
+
FOLDER "samples"
|
|
31
|
+
)
|
|
32
|
+
endfunction()
|
|
33
|
+
|
|
34
|
+
# Add samples
|
|
35
|
+
add_sample(01_HelloWorld)
|