Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
29 changes: 29 additions & 0 deletions libs/JoltC/JoltPhysicsC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ FN(toJpc)(JPH::CollisionGroup *in) { assert(in); return reinterpret_cast<JPC_Col

FN(toJph)(const JPC_SubShapeID *in) { assert(in); return reinterpret_cast<const JPH::SubShapeID *>(in); }
FN(toJph)(const JPC_BodyID *in) { assert(in); return reinterpret_cast<const JPH::BodyID *>(in); }
FN(toJph)(JPC_BodyID *in) { assert(in); return reinterpret_cast<JPH::BodyID *>(in); }

FN(toJpc)(const JPH::SubShapeIDCreator *in) { assert(in); return reinterpret_cast<const JPC_SubShapeIDCreator *>(in); }
FN(toJph)(const JPC_SubShapeIDCreator *in) { assert(in); return reinterpret_cast<const JPH::SubShapeIDCreator *>(in); }
Expand Down Expand Up @@ -353,6 +354,9 @@ FN(toJph)(const JPC_BodyInterface *in) { assert(in); return reinterpret_cast<con
FN(toJpc)(JPH::BodyInterface *in) { assert(in); return reinterpret_cast<JPC_BodyInterface *>(in); }
FN(toJph)(JPC_BodyInterface *in) { assert(in); return reinterpret_cast<JPH::BodyInterface *>(in); }

FN(toJpc)(JPH::BodyInterface::AddState in) { assert(in); return reinterpret_cast<JPC_BodyInterface_AddState* >(in); }
FN(toJph)(JPC_BodyInterface_AddState* in) { assert(in); return reinterpret_cast<JPH::BodyInterface::AddState >(in); }

FN(toJpc)(const JPH::TransformedShape *in) { assert(in); return reinterpret_cast<const JPC_TransformedShape *>(in); }

FN(toJph)(const JPC_MassProperties *in) { assert(in); return reinterpret_cast<const JPH::MassProperties *>(in); }
Expand Down Expand Up @@ -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<JPH::EActivation>(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<JPH::EActivation>(in_mode));
Expand Down
17 changes: 17 additions & 0 deletions libs/JoltC/JoltPhysicsC.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);

Expand Down
95 changes: 65 additions & 30 deletions src/zphysics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}
Expand Down Expand Up @@ -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;
}
};
Expand All @@ -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,
};
Expand Down Expand Up @@ -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)),
Expand All @@ -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)),
Expand Down Expand Up @@ -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)),
Expand Down Expand Up @@ -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)),
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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());
}
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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(
Expand Down
Loading