diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7887c5c..1604929 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,15 +20,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Read .zig-version - id: zigversion - uses: juliangruber/read-file-action@v1 - with: - path: ./.zigversion - name: Install Zig - uses: mlugg/setup-zig@v1 - with: - version: ${{ steps.zigversion.outputs.content }} + uses: mlugg/setup-zig@v2 - name: Check format continue-on-error: true run: zig fmt --check . diff --git a/.zigversion b/.zigversion deleted file mode 100644 index a803cc2..0000000 --- a/.zigversion +++ /dev/null @@ -1 +0,0 @@ -0.14.0 diff --git a/build.zig b/build.zig index 03799d8..69d922d 100644 --- a/build.zig +++ b/build.zig @@ -1,5 +1,16 @@ const std = @import("std"); +fn addMacros(module: *std.Build.Module, options: anytype) void { + if (options.enable_cross_platform_determinism) + module.addCMacro("JPH_CROSS_PLATFORM_DETERMINISTIC", ""); + if (options.enable_debug_renderer) + module.addCMacro("JPH_DEBUG_RENDERER", ""); + if (options.use_double_precision) + module.addCMacro("JPH_DOUBLE_PRECISION", ""); + if (options.enable_asserts) + module.addCMacro("JPH_ENABLE_ASSERTS", ""); +} + pub fn build(b: *std.Build) void { const optimize = b.standardOptimizeOption(.{}); const target = b.standardTargetOptions(.{}); @@ -58,21 +69,18 @@ pub fn build(b: *std.Build) void { }); zjolt.addIncludePath(b.path("libs/JoltC")); - const joltc = if (options.shared) blk: { - const lib = b.addSharedLibrary(.{ - .name = "joltc", + const joltc = b.addLibrary(.{ + .name = "joltc", + .linkage = if (options.shared) .dynamic else .static, + .root_module = b.createModule(.{ .target = target, .optimize = optimize, - }); - if (target.result.os.tag == .windows) { - lib.root_module.addCMacro("JPC_API", "extern __declspec(dllexport)"); - } - break :blk lib; - } else b.addStaticLibrary(.{ - .name = "joltc", - .target = target, - .optimize = optimize, + }), }); + + if (options.shared and target.result.os.tag == .windows) + joltc.root_module.addCMacro("JPC_API", "extern __declspec(dllexport)"); + b.installArtifact(joltc); joltc.addIncludePath(b.path("libs")); @@ -87,15 +95,12 @@ pub fn build(b: *std.Build) void { const src_dir = "libs/Jolt"; const c_flags = &.{ "-std=c++17", - if (options.enable_cross_platform_determinism) "-DJPH_CROSS_PLATFORM_DETERMINISTIC" else "", - if (options.enable_debug_renderer) "-DJPH_DEBUG_RENDERER" else "", - if (options.use_double_precision) "-DJPH_DOUBLE_PRECISION" else "", - if (options.enable_asserts) "-DJPH_ENABLE_ASSERTS" else "", if (options.no_exceptions) "-fno-exceptions" else "", "-fno-access-control", "-fno-sanitize=undefined", }; + addMacros(joltc.root_module, options); joltc.addCSourceFiles(.{ .files = &.{ "libs/JoltC/JoltPhysicsC.cpp", @@ -248,9 +253,11 @@ pub fn build(b: *std.Build) void { const tests = b.addTest(.{ .name = "zphysics-tests", - .root_source_file = b.path("src/zphysics.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("src/zphysics.zig"), + .target = target, + .optimize = optimize, + }), }); b.installArtifact(tests); @@ -259,17 +266,17 @@ pub fn build(b: *std.Build) void { tests.want_lto = false; } + addMacros(tests.root_module, options); tests.addCSourceFile(.{ .file = b.path("libs/JoltC/JoltPhysicsC_Tests.c"), .flags = &.{ - if (options.enable_cross_platform_determinism) "-DJPH_CROSS_PLATFORM_DETERMINISTIC" else "", - if (options.enable_debug_renderer) "-DJPH_DEBUG_RENDERER" else "", - if (options.use_double_precision) "-DJPH_DOUBLE_PRECISION" else "", - if (options.enable_asserts) "-DJPH_ENABLE_ASSERTS" else "", "-fno-sanitize=undefined", }, }); + if (b.option(bool, "verbose", "Print verbose test debug output to stderr") orelse false) + tests.root_module.addCMacro("PRINT_OUTPUT", ""); + tests.root_module.addImport("zphysics_options", options_module); tests.addIncludePath(b.path("libs/JoltC")); tests.linkLibrary(joltc); diff --git a/build.zig.zon b/build.zig.zon index 791865c..7df34c2 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -2,6 +2,7 @@ .name = .zphysics, .fingerprint = 0x1def6aac00c4909d, .version = "0.2.0-dev", + .minimum_zig_version = "0.14.0", .paths = .{ "build.zig", "build.zig.zon", diff --git a/libs/JoltC/JoltPhysicsC.cpp b/libs/JoltC/JoltPhysicsC.cpp index df690dc..5ff34d4 100644 --- a/libs/JoltC/JoltPhysicsC.cpp +++ b/libs/JoltC/JoltPhysicsC.cpp @@ -60,8 +60,8 @@ JPH_SUPPRESS_WARNINGS #define FN(name) static auto name -FN(toJph)(JPC_BodyID in) { return JPH::BodyID(in); } -FN(toJpc)(JPH::BodyID in) { return in.GetIndexAndSequenceNumber(); } +FN(toJph)(JPC_BodyID in) { return JPH::BodyID(in.id); } +FN(toJpc)(JPH::BodyID in) { return (JPC_BodyID){ in.GetIndexAndSequenceNumber() }; } FN(toJpc)(const JPH::Body *in) { assert(in); return reinterpret_cast(in); } FN(toJph)(const JPC_Body *in) { assert(in); return reinterpret_cast(in); } @@ -301,6 +301,7 @@ FN(toJpc)(const JPH::CollisionGroup *in) { assert(in); return reinterpret_cast(in); } FN(toJph)(const JPC_SubShapeID *in) { assert(in); return reinterpret_cast(in); } +FN(toJph)(const JPC_BodyID *in) { assert(in); return reinterpret_cast(in); } FN(toJpc)(const JPH::SubShapeIDCreator *in) { assert(in); return reinterpret_cast(in); } FN(toJph)(const JPC_SubShapeIDCreator *in) { assert(in); return reinterpret_cast(in); } @@ -738,9 +739,9 @@ class DebugRendererImpl final : public JPH::DebugRenderer BatchImpl(const JPC_DebugRenderer_Primitive *c_primitive) : RenderPrimitive(c_primitive) {} ~BatchImpl() { - if (sInstance && sInstance->c_renderer->vtbl->DestroyTriangleBatch) + if (sInstance) { - sInstance->c_renderer->vtbl->DestroyTriangleBatch(sInstance->c_renderer, c_primitive); + sInstance->c_renderer->vtbl->DestroyTriangleBatch(sInstance->c_renderer, (void*)c_primitive); } } @@ -789,6 +790,7 @@ class DebugRendererImpl final : public JPH::DebugRenderer valid &= (c_renderer->vtbl->DrawTriangle != nullptr); valid &= (c_renderer->vtbl->CreateTriangleBatch != nullptr); valid &= (c_renderer->vtbl->CreateTriangleBatchIndexed != nullptr); + valid &= (c_renderer->vtbl->DestroyTriangleBatch != nullptr); valid &= (c_renderer->vtbl->DrawGeometry != nullptr); valid &= (c_renderer->vtbl->DrawText3D != nullptr); return valid ? JPC_DEBUGRENDERER_SUCCESS : JPC_DEBUGRENDERER_INCOMPLETE_IMPL; @@ -2509,12 +2511,24 @@ JPC_BodyInterface_ActivateBody(JPC_BodyInterface *in_iface, JPC_BodyID in_body_i toJph(in_iface)->ActivateBody(toJph(in_body_id)); } +JPC_API void +JPC_BodyInterface_ActivateBodies(JPC_BodyInterface *in_iface, const JPC_BodyID *in_body_ids, int in_num_bodies) +{ + toJph(in_iface)->ActivateBodies(toJph(in_body_ids), in_num_bodies); +} + JPC_API void JPC_BodyInterface_DeactivateBody(JPC_BodyInterface *in_iface, JPC_BodyID in_body_id) { toJph(in_iface)->DeactivateBody(toJph(in_body_id)); } +JPC_API void +JPC_BodyInterface_DeactivateBodies(JPC_BodyInterface *in_iface, const JPC_BodyID *in_body_ids, int in_num_bodies) +{ + toJph(in_iface)->DeactivateBodies(toJph(in_body_ids), in_num_bodies); +} + JPC_API bool JPC_BodyInterface_IsActive(const JPC_BodyInterface *in_iface, JPC_BodyID in_body_id) { @@ -2619,7 +2633,7 @@ JPC_BodyInterface_SetObjectLayer(JPC_BodyInterface *in_iface, JPC_BodyID in_body JPC_API JPC_BodyID JPC_Body_GetID(const JPC_Body *in_body) { - return toJph(in_body)->GetID().GetIndexAndSequenceNumber(); + return (JPC_BodyID){ toJph(in_body)->GetID().GetIndexAndSequenceNumber() }; } //-------------------------------------------------------------------------------------------------- JPC_API bool @@ -3198,19 +3212,19 @@ JPC_MotionProperties_SetMaxAngularVelocity(JPC_MotionProperties *in_properties, JPC_API uint32_t JPC_BodyID_GetIndex(JPC_BodyID in_body_id) { - return JPH::BodyID(in_body_id).GetIndex(); + return JPH::BodyID(in_body_id.id).GetIndex(); } //-------------------------------------------------------------------------------------------------- JPC_API uint8_t JPC_BodyID_GetSequenceNumber(JPC_BodyID in_body_id) { - return JPH::BodyID(in_body_id).GetSequenceNumber(); + return JPH::BodyID(in_body_id.id).GetSequenceNumber(); } //-------------------------------------------------------------------------------------------------- JPC_API bool JPC_BodyID_IsInvalid(JPC_BodyID in_body_id) { - return JPH::BodyID(in_body_id).IsInvalid(); + return JPH::BodyID(in_body_id.id).IsInvalid(); } //-------------------------------------------------------------------------------------------------- // diff --git a/libs/JoltC/JoltPhysicsC.h b/libs/JoltC/JoltPhysicsC.h index 11b9ef2..2970481 100644 --- a/libs/JoltC/JoltPhysicsC.h +++ b/libs/JoltC/JoltPhysicsC.h @@ -292,9 +292,19 @@ typedef enum JPC_ShapeColor { typedef uint16_t JPC_ObjectLayer; typedef uint8_t JPC_BroadPhaseLayer; +typedef struct JPC_BodyID +{ + uint32_t id; +} JPC_BodyID; + +typedef struct JPC_SubShapeID +{ + uint32_t id; +} JPC_SubShapeID; + +#define JPC_ID_EQ(a, b) (a.id == b.id) + // TODO: Consider using structures for IDs -typedef uint32_t JPC_BodyID; -typedef uint32_t JPC_SubShapeID; typedef uint32_t JPC_CollisionGroupID; typedef uint32_t JPC_CollisionSubGroupID; @@ -985,8 +995,6 @@ typedef struct JPC_CharacterContactListenerVTable typedef struct JPC_ContactListenerVTable { - _JPC_VTABLE_HEADER; - // Optional, can be NULL. JPC_ValidateResult (*OnContactValidate)(void *in_self, @@ -1050,7 +1058,7 @@ typedef struct JPC_DebugRendererVTable // Optional void - (*DestroyTriangleBatch)(void *in_self, const void *in_primitive); + (*DestroyTriangleBatch)(void *in_self, void *in_primitive); // Required, *cannot* be NULL. void @@ -1384,9 +1392,9 @@ JPC_PhysicsSystem_GetActiveBodyIDs(const JPC_PhysicsSystem *in_physics_system, /// Access a body, will return NULL if the body ID is no longer valid. /// Use `JPC_PhysicsSystem_GetBodiesUnsafe()` to get an array of all body pointers. #define JPC_TRY_GET_BODY(all_body_ptrs, body_id) \ - JPC_IS_VALID_BODY_POINTER(all_body_ptrs[body_id & JPC_BODY_ID_INDEX_BITS]) && \ - all_body_ptrs[body_id & JPC_BODY_ID_INDEX_BITS]->id == body_id ? \ - all_body_ptrs[body_id & JPC_BODY_ID_INDEX_BITS] : NULL + JPC_IS_VALID_BODY_POINTER(all_body_ptrs[body_id.id & JPC_BODY_ID_INDEX_BITS]) && \ + all_body_ptrs[body_id.id & JPC_BODY_ID_INDEX_BITS]->id.id == body_id.id ? \ + all_body_ptrs[body_id.id & JPC_BODY_ID_INDEX_BITS] : NULL /// Get direct access to all bodies. Not protected by a lock. Use with great care! JPC_API JPC_Body ** @@ -2062,9 +2070,15 @@ JPC_BodyInterface_SetRotation(JPC_BodyInterface *in_iface, JPC_API void JPC_BodyInterface_ActivateBody(JPC_BodyInterface *in_iface, JPC_BodyID in_body_id); +JPC_API void +JPC_BodyInterface_ActivateBodies(JPC_BodyInterface *in_iface, const JPC_BodyID* in_body_ids, int in_num_bodies); + JPC_API void JPC_BodyInterface_DeactivateBody(JPC_BodyInterface *in_iface, JPC_BodyID in_body_id); +JPC_API void +JPC_BodyInterface_DeactivateBodies(JPC_BodyInterface *in_iface, const JPC_BodyID* in_body_ids, int in_num_bodies); + JPC_API bool JPC_BodyInterface_IsActive(const JPC_BodyInterface *in_iface, JPC_BodyID in_body_id); diff --git a/libs/JoltC/JoltPhysicsC_Extensions.cpp b/libs/JoltC/JoltPhysicsC_Extensions.cpp index 9f370c4..1ae96b4 100644 --- a/libs/JoltC/JoltPhysicsC_Extensions.cpp +++ b/libs/JoltC/JoltPhysicsC_Extensions.cpp @@ -62,7 +62,7 @@ JPC_PhysicsSystem_GetBodyIDs(const JPC_PhysicsSystem *in_physics_system, for (const JPH::Body *b : physics_system->mBodyManager.mBodies) if (JPH::BodyManager::sIsValidBodyPointer(b)) { - *out_body_ids = b->GetID().GetIndexAndSequenceNumber(); + out_body_ids->id = b->GetID().GetIndexAndSequenceNumber(); out_body_ids += 1; if (out_num_body_ids) *out_num_body_ids += 1; in_max_body_ids -= 1; @@ -91,7 +91,7 @@ JPC_PhysicsSystem_GetActiveBodyIDs(const JPC_PhysicsSystem *in_physics_system, for (uint32_t i = 0; i < physics_system->mBodyManager.mNumActiveBodies[0]; ++i) { const JPH::BodyID body_id = physics_system->mBodyManager.mActiveBodies[0][i]; - *out_body_ids = body_id.GetIndexAndSequenceNumber(); + out_body_ids->id = body_id.GetIndexAndSequenceNumber(); out_body_ids += 1; if (out_num_body_ids) *out_num_body_ids += 1; in_max_body_ids -= 1; diff --git a/libs/JoltC/JoltPhysicsC_Tests.c b/libs/JoltC/JoltPhysicsC_Tests.c index 395ba89..2210a79 100644 --- a/libs/JoltC/JoltPhysicsC_Tests.c +++ b/libs/JoltC/JoltPhysicsC_Tests.c @@ -5,8 +5,6 @@ #include #include -//#define PRINT_OUTPUT - // Object layers #define NUM_OBJ_LAYERS 2 #define OBJ_LAYER_NON_MOVING 0 @@ -97,9 +95,9 @@ MyContactListener_OnContactValidate(void *in_self, "\tOnContactValidate(): in_base_offset (%f, %f, %f)\n", in_base_offset[0], in_base_offset[1], in_base_offset[2]); fprintf(stderr, "\tOnContactValidate(): penetration_depth (%f)\n", in_collision_result->penetration_depth); - fprintf(stderr, "\tOnContactValidate(): shape1_sub_shape_id (%d)\n", in_collision_result->shape1_sub_shape_id); - fprintf(stderr, "\tOnContactValidate(): shape2_sub_shape_id (%d)\n", in_collision_result->shape2_sub_shape_id); - fprintf(stderr, "\tOnContactValidate(): body2_id (%d)\n", in_collision_result->body2_id); + fprintf(stderr, "\tOnContactValidate(): shape1_sub_shape_id (%d)\n", in_collision_result->shape1_sub_shape_id.id); + fprintf(stderr, "\tOnContactValidate(): shape2_sub_shape_id (%d)\n", in_collision_result->shape2_sub_shape_id.id); + fprintf(stderr, "\tOnContactValidate(): body2_id (%d)\n", in_collision_result->body2_id.id); #endif return JPC_VALIDATE_RESULT_ACCEPT_ALL_CONTACTS; } @@ -214,7 +212,7 @@ MyDebugRenderer_CreateTriangleBatch(void *in_self, (JPC_DebugRenderer_Primitive *)prim ); #ifdef PRINT_OUTPUT - fprintf(stderr, "\tDebugRenderer: CreateTriangleBatch called. Created primitive %x\n", prim); + fprintf(stderr, "\tDebugRenderer: CreateTriangleBatch called. Created primitive %llx\n", (uint64_t)prim); #endif return batch; } @@ -232,11 +230,21 @@ MyDebugRenderer_CreateTriangleBatchIndexed(void *in_self, (JPC_DebugRenderer_Primitive *)prim ); #ifdef PRINT_OUTPUT - fprintf(stderr, "\tDebugRenderer: CreateTriangleBatchIndexed called. Created primitive %x\n", prim); + fprintf(stderr, "\tDebugRenderer: CreateTriangleBatchIndexed called. Created primitive %llx\n", (uint64_t)prim); #endif return batch; } +static void +MyDebugRenderer_DestroyTriangleBatch(void *in_self, void *in_batch) +{ + struct MyDebugRenderer *self = (struct MyDebugRenderer*) in_self; + struct MyRenderPrimitive *prim = (MyRenderPrimitive*)in_batch; +#ifdef PRINT_OUTPUT + fprintf(stderr, "\tDebugRenderer: DestroyTriangleBatch called. Destroyed primitive %llx\n", (uint64_t)prim); +#endif +} + static void MyDebugRenderer_DrawGeometry(void *in_self, const JPC_RMatrix *inMatrix, @@ -252,7 +260,7 @@ MyDebugRenderer_DrawGeometry(void *in_self, JPC_DebugRenderer_TriangleBatch *batch = in_geometry->LODs[0].batch; const JPC_DebugRenderer_Primitive *prim = JPC_DebugRenderer_TriangleBatch_GetPrimitive(batch); #ifdef PRINT_OUTPUT - fprintf(stderr, "\tDebugRenderer: DrawGeometry called for %x\n", prim); + fprintf(stderr, "\tDebugRenderer: DrawGeometry called for %llx\n", (uint64_t)prim); #endif } @@ -277,6 +285,7 @@ MyDebugRenderer_Init(void) .DrawTriangle = MyDebugRenderer_DrawTriangle, .CreateTriangleBatch = MyDebugRenderer_CreateTriangleBatch, .CreateTriangleBatchIndexed = MyDebugRenderer_CreateTriangleBatchIndexed, + .DestroyTriangleBatch = MyDebugRenderer_DestroyTriangleBatch, .DrawGeometry = MyDebugRenderer_DrawGeometry, .DrawText3D = MyDebugRenderer_DrawText3D, }; @@ -541,8 +550,8 @@ JoltCTest_Basic2(void) JPC_Body *floor = JPC_BodyInterface_CreateBody(body_interface, &floor_settings); if (floor == NULL) return 0; const JPC_BodyID floor_id = JPC_Body_GetID(floor); - if (((floor_id & JPC_BODY_ID_SEQUENCE_BITS) >> JPC_BODY_ID_SEQUENCE_SHIFT) != 1) return 0; - if ((floor_id & JPC_BODY_ID_INDEX_BITS) != 0) return 0; + if (((floor_id.id & JPC_BODY_ID_SEQUENCE_BITS) >> JPC_BODY_ID_SEQUENCE_SHIFT) != 1) return 0; + if ((floor_id.id & JPC_BODY_ID_INDEX_BITS) != 0) return 0; if (JPC_Body_IsStatic(floor) == false) return 0; if (JPC_Body_IsDynamic(floor) == true) return 0; @@ -551,8 +560,8 @@ JoltCTest_Basic2(void) JPC_Body *floor1 = JPC_BodyInterface_CreateBody(body_interface, &floor_settings); if (floor1 == NULL) return 0; const JPC_BodyID floor1_id = JPC_Body_GetID(floor1); - if (((floor1_id & JPC_BODY_ID_SEQUENCE_BITS) >> JPC_BODY_ID_SEQUENCE_SHIFT) != 1) return 0; - if ((floor1_id & JPC_BODY_ID_INDEX_BITS) != 1) return 0; + if (((floor1_id.id & JPC_BODY_ID_SEQUENCE_BITS) >> JPC_BODY_ID_SEQUENCE_SHIFT) != 1) return 0; + if ((floor1_id.id & JPC_BODY_ID_INDEX_BITS) != 1) return 0; if (JPC_BodyInterface_IsAdded(body_interface, floor_id) != false) return 0; if (JPC_BodyInterface_IsAdded(body_interface, floor1_id) != false) return 0; @@ -688,8 +697,8 @@ JoltCTest_HelloWorld(void) uint32_t num_body_ids = 0; JPC_PhysicsSystem_GetBodyIDs(physics_system, 2, &num_body_ids, &body_ids[0]); if (num_body_ids != 2) return 0; - if (body_ids[0] != floor_id) return 0; - if (body_ids[1] != sphere_id) return 0; + if (!JPC_ID_EQ(body_ids[0], floor_id)) return 0; + if (!JPC_ID_EQ(body_ids[1], sphere_id)) return 0; } // Test JPC_PhysicsSystem_GetActiveBodyIDs() @@ -698,7 +707,7 @@ JoltCTest_HelloWorld(void) uint32_t num_body_ids = 0; JPC_PhysicsSystem_GetActiveBodyIDs(physics_system, 2, &num_body_ids, &body_ids[0]); if (num_body_ids != 1) return 0; - if (body_ids[0] != sphere_id) return 0; + if (!JPC_ID_EQ(body_ids[0], sphere_id)) return 0; } #ifdef PRINT_OUTPUT @@ -798,7 +807,7 @@ JoltCTest_HelloWorld(void) JPC_BodyLockInterface_LockRead(lock_iface, sphere_id, &lock); if (lock.body) { - JPC_Body *body = bodies[sphere_id & JPC_BODY_ID_INDEX_BITS]; + JPC_Body *body = bodies[sphere_id.id & JPC_BODY_ID_INDEX_BITS]; if (!JPC_IS_VALID_BODY_POINTER(body)) return 0; if (JPC_Body_IsDynamic(body) != true) return 0; @@ -807,10 +816,10 @@ JoltCTest_HelloWorld(void) if (body_checked == NULL) return 0; if (body_checked != body) return 0; - if (body_checked->id != body->id) return 0; + if (!JPC_ID_EQ(body_checked->id, body->id)) return 0; if (body != lock.body) return 0; - if (body->id != sphere_id) return 0; + if (!JPC_ID_EQ(body->id, sphere_id)) return 0; } JPC_BodyLockInterface_UnlockRead(lock_iface, &lock); } diff --git a/src/zphysics.zig b/src/zphysics.zig index 1110290..90b375b 100644 --- a/src/zphysics.zig +++ b/src/zphysics.zig @@ -26,18 +26,36 @@ pub const SharedMutex = opaque {}; pub const BroadPhaseLayer = c.JPC_BroadPhaseLayer; pub const ObjectLayer = c.JPC_ObjectLayer; -pub const BodyId = c.JPC_BodyID; -pub const SubShapeId = c.JPC_SubShapeID; -pub const max_physics_jobs = c.JPC_MAX_PHYSICS_JOBS; -pub const max_physics_barriers = c.JPC_MAX_PHYSICS_BARRIERS; +const BodyIdInt = std.meta.fieldInfo(c.JPC_BodyID, .id).type; +pub const BodyId = enum(BodyIdInt) { + invalid = c.JPC_BODY_ID_INVALID, + index_bits = c.JPC_BODY_ID_INDEX_BITS, + sequence_bits = c.JPC_BODY_ID_SEQUENCE_BITS, + sequence_shift = c.JPC_BODY_ID_SEQUENCE_SHIFT, + _, -pub const body_id_invalid: BodyId = c.JPC_BODY_ID_INVALID; -pub const body_id_index_bits: BodyId = c.JPC_BODY_ID_INDEX_BITS; -pub const body_id_sequence_bits: BodyId = c.JPC_BODY_ID_SEQUENCE_BITS; -pub const body_id_sequence_shift: BodyId = c.JPC_BODY_ID_SEQUENCE_SHIFT; + pub inline fn indexBits(self: BodyId) BodyIdInt { + return @intFromEnum(self) & @intFromEnum(BodyId.index_bits); + } -pub const sub_shape_id_empty: SubShapeId = c.JPC_SUB_SHAPE_ID_EMPTY; + pub inline fn toJpc(self: BodyId) c.JPC_BodyID { + return .{ .id = @intFromEnum(self) }; + } +}; + +const SubShapeIdInt = std.meta.fieldInfo(c.JPC_SubShapeID, .id).type; +pub const SubShapeId = enum(SubShapeIdInt) { + empty = c.JPC_SUB_SHAPE_ID_EMPTY, + _, + + pub inline fn toJpc(self: SubShapeId) c.JPC_SubShapeID { + return .{ .id = @intFromEnum(self) }; + } +}; + +pub const max_physics_jobs = c.JPC_MAX_PHYSICS_JOBS; +pub const max_physics_barriers = c.JPC_MAX_PHYSICS_BARRIERS; pub const debug_renderer_enabled = options.enable_debug_renderer; comptime { @@ -58,14 +76,14 @@ pub inline fn isValidBodyPointer(body: *const Body) bool { /// Use `PhysicsSystem.getBodies()` to get all the bodies. /// NOTE: This function is *not* protected by a lock, use with care! pub inline fn tryGetBody(all_bodies: []const *const Body, body_id: BodyId) ?*const Body { - const body = all_bodies[body_id & body_id_index_bits]; + const body = all_bodies[body_id.indexBits()]; return if (isValidBodyPointer(body) and body.id == body_id) body else null; } /// Access a body, will return a `null` if the `body_id` is no longer valid. /// Use `PhysicsSystem.getBodiesMut()` to get all the bodies. /// NOTE: This function is *not* protected by a lock, use with care! pub inline fn tryGetBodyMut(all_bodies: []const *Body, body_id: BodyId) ?*Body { - const body = all_bodies[body_id & body_id_index_bits]; + const body = all_bodies[body_id.indexBits()]; return if (isValidBodyPointer(body) and body.id == body_id) body else null; } @@ -91,57 +109,99 @@ pub fn RefTargetHeader(comptime first_field_align: u29) type { }; } -pub const StreamOut = extern struct { - __v: *const VTable, +fn initInterface(comptime T: type, comptime VTableT: type) *const VTableT { + const vtable_final = comptime blk: { + const vtable_info = @typeInfo(VTableT); + if (vtable_info != .@"struct" or vtable_info.@"struct".layout != .@"extern") + @compileError("vtable struct " ++ @typeName(VTableT) ++ " must be extern"); + + var vtable: VTableT = undefined; + for (vtable_info.@"struct".fields) |field| { + const field_info = @typeInfo(field.type); + + var is_opt = false; + const opt_fn_info: ?std.builtin.Type.Fn = unbox: switch (field_info) { + .optional => |o| { + is_opt = true; + continue :unbox @typeInfo(o.child); + }, + .pointer => |p| continue :unbox @typeInfo(p.child), + .@"fn" => |f| f, + else => null, + }; - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn writeBytes(self: *T, data: [*]const u8, num_bytes: usize) u32 { - return @as(*StreamOut.VTable, @ptrCast(self.__v)) - .writeBytes(@as(*StreamOut, @ptrCast(self)), data, num_bytes); + if (opt_fn_info) |fn_info| { + if (is_opt) + @compileError("vtable function pointer " ++ field.name ++ " must be non-optional"); + + if (!fn_info.calling_convention.eql(std.builtin.CallingConvention.c)) + @compileError("vtable function pointer " ++ field.name ++ " must be callconv(.c)"); + + if (@hasDecl(T, field.name)) { + @field(vtable, field.name) = &@field(T, field.name); + } else { + if (is_opt) { + @field(vtable, field.name) = null; + } else { + @compileError(@typeName(T) ++ " is missing `pub fn " ++ field.name ++ "`: " ++ @typeName(@TypeOf(@field(vtable, field.name)))); + } + } + } else { + if (field.default_value_ptr) |default_value_ptr| { + @field(vtable, field.name) = @as(*const field.type, @alignCast(@ptrCast(default_value_ptr))).*; + } else @compileError("non-pointer vtable field " ++ field.name ++ " must have a default value"); } - pub inline fn isFailed(self: *const T) bool { - return @as(*const StreamOut.VTable, @ptrCast(self.__v)) - .isFailed(@as(*const StreamOut, @ptrCast(self))); - } - }; - } + } + break :blk vtable; + }; - pub const VTable = extern struct { + return &vtable_final; +} + +pub const StreamOut = extern struct { + __v: *const VTable, + + const VTable = extern struct { __header: VTableHeader = .{}, - writeBytes: *const fn (self: *StreamOut, data: [*]const u8, num_bytes: usize) callconv(.C) void, - isFailed: *const fn (self: *StreamOut) callconv(.C) bool, + writeBytes: *const fn (self: *StreamOut, data: [*]const u8, num_bytes: usize) callconv(.c) void, + isFailed: *const fn (self: *StreamOut) callconv(.c) bool, }; + pub fn init(comptime T: type) StreamOut { + return .{ .__v = initInterface(T, VTable) }; + } + + pub fn writeBytes(self: *StreamOut, data: [*]const u8, num_bytes: usize) void { + self.__v.writeBytes(self, data, num_bytes); + } + + pub fn isFailed(self: *StreamOut) bool { + return self.__v.isFailed(self); + } + comptime { assert(@sizeOf(VTable) == @sizeOf(c.JPC_StreamOutVTable)); } }; pub const AnyWriterStreamOut = extern struct { - usingnamespace StreamOut.Methods(@This()); - __v: *const StreamOut.VTable = &vtable, + stream_out: StreamOut = .init(@This()), writer: *const std.io.AnyWriter, failed: bool = false, - const vtable = StreamOut.VTable{ - .writeBytes = _writeBytes, - .isFailed = _isFailed, - }; - pub fn init(writer: *const std.io.AnyWriter) AnyWriterStreamOut { return .{ .writer = writer }; } - fn _writeBytes(iself: *StreamOut, data: [*]const u8, num_bytes: usize) callconv(.C) void { - const self = @as(*AnyWriterStreamOut, @ptrCast(iself)); + pub fn writeBytes(stream_out: *StreamOut, data: [*]const u8, num_bytes: usize) callconv(.c) void { + const self: *AnyWriterStreamOut = @alignCast(@fieldParentPtr("stream_out", stream_out)); self.writer.writeAll(data[0..num_bytes]) catch { self.failed = true; }; } - fn _isFailed(iself: *StreamOut) callconv(.C) bool { - const self = @as(*AnyWriterStreamOut, @ptrCast(iself)); + pub fn isFailed(stream_out: *StreamOut) callconv(.c) bool { + const self: *AnyWriterStreamOut = @alignCast(@fieldParentPtr("stream_out", stream_out)); return self.failed; } }; @@ -149,67 +209,47 @@ pub const AnyWriterStreamOut = extern struct { pub const StreamIn = extern struct { __v: *const VTable, - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn readBytes(self: *T, data: [*]u8, num_bytes: usize) u32 { - return @as(*StreamIn.VTable, @ptrCast(self.__v)) - .readBytes(@as(*StreamIn, @ptrCast(self)), data, num_bytes); - } - pub inline fn isEOF(self: *const T) bool { - return @as(*const StreamIn.VTable, @ptrCast(self.__v)) - .isEof(@as(*const StreamIn, @ptrCast(self))); - } - pub inline fn isFailed(self: *const T) bool { - return @as(*const StreamIn.VTable, @ptrCast(self.__v)) - .isFailed(@as(*const StreamIn, @ptrCast(self))); - } - }; - } - pub const VTable = extern struct { __header: VTableHeader = .{}, - readBytes: *const fn (self: *StreamIn, data: [*]u8, num_bytes: usize) callconv(.C) void, - isEof: *const fn (self: *StreamIn) callconv(.C) bool, - isFailed: *const fn (self: *StreamIn) callconv(.C) bool, + readBytes: *const fn (self: *StreamIn, data: [*]u8, num_bytes: usize) callconv(.c) void, + isEof: *const fn (self: *StreamIn) callconv(.c) bool, + isFailed: *const fn (self: *StreamIn) callconv(.c) bool, }; + pub fn init(comptime T: type) StreamIn { + return .{ .__v = initInterface(T, VTable) }; + } + comptime { assert(@sizeOf(VTable) == @sizeOf(c.JPC_StreamInVTable)); } }; pub const AnyReaderStreamIn = extern struct { - usingnamespace StreamIn.Methods(@This()); - __v: *const StreamIn.VTable = &vtable, + stream_in: StreamIn = .init(@This()), reader: *const std.io.AnyReader, failed: bool = false, eof: bool = false, - const vtable = StreamIn.VTable{ - .readBytes = _readBytes, - .isEof = _isEof, - .isFailed = _isFailed, - }; - pub fn init(reader: *const std.io.AnyReader) AnyReaderStreamIn { return .{ .reader = reader }; } - fn _readBytes(iself: *StreamIn, data: [*]u8, num_bytes: usize) callconv(.C) void { - const self = @as(*AnyReaderStreamIn, @ptrCast(iself)); + pub fn readBytes(stream_in: *StreamIn, data: [*]u8, num_bytes: usize) callconv(.c) void { + const self: *@This() = @alignCast(@fieldParentPtr("stream_in", stream_in)); self.reader.readNoEof(data[0..num_bytes]) catch |err| switch (err) { error.EndOfStream => self.eof = true, else => self.failed = true, }; } - fn _isEof(iself: *StreamIn) callconv(.C) bool { - const self = @as(*AnyReaderStreamIn, @ptrCast(iself)); + pub fn isEof(stream_in: *StreamIn) callconv(.c) bool { + const self: *@This() = @alignCast(@fieldParentPtr("stream_in", stream_in)); return self.eof; } - fn _isFailed(iself: *StreamIn) callconv(.C) bool { - const self = @as(*AnyReaderStreamIn, @ptrCast(iself)); + pub fn isFailed(stream_in: *StreamIn) callconv(.c) bool { + const self: *@This() = @alignCast(@fieldParentPtr("stream_in", stream_in)); return self.failed; } }; @@ -217,35 +257,24 @@ pub const AnyReaderStreamIn = extern struct { pub const BroadPhaseLayerInterface = extern struct { __v: *const VTable, - pub usingnamespace Methods(@This()); - - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn getNumBroadPhaseLayers(self: *const T) u32 { - return @as(*const BroadPhaseLayerInterface.VTable, @ptrCast(self.__v)) - .getNumBroadPhaseLayers(@as(*const BroadPhaseLayerInterface, @ptrCast(self))); - } - pub inline fn getBroadPhaseLayer(self: *const T, layer: ObjectLayer) u32 { - return @as(*const BroadPhaseLayerInterface.VTable, @ptrCast(self.__v)) - .getBroadPhaseLayer(@as(*const BroadPhaseLayerInterface, @ptrCast(self)), layer); - } - }; + pub fn init(comptime T: type) BroadPhaseLayerInterface { + return .{ .__v = initInterface(T, VTable) }; } pub const VTable = extern struct { __header: VTableHeader = .{}, - getNumBroadPhaseLayers: *const fn (self: *const BroadPhaseLayerInterface) callconv(.C) u32, + getNumBroadPhaseLayers: *const fn (self: *const BroadPhaseLayerInterface) callconv(.c) u32, getBroadPhaseLayer: if (@import("builtin").abi == .msvc) *const fn ( self: *const BroadPhaseLayerInterface, out_layer: *BroadPhaseLayer, layer: ObjectLayer, - ) callconv(.C) *const BroadPhaseLayer + ) callconv(.c) *const BroadPhaseLayer else *const fn ( self: *const BroadPhaseLayerInterface, layer: ObjectLayer, - ) callconv(.C) BroadPhaseLayer, + ) callconv(.c) BroadPhaseLayer, }; comptime { @@ -260,15 +289,8 @@ pub const BroadPhaseLayerInterface = extern struct { pub const ObjectVsBroadPhaseLayerFilter = extern struct { __v: *const VTable, - pub usingnamespace Methods(@This()); - - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn shouldCollide(self: *const T, layer1: ObjectLayer, layer2: BroadPhaseLayer) bool { - return @as(*const ObjectVsBroadPhaseLayerFilter.VTable, @ptrCast(self.__v)) - .shouldCollide(@as(*const ObjectVsBroadPhaseLayerFilter, @ptrCast(self)), layer1, layer2); - } - }; + pub fn init(comptime T: type) ObjectVsBroadPhaseLayerFilter { + return .{ .__v = initInterface(T, VTable) }; } pub const VTable = extern struct { @@ -277,7 +299,7 @@ pub const ObjectVsBroadPhaseLayerFilter = extern struct { self: *const ObjectVsBroadPhaseLayerFilter, layer1: ObjectLayer, layer2: BroadPhaseLayer, - ) callconv(.C) bool, + ) callconv(.c) bool, }; comptime { @@ -292,15 +314,8 @@ pub const ObjectVsBroadPhaseLayerFilter = extern struct { pub const BroadPhaseLayerFilter = extern struct { __v: *const VTable, - pub usingnamespace Methods(@This()); - - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn shouldCollide(self: *const T, layer: BroadPhaseLayer) bool { - return @as(*const BroadPhaseLayerFilter.VTable, @ptrCast(self.__v)) - .shouldCollide(@as(*const BroadPhaseLayerFilter, @ptrCast(self)), layer); - } - }; + pub fn init(comptime T: type) BroadPhaseLayerFilter { + return .{ .__v = initInterface(T, VTable) }; } pub const VTable = extern struct { @@ -308,7 +323,7 @@ pub const BroadPhaseLayerFilter = extern struct { shouldCollide: *const fn ( self: *const BroadPhaseLayerFilter, layer: BroadPhaseLayer, - ) callconv(.C) bool, + ) callconv(.c) bool, }; comptime { @@ -322,20 +337,13 @@ pub const BroadPhaseLayerFilter = extern struct { pub const ObjectLayerPairFilter = extern struct { __v: *const VTable, - pub usingnamespace Methods(@This()); - - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn shouldCollide(self: *const T, layer1: ObjectLayer, layer2: ObjectLayer) bool { - return @as(*const ObjectLayerPairFilter.VTable, @ptrCast(self.__v)) - .shouldCollide(@as(*const ObjectLayerPairFilter, @ptrCast(self)), layer1, layer2); - } - }; + pub fn init(comptime T: type) ObjectLayerPairFilter { + return .{ .__v = initInterface(T, VTable) }; } pub const VTable = extern struct { __header: VTableHeader = .{}, - shouldCollide: *const fn (self: *const ObjectLayerPairFilter, ObjectLayer, ObjectLayer) callconv(.C) bool, + shouldCollide: *const fn (self: *const ObjectLayerPairFilter, ObjectLayer, ObjectLayer) callconv(.c) bool, }; comptime { @@ -349,20 +357,13 @@ pub const ObjectLayerPairFilter = extern struct { pub const ObjectLayerFilter = extern struct { __v: *const VTable, - pub usingnamespace Methods(@This()); - - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn shouldCollide(self: *const T, layer: ObjectLayer) bool { - return @as(*const ObjectLayerFilter.VTable, @ptrCast(self.__v)) - .shouldCollide(@as(*const ObjectLayerFilter, @ptrCast(self)), layer); - } - }; + pub fn init(comptime T: type) ObjectLayerFilter { + return .{ .__v = initInterface(T, VTable) }; } pub const VTable = extern struct { __header: VTableHeader = .{}, - shouldCollide: *const fn (self: *const ObjectLayerFilter, ObjectLayer) callconv(.C) bool, + shouldCollide: *const fn (self: *const ObjectLayerFilter, ObjectLayer) callconv(.c) bool, }; comptime { @@ -381,20 +382,13 @@ pub const PhysicsStepListenerContext = extern struct { pub const PhysicsStepListener = extern struct { __v: *const VTable, - pub usingnamespace Methods(@This()); - - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn onStep(self: *const T, context: *const PhysicsStepListenerContext) void { - return @as(*const PhysicsStepListener.VTable, @ptrCast(self.__v)) - .onStep(@as(*PhysicsStepListener, @ptrCast(self)), context); - } - }; + pub fn init(comptime T: type) PhysicsStepListener { + return .{ .__v = initInterface(T, VTable) }; } pub const VTable = extern struct { __header: VTableHeader = .{}, - onStep: *const fn (self: *PhysicsStepListener, *const PhysicsStepListenerContext) callconv(.C) void, + onStep: *const fn (self: *PhysicsStepListener, *const PhysicsStepListenerContext) callconv(.c) void, }; comptime { @@ -406,27 +400,8 @@ pub const PhysicsStepListener = extern struct { pub const BodyActivationListener = extern struct { __v: *const VTable, - pub usingnamespace Methods(@This()); - - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn onBodyActivated( - self: *T, - body_id: *const BodyId, - user_data: u64, - ) void { - @as(*const BodyActivationListener.VTable, @ptrCast(self.__v)) - .onBodyActivated(@as(*const BodyActivationListener, @ptrCast(self)), body_id, user_data); - } - pub inline fn onBodyDeactivated( - self: *T, - body_id: *const BodyId, - user_data: u64, - ) void { - @as(*const BodyActivationListener.VTable, @ptrCast(self.__v)) - .onBodyDeactivated(@as(*const BodyActivationListener, @ptrCast(self)), body_id, user_data); - } - }; + pub fn init(comptime T: type) BodyActivationListener { + return .{ .__v = initInterface(T, VTable) }; } pub const VTable = extern struct { @@ -435,12 +410,12 @@ pub const BodyActivationListener = extern struct { self: *BodyActivationListener, body_id: *const BodyId, user_data: u64, - ) callconv(.C) void, + ) callconv(.c) void, onBodyDeactivated: *const fn ( self: *BodyActivationListener, body_id: *const BodyId, user_data: u64, - ) callconv(.C) void, + ) callconv(.c) void, }; comptime { @@ -455,140 +430,8 @@ pub const BodyActivationListener = extern struct { pub const CharacterContactListener = extern struct { __v: *const VTable, - pub usingnamespace Methods(@This()); - - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn OnAdjustBodyVelocity( - self: *const T, - character: *const CharacterVirtual, - body: *const Body, - io_linear_velocity: *[3]f32, - io_angular_velocity: *[3]f32, - ) void { - return @as(*const CharacterContactListener.VTable, @ptrCast(self.__v)).OnAdjustBodyVelocity( - @as(*CharacterContactListener, @ptrCast(self)), - character, - body, - io_linear_velocity, - io_angular_velocity, - ); - } - pub inline fn OnContactValidate( - self: *const T, - character: *const CharacterVirtual, - body: *const Body, - sub_shape_id: *const SubShapeId, - ) bool { - return @as(*const CharacterContactListener.VTable, @ptrCast(self.__v)).OnContactValidate( - @as(*CharacterContactListener, @ptrCast(self)), - character, - body, - sub_shape_id, - ); - } - pub inline fn OnCharacterContactValidate( - self: *const T, - character: *const CharacterVirtual, - other_character: *const CharacterVirtual, - sub_shape_id: *const SubShapeId, - ) bool { - return @as(*const CharacterContactListener.VTable, @ptrCast(self.__v)).OnCharacterContactValidate( - @as(*CharacterContactListener, @ptrCast(self)), - character, - other_character, - sub_shape_id, - ); - } - pub inline fn OnContactAdded( - self: *const T, - character: *const CharacterVirtual, - body: *const Body, - sub_shape_id: *const SubShapeId, - contact_position: *const [3]Real, - contact_normal: *const [3]f32, - io_settings: *CharacterContactSettings, - ) void { - return @as(*const CharacterContactListener.VTable, @ptrCast(self.__v)).OnContactAdded( - @as(*CharacterContactListener, @ptrCast(self)), - character, - body, - sub_shape_id, - contact_position, - contact_normal, - io_settings, - ); - } - pub inline fn OnCharacterContactAdded( - self: *const T, - character: *const CharacterVirtual, - other_character: *const CharacterVirtual, - sub_shape_id: *const SubShapeId, - contact_position: *const [3]Real, - contact_normal: *const [3]f32, - io_settings: *CharacterContactSettings, - ) void { - return @as(*const CharacterContactListener.VTable, @ptrCast(self.__v)).OnCharacterContactAdded( - @as(*CharacterContactListener, @ptrCast(self)), - character, - other_character, - sub_shape_id, - contact_position, - contact_normal, - io_settings, - ); - } - pub inline fn OnContactSolve( - self: *const T, - character: *const CharacterVirtual, - body: *const Body, - sub_shape_id: *const SubShapeId, - contact_position: *const [3]Real, - contact_normal: *const [3]f32, - contact_velocity: *const [3]f32, - contact_material: *const Material, - character_velocity: *const [3]f32, - character_velocity_out: *[3]f32, - ) void { - return @as(*const CharacterContactListener.VTable, @ptrCast(self.__v)).OnContactSolve( - @as(*CharacterContactListener, @ptrCast(self)), - character, - body, - sub_shape_id, - contact_position, - contact_normal, - contact_velocity, - contact_material, - character_velocity, - character_velocity_out, - ); - } - pub inline fn OnCharacterContactSolve( - self: *const T, - character: *const CharacterVirtual, - other_character: *const CharacterVirtual, - sub_shape_id: *const SubShapeId, - contact_position: *const [3]Real, - contact_normal: *const [3]f32, - contact_velocity: *const [3]f32, - contact_material: *const Material, - character_velocity: *const [3]f32, - character_velocity_out: *[3]f32, - ) void { - return @as(*const CharacterContactListener.VTable, @ptrCast(self.__v)).OnCharacterContactSolve( - @as(*CharacterContactListener, @ptrCast(self)), - character, - other_character, - sub_shape_id, - contact_position, - contact_normal, - contact_velocity, - contact_material, - character_velocity, - character_velocity_out, - ); - } - }; + pub fn init(comptime T: type) CharacterContactListener { + return .{ .__v = initInterface(T, VTable) }; } pub const VTable = extern struct { @@ -599,19 +442,19 @@ pub const CharacterContactListener = extern struct { body: *const Body, io_linear_velocity: *[3]f32, io_angular_velocity: *[3]f32, - ) callconv(.C) void, + ) callconv(.c) void, OnContactValidate: *const fn ( self: *CharacterContactListener, character: *const CharacterVirtual, body: *const Body, sub_shape_id: *const SubShapeId, - ) callconv(.C) bool, + ) callconv(.c) bool, OnCharacterContactValidate: *const fn ( self: *CharacterContactListener, character: *const CharacterVirtual, other_character: *const CharacterVirtual, sub_shape_id: *const SubShapeId, - ) callconv(.C) bool, + ) callconv(.c) bool, OnContactAdded: *const fn ( self: *CharacterContactListener, character: *const CharacterVirtual, @@ -620,7 +463,7 @@ pub const CharacterContactListener = extern struct { contact_position: *const [3]Real, contact_normal: *const [3]f32, io_settings: *CharacterContactSettings, - ) callconv(.C) void, + ) callconv(.c) void, OnCharacterContactAdded: *const fn ( self: *CharacterContactListener, character: *const CharacterVirtual, @@ -629,7 +472,7 @@ pub const CharacterContactListener = extern struct { contact_position: *const [3]Real, contact_normal: *const [3]f32, io_settings: *CharacterContactSettings, - ) callconv(.C) void, + ) callconv(.c) void, OnContactSolve: *const fn ( self: *CharacterContactListener, character: *const CharacterVirtual, @@ -641,7 +484,7 @@ pub const CharacterContactListener = extern struct { contact_material: *const Material, character_velocity: *const [3]f32, character_velocity_out: *[3]f32, - ) callconv(.C) void, + ) callconv(.c) void, OnCharacterContactSolve: *const fn ( self: *CharacterContactListener, character: *const CharacterVirtual, @@ -653,7 +496,7 @@ pub const CharacterContactListener = extern struct { contact_material: *const Material, character_velocity: *const [3]f32, character_velocity_out: *[3]f32, - ) callconv(.C) void, + ) callconv(.c) void, }; comptime { @@ -666,86 +509,36 @@ pub const CharacterContactListener = extern struct { pub const ContactListener = extern struct { __v: *const VTable, - pub usingnamespace Methods(@This()); - - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn onContactValidate( - self: *T, - body1: *const Body, - body2: *const Body, - base_offset: *const [3]Real, - collision_result: *const CollideShapeResult, - ) ValidateResult { - return @as(*const ContactListener.VTable, @ptrCast(self.__v)) - .onContactValidate( - @as(*const ContactListener, @ptrCast(self)), - body1, - body2, - base_offset, - collision_result, - ); - } - pub inline fn onContactAdded( - self: *T, - body1: *const Body, - body2: *const Body, - manifold: *const ContactManifold, - settings: *ContactSettings, - ) void { - @as(*const ContactListener.VTable, @ptrCast(self.__v)) - .onContactAdded(@as(*const ContactListener, @ptrCast(self)), body1, body2, manifold, settings); - } - pub inline fn onContactPersisted( - self: *T, - body1: *const Body, - body2: *const Body, - manifold: *const ContactManifold, - settings: *ContactSettings, - ) void { - @as(*const ContactListener.VTable, @ptrCast(self.__v)) - .onContactPersisted(@as(*const ContactListener, @ptrCast(self)), body1, body2, manifold, settings); - } - pub inline fn onContactRemoved( - self: *T, - sub_shape_pair: *const SubShapeIdPair, - ) void { - @as(*const ContactListener.VTable, @ptrCast(self.__v)) - .onContactRemoved(@as(*const ContactListener, @ptrCast(self)), sub_shape_pair); - } - }; + pub fn init(comptime T: type) ContactListener { + return .{ .__v = initInterface(T, VTable) }; } pub const VTable = extern struct { - __header: VTableHeader = .{}, - onContactValidate: ?*const fn ( + onContactValidate: *const fn ( self: *ContactListener, body1: *const Body, body2: *const Body, base_offset: *const [3]Real, collision_result: *const CollideShapeResult, - ) callconv(.C) ValidateResult = null, - - onContactAdded: ?*const fn ( + ) callconv(.c) ValidateResult, + onContactAdded: *const fn ( self: *ContactListener, body1: *const Body, body2: *const Body, manifold: *const ContactManifold, settings: *ContactSettings, - ) callconv(.C) void = null, - - onContactPersisted: ?*const fn ( + ) callconv(.c) void, + onContactPersisted: *const fn ( self: *ContactListener, body1: *const Body, body2: *const Body, manifold: *const ContactManifold, settings: *ContactSettings, - ) callconv(.C) void = null, - - onContactRemoved: ?*const fn ( + ) callconv(.c) void, + onContactRemoved: *const fn ( self: *ContactListener, sub_shape_pair: *const SubShapeIdPair, - ) callconv(.C) void = null, + ) callconv(.c) void, }; comptime { @@ -763,25 +556,14 @@ pub const ContactListener = extern struct { pub const BodyFilter = extern struct { __v: *const VTable, - pub usingnamespace Methods(@This()); - - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn shouldCollide(self: *const T, body_id: *const BodyId) bool { - return @as(*const BodyFilter.VTable, @ptrCast(self.__v)) - .shouldCollide(@as(*const BodyFilter, @ptrCast(self)), body_id); - } - pub inline fn shouldCollideLocked(self: *const T, body: *const Body) bool { - return @as(*const BodyFilter.VTable, @ptrCast(self.__v)) - .shouldCollideLocked(@as(*const BodyFilter, @ptrCast(self)), body); - } - }; + pub fn init(comptime T: type) BodyFilter { + return .{ .__v = initInterface(T, VTable) }; } pub const VTable = extern struct { __header: VTableHeader = .{}, - shouldCollide: *const fn (self: *const BodyFilter, body_id: *const BodyId) callconv(.C) bool, - shouldCollideLocked: *const fn (self: *const BodyFilter, body: *const Body) callconv(.C) bool, + shouldCollide: *const fn (self: *const BodyFilter, body_id: *const BodyId) callconv(.c) bool, + shouldCollideLocked: *const fn (self: *const BodyFilter, body: *const Body) callconv(.c) bool, }; comptime { @@ -796,36 +578,8 @@ pub const BodyFilter = extern struct { pub const ShapeFilter = extern struct { __v: *const VTable, - pub usingnamespace Methods(@This()); - - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn shouldCollide( - self: *const T, - receiving_body_id: u32, - shape: *const Shape, - sub_shape_id: *const SubShapeId, - ) bool { - _ = receiving_body_id; - return @as(*const ShapeFilter.VTable, @ptrCast(self.__v)).shouldCollide( - @as(*const ShapeFilter, @ptrCast(self)), - @as(*const ShapeFilter.VTable, @ptrCast(self.__v)).receiving_body_id, - shape, - sub_shape_id, - ); - } - pub inline fn pairShouldCollide( - self: *const T, - receiving_body_id: u32, - shape1: *const Shape, - sub_shape_id1: *const SubShapeId, - shape2: *const Shape, - sub_shape_id2: *const SubShapeId, - ) bool { - _ = receiving_body_id; - return @as(*const ShapeFilter.VTable, @ptrCast(self.__v)).pairShouldCollide(@as(*const ShapeFilter, @ptrCast(self)), @as(*const ShapeFilter.VTable, @ptrCast(self.__v)).receiving_body_id, shape1, sub_shape_id1, shape2, sub_shape_id2); - } - }; + pub fn init(comptime T: type) ShapeFilter { + return .{ .__v = initInterface(T, VTable) }; } pub const VTable = extern struct { @@ -834,15 +588,15 @@ pub const ShapeFilter = extern struct { self: *const ShapeFilter, shape: *const Shape, sub_shape_id: *const SubShapeId, - ) callconv(.C) bool, + ) callconv(.c) bool, pairShouldCollide: *const fn ( self: *const ShapeFilter, shape1: *const Shape, sub_shape_id1: *const SubShapeId, shape2: *const Shape, sub_shape_id2: *const SubShapeId, - ) callconv(.C) bool, - receiving_body_id: u32 = body_id_invalid, // set by jolt before each call to either of the functions above + ) callconv(.c) bool, + receiving_body_id: BodyId = .invalid, // set by jolt before each call to either of the functions above }; comptime { @@ -906,7 +660,7 @@ pub const SubShapeIdPair = extern struct { }; pub const SubShapeIDCreator = extern struct { - id: SubShapeId = sub_shape_id_empty, + id: SubShapeId = .empty, current_bit: u32 = 0, comptime { @@ -1194,7 +948,7 @@ pub const RRayCast = extern struct { }; pub const RayCastResult = extern struct { - body_id: BodyId = body_id_invalid, + body_id: BodyId = .invalid, fraction: f32 = 1.0 + flt_epsilon, sub_shape_id: SubShapeId = undefined, @@ -1259,6 +1013,10 @@ pub const RMatrix = extern struct { }; pub const DebugRenderer = if (!debug_renderer_enabled) extern struct {} else extern struct { + pub fn initVTable(comptime T: type) *const VTable(T) { + return initInterface(T, VTable(T)); + } + pub fn createSingleton(debug_renderer_impl: *anyopaque) !void { switch (@as(DebugRendererResult, @enumFromInt(c.JPC_CreateDebugRendererSingleton(debug_renderer_impl)))) { .success => { @@ -1296,136 +1054,45 @@ pub const DebugRenderer = if (!debug_renderer_enabled) extern struct {} else ext c.JPC_BodyDrawFilter_Destroy(@ptrCast(filter)); } - pub fn Methods(comptime T: type) type { - return extern struct { - pub inline fn drawLine(self: *T, from: *const [3]Real, to: *const [3]Real, color: Color) void { - return @as(*const DebugRenderer.VTable(T), @ptrCast(self.__v)) - .drawLine( - @as(*const T, @ptrCast(self)), - from, - to, - color, - ); - } - pub inline fn drawTriangle( - self: *T, - v1: *const [3]Real, - v2: *const [3]Real, - v3: *const [3]Real, - color: Color, - ) void { - return @as(*const DebugRenderer.VTable(T), @ptrCast(self.__v)) - .drawTriangle( - @as(*const T, @ptrCast(self)), - v1, - v2, - v3, - color, - ); - } - pub inline fn createTriangleBatch( - self: *T, - triangles: []Triangle, - triangle_count: u32, - ) T.Batch { - return @as(*const DebugRenderer.VTable(T), @ptrCast(self.__v)) - .createTriangleBatch( - @as(*const T, @ptrCast(self)), - triangles, - triangle_count, - ); - } - pub inline fn createTriangleBatchIndexed( - self: *T, - vertices: []Vertex, - vertex_count: u32, - indices: []u32, - index_count: u32, - ) T.Batch { - return @as(*const DebugRenderer.VTable(T), @ptrCast(self.__v)) - .createTriangleBatchIndexed( - @as(*const T, @ptrCast(self)), - vertices, - vertex_count, - indices, - index_count, - ); - } - pub inline fn drawGeometry( - self: *T, - model_matrix: *const RMatrix, - world_space_bound: *const AABox, - lod_scale_sq: f32, - color: Color, - geometry: *const Geometry, - cull_mode: CullMode, - cast_shadow: CastShadow, - draw_mode: DrawMode, - ) void { - return @as(*const DebugRenderer.VTable(T), @ptrCast(self.__v)) - .drawGeometry( - @as(*const T, @ptrCast(self)), - model_matrix, - world_space_bound, - lod_scale_sq, - color, - geometry, - cull_mode, - cast_shadow, - draw_mode, - ); - } - pub inline fn drawText3D( - self: *T, - positions: *const [3]Real, - string: [*:0]const u8, - color: Color, - height: f32, - ) void { - return @as(*const DebugRenderer.VTable(T), @ptrCast(self.__v)) - .drawText3D( - @as(*const T, @ptrCast(self)), - positions, - string, - color, - height, - ); - } - }; - } - pub fn VTable(comptime T: type) type { return extern struct { - drawLine: ?*const fn ( + drawLine: *const fn ( self: *T, from: *const [3]Real, to: *const [3]Real, color: Color, - ) callconv(.C) void = null, - drawTriangle: ?*const fn ( + ) callconv(.c) void, + drawTriangle: *const fn ( self: *T, v1: *const [3]Real, v2: *const [3]Real, v3: *const [3]Real, color: Color, - ) callconv(.C) void = null, - createTriangleBatch: ?*const fn ( + ) callconv(.c) void, + /// Implementations should call `DebugRenderer.createTriangleBatch` to + /// allocate the reference-counted TriangleBatch + createTriangleBatch: *const fn ( self: *T, triangles: [*]Triangle, triangle_count: u32, - ) callconv(.C) *anyopaque = null, - createTriangleBatchIndexed: ?*const fn ( + ) callconv(.c) *TriangleBatch, + /// Implementations should call `DebugRenderer.createTriangleBatch` to + /// allocate the reference-counted TriangleBatch + createTriangleBatchIndexed: *const fn ( self: *T, vertices: [*]Vertex, vertex_count: u32, indices: [*]u32, index_count: u32, - ) callconv(.C) *anyopaque = null, - destroyTriangleBatch: ?*const fn ( + ) callconv(.c) *TriangleBatch, + /// Will be called when the reference count of the TriangleBatch + /// returned by the above functions reaches zero. `batch` will be the + /// value that was passed to `DebugRenderer.createTriangleBatch`. + destroyTriangleBatch: *const fn ( self: *T, - batch: *const anyopaque, - ) callconv(.C) void = null, - drawGeometry: ?*const fn ( + batch: *TriangleBatch, + ) callconv(.c) void, + drawGeometry: *const fn ( self: *T, model_matrix: *const RMatrix, world_space_bound: *const AABox, @@ -1435,14 +1102,14 @@ pub const DebugRenderer = if (!debug_renderer_enabled) extern struct {} else ext cull_mode: CullMode, cast_shadow: CastShadow, draw_mode: DrawMode, - ) callconv(.C) void = null, - drawText3D: ?*const fn ( + ) callconv(.c) void, + drawText3D: *const fn ( self: *T, positions: *const [3]Real, string: [*:0]const u8, color: Color, height: f32, - ) callconv(.C) void = null, + ) callconv(.c) void, }; } @@ -1492,7 +1159,7 @@ pub const DebugRenderer = if (!debug_renderer_enabled) extern struct {} else ext }; // zig fmt: on - pub const BodyDrawFilterFunc = *const fn (*const Body) callconv(.C) bool; + pub const BodyDrawFilterFunc = *const fn (*const Body) callconv(.c) bool; pub const BodyDrawFilter = opaque {}; pub const TriangleBatch = opaque {}; @@ -1560,13 +1227,13 @@ pub const GlobalState = struct { }; var state: ?GlobalState = null; -pub const TraceFunc = *const fn (fmt: ?[*:0]const u8, ...) callconv(.C) void; +pub const TraceFunc = *const fn (fmt: ?[*:0]const u8, ...) callconv(.c) void; pub const AssertFailedFunc = *const fn ( expression: ?[*:0]const u8, message: ?[*:0]const u8, file: ?[*:0]const u8, line: u32, -) callconv(.C) bool; +) callconv(.c) bool; pub fn init(allocator: std.mem.Allocator, args: struct { temp_allocator_size: u32 = 16 * 1024 * 1024, @@ -1787,31 +1454,30 @@ pub const PhysicsSystem = opaque { } } - pub usingnamespace if (!debug_renderer_enabled) struct {} else struct { - pub fn drawBodies( - physics_system: *PhysicsSystem, - in_draw_settings: *const DebugRenderer.BodyDrawSettings, - in_draw_filter: ?*const DebugRenderer.BodyDrawFilter, - ) void { - c.JPC_PhysicsSystem_DrawBodies( - @as(*c.JPC_PhysicsSystem, @ptrCast(physics_system)), - @as(*const c.JPC_BodyManager_DrawSettings, @ptrCast(in_draw_settings)), - @as(?*const c.JPC_BodyDrawFilter, @ptrCast(in_draw_filter)), - ); - } + pub const drawBodies = if (debug_renderer_enabled) _drawBodies else void; + pub const drawConstraints = if (debug_renderer_enabled) _drawConstraints else void; + pub const drawConstraintLimits = if (debug_renderer_enabled) _drawConstraintLimits else void; + pub const drawConstraintReferenceFrame = if (debug_renderer_enabled) _drawConstraintReferenceFrame else void; - pub fn drawConstraints(physics_system: *PhysicsSystem) void { - c.JPC_PhysicsSystem_DrawConstraints(@as(*c.JPC_PhysicsSystem, @ptrCast(physics_system))); - } + fn _drawBodies( + physics_system: *PhysicsSystem, + in_draw_settings: *const DebugRenderer.BodyDrawSettings, + in_draw_filter: ?*const DebugRenderer.BodyDrawFilter, + ) void { + c.JPC_PhysicsSystem_DrawBodies(@ptrCast(physics_system), @ptrCast(in_draw_settings), @ptrCast(in_draw_filter)); + } - pub fn drawConstraintLimits(physics_system: *PhysicsSystem) void { - c.JPC_PhysicsSystem_DrawConstraintLimits(@as(*c.JPC_PhysicsSystem, @ptrCast(physics_system))); - } + fn _drawConstraints(physics_system: *PhysicsSystem) void { + c.JPC_PhysicsSystem_DrawConstraints(@ptrCast(physics_system)); + } - pub fn drawConstraintReferenceFrame(physics_system: *PhysicsSystem) void { - c.JPC_PhysicsSystem_DrawConstraintReferenceFrame(@as(*c.JPC_PhysicsSystem, @ptrCast(physics_system))); - } - }; + fn _drawConstraintLimits(physics_system: *PhysicsSystem) void { + c.JPC_PhysicsSystem_DrawConstraintLimits(@ptrCast(physics_system)); + } + + fn _drawConstraintReferenceFrame(physics_system: *PhysicsSystem) void { + c.JPC_PhysicsSystem_DrawConstraintReferenceFrame(@ptrCast(physics_system)); + } pub fn getBodyIds(physics_system: *const PhysicsSystem, body_ids: *std.ArrayList(BodyId)) !void { try body_ids.ensureTotalCapacityPrecise(physics_system.getMaxBodies()); @@ -1820,7 +1486,7 @@ pub const PhysicsSystem = opaque { @as(*const c.JPC_PhysicsSystem, @ptrCast(physics_system)), @as(u32, @intCast(body_ids.capacity)), &num_body_ids, - body_ids.items.ptr, + @ptrCast(body_ids.items.ptr), ); body_ids.items.len = num_body_ids; } @@ -1832,7 +1498,7 @@ pub const PhysicsSystem = opaque { @as(*const c.JPC_PhysicsSystem, @ptrCast(physics_system)), @as(u32, @intCast(body_ids.capacity)), &num_body_ids, - body_ids.items.ptr, + @ptrCast(body_ids.items.ptr), ); body_ids.items.len = num_body_ids; } @@ -1867,7 +1533,7 @@ pub const BodyLockRead = extern struct { ) void { c.JPC_BodyLockInterface_LockRead( @as(*const c.JPC_BodyLockInterface, @ptrCast(lock_interface)), - body_id, + body_id.toJpc(), @as(*c.JPC_BodyLockRead, @ptrCast(read_lock)), ); } @@ -1898,7 +1564,7 @@ pub const BodyLockWrite = extern struct { ) void { c.JPC_BodyLockInterface_LockWrite( @as(*const c.JPC_BodyLockInterface, @ptrCast(lock_interface)), - body_id, + body_id.toJpc(), @as(*c.JPC_BodyLockWrite, @ptrCast(write_lock)), ); } @@ -1935,7 +1601,7 @@ pub const BodyInterface = opaque { pub fn createBodyWithId(body_iface: *BodyInterface, body_id: BodyId, settings: BodyCreationSettings) !*Body { const body = c.JPC_BodyInterface_CreateBodyWithID( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), @as(*const c.JPC_BodyCreationSettings, @ptrCast(&settings)), ); if (body == null) @@ -1944,24 +1610,34 @@ pub const BodyInterface = opaque { } pub fn destroyBody(body_iface: *BodyInterface, body_id: BodyId) void { - c.JPC_BodyInterface_DestroyBody(@as(*c.JPC_BodyInterface, @ptrCast(body_iface)), body_id); + c.JPC_BodyInterface_DestroyBody( + @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), + body_id.toJpc(), + ); } pub fn addBody(body_iface: *BodyInterface, body_id: BodyId, mode: Activation) void { - c.JPC_BodyInterface_AddBody(@as(*c.JPC_BodyInterface, @ptrCast(body_iface)), body_id, @intFromEnum(mode)); + c.JPC_BodyInterface_AddBody( + @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), + body_id.toJpc(), + @intFromEnum(mode), + ); } pub fn removeBody(body_iface: *BodyInterface, body_id: BodyId) void { - c.JPC_BodyInterface_RemoveBody(@as(*c.JPC_BodyInterface, @ptrCast(body_iface)), body_id); + c.JPC_BodyInterface_RemoveBody( + @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), + body_id.toJpc(), + ); } pub fn createAndAddBody(body_iface: *BodyInterface, settings: BodyCreationSettings, mode: Activation) !BodyId { - const body_id = c.JPC_BodyInterface_CreateAndAddBody( + const body_id: BodyId = @enumFromInt(c.JPC_BodyInterface_CreateAndAddBody( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), @as(*const c.JPC_BodyCreationSettings, @ptrCast(&settings)), @intFromEnum(mode), - ); - if (body_id == body_id_invalid) + ).id); + if (body_id == .invalid) return error.FailedToCreateBody; return body_id; } @@ -1972,19 +1648,47 @@ pub const BodyInterface = opaque { } pub fn isAdded(body_iface: *const BodyInterface, body_id: BodyId) bool { - return c.JPC_BodyInterface_IsAdded(@as(*const c.JPC_BodyInterface, @ptrCast(body_iface)), body_id); + return c.JPC_BodyInterface_IsAdded( + @as(*const c.JPC_BodyInterface, @ptrCast(body_iface)), + body_id.toJpc(), + ); } pub fn activate(body_iface: *BodyInterface, body_id: BodyId) void { - return c.JPC_BodyInterface_ActivateBody(@as(*c.JPC_BodyInterface, @ptrCast(body_iface)), body_id); + return c.JPC_BodyInterface_ActivateBody( + @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), + body_id.toJpc(), + ); + } + + pub fn activateBodies(body_iface: *BodyInterface, body_ids: []const BodyId) void { + return c.JPC_BodyInterface_ActivateBodies( + @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), + @ptrCast(body_ids.ptr), + @intCast(body_ids.len), + ); } pub fn deactivate(body_iface: *BodyInterface, body_id: BodyId) void { - return c.JPC_BodyInterface_DeactivateBody(@as(*c.JPC_BodyInterface, @ptrCast(body_iface)), body_id); + return c.JPC_BodyInterface_DeactivateBody( + @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), + body_id.toJpc(), + ); + } + + pub fn deactivateBodies(body_iface: *BodyInterface, body_ids: []const BodyId) void { + return c.JPC_BodyInterface_DeactivateBodies( + @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), + @ptrCast(body_ids.ptr), + @intCast(body_ids.len), + ); } pub fn isActive(body_iface: *const BodyInterface, body_id: BodyId) bool { - return c.JPC_BodyInterface_IsActive(@as(*const c.JPC_BodyInterface, @ptrCast(body_iface)), body_id); + return c.JPC_BodyInterface_IsActive( + @as(*const c.JPC_BodyInterface, @ptrCast(body_iface)), + body_id.toJpc(), + ); } pub fn setLinearAndAngularVelocity( @@ -1995,7 +1699,7 @@ pub const BodyInterface = opaque { ) void { return c.JPC_BodyInterface_SetLinearAndAngularVelocity( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &linear_velocity, &angular_velocity, ); @@ -2008,7 +1712,7 @@ pub const BodyInterface = opaque { var angular: [3]f32 = undefined; c.JPC_BodyInterface_GetLinearAndAngularVelocity( @as(*const c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &linear, &angular, ); @@ -2018,7 +1722,7 @@ pub const BodyInterface = opaque { pub fn setLinearVelocity(body_iface: *BodyInterface, body_id: BodyId, velocity: [3]f32) void { return c.JPC_BodyInterface_SetLinearVelocity( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &velocity, ); } @@ -2026,7 +1730,7 @@ pub const BodyInterface = opaque { var velocity: [3]f32 = undefined; c.JPC_BodyInterface_GetLinearVelocity( @as(*const c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &velocity, ); return velocity; @@ -2035,7 +1739,7 @@ pub const BodyInterface = opaque { pub fn addLinearVelocity(body_iface: *BodyInterface, body_id: BodyId, velocity: [3]f32) void { return c.JPC_BodyInterface_AddLinearVelocity( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &velocity, ); } @@ -2048,7 +1752,7 @@ pub const BodyInterface = opaque { ) void { return c.JPC_BodyInterface_AddLinearAndAngularVelocity( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &linear_velocity, &angular_velocity, ); @@ -2057,7 +1761,7 @@ pub const BodyInterface = opaque { pub fn setAngularVelocity(body_iface: *BodyInterface, body_id: BodyId, velocity: [3]f32) void { return c.JPC_BodyInterface_SetAngularVelocity( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &velocity, ); } @@ -2065,7 +1769,7 @@ pub const BodyInterface = opaque { var velocity: [3]f32 = undefined; c.JPC_BodyInterface_GetAngularVelocity( @as(*const c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &velocity, ); return velocity; @@ -2075,7 +1779,7 @@ pub const BodyInterface = opaque { var velocity: [3]f32 = undefined; c.JPC_BodyInterface_GetPointVelocity( @as(*const c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &point, &velocity, ); @@ -2086,21 +1790,21 @@ pub const BodyInterface = opaque { var position: [3]Real = undefined; c.JPC_BodyInterface_GetPosition( @as(*const c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &position, ); return position; } pub fn setPosition(body_iface: *BodyInterface, body_id: BodyId, in_position: [3]Real, in_activation_type: Activation) void { - c.JPC_BodyInterface_SetPosition(@as(*c.JPC_BodyInterface, @ptrCast(body_iface)), body_id, &in_position, @intFromEnum(in_activation_type)); + c.JPC_BodyInterface_SetPosition(@as(*c.JPC_BodyInterface, @ptrCast(body_iface)), body_id.toJpc(), &in_position, @intFromEnum(in_activation_type)); } pub fn getCenterOfMassPosition(body_iface: *const BodyInterface, body_id: BodyId) [3]Real { var position: [3]Real = undefined; c.JPC_BodyInterface_GetCenterOfMassPosition( @as(*const c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &position, ); return position; @@ -2110,14 +1814,14 @@ pub const BodyInterface = opaque { var rotation: [4]f32 = undefined; c.JPC_BodyInterface_GetRotation( @as(*const c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &rotation, ); return rotation; } pub fn setRotation(body_iface: *BodyInterface, body_id: BodyId, in_rotation: [4]f32, in_activation_type: Activation) void { - c.JPC_BodyInterface_SetRotation(@as(*c.JPC_BodyInterface, @ptrCast(body_iface)), body_id, &in_rotation, @intFromEnum(in_activation_type)); + c.JPC_BodyInterface_SetRotation(@as(*c.JPC_BodyInterface, @ptrCast(body_iface)), body_id.toJpc(), &in_rotation, @intFromEnum(in_activation_type)); } pub fn setPositionRotationAndVelocity( @@ -2130,7 +1834,7 @@ pub const BodyInterface = opaque { ) void { return c.JPC_BodyInterface_SetPositionRotationAndVelocity( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &position, &rotation, &linear_velocity, @@ -2141,14 +1845,14 @@ pub const BodyInterface = opaque { pub fn addForce(body_iface: *BodyInterface, body_id: BodyId, force: [3]f32) void { return c.JPC_BodyInterface_AddForce( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &force, ); } pub fn addForceAtPosition(body_iface: *BodyInterface, body_id: BodyId, force: [3]f32, position: [3]Real) void { return c.JPC_BodyInterface_AddForceAtPosition( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &force, &position, ); @@ -2157,14 +1861,14 @@ pub const BodyInterface = opaque { pub fn addTorque(body_iface: *BodyInterface, body_id: BodyId, torque: [3]f32) void { return c.JPC_BodyInterface_AddTorque( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &torque, ); } pub fn addForceAndTorque(body_iface: *BodyInterface, body_id: BodyId, force: [3]f32, torque: [3]f32) void { return c.JPC_BodyInterface_AddForceAndTorque( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &force, &torque, ); @@ -2173,7 +1877,7 @@ pub const BodyInterface = opaque { pub fn addImpulse(body_iface: *BodyInterface, body_id: BodyId, impulse: [3]f32) void { return c.JPC_BodyInterface_AddImpulse( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &impulse, ); } @@ -2185,7 +1889,7 @@ pub const BodyInterface = opaque { ) void { return c.JPC_BodyInterface_AddImpulseAtPosition( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &impulse, &position, ); @@ -2194,7 +1898,7 @@ pub const BodyInterface = opaque { pub fn addAngularImpulse(body_iface: *BodyInterface, body_id: BodyId, impulse: [3]f32) void { return c.JPC_BodyInterface_AddAngularImpulse( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), &impulse, ); } @@ -2203,7 +1907,7 @@ pub const BodyInterface = opaque { return @as(MotionType, @enumFromInt( c.JPC_BodyInterface_GetMotionType( @ptrCast(body_iface), - body_id, + body_id.toJpc(), ), )); } @@ -2211,20 +1915,23 @@ pub const BodyInterface = opaque { pub fn setMotionType(body_iface: *BodyInterface, body_id: BodyId, in_motion_type: MotionType, in_activation_type: Activation) void { return c.JPC_BodyInterface_SetMotionType( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), @intFromEnum(in_motion_type), @intFromEnum(in_activation_type), ); } pub fn getObjectLayer(body_iface: *BodyInterface, body_id: BodyId) ObjectLayer { - return c.JPC_BodyInterface_GetObjectLayer(@as(*c.JPC_BodyInterface, @ptrCast(body_iface)), body_id); + return c.JPC_BodyInterface_GetObjectLayer( + @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), + body_id.toJpc(), + ); } pub fn setObjectLayer(body_iface: *BodyInterface, body_id: BodyId, in_layer: ObjectLayer) void { c.JPC_BodyInterface_SetObjectLayer( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), - body_id, + body_id.toJpc(), in_layer, ); } @@ -2284,7 +1991,7 @@ pub const Body = extern struct { flags: u8, pub fn getId(body: *const Body) BodyId { - return c.JPC_Body_GetID(@as(*const c.JPC_Body, @ptrCast(body))); + return @enumFromInt(c.JPC_Body_GetID(@as(*const c.JPC_Body, @ptrCast(body))).id); } pub fn isActive(body: *const Body) bool { @@ -2565,7 +2272,7 @@ pub const Body = extern struct { var normal: [3]f32 = undefined; c.JPC_Body_GetWorldSpaceSurfaceNormal( @as(*const c.JPC_Body, @ptrCast(body)), - sub_shape_id, + sub_shape_id.toJpc(), &position, &normal, ); @@ -2987,41 +2694,29 @@ pub const MotionProperties = extern struct { // //-------------------------------------------------------------------------------------------------- pub const ShapeSettings = opaque { - pub usingnamespace Methods(@This()); + pub fn addRef(shape_settings: *ShapeSettings) void { + c.JPC_ShapeSettings_AddRef(@ptrCast(shape_settings)); + } - fn Methods(comptime T: type) type { - return struct { - pub fn asShapeSettings(shape_settings: *const T) *const ShapeSettings { - return @as(*const ShapeSettings, @ptrCast(shape_settings)); - } - pub fn asShapeSettingsMut(shape_settings: *T) *ShapeSettings { - return @as(*ShapeSettings, @ptrCast(shape_settings)); - } + pub fn release(shape_settings: *ShapeSettings) void { + c.JPC_ShapeSettings_Release(@ptrCast(shape_settings)); + } - pub fn addRef(shape_settings: *T) void { - c.JPC_ShapeSettings_AddRef(@as(*c.JPC_ShapeSettings, @ptrCast(shape_settings))); - } - pub fn release(shape_settings: *T) void { - c.JPC_ShapeSettings_Release(@as(*c.JPC_ShapeSettings, @ptrCast(shape_settings))); - } - pub fn getRefCount(shape_settings: *const T) u32 { - return c.JPC_ShapeSettings_GetRefCount(@as(*const c.JPC_ShapeSettings, @ptrCast(shape_settings))); - } + pub fn getRefCount(shape_settings: *const ShapeSettings) u32 { + return c.JPC_ShapeSettings_GetRefCount(@as(*const c.JPC_ShapeSettings, @ptrCast(shape_settings))); + } - pub fn createShape(shape_settings: *const T) !*Shape { - const shape = c.JPC_ShapeSettings_CreateShape(@as(*const c.JPC_ShapeSettings, @ptrCast(shape_settings))); - if (shape == null) - return error.FailedToCreateShape; - return @as(*Shape, @ptrCast(shape)); - } + pub fn createShape(shape_settings: *const ShapeSettings) !*Shape { + return @ptrCast(c.JPC_ShapeSettings_CreateShape(@ptrCast(shape_settings)) orelse + return error.FailedToCreateShape); + } - pub fn getUserData(shape_settings: *const T) u64 { - return c.JPC_ShapeSettings_GetUserData(@as(*const c.JPC_ShapeSettings, @ptrCast(shape_settings))); - } - pub fn setUserData(shape_settings: *T, user_data: u64) void { - return c.JPC_ShapeSettings_SetUserData(@as(*c.JPC_ShapeSettings, @ptrCast(shape_settings)), user_data); - } - }; + pub fn getUserData(shape_settings: *const ShapeSettings) u64 { + return c.JPC_ShapeSettings_GetUserData(@ptrCast(shape_settings)); + } + + pub fn setUserData(shape_settings: *ShapeSettings, user_data: u64) void { + return c.JPC_ShapeSettings_SetUserData(@ptrCast(shape_settings), user_data); } }; //-------------------------------------------------------------------------------------------------- @@ -3030,40 +2725,27 @@ pub const ShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const ConvexShapeSettings = opaque { - pub usingnamespace Methods(@This()); + pub fn asShapeSettings(convex_shape_settings: *ConvexShapeSettings) *ShapeSettings { + return @ptrCast(convex_shape_settings); + } - fn Methods(comptime T: type) type { - return struct { - pub usingnamespace ShapeSettings.Methods(T); + pub fn getMaterial(convex_shape_settings: *const ConvexShapeSettings) ?*const Material { + return @ptrCast(c.JPC_ConvexShapeSettings_GetMaterial(@ptrCast(convex_shape_settings))); + } - pub fn asConvexShapeSettings(convex_shape_settings: *T) *ConvexShapeSettings { - return @as(*ConvexShapeSettings, @ptrCast(convex_shape_settings)); - } + pub fn setMaterial(convex_shape_settings: *ConvexShapeSettings, material: ?*Material) void { + c.JPC_ConvexShapeSettings_SetMaterial( + @ptrCast(convex_shape_settings), + @ptrCast(material), + ); + } - pub fn getMaterial(convex_shape_settings: *const T) ?*const Material { - return @as(?*const Material, @ptrCast(c.JPC_ConvexShapeSettings_GetMaterial( - @as(*const c.JPC_ConvexShapeSettings, @ptrCast(convex_shape_settings)), - ))); - } - pub fn setMaterial(convex_shape_settings: *T, material: ?*Material) void { - c.JPC_ConvexShapeSettings_SetMaterial( - @as(*c.JPC_ConvexShapeSettings, @ptrCast(convex_shape_settings)), - @as(?*c.JPC_PhysicsMaterial, @ptrCast(material)), - ); - } + pub fn getDensity(convex_shape_settings: *const ConvexShapeSettings) f32 { + return c.JPC_ConvexShapeSettings_GetDensity(@ptrCast(convex_shape_settings)); + } - pub fn getDensity(convex_shape_settings: *const T) f32 { - return c.JPC_ConvexShapeSettings_GetDensity( - @as(*const c.JPC_ConvexShapeSettings, @ptrCast(convex_shape_settings)), - ); - } - pub fn setDensity(shape_settings: *T, density: f32) void { - c.JPC_ConvexShapeSettings_SetDensity( - @as(*c.JPC_ConvexShapeSettings, @ptrCast(shape_settings)), - density, - ); - } - }; + pub fn setDensity(shape_settings: *ConvexShapeSettings, density: f32) void { + c.JPC_ConvexShapeSettings_SetDensity(@ptrCast(shape_settings), density); } }; //-------------------------------------------------------------------------------------------------- @@ -3072,33 +2754,39 @@ pub const ConvexShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const BoxShapeSettings = opaque { - pub usingnamespace ConvexShapeSettings.Methods(@This()); + pub fn asShapeSettings(box_shape_settings: *BoxShapeSettings) *ShapeSettings { + return @ptrCast(box_shape_settings); + } + + pub fn asConvexShapeSettings(box_shape_settings: *BoxShapeSettings) *ConvexShapeSettings { + return @ptrCast(box_shape_settings); + } pub fn create(half_extent: [3]f32) !*BoxShapeSettings { - const box_shape_settings = c.JPC_BoxShapeSettings_Create(&half_extent); - if (box_shape_settings == null) - return error.FailedToCreateBoxShapeSettings; - return @as(*BoxShapeSettings, @ptrCast(box_shape_settings)); + return @ptrCast(c.JPC_BoxShapeSettings_Create(&half_extent) orelse + return error.FailedToCreateBoxShapeSettings); } pub fn getHalfExtent(box_shape_settings: *const BoxShapeSettings) [3]f32 { var half_extent: [3]f32 = undefined; c.JPC_BoxShapeSettings_GetHalfExtent( - @as(*const c.JPC_BoxShapeSettings, @ptrCast(box_shape_settings)), + @ptrCast(box_shape_settings), &half_extent, ); return half_extent; } + pub fn setHalfExtent(box_shape_settings: *BoxShapeSettings, half_extent: [3]f32) void { - c.JPC_BoxShapeSettings_SetHalfExtent(@as(*c.JPC_BoxShapeSettings, @ptrCast(box_shape_settings)), &half_extent); + c.JPC_BoxShapeSettings_SetHalfExtent(@ptrCast(box_shape_settings), &half_extent); } pub fn getConvexRadius(box_shape_settings: *const BoxShapeSettings) f32 { - return c.JPC_BoxShapeSettings_GetConvexRadius(@as(*const c.JPC_BoxShapeSettings, @ptrCast(box_shape_settings))); + return c.JPC_BoxShapeSettings_GetConvexRadius(@ptrCast(box_shape_settings)); } + pub fn setConvexRadius(box_shape_settings: *BoxShapeSettings, convex_radius: f32) void { c.JPC_BoxShapeSettings_SetConvexRadius( - @as(*c.JPC_BoxShapeSettings, @ptrCast(box_shape_settings)), + @ptrCast(box_shape_settings), convex_radius, ); } @@ -3109,25 +2797,25 @@ pub const BoxShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const SphereShapeSettings = opaque { - pub usingnamespace ConvexShapeSettings.Methods(@This()); + pub fn asShapeSettings(sphere_shape_settings: *SphereShapeSettings) *ShapeSettings { + return @ptrCast(sphere_shape_settings); + } + + pub fn asConvexShapeSettings(sphere_shape_settings: *SphereShapeSettings) *ConvexShapeSettings { + return @ptrCast(sphere_shape_settings); + } pub fn create(radius: f32) !*SphereShapeSettings { - const sphere_shape_settings = c.JPC_SphereShapeSettings_Create(radius); - if (sphere_shape_settings == null) - return error.FailedToCreateSphereShapeSettings; - return @as(*SphereShapeSettings, @ptrCast(sphere_shape_settings)); + return @ptrCast(c.JPC_SphereShapeSettings_Create(radius) orelse + return error.FailedToCreateSphereShapeSettings); } pub fn getRadius(sphere_shape_settings: *const SphereShapeSettings) f32 { - return c.JPC_SphereShapeSettings_GetRadius( - @as(*const c.JPC_SphereShapeSettings, @ptrCast(sphere_shape_settings)), - ); + return c.JPC_SphereShapeSettings_GetRadius(@ptrCast(sphere_shape_settings)); } + pub fn setRadius(sphere_shape_settings: *SphereShapeSettings, radius: f32) void { - c.JPC_SphereShapeSettings_SetRadius( - @as(*c.JPC_SphereShapeSettings, @ptrCast(sphere_shape_settings)), - radius, - ); + c.JPC_SphereShapeSettings_SetRadius(@ptrCast(sphere_shape_settings), radius); } }; //-------------------------------------------------------------------------------------------------- @@ -3136,23 +2824,29 @@ pub const SphereShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const TriangleShapeSettings = opaque { - pub usingnamespace ConvexShapeSettings.Methods(@This()); + pub fn asShapeSettings(triangle_shape_settings: *TriangleShapeSettings) *ShapeSettings { + return @ptrCast(triangle_shape_settings); + } + + pub fn asConvexShapeSettings(triangle_shape_settings: *TriangleShapeSettings) *ConvexShapeSettings { + return @ptrCast(triangle_shape_settings); + } pub fn create(v1: [3]f32, v2: [3]f32, v3: [3]f32) !*TriangleShapeSettings { - const triangle_shape_settings = c.JPC_TriangleShapeSettings_Create(&v1, &v2, &v3); - if (triangle_shape_settings == null) - return error.FailedToCreateTriangleShapeSettings; - return @as(*TriangleShapeSettings, @ptrCast(triangle_shape_settings)); + return @ptrCast(c.JPC_TriangleShapeSettings_Create( + &v1, + &v2, + &v3, + ) orelse return error.FailedToCreateTriangleShapeSettings); } pub fn getConvexRadius(triangle_shape_settings: *const TriangleShapeSettings) f32 { - return c.JPC_TriangleShapeSettings_GetConvexRadius( - @as(*const c.JPC_TriangleShapeSettings, @ptrCast(triangle_shape_settings)), - ); + return c.JPC_TriangleShapeSettings_GetConvexRadius(@ptrCast(triangle_shape_settings)); } + pub fn setConvexRadius(triangle_shape_settings: *TriangleShapeSettings, convex_radius: f32) void { c.JPC_TriangleShapeSettings_SetConvexRadius( - @as(*c.JPC_TriangleShapeSettings, @ptrCast(triangle_shape_settings)), + @ptrCast(triangle_shape_settings), convex_radius, ); } @@ -3163,35 +2857,36 @@ pub const TriangleShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const CapsuleShapeSettings = opaque { - pub usingnamespace ConvexShapeSettings.Methods(@This()); + pub fn asShapeSettings(capsule_shape_settings: *CapsuleShapeSettings) *ShapeSettings { + return @ptrCast(capsule_shape_settings); + } + + pub fn asConvexShapeSettings(capsule_shape_settings: *CapsuleShapeSettings) *ConvexShapeSettings { + return @ptrCast(capsule_shape_settings); + } pub fn create(half_height: f32, radius: f32) !*CapsuleShapeSettings { - const capsule_shape_settings = c.JPC_CapsuleShapeSettings_Create(half_height, radius); - if (capsule_shape_settings == null) - return error.FailedToCreateCapsuleShapeSettings; - return @as(*CapsuleShapeSettings, @ptrCast(capsule_shape_settings)); + return @ptrCast(c.JPC_CapsuleShapeSettings_Create( + half_height, + radius, + ) orelse return error.FailedToCreateCapsuleShapeSettings); } pub fn getHalfHeight(capsule_shape_settings: *const CapsuleShapeSettings) f32 { - return c.JPC_CapsuleShapeSettings_GetHalfHeight( - @as(*const c.JPC_CapsuleShapeSettings, @ptrCast(capsule_shape_settings)), - ); + return c.JPC_CapsuleShapeSettings_GetHalfHeight(@ptrCast(capsule_shape_settings)); } + pub fn setHalfHeight(capsule_shape_settings: *CapsuleShapeSettings, half_height: f32) void { - c.JPC_CapsuleShapeSettings_SetHalfHeight( - @as(*c.JPC_CapsuleShapeSettings, @ptrCast(capsule_shape_settings)), - half_height, - ); + c.JPC_CapsuleShapeSettings_SetHalfHeight(@ptrCast(capsule_shape_settings), half_height); } pub fn getRadius(capsule_shape_settings: *const CapsuleShapeSettings) f32 { - return c.JPC_CapsuleShapeSettings_GetRadius( - @as(*const c.JPC_CapsuleShapeSettings, @ptrCast(capsule_shape_settings)), - ); + return c.JPC_CapsuleShapeSettings_GetRadius(@ptrCast(capsule_shape_settings)); } + pub fn setRadius(capsule_shape_settings: *CapsuleShapeSettings, radius: f32) void { c.JPC_CapsuleShapeSettings_SetRadius( - @as(*c.JPC_CapsuleShapeSettings, @ptrCast(capsule_shape_settings)), + @ptrCast(capsule_shape_settings), radius, ); } @@ -3202,36 +2897,41 @@ pub const CapsuleShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const TaperedCapsuleShapeSettings = opaque { - pub usingnamespace ConvexShapeSettings.Methods(@This()); + pub fn asShapeSettings(tapered_capsule_shape_settings: *TaperedCapsuleShapeSettings) *ShapeSettings { + return @ptrCast(tapered_capsule_shape_settings); + } + + pub fn asConvexShapeSettings(tapered_capsule_shape_settings: *TaperedCapsuleShapeSettings) *ConvexShapeSettings { + return @ptrCast(tapered_capsule_shape_settings); + } pub fn create(half_height: f32, top_radius: f32, bottom_radius: f32) !*TaperedCapsuleShapeSettings { - const capsule_shape_settings = c.JPC_TaperedCapsuleShapeSettings_Create( + return @ptrCast(c.JPC_TaperedCapsuleShapeSettings_Create( half_height, top_radius, bottom_radius, - ); - if (capsule_shape_settings == null) - return error.FailedToCreateTaperedCapsuleShapeSettings; - return @as(*TaperedCapsuleShapeSettings, @ptrCast(capsule_shape_settings)); + ) orelse return error.FailedToCreateTaperedCapsuleShapeSettings); } pub fn getHalfHeight(capsule_shape_settings: *const TaperedCapsuleShapeSettings) f32 { return c.JPC_TaperedCapsuleShapeSettings_GetHalfHeight( - @as(*const c.JPC_TaperedCapsuleShapeSettings, @ptrCast(capsule_shape_settings)), + @ptrCast(capsule_shape_settings), ); } + pub fn setHalfHeight(capsule_shape_settings: *TaperedCapsuleShapeSettings, half_height: f32) void { c.JPC_TaperedCapsuleShapeSettings_SetHalfHeight( - @as(*c.JPC_TaperedCapsuleShapeSettings, @ptrCast(capsule_shape_settings)), + @ptrCast(capsule_shape_settings), half_height, ); } pub fn getTopRadius(capsule_shape_settings: *const TaperedCapsuleShapeSettings) f32 { return c.JPC_TaperedCapsuleShapeSettings_GetTopRadius( - @as(*const c.JPC_TaperedCapsuleShapeSettings, @ptrCast(capsule_shape_settings)), + @ptrCast(capsule_shape_settings), ); } + pub fn setTopRadius(capsule_shape_settings: *TaperedCapsuleShapeSettings, radius: f32) void { c.JPC_TaperedCapsuleShapeSettings_SetTopRadius( @as(*c.JPC_TaperedCapsuleShapeSettings, @ptrCast(capsule_shape_settings)), @@ -3244,6 +2944,7 @@ pub const TaperedCapsuleShapeSettings = opaque { @as(*const c.JPC_TaperedCapsuleShapeSettings, @ptrCast(capsule_shape_settings)), ); } + pub fn setBottomRadius(capsule_shape_settings: *TaperedCapsuleShapeSettings, radius: f32) void { c.JPC_TaperedCapsuleShapeSettings_SetBottomRadius( @as(*c.JPC_TaperedCapsuleShapeSettings, @ptrCast(capsule_shape_settings)), @@ -3257,47 +2958,56 @@ pub const TaperedCapsuleShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const CylinderShapeSettings = opaque { - pub usingnamespace ConvexShapeSettings.Methods(@This()); + pub fn asShapeSettings(cylinder_shape_settings: *CylinderShapeSettings) *ShapeSettings { + return @ptrCast(cylinder_shape_settings); + } + + pub fn asConvexShapeSettings(cylinder_shape_settings: *CylinderShapeSettings) *ConvexShapeSettings { + return @ptrCast(cylinder_shape_settings); + } pub fn create(half_height: f32, radius: f32) !*CylinderShapeSettings { - const cylinder_shape_settings = c.JPC_CylinderShapeSettings_Create(half_height, radius); - if (cylinder_shape_settings == null) - return error.FailedToCreateCylinderShapeSettings; - return @as(*CylinderShapeSettings, @ptrCast(cylinder_shape_settings)); + return @ptrCast(c.JPC_CylinderShapeSettings_Create( + half_height, + radius, + ) orelse return error.FailedToCreateCylinderShapeSettings); } pub fn getConvexRadius(cylinder_shape_settings: *const CylinderShapeSettings) f32 { return c.JPC_CylinderShapeSettings_GetConvexRadius( - @as(*const c.JPC_CylinderShapeSettings, @ptrCast(cylinder_shape_settings)), + @ptrCast(cylinder_shape_settings), ); } + pub fn setConvexRadius(cylinder_shape_settings: *CylinderShapeSettings, convex_radius: f32) void { c.JPC_CylinderShapeSettings_SetConvexRadius( - @as(*c.JPC_CylinderShapeSettings, @ptrCast(cylinder_shape_settings)), + @ptrCast(cylinder_shape_settings), convex_radius, ); } pub fn getHalfHeight(cylinder_shape_settings: *const CylinderShapeSettings) f32 { return c.JPC_CylinderShapeSettings_GetHalfHeight( - @as(*const c.JPC_CylinderShapeSettings, @ptrCast(cylinder_shape_settings)), + @ptrCast(cylinder_shape_settings), ); } + pub fn setHalfHeight(cylinder_shape_settings: *CylinderShapeSettings, half_height: f32) void { c.JPC_CylinderShapeSettings_SetHalfHeight( - @as(*c.JPC_CylinderShapeSettings, @ptrCast(cylinder_shape_settings)), + @ptrCast(cylinder_shape_settings), half_height, ); } pub fn getRadius(cylinder_shape_settings: *const CylinderShapeSettings) f32 { return c.JPC_CylinderShapeSettings_GetRadius( - @as(*const c.JPC_CylinderShapeSettings, @ptrCast(cylinder_shape_settings)), + @ptrCast(cylinder_shape_settings), ); } + pub fn setRadius(cylinder_shape_settings: *CylinderShapeSettings, radius: f32) void { c.JPC_CylinderShapeSettings_SetRadius( - @as(*c.JPC_CylinderShapeSettings, @ptrCast(cylinder_shape_settings)), + @ptrCast(cylinder_shape_settings), radius, ); } @@ -3308,23 +3018,31 @@ pub const CylinderShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const ConvexHullShapeSettings = opaque { - pub usingnamespace ConvexShapeSettings.Methods(@This()); + pub fn asShapeSettings(convex_hull_shape_settings: *ConvexHullShapeSettings) *ShapeSettings { + return @ptrCast(convex_hull_shape_settings); + } + + pub fn asConvexShapeSettings(convex_hull_shape_settings: *ConvexHullShapeSettings) *ConvexShapeSettings { + return @ptrCast(convex_hull_shape_settings); + } pub fn create(vertices: *const anyopaque, num_vertices: u32, vertex_size: u32) !*ConvexHullShapeSettings { - const settings = c.JPC_ConvexHullShapeSettings_Create(vertices, num_vertices, vertex_size); - if (settings == null) - return error.FailedToCreateConvexHullShapeSettings; - return @as(*ConvexHullShapeSettings, @ptrCast(settings)); + return @ptrCast(c.JPC_ConvexHullShapeSettings_Create( + vertices, + num_vertices, + vertex_size, + ) orelse return error.FailedToCreateConvexHullShapeSettings); } pub fn getMaxConvexRadius(settings: *const ConvexHullShapeSettings) f32 { return c.JPC_ConvexHullShapeSettings_GetMaxConvexRadius( - @as(*const c.JPC_ConvexHullShapeSettings, @ptrCast(settings)), + @ptrCast(settings), ); } + pub fn setMaxConvexRadius(settings: *ConvexHullShapeSettings, radius: f32) void { c.JPC_ConvexHullShapeSettings_SetMaxConvexRadius( - @as(*c.JPC_ConvexHullShapeSettings, @ptrCast(settings)), + @ptrCast(settings), radius, ); } @@ -3335,38 +3053,42 @@ pub const ConvexHullShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const HeightFieldShapeSettings = opaque { - pub usingnamespace ShapeSettings.Methods(@This()); + pub fn asShapeSettings(height_field_shape_settings: *HeightFieldShapeSettings) *ShapeSettings { + return @ptrCast(height_field_shape_settings); + } pub fn create( samples: [*]const f32, // height_field_size^2 samples height_field_size: u32, // height_field_size / block_size must be a power of 2 and minimally 2 ) !*HeightFieldShapeSettings { - const settings = c.JPC_HeightFieldShapeSettings_Create(samples, height_field_size); - if (settings == null) - return error.FailedToCreateHeightFieldShapeSettings; - return @as(*HeightFieldShapeSettings, @ptrCast(settings)); + return @ptrCast(c.JPC_HeightFieldShapeSettings_Create( + samples, + height_field_size, + ) orelse return error.FailedToCreateHeightFieldShapeSettings); } pub fn getBlockSize(settings: *const HeightFieldShapeSettings) u32 { return c.JPC_HeightFieldShapeSettings_GetBlockSize( - @as(*const c.JPC_HeightFieldShapeSettings, @ptrCast(settings)), + @ptrCast(settings), ); } + pub fn setBlockSize(settings: *HeightFieldShapeSettings, block_size: u32) void { c.JPC_HeightFieldShapeSettings_SetBlockSize( - @as(*c.JPC_HeightFieldShapeSettings, @ptrCast(settings)), + @ptrCast(settings), block_size, ); } pub fn getBitsPerSample(settings: *const HeightFieldShapeSettings) u32 { return c.JPC_HeightFieldShapeSettings_GetBitsPerSample( - @as(*const c.JPC_HeightFieldShapeSettings, @ptrCast(settings)), + @ptrCast(settings), ); } + pub fn setBitsPerSample(settings: *HeightFieldShapeSettings, num_bits: u32) void { c.JPC_HeightFieldShapeSettings_SetBitsPerSample( - @as(*c.JPC_HeightFieldShapeSettings, @ptrCast(settings)), + @ptrCast(settings), num_bits, ); } @@ -3374,14 +3096,15 @@ pub const HeightFieldShapeSettings = opaque { pub fn getOffset(settings: *const HeightFieldShapeSettings) [3]f32 { var offset: [3]f32 = undefined; c.JPC_HeightFieldShapeSettings_GetOffset( - @as(*const c.JPC_HeightFieldShapeSettings, @ptrCast(settings)), + @ptrCast(settings), &offset, ); return offset; } + pub fn setOffset(settings: *HeightFieldShapeSettings, offset: [3]f32) void { c.JPC_HeightFieldShapeSettings_SetOffset( - @as(*c.JPC_HeightFieldShapeSettings, @ptrCast(settings)), + @ptrCast(settings), &offset, ); } @@ -3389,14 +3112,15 @@ pub const HeightFieldShapeSettings = opaque { pub fn getScale(settings: *const HeightFieldShapeSettings) [3]f32 { var scale: [3]f32 = undefined; c.JPC_HeightFieldShapeSettings_GetScale( - @as(*const c.JPC_HeightFieldShapeSettings, @ptrCast(settings)), + @ptrCast(settings), &scale, ); return scale; } + pub fn setScale(settings: *HeightFieldShapeSettings, scale: [3]f32) void { c.JPC_HeightFieldShapeSettings_SetScale( - @as(*c.JPC_HeightFieldShapeSettings, @ptrCast(settings)), + @ptrCast(settings), &scale, ); } @@ -3407,7 +3131,9 @@ pub const HeightFieldShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const MeshShapeSettings = opaque { - pub usingnamespace ShapeSettings.Methods(@This()); + pub fn asShapeSettings(mesh_shape_settings: *MeshShapeSettings) *ShapeSettings { + return @ptrCast(mesh_shape_settings); + } pub fn create( vertices: *const anyopaque, @@ -3415,32 +3141,29 @@ pub const MeshShapeSettings = opaque { vertex_size: u32, indices: []const u32, ) !*MeshShapeSettings { - const settings = c.JPC_MeshShapeSettings_Create( + return @ptrCast(c.JPC_MeshShapeSettings_Create( vertices, num_vertices, vertex_size, indices.ptr, - @as(u32, @intCast(indices.len)), - ); - if (settings == null) - return error.FailedToCreateMeshShapeSettings; - return @as(*MeshShapeSettings, @ptrCast(settings)); + @intCast(indices.len), + ) orelse return error.FailedToCreateMeshShapeSettings); } pub fn getMaxTrianglesPerLeaf(settings: *const MeshShapeSettings) u32 { return c.JPC_MeshShapeSettings_GetMaxTrianglesPerLeaf( - @as(*const c.JPC_MeshShapeSettings, @ptrCast(settings)), + @ptrCast(settings), ); } pub fn setMaxTrianglesPerLeaf(settings: *MeshShapeSettings, max_triangles: u32) void { c.JPC_MeshShapeSettings_SetMaxTrianglesPerLeaf( - @as(*c.JPC_MeshShapeSettings, @ptrCast(settings)), + @ptrCast(settings), max_triangles, ); } pub fn sanitize(settings: *MeshShapeSettings) void { - c.JPC_MeshShapeSettings_Sanitize(@as(*c.JPC_MeshShapeSettings, @ptrCast(settings))); + c.JPC_MeshShapeSettings_Sanitize(@ptrCast(settings)); } }; //-------------------------------------------------------------------------------------------------- @@ -3449,38 +3172,34 @@ pub const MeshShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const DecoratedShapeSettings = opaque { - pub usingnamespace ShapeSettings.Methods(@This()); + pub fn asShapeSettings(decorated_shape_settings: *DecoratedShapeSettings) *ShapeSettings { + return @ptrCast(decorated_shape_settings); + } pub fn createRotatedTranslated( inner_shape: *const ShapeSettings, rotation: [4]f32, translation: [3]f32, ) !*DecoratedShapeSettings { - const settings = c.JPC_RotatedTranslatedShapeSettings_Create( + return @ptrCast(c.JPC_RotatedTranslatedShapeSettings_Create( @as(*const c.JPC_ShapeSettings, @ptrCast(inner_shape)), &rotation, &translation, - ); - if (settings == null) return error.FailedToCreateDecoratedShapeSettings; - return @as(*DecoratedShapeSettings, @ptrCast(settings)); + ) orelse return error.FailedToCreateDecoratedShapeSettings); } pub fn createScaled(inner_shape: *const ShapeSettings, scale: [3]f32) !*DecoratedShapeSettings { - const settings = c.JPC_ScaledShapeSettings_Create( - @as(*const c.JPC_ShapeSettings, @ptrCast(inner_shape)), + return @ptrCast(c.JPC_ScaledShapeSettings_Create( + @ptrCast(inner_shape), &scale, - ); - if (settings == null) return error.FailedToCreateDecoratedShapeSettings; - return @as(*DecoratedShapeSettings, @ptrCast(settings)); + ) orelse return error.FailedToCreateDecoratedShapeSettings); } pub fn createOffsetCenterOfMass(inner_shape: *const ShapeSettings, offset: [3]f32) !*DecoratedShapeSettings { - const settings = c.JPC_OffsetCenterOfMassShapeSettings_Create( + return @ptrCast(c.JPC_OffsetCenterOfMassShapeSettings_Create( @as(*const c.JPC_ShapeSettings, @ptrCast(inner_shape)), &offset, - ); - if (settings == null) return error.FailedToCreateDecoratedShapeSettings; - return @as(*DecoratedShapeSettings, @ptrCast(settings)); + ) orelse return error.FailedToCreateDecoratedShapeSettings); } }; //-------------------------------------------------------------------------------------------------- @@ -3489,26 +3208,32 @@ pub const DecoratedShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const CompoundShapeSettings = opaque { - pub usingnamespace ShapeSettings.Methods(@This()); + pub fn asShapeSettings(compound_shape_settings: *CompoundShapeSettings) *ShapeSettings { + return @ptrCast(compound_shape_settings); + } pub fn createStatic() !*CompoundShapeSettings { - const settings = c.JPC_StaticCompoundShapeSettings_Create(); - if (settings == null) return error.FailedToCreateCompoundShapeSettings; - return @as(*CompoundShapeSettings, @ptrCast(settings)); + return @ptrCast(c.JPC_StaticCompoundShapeSettings_Create() orelse + return error.FailedToCreateCompoundShapeSettings); } pub fn createMutable() !*CompoundShapeSettings { - const settings = c.JPC_MutableCompoundShapeSettings_Create(); - if (settings == null) return error.FailedToCreateCompoundShapeSettings; - return @as(*CompoundShapeSettings, @ptrCast(settings)); + return @ptrCast(c.JPC_MutableCompoundShapeSettings_Create() orelse + return error.FailedToCreateCompoundShapeSettings); } - pub fn addShape(settings: *CompoundShapeSettings, position: [3]f32, rotation: [4]f32, shape: *const ShapeSettings, user_data: u32) void { + pub fn addShape( + settings: *CompoundShapeSettings, + position: [3]f32, + rotation: [4]f32, + shape: *const ShapeSettings, + user_data: u32, + ) void { c.JPC_CompoundShapeSettings_AddShape( - @as(*c.JPC_CompoundShapeSettings, @ptrCast(settings)), + @ptrCast(settings), &position, &rotation, - @as(*const c.JPC_ShapeSettings, @ptrCast(shape)), + @ptrCast(shape), user_data, ); } @@ -3519,8 +3244,6 @@ pub const CompoundShapeSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const Shape = opaque { - pub usingnamespace Methods(@This()); - pub const Type = enum(c.JPC_ShapeType) { convex = c.JPC_SHAPE_TYPE_CONVEX, compound = c.JPC_SHAPE_TYPE_COMPOUND, @@ -3590,113 +3313,106 @@ pub const Shape = opaque { return @as(*Shape, @ptrCast(shape)); } - fn Methods(comptime T: type) type { - return struct { - pub fn asShape(shape: *const T) *const Shape { - return @as(*const Shape, @ptrCast(shape)); - } - pub fn asShapeMut(shape: *T) *Shape { - return @as(*Shape, @ptrCast(shape)); - } + pub fn addRef(shape: *Shape) void { + c.JPC_Shape_AddRef(@ptrCast(shape)); + } - pub fn addRef(shape: *T) void { - c.JPC_Shape_AddRef(@as(*c.JPC_Shape, @ptrCast(shape))); - } - pub fn release(shape: *T) void { - c.JPC_Shape_Release(@as(*c.JPC_Shape, @ptrCast(shape))); - } - pub fn getRefCount(shape: *const T) u32 { - return c.JPC_Shape_GetRefCount(@as(*const c.JPC_Shape, @ptrCast(shape))); - } + pub fn release(shape: *Shape) void { + c.JPC_Shape_Release(@ptrCast(shape)); + } - pub fn getType(shape: *const T) Type { - return @as( - Type, - @enumFromInt(c.JPC_Shape_GetType(@as(*const c.JPC_Shape, @ptrCast(shape)))), - ); - } - pub fn getSubType(shape: *const T) SubType { - return @as( - SubType, - @enumFromInt(c.JPC_Shape_GetSubType(@as(*const c.JPC_Shape, @ptrCast(shape)))), - ); - } + pub fn getRefCount(shape: *const Shape) u32 { + return c.JPC_Shape_GetRefCount(@ptrCast(shape)); + } - pub fn getUserData(shape: *const T) u64 { - return c.JPC_Shape_GetUserData(@as(*const c.JPC_Shape, @ptrCast(shape))); - } - pub fn setUserData(shape: *T, user_data: u64) void { - return c.JPC_Shape_SetUserData(@as(*c.JPC_Shape, @ptrCast(shape)), user_data); - } + pub fn getType(shape: *const Shape) Type { + return @as( + Type, + @enumFromInt(c.JPC_Shape_GetType(@ptrCast(shape))), + ); + } - pub fn getVolume(shape: *const T) f32 { - return c.JPC_Shape_GetVolume(@as(*const c.JPC_Shape, @ptrCast(shape))); - } + pub fn getSubType(shape: *const Shape) SubType { + return @as( + SubType, + @enumFromInt(c.JPC_Shape_GetSubType(@ptrCast(shape))), + ); + } - pub fn getCenterOfMass(shape: *const T) [3]f32 { - var center: [3]f32 = undefined; - c.JPC_Shape_GetCenterOfMass(@as(*const c.JPC_Shape, @ptrCast(shape)), ¢er); - return center; - } + pub fn getUserData(shape: *const Shape) u64 { + return c.JPC_Shape_GetUserData(@ptrCast(shape)); + } - pub fn getLocalBounds(shape: *const T) AABox { - const aabox = c.JPC_Shape_GetLocalBounds(@as(*const c.JPC_Shape, @ptrCast(shape))); - return @as(*AABox, @constCast(@ptrCast(&aabox))).*; - } + pub fn setUserData(shape: *Shape, user_data: u64) void { + return c.JPC_Shape_SetUserData(@ptrCast(shape), user_data); + } - pub fn getSurfaceNormal(shape: *const T, sub_shape_id: SubShapeId, local_pos: [3]f32) [3]f32 { - var normal: [3]f32 = undefined; - c.JPC_Shape_GetSurfaceNormal( - @as(*const c.JPC_Shape, @ptrCast(shape)), - sub_shape_id, - &local_pos, - &normal, - ); - return normal; - } + pub fn getVolume(shape: *const Shape) f32 { + return c.JPC_Shape_GetVolume(@ptrCast(shape)); + } - pub fn getSupportingFace( - shape: *const T, - sub_shape_id: SubShapeId, - direction: [3]f32, - shape_scale: [3]f32, - com_transform: [16]f32, - ) SupportingFace { - const c_face = c.JPC_Shape_GetSupportingFace( - @as(*const c.JPC_Shape, @ptrCast(shape)), - sub_shape_id, - &direction, - &shape_scale, - &com_transform, - ); - return @as(*const SupportingFace, @ptrCast(&c_face)).*; - } + pub fn getCenterOfMass(shape: *const Shape) [3]f32 { + var center: [3]f32 = undefined; + c.JPC_Shape_GetCenterOfMass(@ptrCast(shape), ¢er); + return center; + } - pub fn castRay( - shape: *const T, - ray: RayCast, - args: struct { - sub_shape_id_creator: SubShapeIDCreator = .{}, - }, - ) struct { has_hit: bool, hit: RayCastResult } { - var hit: RayCastResult = .{}; - const has_hit = c.JPC_Shape_CastRay( - @as(*const c.JPC_Shape, @ptrCast(shape)), - @as(*const c.JPC_RayCast, @ptrCast(&ray)), - @as(*const c.JPC_SubShapeIDCreator, @ptrCast(&args.sub_shape_id_creator)), - @as(*c.JPC_RayCastResult, @ptrCast(&hit)), - ); - return .{ .has_hit = has_hit, .hit = hit }; - } + pub fn getLocalBounds(shape: *const Shape) AABox { + const aabox = c.JPC_Shape_GetLocalBounds(@ptrCast(shape)); + return @as(*AABox, @constCast(@ptrCast(&aabox))).*; + } - pub fn saveBinaryState(shape: *const T, stream_out: *StreamOut) void { - c.JPC_Shape_SaveBinaryState(@as(*const c.JPC_Shape, @ptrCast(shape)), stream_out); - } + pub fn getSurfaceNormal(shape: *const Shape, sub_shape_id: SubShapeId, local_pos: [3]f32) [3]f32 { + var normal: [3]f32 = undefined; + c.JPC_Shape_GetSurfaceNormal( + @ptrCast(shape), + sub_shape_id.toJpc(), + &local_pos, + &normal, + ); + return normal; + } - pub fn saveWithChildrenAll(shape: *const T, stream_out: *StreamOut) void { - c.JPC_Shape_SaveWithChildren_All(@as(*const c.JPC_Shape, @ptrCast(shape)), stream_out); - } - }; + pub fn getSupportingFace( + shape: *const Shape, + sub_shape_id: SubShapeId, + direction: [3]f32, + shape_scale: [3]f32, + com_transform: [16]f32, + ) SupportingFace { + const c_face = c.JPC_Shape_GetSupportingFace( + @ptrCast(shape), + sub_shape_id.toJpc(), + &direction, + &shape_scale, + &com_transform, + ); + return @as(*const SupportingFace, @ptrCast(&c_face)).*; + } + + pub fn castRay( + shape: *const Shape, + ray: RayCast, + args: struct { + sub_shape_id_creator: SubShapeIDCreator = .{}, + }, + ) struct { has_hit: bool, hit: RayCastResult } { + var hit: RayCastResult = .{}; + const has_hit = c.JPC_Shape_CastRay( + @ptrCast(shape), + @ptrCast(&ray), + @ptrCast(&args.sub_shape_id_creator), + @ptrCast(&hit), + ); + return .{ .has_hit = has_hit, .hit = hit }; + } + + pub fn saveBinaryState(shape: *const Shape, stream_out: *StreamOut) void { + c.JPC_Shape_SaveBinaryState(@ptrCast(shape), stream_out); + } + + pub fn saveWithChildrenAll(shape: *const Shape, stream_out: *StreamOut) void { + c.JPC_Shape_SaveWithChildren_All(@ptrCast(shape), stream_out); } }; @@ -3706,15 +3422,22 @@ pub const Shape = opaque { // //-------------------------------------------------------------------------------------------------- pub const BoxShape = opaque { - pub usingnamespace Shape.Methods(@This()); + pub fn asShape(shape: *const BoxShape) *const Shape { + return @ptrCast(shape); + } + + pub fn asShapeMut(shape: *BoxShape) *Shape { + return @ptrCast(shape); + } pub fn asBoxShape(shape: *const Shape) *const BoxShape { assert(shape.getSubType() == .box); - return @as(*const BoxShape, @ptrCast(shape)); + return @ptrCast(shape); } + pub fn asBoxShapeMut(shape: *Shape) *BoxShape { assert(shape.getSubType() == .box); - return @as(*BoxShape, @ptrCast(shape)); + return @ptrCast(shape); } pub fn getHalfExtent(shape: *const BoxShape) [3]f32 { @@ -3730,32 +3453,41 @@ pub const BoxShape = opaque { // //-------------------------------------------------------------------------------------------------- pub const ConvexHullShape = opaque { - pub usingnamespace Shape.Methods(@This()); + pub fn asShape(shape: *const BoxShape) *const Shape { + return @ptrCast(shape); + } + + pub fn asShapeMut(shape: *BoxShape) *Shape { + return @ptrCast(shape); + } pub fn asConvexHullShape(shape: *const Shape) *const ConvexHullShape { assert(shape.getSubType() == .convex_hull); - return @as(*const ConvexHullShape, @ptrCast(shape)); + return @ptrCast(shape); } + pub fn asConvexHullShapeMut(shape: *Shape) *ConvexHullShape { assert(shape.getSubType() == .convex_hull); - return @as(*ConvexHullShape, @ptrCast(shape)); + return @ptrCast(shape); } pub fn getNumPoints(shape: *const ConvexHullShape) u32 { - return c.JPC_ConvexHullShape_GetNumPoints(@as(*const c.JPC_ConvexHullShape, @ptrCast(shape))); + return c.JPC_ConvexHullShape_GetNumPoints(@ptrCast(shape)); } + pub fn getPoint(shape: *const ConvexHullShape, in_point_index: u32) [3]f32 { var point: [3]f32 = undefined; - c.JPC_ConvexHullShape_GetPoint(@as(*const c.JPC_ConvexHullShape, @ptrCast(shape)), in_point_index, &point); + c.JPC_ConvexHullShape_GetPoint(@ptrCast(shape), in_point_index, &point); return point; } pub fn getNumFaces(shape: *const ConvexHullShape) u32 { - return c.JPC_ConvexHullShape_GetNumFaces(@as(*const c.JPC_ConvexHullShape, @ptrCast(shape))); + return c.JPC_ConvexHullShape_GetNumFaces(@ptrCast(shape)); } + pub fn getNumVerticesInFace(shape: *const ConvexHullShape, in_face_index: u32) u32 { return c.JPC_ConvexHullShape_GetNumVerticesInFace( - @as(*const c.JPC_ConvexHullShape, @ptrCast(shape)), + @ptrCast(shape), in_face_index, ); } @@ -3765,9 +3497,9 @@ pub const ConvexHullShape = opaque { /// The return value gives the number of vertices in the face, identical to getNumVerticesInFace(in_face_index). pub fn getFaceVertices(shape: *const ConvexHullShape, in_face_index: u32, out_vertex_buffer: []u32) u32 { return c.JPC_ConvexHullShape_GetFaceVertices( - @as(*const c.JPC_ConvexHullShape, @ptrCast(shape)), + @ptrCast(shape), in_face_index, - @as(u32, @intCast(out_vertex_buffer.len)), + @intCast(out_vertex_buffer.len), out_vertex_buffer.ptr, ); } @@ -3778,37 +3510,27 @@ pub const ConvexHullShape = opaque { // //-------------------------------------------------------------------------------------------------- pub const ConstraintSettings = opaque { - pub usingnamespace Methods(@This()); + pub fn addRef(constraint_settings: *ConstraintSettings) void { + c.JPC_ConstraintSettings_AddRef(@ptrCast(constraint_settings)); + } - fn Methods(comptime T: type) type { - return struct { - pub fn asConstraintSettings(constraint_settings: *const T) *const ConstraintSettings { - return @as(*const ConstraintSettings, @ptrCast(constraint_settings)); - } - pub fn asConstraintSettingsMut(constraint_settings: *T) *ConstraintSettings { - return @as(*ConstraintSettings, @ptrCast(constraint_settings)); - } + pub fn release(constraint_settings: *ConstraintSettings) void { + c.JPC_ConstraintSettings_Release(@ptrCast(constraint_settings)); + } - pub fn addRef(constraint_settings: *T) void { - c.JPC_ConstraintSettings_AddRef(@as(*c.JPC_ConstraintSettings, @ptrCast(constraint_settings))); - } - pub fn release(constraint_settings: *T) void { - c.JPC_ConstraintSettings_Release(@as(*c.JPC_ConstraintSettings, @ptrCast(constraint_settings))); - } - pub fn getRefCount(constraint_settings: *const T) u32 { - return c.JPC_ConstraintSettings_GetRefCount(@as(*const c.JPC_ConstraintSettings, @ptrCast(constraint_settings))); - } + pub fn getRefCount(constraint_settings: *const ConstraintSettings) u32 { + return c.JPC_ConstraintSettings_GetRefCount(@ptrCast(constraint_settings)); + } - pub fn getUserData(constraint_settings: *const T) u64 { - return c.JPC_ConstraintSettings_GetUserData(@as(*const c.JPC_ConstraintSettings, @ptrCast(constraint_settings))); - } - pub fn setUserData(constraint_settings: *T, user_data: u64) void { - return c.JPC_ConstraintSettings_SetUserData( - @as(*c.JPC_ConstraintSettings, @ptrCast(constraint_settings)), - user_data, - ); - } - }; + pub fn getUserData(constraint_settings: *const ConstraintSettings) u64 { + return c.JPC_ConstraintSettings_GetUserData(@ptrCast(constraint_settings)); + } + + pub fn setUserData(constraint_settings: *ConstraintSettings, user_data: u64) void { + return c.JPC_ConstraintSettings_SetUserData( + @ptrCast(constraint_settings), + user_data, + ); } }; //-------------------------------------------------------------------------------------------------- @@ -3817,27 +3539,24 @@ pub const ConstraintSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const TwoBodyConstraintSettings = opaque { - pub usingnamespace Methods(@This()); - - fn Methods(comptime T: type) type { - return struct { - pub usingnamespace ConstraintSettings.Methods(T); + pub fn asConstraintSettings(self: *const TwoBodyConstraintSettings) *const ConstraintSettings { + return @ptrCast(self); + } - pub fn asTwoBodyConstraintSettings(two_body_constraint_settings: *T) *TwoBodyConstraintSettings { - return @as(*TwoBodyConstraintSettings, @ptrCast(two_body_constraint_settings)); - } + pub fn asConstraintSettingsMut(self: *TwoBodyConstraintSettings) *ConstraintSettings { + return @ptrCast(self); + } - pub fn createConstraint(two_body_constraint_settings: *const T, body1: *Body, body2: *Body) !*Constraint { - const constraint = c.JPC_TwoBodyConstraintSettings_CreateConstraint( - @as(*const c.JPC_TwoBodyConstraintSettings, @ptrCast(two_body_constraint_settings)), - @as(*c.JPC_Body, @ptrCast(body1)), - @as(*c.JPC_Body, @ptrCast(body2)), - ); - if (constraint == null) - return error.FailedToCreateConstraint; - return @as(*Constraint, @ptrCast(constraint)); - } - }; + pub fn createConstraint( + self: *const TwoBodyConstraintSettings, + body1: *Body, + body2: *Body, + ) !*Constraint { + return @ptrCast(c.JPC_TwoBodyConstraintSettings_CreateConstraint( + @ptrCast(self), + @ptrCast(body1), + @ptrCast(body2), + ) orelse return error.FailedToCreateConstraint); } }; //-------------------------------------------------------------------------------------------------- @@ -3846,12 +3565,9 @@ pub const TwoBodyConstraintSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const FixedConstraintSettings = opaque { - pub usingnamespace TwoBodyConstraintSettings.Methods(@This()); - pub fn create() !*FixedConstraintSettings { - const fixed_constraint_settings = c.JPC_FixedConstraintSettings_Create(); - if (fixed_constraint_settings == null) return error.FailedToCreateFixedConstraintSettings; - return @as(*FixedConstraintSettings, @ptrCast(fixed_constraint_settings)); + return @ptrCast(c.JPC_FixedConstraintSettings_Create() orelse + return error.FailedToCreateFixedConstraintSettings); } pub fn setSpace(settings: *FixedConstraintSettings, space: Constraint.Space) void { @@ -3874,8 +3590,6 @@ pub const FixedConstraintSettings = opaque { // //-------------------------------------------------------------------------------------------------- pub const Constraint = opaque { - pub usingnamespace Methods(@This()); - pub const Type = enum(c.JPC_ConstraintType) { constraint = c.JPC_CONSTRAINT_TYPE_CONSTRAINT, two_body_constraint = c.JPC_CONSTRAINT_TYPE_TWO_BODY_CONSTRAINT, @@ -3906,45 +3620,40 @@ pub const Constraint = opaque { world_space = c.JPC_CONSTRAINT_SPACE_WORLD_SPACE, }; - fn Methods(comptime T: type) type { - return struct { - pub fn asConstraint(constraint: *const T) *const Constraint { - return @as(*const Constraint, @ptrCast(constraint)); - } - pub fn asConstraintMut(constraint: *T) *Constraint { - return @as(*Constraint, @ptrCast(constraint)); - } + // pub fn asConstraint(constraint: *const Constraint) *const Constraint { + // return @ptrCast(constraint); + // } - pub fn addRef(constraint: *T) void { - c.JPC_Constraint_AddRef(@as(*c.JPC_Constraint, @ptrCast(constraint))); - } - pub fn release(constraint: *T) void { - c.JPC_Constraint_Release(@as(*c.JPC_Constraint, @ptrCast(constraint))); - } - pub fn getRefCount(constraint: *const T) u32 { - return c.JPC_Constraint_GetRefCount(@as(*const c.JPC_Constraint, @ptrCast(constraint))); - } + // pub fn asConstraintMut(constraint: *Constraint) *Constraint { + // return @ptrCast(constraint); + // } - pub fn getType(constraint: *const T) Type { - return @as( - Type, - @enumFromInt(c.JPC_Constraint_GetType(@as(*const c.JPC_Constraint, @ptrCast(constraint)))), - ); - } - pub fn getSubType(constraint: *const T) SubType { - return @as( - SubType, - @enumFromInt(c.JPC_Constraint_GetSubType(@as(*const c.JPC_Constraint, @ptrCast(constraint)))), - ); - } + pub fn addRef(constraint: *Constraint) void { + c.JPC_Constraint_AddRef(@ptrCast(constraint)); + } - pub fn getUserData(constraint: *const T) u64 { - return c.JPC_Constraint_GetUserData(@as(*const c.JPC_Constraint, @ptrCast(constraint))); - } - pub fn setUserData(constraint: *T, user_data: u64) void { - return c.JPC_Constraint_SetUserData(@as(*c.JPC_Constraint, @ptrCast(constraint)), user_data); - } - }; + pub fn release(constraint: *Constraint) void { + c.JPC_Constraint_Release(@ptrCast(constraint)); + } + + pub fn getRefCount(constraint: *const Constraint) u32 { + return c.JPC_Constraint_GetRefCount(@ptrCast(constraint)); + } + + pub fn getType(constraint: *const Constraint) Type { + return @enumFromInt(c.JPC_Constraint_GetType(@ptrCast(constraint))); + } + + pub fn getSubType(constraint: *const Constraint) SubType { + return @enumFromInt(c.JPC_Constraint_GetSubType(@ptrCast(constraint))); + } + + pub fn getUserData(constraint: *const Constraint) u64 { + return c.JPC_Constraint_GetUserData(@ptrCast(constraint)); + } + + pub fn setUserData(constraint: *Constraint, user_data: u64) void { + return c.JPC_Constraint_SetUserData(@ptrCast(constraint), user_data); } }; //-------------------------------------------------------------------------------------------------- @@ -3952,7 +3661,7 @@ pub const Constraint = opaque { // Memory allocation // //-------------------------------------------------------------------------------------------------- -fn zphysicsAlloc(size: usize) callconv(.C) ?*anyopaque { +fn zphysicsAlloc(size: usize) callconv(.c) ?*anyopaque { state.?.mem_mutex.lock(); defer state.?.mem_mutex.unlock(); @@ -3971,7 +3680,7 @@ fn zphysicsAlloc(size: usize) callconv(.C) ?*anyopaque { return ptr; } -fn zphysicsRealloc(maybe_ptr: ?*anyopaque, reported_old_size: usize, new_size: usize) callconv(.C) ?*anyopaque { +fn zphysicsRealloc(maybe_ptr: ?*anyopaque, reported_old_size: usize, new_size: usize) callconv(.c) ?*anyopaque { state.?.mem_mutex.lock(); defer state.?.mem_mutex.unlock(); @@ -3997,7 +3706,7 @@ fn zphysicsRealloc(maybe_ptr: ?*anyopaque, reported_old_size: usize, new_size: u return mem.ptr; } -fn zphysicsAlignedAlloc(size: usize, alignment: usize) callconv(.C) ?*anyopaque { +fn zphysicsAlignedAlloc(size: usize, alignment: usize) callconv(.c) ?*anyopaque { state.?.mem_mutex.lock(); defer state.?.mem_mutex.unlock(); @@ -4016,7 +3725,7 @@ fn zphysicsAlignedAlloc(size: usize, alignment: usize) callconv(.C) ?*anyopaque return ptr; } -fn zphysicsFree(maybe_ptr: ?*anyopaque) callconv(.C) void { +fn zphysicsFree(maybe_ptr: ?*anyopaque) callconv(.c) void { if (maybe_ptr) |ptr| { state.?.mem_mutex.lock(); defer state.?.mem_mutex.unlock(); @@ -4134,9 +3843,9 @@ test "zphysics.basic" { const my_object_should_collide = test_cb1.MyObjectLayerPairFilter{}; const physics_system = try PhysicsSystem.create( - @as(*const BroadPhaseLayerInterface, @ptrCast(&my_broad_phase_layer_interface)), - @as(*const ObjectVsBroadPhaseLayerFilter, @ptrCast(&my_broad_phase_should_collide)), - @as(*const ObjectLayerPairFilter, @ptrCast(&my_object_should_collide)), + @ptrCast(&my_broad_phase_layer_interface), + @ptrCast(&my_broad_phase_should_collide), + @ptrCast(&my_object_should_collide), .{ .max_bodies = 1024, .num_body_mutexes = 0, @@ -4187,23 +3896,23 @@ test "zphysics.basic" { var box_shape_settings: ?*BoxShapeSettings = null; box_shape_settings = try BoxShapeSettings.create(.{ 1.0, 2.0, 3.0 }); defer { - if (box_shape_settings) |bss| bss.release(); + if (box_shape_settings) |bss| bss.asShapeSettings().release(); } - box_shape_settings.?.setDensity(2.0); - try expect(box_shape_settings.?.getDensity() == 2.0); + box_shape_settings.?.asConvexShapeSettings().setDensity(2.0); + try expect(box_shape_settings.?.asConvexShapeSettings().getDensity() == 2.0); - box_shape_settings.?.setUserData(123); - try expect(box_shape_settings.?.getUserData() == 123); + box_shape_settings.?.asShapeSettings().setUserData(123); + try expect(box_shape_settings.?.asShapeSettings().getUserData() == 123); box_shape_settings.?.setConvexRadius(0.5); try expect(box_shape_settings.?.getConvexRadius() == 0.5); - try expect(box_shape_settings.?.getRefCount() == 1); - box_shape_settings.?.addRef(); - try expect(box_shape_settings.?.getRefCount() == 2); - box_shape_settings.?.release(); - try expect(box_shape_settings.?.getRefCount() == 1); + try expect(box_shape_settings.?.asShapeSettings().getRefCount() == 1); + box_shape_settings.?.asShapeSettings().addRef(); + try expect(box_shape_settings.?.asShapeSettings().getRefCount() == 2); + box_shape_settings.?.asShapeSettings().release(); + try expect(box_shape_settings.?.asShapeSettings().getRefCount() == 1); { var he = box_shape_settings.?.getHalfExtent(); @@ -4216,18 +3925,18 @@ test "zphysics.basic" { try expect(box_shape_settings.?.asConvexShapeSettings().getDensity() == 2.0); try expect(box_shape_settings.?.asShapeSettings().getRefCount() == 1); - const box_shape = try box_shape_settings.?.createShape(); + const box_shape = try box_shape_settings.?.asShapeSettings().createShape(); defer box_shape.release(); { - const bs = try box_shape_settings.?.createShape(); + const bs = try box_shape_settings.?.asShapeSettings().createShape(); defer bs.release(); try expect(bs == box_shape); try expect(bs.getRefCount() == 3); } try expect(box_shape.getRefCount() == 2); - box_shape_settings.?.release(); + box_shape_settings.?.asShapeSettings().release(); box_shape_settings = null; try expect(box_shape.getRefCount() == 1); @@ -4255,20 +3964,20 @@ test "zphysics.shape.sphere" { defer physics_system.destroy(); const sphere_shape_settings = try SphereShapeSettings.create(10.0); - defer sphere_shape_settings.release(); + defer sphere_shape_settings.asShapeSettings().release(); try expect(sphere_shape_settings.getRadius() == 10.0); sphere_shape_settings.setRadius(2.0); try expect(sphere_shape_settings.getRadius() == 2.0); - sphere_shape_settings.setDensity(2.0); - try expect(sphere_shape_settings.getDensity() == 2.0); + sphere_shape_settings.asConvexShapeSettings().setDensity(2.0); + try expect(sphere_shape_settings.asConvexShapeSettings().getDensity() == 2.0); - sphere_shape_settings.setMaterial(null); - try expect(sphere_shape_settings.getMaterial() == null); + sphere_shape_settings.asConvexShapeSettings().setMaterial(null); + try expect(sphere_shape_settings.asConvexShapeSettings().getMaterial() == null); - const sphere_shape = try sphere_shape_settings.createShape(); + const sphere_shape = try sphere_shape_settings.asShapeSettings().createShape(); defer sphere_shape.release(); try expect(sphere_shape.getRefCount() == 2); @@ -4296,7 +4005,7 @@ test "zphysics.shape.capsule" { defer physics_system.destroy(); const capsule_shape_settings = try CapsuleShapeSettings.create(10.0, 2.0); - defer capsule_shape_settings.release(); + defer capsule_shape_settings.asShapeSettings().release(); try expect(capsule_shape_settings.getRadius() == 2.0); try expect(capsule_shape_settings.getHalfHeight() == 10.0); @@ -4307,7 +4016,7 @@ test "zphysics.shape.capsule" { capsule_shape_settings.setHalfHeight(1.0); try expect(capsule_shape_settings.getHalfHeight() == 1.0); - const capsule_shape = try capsule_shape_settings.createShape(); + const capsule_shape = try capsule_shape_settings.asShapeSettings().createShape(); defer capsule_shape.release(); try expect(capsule_shape.getRefCount() == 2); @@ -4335,7 +4044,7 @@ test "zphysics.shape.taperedcapsule" { defer physics_system.destroy(); const capsule_shape_settings = try TaperedCapsuleShapeSettings.create(10.0, 2.0, 3.0); - defer capsule_shape_settings.release(); + defer capsule_shape_settings.asShapeSettings().release(); try expect(capsule_shape_settings.getTopRadius() == 2.0); try expect(capsule_shape_settings.getBottomRadius() == 3.0); @@ -4347,7 +4056,7 @@ test "zphysics.shape.taperedcapsule" { capsule_shape_settings.setBottomRadius(1.0); try expect(capsule_shape_settings.getBottomRadius() == 1.0); - const capsule_shape = try capsule_shape_settings.createShape(); + const capsule_shape = try capsule_shape_settings.asShapeSettings().createShape(); defer capsule_shape.release(); try expect(capsule_shape.getRefCount() == 2); @@ -4375,7 +4084,7 @@ test "zphysics.shape.cylinder" { defer physics_system.destroy(); const cylinder_shape_settings = try CylinderShapeSettings.create(10.0, 2.0); - defer cylinder_shape_settings.release(); + defer cylinder_shape_settings.asShapeSettings().release(); try expect(cylinder_shape_settings.getRadius() == 2.0); try expect(cylinder_shape_settings.getHalfHeight() == 10.0); @@ -4389,7 +4098,7 @@ test "zphysics.shape.cylinder" { cylinder_shape_settings.setConvexRadius(0.5); try expect(cylinder_shape_settings.getConvexRadius() == 0.5); - const cylinder_shape = try cylinder_shape_settings.createShape(); + const cylinder_shape = try cylinder_shape_settings.asShapeSettings().createShape(); defer cylinder_shape.release(); try expect(cylinder_shape.getRefCount() == 2); @@ -4419,12 +4128,12 @@ test "zphysics.shape.convexhull" { const points = [_]f32{ 0, 0, 0, 1, 1, 1, 1, 1, 0 }; const settings = try ConvexHullShapeSettings.create(&points, 3, 12); - defer settings.release(); + defer settings.asShapeSettings().release(); settings.setMaxConvexRadius(0.1); try expect(settings.getMaxConvexRadius() == 0.1); - const shape = try settings.createShape(); + const shape = try settings.asShapeSettings().createShape(); defer shape.release(); try expect(shape.getRefCount() == 2); @@ -4455,7 +4164,7 @@ test "zphysics.shape.heightfield" { // Height field size is 4x4 const settings = try HeightFieldShapeSettings.create(&points, 4); - defer settings.release(); + defer settings.asShapeSettings().release(); settings.setBlockSize(2); settings.setBitsPerSample(6); @@ -4471,7 +4180,7 @@ test "zphysics.shape.heightfield" { try expect(settings.getScale()[1] == 5); try expect(settings.getScale()[2] == 6); - const shape = try settings.createShape(); + const shape = try settings.asShapeSettings().createShape(); defer shape.release(); try expect(shape.getRefCount() == 2); @@ -4502,14 +4211,14 @@ test "zphysics.shape.meshshape" { const indices = [3]u32{ 0, 1, 2 }; const settings = try MeshShapeSettings.create(&vertices, 3, @sizeOf([3]f32), &indices); - defer settings.release(); + defer settings.asShapeSettings().release(); settings.setMaxTrianglesPerLeaf(4); settings.sanitize(); try expect(settings.getMaxTrianglesPerLeaf() == 4); - const shape = try settings.createShape(); + const shape = try settings.asShapeSettings().createShape(); defer shape.release(); try expect(shape.getRefCount() == 2); @@ -4545,9 +4254,9 @@ test "zphysics.body.basic" { const body_interface = physics_system.getBodyInterface(); const floor_shape_settings = try BoxShapeSettings.create(.{ 100.0, 1.0, 100.0 }); - defer floor_shape_settings.release(); + defer floor_shape_settings.asShapeSettings().release(); - const floor_shape = try floor_shape_settings.createShape(); + const floor_shape = try floor_shape_settings.asShapeSettings().createShape(); defer floor_shape.release(); var shape_ray = RayCast{ .origin = .{ 0, 2, 0, 1 }, .direction = .{ 101, -1, 0, 0 } }; @@ -4579,23 +4288,23 @@ test "zphysics.body.basic" { var result = query.castRay(.{ .origin = .{ 0, 10, 0, 1 }, .direction = .{ 0, -20, 0, 0 } }, .{}); try expect(result.has_hit == true); try expect(result.hit.body_id == body_id); - try expect(result.hit.sub_shape_id == sub_shape_id_empty); + try expect(result.hit.sub_shape_id == .empty); try expect(std.math.approxEqAbs(f32, result.hit.fraction, 0.5, 0.001) == true); result = query.castRay(.{ .origin = .{ 0, 10, 0, 1 }, .direction = .{ 0, 20, 0, 0 } }, .{}); try expect(result.has_hit == false); - try expect(result.hit.body_id == body_id_invalid); + try expect(result.hit.body_id == .invalid); result = query.castRay(.{ .origin = .{ 0, 10, 0, 1 }, .direction = .{ 0, -5, 0, 0 } }, .{}); try expect(result.has_hit == false); - try expect(result.hit.body_id == body_id_invalid); + try expect(result.hit.body_id == .invalid); const ray = c.JPC_RRayCast{ .origin = .{ 0, 10, 0, 0 }, .direction = .{ 0, -20, 0, 0 }, }; var hit: c.JPC_RayCastResult = .{ - .body_id = body_id_invalid, + .body_id = BodyId.invalid.toJpc(), .fraction = 1.0 + flt_epsilon, .sub_shape_id = undefined, }; @@ -4638,10 +4347,10 @@ test "zphysics.body.basic" { if (read_lock.body) |locked_body| { const all_bodies: []const *const Body = physics_system.getBodiesUnsafe(); - try expect(isValidBodyPointer(all_bodies[body_id & body_id_index_bits])); - try expect(locked_body == all_bodies[body_id & body_id_index_bits]); + try expect(isValidBodyPointer(all_bodies[body_id.indexBits()])); + try expect(locked_body == all_bodies[body_id.indexBits()]); try expect(locked_body.id == body_id); - try expect(locked_body.id == all_bodies[body_id & body_id_index_bits].id); + try expect(locked_body.id == all_bodies[body_id.indexBits()].id); } } { @@ -4654,13 +4363,13 @@ test "zphysics.body.basic" { if (write_lock.body) |locked_body| { const all_bodies_mut: []const *Body = physics_system.getBodiesMutUnsafe(); - try expect(isValidBodyPointer(all_bodies_mut[body_id & body_id_index_bits])); - try expect(locked_body == all_bodies_mut[body_id & body_id_index_bits]); + try expect(isValidBodyPointer(all_bodies_mut[body_id.indexBits()])); + try expect(locked_body == all_bodies_mut[body_id.indexBits()]); try expect(locked_body.id == body_id); - try expect(locked_body.id == all_bodies_mut[body_id & body_id_index_bits].id); + try expect(locked_body.id == all_bodies_mut[body_id.indexBits()].id); - all_bodies_mut[body_id & body_id_index_bits].user_data = 12345; - try expect(all_bodies_mut[body_id & body_id_index_bits].user_data == 12345); + all_bodies_mut[body_id.indexBits()].user_data = 12345; + try expect(all_bodies_mut[body_id.indexBits()].user_data == 12345); } } @@ -4722,9 +4431,9 @@ test "zphysics.body.motion" { const lock_interface = physics_system.getBodyLockInterface(); const shape_settings = try BoxShapeSettings.create(.{ 1.0, 2.0, 3.0 }); - defer shape_settings.release(); + defer shape_settings.asShapeSettings().release(); - const shape = try shape_settings.createShape(); + const shape = try shape_settings.asShapeSettings().createShape(); defer shape.release(); const body_settings = BodyCreationSettings{ @@ -4763,8 +4472,8 @@ test "zphysics.body.motion" { try expect(body.user_data == 0xC0DE_C0DE_C0DE_C0DE); try expect(body.getAllowSleeping() == false); - const normal0 = body.getWorldSpaceSurfaceNormal(sub_shape_id_empty, .{ 0, 12, 0 }); - const normal1 = body.getWorldSpaceSurfaceNormal(sub_shape_id_empty, .{ -1, 10, 0 }); + const normal0 = body.getWorldSpaceSurfaceNormal(.empty, .{ 0, 12, 0 }); + const normal1 = body.getWorldSpaceSurfaceNormal(.empty, .{ -1, 10, 0 }); try expect(std.math.approxEqAbs(f32, normal0[0], 0.0, 0.001) == true); try expect(std.math.approxEqAbs(f32, normal0[1], 1.0, 0.001) == true); @@ -4805,17 +4514,19 @@ test "zphysics.debugrenderer" { const my_object_should_collide = test_cb1.MyObjectLayerPairFilter{}; const physics_system = try PhysicsSystem.create( - @as(*const BroadPhaseLayerInterface, @ptrCast(&my_broad_phase_layer_interface)), - @as(*const ObjectVsBroadPhaseLayerFilter, @ptrCast(&my_broad_phase_should_collide)), - @as(*const ObjectLayerPairFilter, @ptrCast(&my_object_should_collide)), + @ptrCast(&my_broad_phase_layer_interface), + @ptrCast(&my_broad_phase_should_collide), + @ptrCast(&my_object_should_collide), .{}, ); defer physics_system.destroy(); + try std.testing.expectEqual(24, my_debug_renderer.prim_head); + const shape_settings = try BoxShapeSettings.create(.{ 1.0, 2.0, 3.0 }); - defer shape_settings.release(); + defer shape_settings.asShapeSettings().release(); - const shape = try shape_settings.createShape(); + const shape = try shape_settings.asShapeSettings().createShape(); defer shape.release(); const body_settings = BodyCreationSettings{ @@ -4839,6 +4550,7 @@ test "zphysics.debugrenderer" { defer DebugRenderer.destroyBodyDrawFilter(draw_filter); physics_system.drawBodies(&draw_settings, draw_filter); + try std.testing.expectEqual(1, my_debug_renderer.draw_geometry_count); } test "zphysics.serialization" { @@ -4847,9 +4559,9 @@ test "zphysics.serialization" { const half_extents: [3]f32 = .{ 1.0, 2.0, 3.0 }; const shape_settings = try BoxShapeSettings.create(half_extents); - defer shape_settings.release(); + defer shape_settings.asShapeSettings().release(); - const shape = try shape_settings.createShape(); + const shape = try shape_settings.asShapeSettings().createShape(); defer shape.release(); var buf: std.ArrayListUnmanaged(u8) = .{}; @@ -4895,19 +4607,9 @@ const test_cb1 = struct { }; const MyBroadphaseLayerInterface = extern struct { - usingnamespace BroadPhaseLayerInterface.Methods(@This()); - __v: *const BroadPhaseLayerInterface.VTable = &vtable, - + interface: BroadPhaseLayerInterface = .init(@This()), object_to_broad_phase: [object_layers.len]BroadPhaseLayer = undefined, - const vtable = BroadPhaseLayerInterface.VTable{ - .getNumBroadPhaseLayers = _getNumBroadPhaseLayers, - .getBroadPhaseLayer = if (@import("builtin").abi == .msvc) - _getBroadPhaseLayerMsvc - else - _getBroadPhaseLayer, - }; - fn init() MyBroadphaseLayerInterface { var layer_interface: MyBroadphaseLayerInterface = .{}; layer_interface.object_to_broad_phase[object_layers.non_moving] = broad_phase_layers.non_moving; @@ -4915,41 +4617,40 @@ const test_cb1 = struct { return layer_interface; } - fn _getNumBroadPhaseLayers(iself: *const BroadPhaseLayerInterface) callconv(.C) u32 { - const self = @as(*const MyBroadphaseLayerInterface, @ptrCast(iself)); - return @as(u32, @intCast(self.object_to_broad_phase.len)); + pub fn getNumBroadPhaseLayers(interface: *const BroadPhaseLayerInterface) callconv(.c) u32 { + const self: *const MyBroadphaseLayerInterface = @alignCast(@fieldParentPtr("interface", interface)); + return @intCast(self.object_to_broad_phase.len); } + pub const getBroadPhaseLayer = if (builtin.abi == .msvc) _getBroadPhaseLayerMsvc else _getBroadPhaseLayer; + fn _getBroadPhaseLayer( - iself: *const BroadPhaseLayerInterface, + interface: *const BroadPhaseLayerInterface, layer: ObjectLayer, - ) callconv(.C) BroadPhaseLayer { - const self = @as(*const MyBroadphaseLayerInterface, @ptrCast(iself)); - return self.object_to_broad_phase[@as(usize, @intCast(layer))]; + ) callconv(.c) BroadPhaseLayer { + const self: *const MyBroadphaseLayerInterface = @alignCast(@fieldParentPtr("interface", interface)); + return self.object_to_broad_phase[@intCast(layer)]; } fn _getBroadPhaseLayerMsvc( - iself: *const BroadPhaseLayerInterface, + interface: *const BroadPhaseLayerInterface, out_layer: *BroadPhaseLayer, layer: ObjectLayer, - ) callconv(.C) *const BroadPhaseLayer { - const self = @as(*const MyBroadphaseLayerInterface, @ptrCast(iself)); - out_layer.* = self.object_to_broad_phase[@as(usize, @intCast(layer))]; + ) callconv(.c) *const BroadPhaseLayer { + const self: *const MyBroadphaseLayerInterface = @alignCast(@fieldParentPtr("interface", interface)); + out_layer.* = self.object_to_broad_phase[@intCast(layer)]; return out_layer; } }; const MyObjectVsBroadPhaseLayerFilter = extern struct { - usingnamespace ObjectVsBroadPhaseLayerFilter.Methods(@This()); - __v: *const ObjectVsBroadPhaseLayerFilter.VTable = &vtable, + filter: ObjectVsBroadPhaseLayerFilter = .init(@This()), - const vtable = ObjectVsBroadPhaseLayerFilter.VTable{ .shouldCollide = _shouldCollide }; - - fn _shouldCollide( + pub fn shouldCollide( _: *const ObjectVsBroadPhaseLayerFilter, layer1: ObjectLayer, layer2: BroadPhaseLayer, - ) callconv(.C) bool { + ) callconv(.c) bool { return switch (layer1) { object_layers.non_moving => layer2 == broad_phase_layers.moving, object_layers.moving => true, @@ -4959,16 +4660,13 @@ const test_cb1 = struct { }; const MyObjectLayerPairFilter = extern struct { - usingnamespace ObjectLayerPairFilter.Methods(@This()); - __v: *const ObjectLayerPairFilter.VTable = &vtable, - - const vtable = ObjectLayerPairFilter.VTable{ .shouldCollide = _shouldCollide }; + interface: ObjectLayerPairFilter = .init(@This()), - fn _shouldCollide( + pub fn shouldCollide( _: *const ObjectLayerPairFilter, object1: ObjectLayer, object2: ObjectLayer, - ) callconv(.C) bool { + ) callconv(.c) bool { return switch (object1) { object_layers.non_moving => object2 == object_layers.moving, object_layers.moving => true, @@ -4978,15 +4676,12 @@ const test_cb1 = struct { }; const MyPhysicsStepListener = extern struct { - usingnamespace PhysicsStepListener.Methods(@This()); - __v: *const PhysicsStepListener.VTable = &vtable, + listener: PhysicsStepListener = .init(@This()), steps_heard: u32 = 0, physics_system: *PhysicsSystem, - const vtable = PhysicsStepListener.VTable{ .onStep = _onStep }; - - fn _onStep(psl: *PhysicsStepListener, context: *const PhysicsStepListenerContext) callconv(.C) void { - const self = @as(*MyPhysicsStepListener, @ptrCast(psl)); + pub fn onStep(listener: *PhysicsStepListener, context: *const PhysicsStepListenerContext) callconv(.c) void { + const self: *MyPhysicsStepListener = @alignCast(@fieldParentPtr("listener", listener)); assert(context.physics_system == self.physics_system); self.steps_heard += 1; } @@ -4994,26 +4689,17 @@ const test_cb1 = struct { const MyDebugRenderer = if (!debug_renderer_enabled) void else extern struct { const MyRenderPrimitive = extern struct { - // Actual render data goes here - foobar: i32 = 0, + allocated: bool = false, }; - usingnamespace DebugRenderer.Methods(@This()); - __v: *const DebugRenderer.VTable(@This()) = &vtable, + const VTable = DebugRenderer.VTable(@This()); + vtable: *const VTable = DebugRenderer.initVTable(@This()), - primitives: [32]MyRenderPrimitive = [_]MyRenderPrimitive{.{}} ** 32, + primitives: [32]MyRenderPrimitive = @splat(.{}), prim_head: i32 = -1, + draw_geometry_count: usize = 0, - const vtable = DebugRenderer.VTable(@This()){ - .drawLine = drawLine, - .drawTriangle = drawTriangle, - .createTriangleBatch = createTriangleBatch, - .createTriangleBatchIndexed = createTriangleBatchIndexed, - .drawGeometry = drawGeometry, - .drawText3D = drawText3D, - }; - - pub fn shouldBodyDraw(_: *const Body) callconv(.C) bool { + pub fn shouldBodyDraw(_: *const Body) callconv(.c) bool { return true; } @@ -5022,7 +4708,7 @@ const test_cb1 = struct { from: *const [3]Real, to: *const [3]Real, color: DebugRenderer.Color, - ) callconv(.C) void { + ) callconv(.c) void { _ = self; _ = from; _ = to; @@ -5034,7 +4720,7 @@ const test_cb1 = struct { v2: *const [3]Real, v3: *const [3]Real, color: DebugRenderer.Color, - ) callconv(.C) void { + ) callconv(.c) void { _ = self; _ = v1; _ = v2; @@ -5045,11 +4731,12 @@ const test_cb1 = struct { self: *MyDebugRenderer, triangles: [*]DebugRenderer.Triangle, triangle_count: u32, - ) callconv(.C) *anyopaque { + ) callconv(.c) *DebugRenderer.TriangleBatch { _ = triangles; _ = triangle_count; self.prim_head += 1; - const prim = &self.primitives[@as(usize, @intCast(self.prim_head))]; + const prim = &self.primitives[@intCast(self.prim_head)]; + prim.allocated = true; return DebugRenderer.createTriangleBatch(prim); } fn createTriangleBatchIndexed( @@ -5058,15 +4745,24 @@ const test_cb1 = struct { vertex_count: u32, indices: [*]u32, index_count: u32, - ) callconv(.C) *anyopaque { + ) callconv(.c) *DebugRenderer.TriangleBatch { _ = vertices; _ = vertex_count; _ = indices; _ = index_count; self.prim_head += 1; - const prim = &self.primitives[@as(usize, @intCast(self.prim_head))]; + const prim = &self.primitives[@intCast(self.prim_head)]; + prim.allocated = true; return DebugRenderer.createTriangleBatch(prim); } + fn destroyTriangleBatch( + self: *MyDebugRenderer, + batch: *anyopaque, + ) callconv(.c) void { + _ = self; + const primitive: *MyRenderPrimitive = @alignCast(@ptrCast(batch)); + primitive.allocated = false; + } fn drawGeometry( self: *MyDebugRenderer, model_matrix: *const RMatrix, @@ -5077,8 +4773,7 @@ const test_cb1 = struct { cull_mode: DebugRenderer.CullMode, cast_shadow: DebugRenderer.CastShadow, draw_mode: DebugRenderer.DrawMode, - ) callconv(.C) void { - _ = self; + ) callconv(.c) void { _ = model_matrix; _ = world_space_bound; _ = lod_scale_sq; @@ -5087,6 +4782,7 @@ const test_cb1 = struct { _ = cull_mode; _ = cast_shadow; _ = draw_mode; + self.draw_geometry_count += 1; } fn drawText3D( self: *MyDebugRenderer, @@ -5094,7 +4790,7 @@ const test_cb1 = struct { string: [*:0]const u8, color: DebugRenderer.Color, height: f32, - ) callconv(.C) void { + ) callconv(.c) void { _ = self; _ = positions; _ = string;