diff --git a/build.zig.zon b/build.zig.zon index 7df34c2..2011316 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -2,7 +2,7 @@ .name = .zphysics, .fingerprint = 0x1def6aac00c4909d, .version = "0.2.0-dev", - .minimum_zig_version = "0.14.0", + .minimum_zig_version = "0.15.1", .paths = .{ "build.zig", "build.zig.zon", diff --git a/libs/JoltC/JoltPhysicsC.cpp b/libs/JoltC/JoltPhysicsC.cpp index 5ff34d4..417a41e 100644 --- a/libs/JoltC/JoltPhysicsC.cpp +++ b/libs/JoltC/JoltPhysicsC.cpp @@ -302,6 +302,7 @@ FN(toJpc)(JPH::CollisionGroup *in) { assert(in); return reinterpret_cast(in); } FN(toJph)(const JPC_BodyID *in) { assert(in); return reinterpret_cast(in); } +FN(toJph)(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); } @@ -353,6 +354,9 @@ FN(toJph)(const JPC_BodyInterface *in) { assert(in); return reinterpret_cast(in); } FN(toJph)(JPC_BodyInterface *in) { assert(in); return reinterpret_cast(in); } +FN(toJpc)(JPH::BodyInterface::AddState in) { assert(in); return reinterpret_cast(in); } +FN(toJph)(JPC_BodyInterface_AddState* in) { assert(in); return reinterpret_cast(in); } + FN(toJpc)(const JPH::TransformedShape *in) { assert(in); return reinterpret_cast(in); } FN(toJph)(const JPC_MassProperties *in) { assert(in); return reinterpret_cast(in); } @@ -2356,6 +2360,31 @@ JPC_BodyInterface_DestroyBody(JPC_BodyInterface *in_iface, JPC_BodyID in_body_id } //-------------------------------------------------------------------------------------------------- JPC_API void +JPC_BodyInterface_AddBodiesAbort(JPC_BodyInterface *in_iface, + JPC_BodyID* in_body_ids, + int in_num_bodies, + JPC_BodyInterface_AddState* add_state) +{ + return toJph(in_iface)->AddBodiesAbort(toJph(in_body_ids), in_num_bodies, toJph(add_state)); +} +//-------------------------------------------------------------------------------------------------- +JPC_API void +JPC_BodyInterface_AddBodiesFinalize(JPC_BodyInterface *in_iface, + JPC_BodyID* in_body_ids, + int in_num_bodies, + JPC_BodyInterface_AddState* add_state, + JPC_Activation in_mode) +{ + return toJph(in_iface)->AddBodiesFinalize(toJph(in_body_ids), in_num_bodies, toJph(add_state), static_cast(in_mode)); +} +//-------------------------------------------------------------------------------------------------- +JPC_API JPC_BodyInterface_AddState* +JPC_BodyInterface_AddBodiesPrepare(JPC_BodyInterface *in_iface, JPC_BodyID* in_body_ids, int in_num_bodies) +{ + return toJpc(toJph(in_iface)->AddBodiesPrepare(toJph(in_body_ids), in_num_bodies)); +} +//-------------------------------------------------------------------------------------------------- +JPC_API void JPC_BodyInterface_AddBody(JPC_BodyInterface *in_iface, JPC_BodyID in_body_id, JPC_Activation in_mode) { toJph(in_iface)->AddBody(toJph(in_body_id), static_cast(in_mode)); diff --git a/libs/JoltC/JoltPhysicsC.h b/libs/JoltC/JoltPhysicsC.h index f405e07..ce91bbb 100644 --- a/libs/JoltC/JoltPhysicsC.h +++ b/libs/JoltC/JoltPhysicsC.h @@ -330,6 +330,7 @@ typedef bool (*JPC_AssertFailedFunction)( typedef struct JPC_TempAllocator JPC_TempAllocator; typedef struct JPC_JobSystem JPC_JobSystem; typedef struct JPC_BodyInterface JPC_BodyInterface; +typedef struct JPC_BodyInterface_AddState JPC_BodyInterface_AddState; typedef struct JPC_BodyLockInterface JPC_BodyLockInterface; typedef struct JPC_NarrowPhaseQuery JPC_NarrowPhaseQuery; @@ -2026,6 +2027,22 @@ JPC_BodyInterface_CreateBodyWithID(JPC_BodyInterface *in_iface, JPC_API void JPC_BodyInterface_DestroyBody(JPC_BodyInterface *in_iface, JPC_BodyID in_body_id); +JPC_API void +JPC_BodyInterface_AddBodiesAbort(JPC_BodyInterface *in_iface, + JPC_BodyID* in_body_ids, + int in_num_bodies, + JPC_BodyInterface_AddState* add_state); + +JPC_API void +JPC_BodyInterface_AddBodiesFinalize(JPC_BodyInterface *in_iface, + JPC_BodyID* in_body_ids, + int in_num_bodies, + JPC_BodyInterface_AddState* add_state, + JPC_Activation in_mode); + +JPC_API JPC_BodyInterface_AddState* +JPC_BodyInterface_AddBodiesPrepare(JPC_BodyInterface *in_iface, JPC_BodyID* in_body_ids, int in_num_bodies); + JPC_API void JPC_BodyInterface_AddBody(JPC_BodyInterface *in_iface, JPC_BodyID in_body_id, JPC_Activation in_mode); diff --git a/src/zphysics.zig b/src/zphysics.zig index c9e1d67..b9061fe 100644 --- a/src/zphysics.zig +++ b/src/zphysics.zig @@ -148,7 +148,7 @@ fn initInterface(comptime T: type, comptime VTableT: type) *const VTableT { } } else { if (field.default_value_ptr) |default_value_ptr| { - @field(vtable, field.name) = @as(*const field.type, @alignCast(@ptrCast(default_value_ptr))).*; + @field(vtable, field.name) = @as(*const field.type, @ptrCast(@alignCast(default_value_ptr))).*; } else @compileError("non-pointer vtable field " ++ field.name ++ " must have a default value"); } } @@ -184,24 +184,24 @@ pub const StreamOut = extern struct { } }; -pub const AnyWriterStreamOut = extern struct { +pub const WriterStreamOut = extern struct { stream_out: StreamOut = .init(@This()), - writer: *const std.io.AnyWriter, + writer: *std.Io.Writer, failed: bool = false, - pub fn init(writer: *const std.io.AnyWriter) AnyWriterStreamOut { + pub fn init(writer: *std.Io.Writer) WriterStreamOut { return .{ .writer = writer }; } pub fn writeBytes(stream_out: *StreamOut, data: [*]const u8, num_bytes: usize) callconv(.c) void { - const self: *AnyWriterStreamOut = @alignCast(@fieldParentPtr("stream_out", stream_out)); + const self: *WriterStreamOut = @alignCast(@fieldParentPtr("stream_out", stream_out)); self.writer.writeAll(data[0..num_bytes]) catch { self.failed = true; }; } pub fn isFailed(stream_out: *StreamOut) callconv(.c) bool { - const self: *AnyWriterStreamOut = @alignCast(@fieldParentPtr("stream_out", stream_out)); + const self: *WriterStreamOut = @alignCast(@fieldParentPtr("stream_out", stream_out)); return self.failed; } }; @@ -225,19 +225,19 @@ pub const StreamIn = extern struct { } }; -pub const AnyReaderStreamIn = extern struct { +pub const ReaderStreamIn = extern struct { stream_in: StreamIn = .init(@This()), - reader: *const std.io.AnyReader, + reader: *std.Io.Reader, failed: bool = false, eof: bool = false, - pub fn init(reader: *const std.io.AnyReader) AnyReaderStreamIn { + pub fn init(reader: *std.Io.Reader) ReaderStreamIn { return .{ .reader = reader }; } 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) { + self.reader.readSliceAll(data[0..num_bytes]) catch |err| switch (err) { error.EndOfStream => self.eof = true, else => self.failed = true, }; @@ -1509,8 +1509,12 @@ pub const PhysicsSystem = opaque { 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()); + pub fn getBodyIds( + physics_system: *const PhysicsSystem, + allocator: std.mem.Allocator, + body_ids: *std.ArrayList(BodyId), + ) !void { + try body_ids.ensureTotalCapacityPrecise(allocator, physics_system.getMaxBodies()); var num_body_ids: u32 = 0; c.JPC_PhysicsSystem_GetBodyIDs( @as(*const c.JPC_PhysicsSystem, @ptrCast(physics_system)), @@ -1521,8 +1525,12 @@ pub const PhysicsSystem = opaque { body_ids.items.len = num_body_ids; } - pub fn getActiveBodyIds(physics_system: *const PhysicsSystem, body_ids: *std.ArrayList(BodyId)) !void { - try body_ids.ensureTotalCapacityPrecise(physics_system.getMaxBodies()); + pub fn getActiveBodyIds( + physics_system: *const PhysicsSystem, + allocator: std.mem.Allocator, + body_ids: *std.ArrayList(BodyId), + ) !void { + try body_ids.ensureTotalCapacityPrecise(allocator, physics_system.getMaxBodies()); var num_body_ids: u32 = 0; c.JPC_PhysicsSystem_GetActiveBodyIDs( @as(*const c.JPC_PhysicsSystem, @ptrCast(physics_system)), @@ -1618,6 +1626,8 @@ pub const BodyLockWrite = extern struct { // //-------------------------------------------------------------------------------------------------- pub const BodyInterface = opaque { + pub const AddState = *opaque {}; + pub fn createBody(body_iface: *BodyInterface, settings: BodyCreationSettings) !*Body { const body = c.JPC_BodyInterface_CreateBody( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), @@ -1646,6 +1656,33 @@ pub const BodyInterface = opaque { ); } + pub fn addBodiesAbort(body_iface: *BodyInterface, body_ids: []BodyId, add_state: AddState) void { + c.JPC_BodyInterface_AddBodiesAbort( + @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), + @ptrCast(body_ids.ptr), + @intCast(body_ids.len), + @ptrCast(add_state), + ); + } + + pub fn addBodiesFinalize(body_iface: *BodyInterface, body_ids: []BodyId, add_state: AddState, mode: Activation) void { + c.JPC_BodyInterface_AddBodiesFinalize( + @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), + @ptrCast(body_ids.ptr), + @intCast(body_ids.len), + @ptrCast(add_state), + @intFromEnum(mode), + ); + } + + pub fn addBodiesPrepare(body_iface: *BodyInterface, body_ids: []BodyId) AddState { + return @ptrCast(c.JPC_BodyInterface_AddBodiesPrepare( + @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), + @ptrCast(body_ids.ptr), + @intCast(body_ids.len), + )); + } + pub fn addBody(body_iface: *BodyInterface, body_id: BodyId, mode: Activation) void { c.JPC_BodyInterface_AddBody( @as(*c.JPC_BodyInterface, @ptrCast(body_iface)), @@ -3390,7 +3427,7 @@ pub const Shape = opaque { pub fn getLocalBounds(shape: *const Shape) AABox { const aabox = c.JPC_Shape_GetLocalBounds(@ptrCast(shape)); - return @as(*AABox, @constCast(@ptrCast(&aabox))).*; + return @as(*AABox, @ptrCast(@constCast(&aabox))).*; } pub fn getSurfaceNormal(shape: *const Shape, sub_shape_id: SubShapeId, local_pos: [3]f32) [3]f32 { @@ -4356,18 +4393,18 @@ test "zphysics.body.basic" { } { - var body_ids = std.ArrayList(BodyId).init(std.testing.allocator); - defer body_ids.deinit(); - try physics_system.getBodyIds(&body_ids); + var body_ids: std.ArrayList(BodyId) = .empty; + defer body_ids.deinit(std.testing.allocator); + try physics_system.getBodyIds(std.testing.allocator, &body_ids); try expect(body_ids.items.len == 1); try expect(body_ids.capacity >= physics_system.getMaxBodies()); try expect(body_ids.items[0] == body_id); } { - var body_ids = std.ArrayList(BodyId).init(std.testing.allocator); - defer body_ids.deinit(); - try physics_system.getActiveBodyIds(&body_ids); + var body_ids: std.ArrayList(BodyId) = .empty; + defer body_ids.deinit(std.testing.allocator); + try physics_system.getActiveBodyIds(std.testing.allocator, &body_ids); try expect(body_ids.items.len == 0); try expect(body_ids.capacity >= physics_system.getMaxBodies()); } @@ -4599,20 +4636,18 @@ test "zphysics.serialization" { const shape = try shape_settings.asShapeSettings().createShape(); defer shape.release(); - var buf: std.ArrayListUnmanaged(u8) = .{}; - defer buf.deinit(std.testing.allocator); + var buf: std.Io.Writer.Allocating = .init(std.testing.allocator); + defer buf.deinit(); { - const writer = buf.writer(std.testing.allocator).any(); - var stream_out = AnyWriterStreamOut.init(&writer); + var stream_out = WriterStreamOut.init(&buf.writer); shape.saveBinaryState(@ptrCast(&stream_out)); - try std.testing.expectEqual(1 + 8 + 4 + 12 + 4, buf.items.len); + try std.testing.expectEqual(1 + 8 + 4 + 12 + 4, buf.written().len); } { - var stream = std.io.fixedBufferStream(buf.items); - const reader = stream.reader().any(); - var stream_in = AnyReaderStreamIn.init(&reader); + var reader: std.Io.Reader = .fixed(buf.written()); + var stream_in = ReaderStreamIn.init(&reader); const shape_restored = try Shape.restoreFromBinaryState(@ptrCast(&stream_in)); defer shape_restored.release(); @@ -4795,7 +4830,7 @@ const test_cb1 = struct { batch: *anyopaque, ) callconv(.c) void { _ = self; - const primitive: *MyRenderPrimitive = @alignCast(@ptrCast(batch)); + const primitive: *MyRenderPrimitive = @ptrCast(@alignCast(batch)); primitive.allocated = false; } fn drawGeometry(