Minor physics cleanup;

This commit is contained in:
bjorn 2022-03-30 22:01:51 -07:00
parent b115e5865f
commit 8fcdfd2bb4
6 changed files with 82 additions and 64 deletions

View File

@ -1,5 +1,7 @@
#include "api.h"
#include "physics/physics.h"
#include "core/maf.h"
#include "util.h"
#include <lua.h>
#include <lauxlib.h>
#include <stdbool.h>

View File

@ -3,6 +3,7 @@
#include "util.h"
#include <lua.h>
#include <lauxlib.h>
#include <string.h>
void luax_pushjoint(lua_State* L, Joint* joint) {
switch (lovrJointGetType(joint)) {

View File

@ -1,8 +1,10 @@
#include "api.h"
#include "physics/physics.h"
#include "core/maf.h"
#include "util.h"
#include <lua.h>
#include <lauxlib.h>
#include <string.h>
void luax_pushshape(lua_State* L, Shape* shape) {
switch (lovrShapeGetType(shape)) {

View File

@ -3,7 +3,9 @@
#include "util.h"
#include <lua.h>
#include <lauxlib.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
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 },

View File

@ -1,7 +1,8 @@
#include "physics.h"
#include "core/maf.h"
#include "util.h"
#include <ode/ode.h>
#include <stdlib.h>
#include <stdbool.h>
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];
}

View File

@ -1,8 +1,6 @@
#include "core/maf.h"
#include "util.h"
#include <stdint.h>
#include <stdbool.h>
#include <ode/ode.h>
#include <stdint.h>
#include <stddef.h>
#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