170 lines
5.2 KiB
Zig
170 lines
5.2 KiB
Zig
const std = @import("std");
|
|
|
|
pub const zphysics = @import("zphysics");
|
|
pub const core = @import("core");
|
|
|
|
pub const PhysicsCollider = @import("physicsCollider.zig").PhysicsCollider;
|
|
pub const PhysicsCharacter = @import("physicsCharacter.zig").PhysicsCharacter;
|
|
|
|
pub const ConvexShapeSettings = zphysics.ConvexShapeSettings;
|
|
pub const BoxShapeSettings = zphysics.BoxShapeSettings;
|
|
pub const SphereShapeSettings = zphysics.SphereShapeSettings;
|
|
pub const TriangleShapeSettings = zphysics.TriangleShapeSettings;
|
|
pub const CapsuleShapeSettings = zphysics.CapsuleShapeSettings;
|
|
pub const TaperedCapsuleShapeSettings = zphysics.TaperedCapsuleShapeSettings;
|
|
pub const CylinderShapeSettings = zphysics.CylinderShapeSettings;
|
|
pub const ConvexHullShapeSettings = zphysics.ConvexHullShapeSettings;
|
|
pub const HeightFieldShapeSettings = zphysics.HeightFieldShapeSettings;
|
|
pub const MeshShapeSettings = zphysics.MeshShapeSettings;
|
|
pub const DecoratedShapeSettings = zphysics.DecoratedShapeSettings;
|
|
pub const CompoundShapeSettings = zphysics.CompoundShapeSettings;
|
|
|
|
pub const BodyId = zphysics.BodyId;
|
|
|
|
pub const ShapeSettings = runtime.ShapeSettings;
|
|
|
|
pub const BodyCreationSettings = zphysics.BodyCreationSettings;
|
|
pub const Activation = zphysics.Activation;
|
|
|
|
pub const ObjectLayers = runtime.ObjectLayers;
|
|
|
|
const runtime = @import("physicsSystem.zig");
|
|
pub const IgnoreFixedBodiesFilter = runtime.IgnoreFixedBodiesFilter;
|
|
|
|
pub const PrimitiveType = enum {
|
|
box,
|
|
sphere,
|
|
};
|
|
|
|
pub const ComponentList = struct {
|
|
pub const _PhysicsCharacter = PhysicsCharacter;
|
|
pub const _PhysicsCollider = PhysicsCollider;
|
|
};
|
|
|
|
// low level helpers - old api
|
|
pub fn addPrimitiveBody(primitive: PrimitiveType, settings: BodyCreationSettings, activationMode: Activation) !BodyId {
|
|
const interface = context().system.getBodyInterfaceMut();
|
|
var s = settings;
|
|
|
|
switch (primitive) {
|
|
.box => {
|
|
s.shape = context().primBoxShape;
|
|
},
|
|
.sphere => {
|
|
s.shape = context().primSphereShape;
|
|
},
|
|
}
|
|
|
|
return try interface.createAndAddBody(s, activationMode);
|
|
}
|
|
|
|
pub fn setBodyPosition(id: BodyId, pos: core.Vectorf) void {
|
|
const interface = context().system.getBodyInterfaceMut();
|
|
interface.setPosition(id, pos.toArr3(), .activate);
|
|
}
|
|
|
|
pub fn setBodyRotation(id: BodyId, rot: core.Rotation) void {
|
|
const interface = context().system.getBodyInterfaceMut();
|
|
interface.setRotation(id, rot.quat, .activate);
|
|
}
|
|
|
|
pub fn optimizeBroadPhase() void {
|
|
context().system.optimizeBroadPhase();
|
|
}
|
|
|
|
pub const context = core.EngineObject(runtime.PhysicsRuntime).get;
|
|
|
|
pub fn removeShape(name: *core.Name) void {
|
|
context().removeShape(name);
|
|
}
|
|
|
|
pub fn addShape(name: []const u8, settings: ShapeSettings) !void {
|
|
var n = core.MakeName(name);
|
|
try context().createShape(&n, settings);
|
|
}
|
|
|
|
pub fn start_module(spec: *core.SpecVariantMap, args: anytype, allocator: std.mem.Allocator) !void {
|
|
_ = args;
|
|
_ = spec;
|
|
|
|
core.engine_logs("starting physics");
|
|
try core.defineComponentList(ComponentList, allocator);
|
|
_ = try core.createObject(runtime.PhysicsRuntime, .{ .can_tick = true });
|
|
}
|
|
|
|
pub fn setupFromModule() void {
|
|
core.ecs.patchComponentList(ComponentList);
|
|
}
|
|
|
|
pub fn shutdown_module(allocator: std.mem.Allocator) void {
|
|
core.undefineComponentList(ComponentList);
|
|
_ = allocator;
|
|
// core.getEngineObject(runtime.PhysicsRuntime).?.system.destroy();
|
|
}
|
|
|
|
pub const Module: core.ModuleDescription = .{
|
|
.name = "physics",
|
|
.enabledByDefault = false,
|
|
};
|
|
|
|
pub fn releaseShape(name: core.Name) void {
|
|
var n = name;
|
|
context().shapes.get(n.handle()).?.shape.release();
|
|
}
|
|
|
|
pub const RayCastSettings = struct {
|
|
entityLookup: bool = false,
|
|
getNormalsSlow: bool = false,
|
|
bodyFilter: ?*const anyopaque = null,
|
|
};
|
|
|
|
pub const RayCastResult = struct {
|
|
body: BodyId,
|
|
point: core.Vectorf,
|
|
normal: ?core.Vectorf = null, // how to get this?
|
|
entity: ?core.Entity = null,
|
|
};
|
|
|
|
pub fn traceLine(start: core.Vectorf, direction: core.Vectorf, settings: RayCastSettings) ?RayCastResult {
|
|
const query = context().system.getNarrowPhaseQuery();
|
|
const result = query.castRay(.{
|
|
.origin = start.toZm(),
|
|
.direction = direction.toZm(),
|
|
}, .{
|
|
.body_filter = @ptrCast(@alignCast(settings.bodyFilter)),
|
|
});
|
|
|
|
if (!result.has_hit) {
|
|
return null;
|
|
}
|
|
|
|
var rv: RayCastResult = .{
|
|
.body = result.hit.body_id,
|
|
.point = direction.fmul(result.hit.fraction).add(start),
|
|
};
|
|
|
|
if (settings.entityLookup) {
|
|
rv.entity = context().idToEntity.get(rv.body).?;
|
|
}
|
|
|
|
// VERY SLOW
|
|
if (settings.getNormalsSlow) {
|
|
const lock_interface = context().system.getBodyLockInterfaceNoLock();
|
|
|
|
var read_lock: zphysics.BodyLockRead = .{};
|
|
read_lock.lock(lock_interface, rv.body);
|
|
defer read_lock.unlock();
|
|
|
|
if (read_lock.body) |body| {
|
|
rv.normal = core.Vectorf.fromArr3(body.getWorldSpaceSurfaceNormal(result.hit.sub_shape_id, rv.point.toArr3()));
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
pub fn applyForce(body: BodyId, impulse: core.Vectorf, position: core.Vectorf) void {
|
|
const interface = context().system.getBodyInterfaceMut();
|
|
interface.addImpulseAtPosition(body, impulse.toArr3(), position.toArr3());
|
|
}
|