diff --git a/src/api/l_physics_collider.c b/src/api/l_physics_collider.c index dc9dfd90..d2a800d5 100644 --- a/src/api/l_physics_collider.c +++ b/src/api/l_physics_collider.c @@ -1,5 +1,7 @@ #include "api.h" #include "physics/physics.h" +#include "core/maf.h" +#include "util.h" #include #include #include diff --git a/src/api/l_physics_joints.c b/src/api/l_physics_joints.c index 349f4fe0..d9c1b785 100644 --- a/src/api/l_physics_joints.c +++ b/src/api/l_physics_joints.c @@ -3,6 +3,7 @@ #include "util.h" #include #include +#include void luax_pushjoint(lua_State* L, Joint* joint) { switch (lovrJointGetType(joint)) { diff --git a/src/api/l_physics_shapes.c b/src/api/l_physics_shapes.c index d84601bc..4421e7e5 100644 --- a/src/api/l_physics_shapes.c +++ b/src/api/l_physics_shapes.c @@ -1,8 +1,10 @@ #include "api.h" #include "physics/physics.h" +#include "core/maf.h" #include "util.h" #include #include +#include void luax_pushshape(lua_State* L, Shape* shape) { switch (lovrShapeGetType(shape)) { diff --git a/src/api/l_physics_world.c b/src/api/l_physics_world.c index ba592c63..6864283d 100644 --- a/src/api/l_physics_world.c +++ b/src/api/l_physics_world.c @@ -3,7 +3,9 @@ #include "util.h" #include #include +#include #include +#include static void collisionResolver(World* world, void* userdata) { lua_State* L = userdata; @@ -205,6 +207,18 @@ static int l_lovrWorldCollide(lua_State* L) { return 1; } +static int l_lovrWorldRaycast(lua_State* L) { + World* world = luax_checktype(L, 1, World); + float start[4], end[4]; + int index; + index = luax_readvec3(L, 2, start, NULL); + index = luax_readvec3(L, index, end, NULL); + luaL_checktype(L, index, LUA_TFUNCTION); + lua_settop(L, index); + lovrWorldRaycast(world, start[0], start[1], start[2], end[0], end[1], end[2], raycastCallback, L); + return 0; +} + static int l_lovrWorldGetGravity(lua_State* L) { World* world = luax_checktype(L, 1, World); float x, y, z; @@ -300,18 +314,6 @@ static int l_lovrWorldSetSleepingAllowed(lua_State* L) { return 0; } -static int l_lovrWorldRaycast(lua_State* L) { - World* world = luax_checktype(L, 1, World); - float start[4], end[4]; - int index; - index = luax_readvec3(L, 2, start, NULL); - index = luax_readvec3(L, index, end, NULL); - luaL_checktype(L, index, LUA_TFUNCTION); - lua_settop(L, index); - lovrWorldRaycast(world, start[0], start[1], start[2], end[0], end[1], end[2], raycastCallback, L); - return 0; -} - static int l_lovrWorldDisableCollisionBetween(lua_State* L) { World* world = luax_checktype(L, 1, World); const char* tag1 = luaL_checkstring(L, 2); @@ -349,6 +351,7 @@ const luaL_Reg lovrWorld[] = { { "computeOverlaps", l_lovrWorldComputeOverlaps }, { "overlaps", l_lovrWorldOverlaps }, { "collide", l_lovrWorldCollide }, + { "raycast", l_lovrWorldRaycast }, { "getGravity", l_lovrWorldGetGravity }, { "setGravity", l_lovrWorldSetGravity }, { "getTightness", l_lovrWorldGetTightness }, @@ -361,7 +364,6 @@ const luaL_Reg lovrWorld[] = { { "setAngularDamping", l_lovrWorldSetAngularDamping }, { "isSleepingAllowed", l_lovrWorldIsSleepingAllowed }, { "setSleepingAllowed", l_lovrWorldSetSleepingAllowed }, - { "raycast", l_lovrWorldRaycast }, { "disableCollisionBetween", l_lovrWorldDisableCollisionBetween }, { "enableCollisionBetween", l_lovrWorldEnableCollisionBetween }, { "isCollisionEnabledBetween", l_lovrWorldIsCollisionEnabledBetween }, diff --git a/src/modules/physics/physics.c b/src/modules/physics/physics.c index f5ca1ed5..2ab64e91 100644 --- a/src/modules/physics/physics.c +++ b/src/modules/physics/physics.c @@ -1,7 +1,8 @@ #include "physics.h" +#include "core/maf.h" #include "util.h" +#include #include -#include struct World { uint32_t ref; @@ -56,6 +57,11 @@ static void customNearCallback(void* data, dGeomID shapeA, dGeomID shapeB) { arr_push(&world->overlaps, dGeomGetData(shapeB)); } +typedef struct { + RaycastCallback callback; + void* userdata; +} RaycastData; + static void raycastCallback(void* data, dGeomID a, dGeomID b) { RaycastCallback callback = ((RaycastData*) data)->callback; void* userdata = ((RaycastData*) data)->userdata; @@ -246,6 +252,18 @@ int lovrWorldCollide(World* world, Shape* a, Shape* b, float friction, float res return contactCount; } +void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, float y2, float z2, RaycastCallback callback, void* userdata) { + RaycastData data = { .callback = callback, .userdata = userdata }; + float dx = x2 - x1; + float dy = y2 - y1; + float dz = z2 - z1; + float length = sqrtf(dx * dx + dy * dy + dz * dz); + dGeomID ray = dCreateRay(world->space, length); + dGeomRaySet(ray, x1, y1, z1, dx, dy, dz); + dSpaceCollide2(ray, (dGeomID) world->space, &data, raycastCallback); + dGeomDestroy(ray); +} + Collider* lovrWorldGetFirstCollider(World* world) { return world->head; } @@ -306,18 +324,6 @@ void lovrWorldSetSleepingAllowed(World* world, bool allowed) { dWorldSetAutoDisableFlag(world->id, allowed); } -void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, float y2, float z2, RaycastCallback callback, void* userdata) { - RaycastData data = { .callback = callback, .userdata = userdata }; - float dx = x2 - x1; - float dy = y2 - y1; - float dz = z2 - z1; - float length = sqrtf(dx * dx + dy * dy + dz * dz); - dGeomID ray = dCreateRay(world->space, length); - dGeomRaySet(ray, x1, y1, z1, dx, dy, dz); - dSpaceCollide2(ray, (dGeomID) world->space, &data, raycastCallback); - dGeomDestroy(ray); -} - const char* lovrWorldGetTagName(World* world, uint32_t tag) { return (tag == NO_TAG) ? NULL : world->tags[tag]; } diff --git a/src/modules/physics/physics.h b/src/modules/physics/physics.h index ad58a43b..983d27cb 100644 --- a/src/modules/physics/physics.h +++ b/src/modules/physics/physics.h @@ -1,8 +1,6 @@ -#include "core/maf.h" -#include "util.h" -#include #include -#include +#include +#include #pragma once @@ -10,21 +8,6 @@ #define MAX_TAGS 16 #define NO_TAG ~0u -typedef enum { - SHAPE_SPHERE, - SHAPE_BOX, - SHAPE_CAPSULE, - SHAPE_CYLINDER, - SHAPE_MESH, -} ShapeType; - -typedef enum { - JOINT_BALL, - JOINT_DISTANCE, - JOINT_HINGE, - JOINT_SLIDER -} JointType; - typedef struct World World; typedef struct Collider Collider; typedef struct Shape Shape; @@ -44,14 +27,11 @@ typedef Joint SliderJoint; typedef void (*CollisionResolver)(World* world, void* userdata); typedef void (*RaycastCallback)(Shape* shape, float x, float y, float z, float nx, float ny, float nz, void* userdata); -typedef struct { - RaycastCallback callback; - void* userdata; -} RaycastData; - bool lovrPhysicsInit(void); void lovrPhysicsDestroy(void); +// World + World* lovrWorldCreate(float xg, float yg, float zg, bool allowSleep, const char** tags, uint32_t tagCount); void lovrWorldDestroy(void* ref); void lovrWorldDestroyData(World* world); @@ -59,6 +39,7 @@ void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* u void lovrWorldComputeOverlaps(World* world); int lovrWorldGetNextOverlap(World* world, Shape** a, Shape** b); int lovrWorldCollide(World* world, Shape* a, Shape* b, float friction, float restitution); +void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, float y2, float z2, RaycastCallback callback, void* userdata); Collider* lovrWorldGetFirstCollider(World* world); void lovrWorldGetGravity(World* world, float* x, float* y, float* z); void lovrWorldSetGravity(World* world, float x, float y, float z); @@ -72,12 +53,13 @@ void lovrWorldGetAngularDamping(World* world, float* damping, float* threshold); void lovrWorldSetAngularDamping(World* world, float damping, float threshold); bool lovrWorldIsSleepingAllowed(World* world); void lovrWorldSetSleepingAllowed(World* world, bool allowed); -void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, float y2, float z2, RaycastCallback callback, void* userdata); const char* lovrWorldGetTagName(World* world, uint32_t tag); int lovrWorldDisableCollisionBetween(World* world, const char* tag1, const char* tag2); int lovrWorldEnableCollisionBetween(World* world, const char* tag1, const char* tag2); int lovrWorldIsCollisionEnabledBetween(World* world, const char* tag1, const char* tag); +// Collider + Collider* lovrColliderCreate(World* world, float x, float y, float z); void lovrColliderDestroy(void* ref); void lovrColliderDestroyData(Collider* collider); @@ -110,8 +92,8 @@ void lovrColliderGetMassData(Collider* collider, float* cx, float* cy, float* cz void lovrColliderSetMassData(Collider* collider, float cx, float cy, float cz, float mass, float inertia[6]); void lovrColliderGetPosition(Collider* collider, float* x, float* y, float* z); void lovrColliderSetPosition(Collider* collider, float x, float y, float z); -void lovrColliderGetOrientation(Collider* collider, quat orientation); -void lovrColliderSetOrientation(Collider* collider, quat orientation); +void lovrColliderGetOrientation(Collider* collider, float* orientation); +void lovrColliderSetOrientation(Collider* collider, float* orientation); void lovrColliderGetLinearVelocity(Collider* collider, float* x, float* y, float* z); void lovrColliderSetLinearVelocity(Collider* collider, float x, float y, float z); void lovrColliderGetAngularVelocity(Collider* collider, float* x, float* y, float* z); @@ -132,6 +114,16 @@ void lovrColliderGetLinearVelocityFromLocalPoint(Collider* collider, float x, fl void lovrColliderGetLinearVelocityFromWorldPoint(Collider* collider, float wx, float wy, float wz, float* vx, float* vy, float* vz); void lovrColliderGetAABB(Collider* collider, float aabb[6]); +// Shapes + +typedef enum { + SHAPE_SPHERE, + SHAPE_BOX, + SHAPE_CAPSULE, + SHAPE_CYLINDER, + SHAPE_MESH, +} ShapeType; + void lovrShapeDestroy(void* ref); void lovrShapeDestroyData(Shape* shape); ShapeType lovrShapeGetType(Shape* shape); @@ -144,38 +136,49 @@ void* lovrShapeGetUserData(Shape* shape); void lovrShapeSetUserData(Shape* shape, void* data); void lovrShapeGetPosition(Shape* shape, float* x, float* y, float* z); void lovrShapeSetPosition(Shape* shape, float x, float y, float z); -void lovrShapeGetOrientation(Shape* shape, quat orientation); -void lovrShapeSetOrientation(Shape* shape, quat orientation); +void lovrShapeGetOrientation(Shape* shape, float* orientation); +void lovrShapeSetOrientation(Shape* shape, float* orientation); void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float* cz, float* mass, float inertia[6]); void lovrShapeGetAABB(Shape* shape, float aabb[6]); SphereShape* lovrSphereShapeCreate(float radius); -#define lovrSphereShapeDestroy lovrShapeDestroy float lovrSphereShapeGetRadius(SphereShape* sphere); void lovrSphereShapeSetRadius(SphereShape* sphere, float radius); BoxShape* lovrBoxShapeCreate(float x, float y, float z); -#define lovrBoxShapeDestroy lovrShapeDestroy void lovrBoxShapeGetDimensions(BoxShape* box, float* x, float* y, float* z); void lovrBoxShapeSetDimensions(BoxShape* box, float x, float y, float z); CapsuleShape* lovrCapsuleShapeCreate(float radius, float length); -#define lovrCapsuleShapeDestroy lovrShapeDestroy float lovrCapsuleShapeGetRadius(CapsuleShape* capsule); void lovrCapsuleShapeSetRadius(CapsuleShape* capsule, float radius); float lovrCapsuleShapeGetLength(CapsuleShape* capsule); void lovrCapsuleShapeSetLength(CapsuleShape* capsule, float length); CylinderShape* lovrCylinderShapeCreate(float radius, float length); -#define lovrCylinderShapeDestroy lovrShapeDestroy float lovrCylinderShapeGetRadius(CylinderShape* cylinder); void lovrCylinderShapeSetRadius(CylinderShape* cylinder, float radius); float lovrCylinderShapeGetLength(CylinderShape* cylinder); void lovrCylinderShapeSetLength(CylinderShape* cylinder, float length); -MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount, dTriIndex indices[]); +MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount, uint32_t indices[]); + +// These tokens need to exist for Lua bindings +#define lovrSphereShapeDestroy lovrShapeDestroy +#define lovrBoxShapeDestroy lovrShapeDestroy +#define lovrCapsuleShapeDestroy lovrShapeDestroy +#define lovrCylinderShapeDestroy lovrShapeDestroy #define lovrMeshShapeDestroy lovrShapeDestroy +// Joints + +typedef enum { + JOINT_BALL, + JOINT_DISTANCE, + JOINT_HINGE, + JOINT_SLIDER +} JointType; + void lovrJointDestroy(void* ref); void lovrJointDestroyData(Joint* joint); JointType lovrJointGetType(Joint* joint); @@ -190,7 +193,6 @@ bool lovrJointIsEnabled(Joint* joint); void lovrJointSetEnabled(Joint* joint, bool enable); BallJoint* lovrBallJointCreate(Collider* a, Collider* b, float x, float y, float z); -#define lovrBallJointDestroy lovrJointDestroy void lovrBallJointGetAnchors(BallJoint* joint, float* x1, float* y1, float* z1, float* x2, float* y2, float* z2); void lovrBallJointSetAnchor(BallJoint* joint, float x, float y, float z); float lovrBallJointGetResponseTime(Joint* joint); @@ -199,7 +201,6 @@ float lovrBallJointGetTightness(Joint* joint); void lovrBallJointSetTightness(Joint* joint, float tightness); DistanceJoint* lovrDistanceJointCreate(Collider* a, Collider* b, float x1, float y1, float z1, float x2, float y2, float z2); -#define lovrDistanceJointDestroy lovrJointDestroy void lovrDistanceJointGetAnchors(DistanceJoint* joint, float* x1, float* y1, float* z1, float* x2, float* y2, float* z2); void lovrDistanceJointSetAnchors(DistanceJoint* joint, float x1, float y1, float z1, float x2, float y2, float z2); float lovrDistanceJointGetDistance(DistanceJoint* joint); @@ -210,7 +211,6 @@ float lovrDistanceJointGetTightness(Joint* joint); void lovrDistanceJointSetTightness(Joint* joint, float tightness); HingeJoint* lovrHingeJointCreate(Collider* a, Collider* b, float x, float y, float z, float ax, float ay, float az); -#define lovrHingeJointDestroy lovrJointDestroy void lovrHingeJointGetAnchors(HingeJoint* joint, float* x1, float* y1, float* z1, float* x2, float* y2, float* z2); void lovrHingeJointSetAnchor(HingeJoint* joint, float x, float y, float z); void lovrHingeJointGetAxis(HingeJoint* joint, float* x, float* y, float* z); @@ -222,7 +222,6 @@ float lovrHingeJointGetUpperLimit(HingeJoint* joint); void lovrHingeJointSetUpperLimit(HingeJoint* joint, float limit); SliderJoint* lovrSliderJointCreate(Collider* a, Collider* b, float ax, float ay, float az); -#define lovrSliderJointDestroy lovrJointDestroy void lovrSliderJointGetAxis(SliderJoint* joint, float* x, float* y, float* z); void lovrSliderJointSetAxis(SliderJoint* joint, float x, float y, float z); float lovrSliderJointGetPosition(SliderJoint* joint); @@ -230,3 +229,9 @@ float lovrSliderJointGetLowerLimit(SliderJoint* joint); void lovrSliderJointSetLowerLimit(SliderJoint* joint, float limit); float lovrSliderJointGetUpperLimit(SliderJoint* joint); void lovrSliderJointSetUpperLimit(SliderJoint* joint, float limit); + +// These tokens need to exist for Lua bindings +#define lovrBallJointDestroy lovrJointDestroy +#define lovrDistanceJointDestroy lovrJointDestroy +#define lovrHingeJointDestroy lovrJointDestroy +#define lovrSliderJointDestroy lovrJointDestroy