Compare commits

..

28 Commits

Author SHA1 Message Date
Bjorn 9b57b3de70
Merge 060e72c525 into f4d1161a3d 2024-04-07 20:48:14 +00:00
bjorn 060e72c525 Rename CompoundShape 'shape' to 'child';
Maybe slightly less ambiguous/confusing?
2024-04-07 13:47:52 -07:00
bjorn 47dec01772 rm more useless checks; 2024-04-07 13:47:52 -07:00
bjorn 582ee1625f CompoundShape:replaceShape fixes; 2024-04-07 13:47:52 -07:00
bjorn e36374c4cf rm useless check; 2024-04-07 13:47:52 -07:00
bjorn 98601b3425 Collider:setShape accepts nil;
Internally it still uses a teeny tiny sphere (it's kinda like the
collider's shape is a "point").
2024-04-07 13:47:52 -07:00
bjorn 2ac0d6946e Move shape arg to last argument of query callbacks;
Also fix an off-by-one error.
2024-04-07 13:47:52 -07:00
bjorn b589cec975 Collider:getShape takes optional child index;
For convenience when you're trying to dig a leaf shape out of a CompoundShape.

It's ignored if the collider's shape is not a CompoundShape.
2024-04-07 13:47:52 -07:00
bjorn 8bdab9f2d4 Shape:getAABB; 2024-04-07 13:47:52 -07:00
bjorn 5751068728 Move Shape:is/setSensor and Shape:is/setEnabled to Collider; 2024-04-07 13:47:52 -07:00
bjorn 481a9dafa2 newCollider takes optional Shape as first arg; 2024-04-07 13:47:52 -07:00
bjorn 95cc6c2753 Shape fixes;
- Collider always has Shape now.  When left off or set to null, it's a
  tiny sphere (representing a point).
- Preserve shape offset when changing shape.
2024-04-07 13:47:52 -07:00
bjorn f35cda7db8 lovrColliderCreate takes shape;
Jolt requires a shape, also it saves a bit of work.
2024-04-07 13:47:52 -07:00
bjorn 907d89c913 Add Collider:getShapes for backcompat; 2024-04-07 13:47:52 -07:00
bjorn ff0f39fc7b rm unused shape prototypes; 2024-04-07 13:47:52 -07:00
bjorn b809db1d83 ODE compatibility; 2024-04-07 13:47:52 -07:00
bjorn 051266f8ea Collider shape is required I think;
Jolt doesn't really support bodies without shapes.
2024-04-07 13:47:52 -07:00
bjorn 930e713079 Add Collider:get/setShapeOffset; 2024-04-07 13:47:52 -07:00
bjorn 4f26182595 World queries return collider/shapeindex instead of Shape; 2024-04-07 13:47:52 -07:00
bjorn 8cbdda00f3 Require frozen CompoundShapes to have at least 2 children;
If you create a StaticCompoundShape with 1 child, Jolt creates a
RotatedTranslatedShape.  It would be a pain to have to branch on that,
so let's just require 2 children.
2024-04-07 13:47:52 -07:00
bjorn 10f965d69e rm Shape setters;
Jolt doesn't support this and requires you to recreate the shape.  Since
the shape -> collider relationship is 1:N, we can't really create a new
shape because we'd have to figure out which colliders/compoundshapes to
assign it to, which isn't feasible.
2024-04-07 13:47:52 -07:00
bjorn a7bf4ca2a4 CompoundShape fixes; 2024-04-07 13:47:52 -07:00
bjorn c27694fd8e Shapes set their userdata; 2024-04-07 13:47:52 -07:00
bjorn b3e9e55b8a CompoundShape API; 2024-04-07 13:47:52 -07:00
bjorn 6f0b6391df Start CompoundShape; 2024-04-07 13:47:52 -07:00
bjorn ce58619094 Colliders can only have 1 shape; rm shape pose; 2024-04-07 13:47:52 -07:00
bjorn 9b6f58ac1e Update Jolt; 2024-04-07 13:47:52 -07:00
bjorn f4d1161a3d Disable Jolt profiler and debug renderer; 2024-04-07 13:46:57 -07:00
8 changed files with 129 additions and 97 deletions

View File

@ -185,6 +185,8 @@ if(LOVR_ENABLE_PHYSICS)
set(LOVR_PHYSICS_LIB ode)
endif()
elseif(LOVR_PHYSICS_LIBRARY STREQUAL "JOLT")
set(DEBUG_RENDERER_IN_DEBUG_AND_RELEASE OFF CACHE BOOL "")
set(PROFILER_IN_DEBUG_AND_RELEASE OFF CACHE BOOL "")
add_subdirectory(deps/jolt-physics-sharp jolt)
set(LOVR_PHYSICS_LIB joltc)
endif()

@ -1 +1 @@
Subproject commit 22a062b3729f72eaaa24148195368e8b564ecfd1
Subproject commit 2cda386d71174bec355888539679f7a4f7be1c2a

View File

@ -40,14 +40,19 @@ static int l_lovrColliderGetWorld(lua_State* L) {
static int l_lovrColliderGetShape(lua_State* L) {
Collider* collider = luax_checktype(L, 1, Collider);
Shape* shape = lovrColliderGetShape(collider);
luax_pushshape(L, shape);
uint32_t child = lua_gettop(L) == 1 ? ~0u : luax_checku32(L, 2) - 1;
Shape* shape = lovrColliderGetShape(collider, child);
if (shape) {
luax_pushshape(L, shape);
} else {
lua_pushnil(L);
}
return 1;
}
static int l_lovrColliderSetShape(lua_State* L) {
Collider* collider = luax_checktype(L, 1, Collider);
Shape* shape = luax_checkshape(L, 2);
Shape* shape = lua_isnoneornil(L, 2) ? NULL : luax_checkshape(L, 2);
lovrColliderSetShape(collider, shape);
return 0;
}
@ -587,7 +592,7 @@ static int l_lovrColliderSetTag(lua_State* L) {
// Deprecated
static int l_lovrColliderGetShapes(lua_State* L) {
Collider* collider = luax_checktype(L, 1, Collider);
Shape* shape = lovrColliderGetShape(collider);
Shape* shape = lovrColliderGetShape(collider, ~0u);
lua_createtable(L, 1, 0);
luax_pushshape(L, shape);
lua_rawseti(L, -2, 1);

View File

@ -159,7 +159,6 @@ Shape* luax_newcompoundshape(lua_State* L, int index) {
lua_rawgeti(L, -1, 1);
shapes[i] = luax_checkshape(L, -1);
lovrCheck(shapes[i], "Expected a Shape for CompoundShape entry #%d", i + 1);
lua_pop(L, 1);
int index = 2;
@ -284,8 +283,15 @@ static int l_lovrShapeGetMass(lua_State* L) {
static int l_lovrShapeGetAABB(lua_State* L) {
Shape* shape = luax_checkshape(L, 1);
float aabb[6];
lovrShapeGetAABB(shape, aabb);
float position[3], orientation[4], aabb[6];
if (lua_gettop(L) >= 2) {
int index = 2;
index = luax_readvec3(L, index, position, NULL);
index = luax_readquat(L, index, orientation, NULL);
lovrShapeGetAABB(shape, position, orientation, aabb);
} else {
lovrShapeGetAABB(shape, NULL, NULL, aabb);
}
for (int i = 0; i < 6; i++) {
lua_pushnumber(L, aabb[i]);
}
@ -383,68 +389,68 @@ static int l_lovrCompoundShapeIsFrozen(lua_State* L) {
return 1;
}
static int l_lovrCompoundShapeAddShape(lua_State* L) {
static int l_lovrCompoundShapeAddChild(lua_State* L) {
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
Shape* child = luax_checkshape(L, 2);
float position[3], orientation[4];
int index = 3;
index = luax_readvec3(L, index, position, NULL);
index = luax_readquat(L, index, orientation, NULL);
lovrCompoundShapeAddShape(shape, child, position, orientation);
lovrCompoundShapeAddChild(shape, child, position, orientation);
return 0;
}
static int l_lovrCompoundShapeReplaceShape(lua_State* L) {
static int l_lovrCompoundShapeReplaceChild(lua_State* L) {
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
uint32_t index = luax_checku32(L, 2);
uint32_t index = luax_checku32(L, 2) - 1;
Shape* child = luax_checkshape(L, 3);
float position[3], orientation[4];
int i = 4;
i = luax_readvec3(L, i, position, NULL);
i = luax_readquat(L, i, orientation, NULL);
lovrCompoundShapeReplaceShape(shape, index, child, position, orientation);
lovrCompoundShapeReplaceChild(shape, index, child, position, orientation);
return 0;
}
static int l_lovrCompoundShapeRemoveShape(lua_State* L) {
static int l_lovrCompoundShapeRemoveChild(lua_State* L) {
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
uint32_t index = luax_checku32(L, 2) - 1;
lovrCompoundShapeRemoveShape(shape, index);
lovrCompoundShapeRemoveChild(shape, index);
return 0;
}
static int l_lovrCompoundShapeGetShape(lua_State* L) {
static int l_lovrCompoundShapeGetChild(lua_State* L) {
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
uint32_t index = luax_checku32(L, 2) - 1;
Shape* child = lovrCompoundShapeGetShape(shape, index);
Shape* child = lovrCompoundShapeGetChild(shape, index);
luax_pushshape(L, child);
return 1;
}
static int l_lovrCompoundShapeGetShapes(lua_State* L) {
static int l_lovrCompoundShapeGetChildren(lua_State* L) {
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
int count = (int) lovrCompoundShapeGetShapeCount(shape);
int count = (int) lovrCompoundShapeGetChildCount(shape);
lua_createtable(L, count, 0);
for (int i = 0; i < count; i++) {
Shape* child = lovrCompoundShapeGetShape(shape, (uint32_t) i);
Shape* child = lovrCompoundShapeGetChild(shape, (uint32_t) i);
luax_pushshape(L, child);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
static int l_lovrCompoundShapeGetShapeCount(lua_State* L) {
static int l_lovrCompoundShapeGetChildCount(lua_State* L) {
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
uint32_t count = lovrCompoundShapeGetShapeCount(shape);
uint32_t count = lovrCompoundShapeGetChildCount(shape);
lua_pushinteger(L, count);
return 1;
}
static int l_lovrCompoundShapeGetShapeOffset(lua_State* L) {
static int l_lovrCompoundShapeGetChildOffset(lua_State* L) {
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
uint32_t index = luax_checku32(L, 2) - 1;
float position[3], orientation[4], angle, ax, ay, az;
lovrCompoundShapeGetShapeOffset(shape, index, position, orientation);
lovrCompoundShapeGetChildOffset(shape, index, position, orientation);
quat_getAngleAxis(orientation, &angle, &ax, &ay, &az);
lua_pushnumber(L, position[0]);
lua_pushnumber(L, position[1]);
@ -456,28 +462,28 @@ static int l_lovrCompoundShapeGetShapeOffset(lua_State* L) {
return 7;
}
static int l_lovrCompoundShapeSetShapeOffset(lua_State* L) {
static int l_lovrCompoundShapeSetChildOffset(lua_State* L) {
CompoundShape* shape = luax_checktype(L, 1, CompoundShape);
uint32_t index = luax_checku32(L, 2) - 1;
float position[3], orientation[4];
int i = 3;
i = luax_readvec3(L, i, position, NULL);
i = luax_readquat(L, i, orientation, NULL);
lovrCompoundShapeSetShapeOffset(shape, index, position, orientation);
lovrCompoundShapeSetChildOffset(shape, index, position, orientation);
return 0;
}
const luaL_Reg lovrCompoundShape[] = {
lovrShape,
{ "isFrozen", l_lovrCompoundShapeIsFrozen },
{ "addShape", l_lovrCompoundShapeAddShape },
{ "replaceShape", l_lovrCompoundShapeReplaceShape },
{ "removeShape", l_lovrCompoundShapeRemoveShape },
{ "getShape", l_lovrCompoundShapeGetShape },
{ "getShapes", l_lovrCompoundShapeGetShapes },
{ "getShapeCount", l_lovrCompoundShapeGetShapeCount },
{ "getShapeOffset", l_lovrCompoundShapeGetShapeOffset },
{ "setShapeOffset", l_lovrCompoundShapeSetShapeOffset },
{ "__len", l_lovrCompoundShapeGetShapeCount }, // :)
{ "addChild", l_lovrCompoundShapeAddChild },
{ "replaceChild", l_lovrCompoundShapeReplaceChild },
{ "removeChild", l_lovrCompoundShapeRemoveChild },
{ "getChild", l_lovrCompoundShapeGetChild },
{ "getChildren", l_lovrCompoundShapeGetChildren },
{ "getChildCount", l_lovrCompoundShapeGetChildCount },
{ "getChildOffset", l_lovrCompoundShapeGetChildOffset },
{ "setChildOffset", l_lovrCompoundShapeSetChildOffset },
{ "__len", l_lovrCompoundShapeGetChildCount }, // :)
{ NULL, NULL }
};

View File

@ -27,17 +27,17 @@ static int nextOverlap(lua_State* L) {
}
}
static bool raycastCallback(Collider* collider, uint32_t shape, float position[3], float normal[3], void* userdata) {
static bool raycastCallback(Collider* collider, float position[3], float normal[3], uint32_t shape, void* userdata) {
lua_State* L = userdata;
lua_pushvalue(L, -1);
luax_pushtype(L, Collider, collider);
lua_pushinteger(L, shape);
lua_pushnumber(L, position[0]);
lua_pushnumber(L, position[1]);
lua_pushnumber(L, position[2]);
lua_pushnumber(L, normal[0]);
lua_pushnumber(L, normal[1]);
lua_pushnumber(L, normal[2]);
lua_pushinteger(L, shape + 1);
lua_call(L, 8, 1);
bool shouldStop = lua_type(L, -1) == LUA_TBOOLEAN && !lua_toboolean(L, -1);
lua_pop(L, 1);
@ -54,7 +54,7 @@ typedef struct {
float normal[3];
} RaycastData;
static bool raycastAnyCallback(Collider* collider, uint32_t shape, float position[3], float normal[3], void* userdata) {
static bool raycastAnyCallback(Collider* collider, float position[3], float normal[3], uint32_t shape, void* userdata) {
RaycastData* data = userdata;
if (data->tag) {
const char* tag = lovrColliderGetTag(collider);
@ -70,7 +70,7 @@ static bool raycastAnyCallback(Collider* collider, uint32_t shape, float positio
return true;
}
static bool raycastClosestCallback(Collider* collider, uint32_t shape, float position[3], float normal[3], void* userdata) {
static bool raycastClosestCallback(Collider* collider, float position[3], float normal[3], uint32_t shape, void* userdata) {
RaycastData* data = userdata;
if (data->tag) {
const char* tag = lovrColliderGetTag(collider);
@ -93,7 +93,7 @@ static bool queryCallback(Collider* collider, uint32_t shape, void* userdata) {
lua_State* L = userdata;
lua_pushvalue(L, -1);
luax_pushtype(L, Collider, collider);
lua_pushinteger(L, shape);
lua_pushinteger(L, shape + 1);
lua_call(L, 2, 1);
bool shouldStop = lua_type(L, -1) == LUA_TBOOLEAN && !lua_toboolean(L, -1);
lua_pop(L, 1);
@ -309,13 +309,13 @@ static int l_lovrWorldRaycastAny(lua_State* L) {
lovrWorldRaycast(world, start[0], start[1], start[2], end[0], end[1], end[2], raycastAnyCallback, &data);
if (data.collider) {
luax_pushtype(L, Collider, data.collider);
lua_pushinteger(L, data.shape);
lua_pushnumber(L, data.position[0]);
lua_pushnumber(L, data.position[1]);
lua_pushnumber(L, data.position[2]);
lua_pushnumber(L, data.normal[0]);
lua_pushnumber(L, data.normal[1]);
lua_pushnumber(L, data.normal[2]);
lua_pushinteger(L, data.shape + 1);
return 8;
} else {
lua_pushnil(L);
@ -334,13 +334,13 @@ static int l_lovrWorldRaycastClosest(lua_State* L) {
lovrWorldRaycast(world, start[0], start[1], start[2], end[0], end[1], end[2], raycastClosestCallback, &data);
if (data.shape) {
luax_pushtype(L, Collider, data.collider);
lua_pushinteger(L, data.shape);
lua_pushnumber(L, data.position[0]);
lua_pushnumber(L, data.position[1]);
lua_pushnumber(L, data.position[2]);
lua_pushnumber(L, data.normal[0]);
lua_pushnumber(L, data.normal[1]);
lua_pushnumber(L, data.normal[2]);
lua_pushinteger(L, data.shape + 1);
return 8;
} else {
lua_pushnil(L);

View File

@ -27,8 +27,8 @@ typedef Joint HingeJoint;
typedef Joint SliderJoint;
typedef void (*CollisionResolver)(World* world, void* userdata);
typedef bool (*RaycastCallback)(Collider* collider, uint32_t shape, float position[3], float normal[3], void* userdata);
typedef bool (*QueryCallback)(Collider* collider, uint32_t shape, void* userdata);
typedef bool (*RaycastCallback)(Collider* collider, float position[3], float normal[3], uint32_t child, void* userdata);
typedef bool (*QueryCallback)(Collider* collider, uint32_t child, void* userdata);
bool lovrPhysicsInit(void);
void lovrPhysicsDestroy(void);
@ -95,7 +95,7 @@ void lovrColliderSetEnabled(Collider* collider, bool enable);
void lovrColliderInitInertia(Collider* collider, Shape* shape);
World* lovrColliderGetWorld(Collider* collider);
Collider* lovrColliderGetNext(Collider* collider);
Shape* lovrColliderGetShape(Collider* collider);
Shape* lovrColliderGetShape(Collider* collider, uint32_t child);
void lovrColliderSetShape(Collider* collider, Shape* shape);
void lovrColliderGetShapeOffset(Collider* collider, float* position, float* orientation);
void lovrColliderSetShapeOffset(Collider* collider, float* position, float* orientation);
@ -165,7 +165,7 @@ void lovrShapeDestroy(void* ref);
void lovrShapeDestroyData(Shape* shape);
ShapeType lovrShapeGetType(Shape* shape);
void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float* cz, float* mass, float inertia[6]);
void lovrShapeGetAABB(Shape* shape, float aabb[6]);
void lovrShapeGetAABB(Shape* shape, float position[3], float orientation[4], float aabb[6]);
SphereShape* lovrSphereShapeCreate(float radius);
float lovrSphereShapeGetRadius(SphereShape* sphere);
@ -187,13 +187,13 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ,
CompoundShape* lovrCompoundShapeCreate(Shape** shapes, float* positions, float* orientations, uint32_t count, bool freeze);
bool lovrCompoundShapeIsFrozen(CompoundShape* shape);
void lovrCompoundShapeAddShape(CompoundShape* shape, Shape* child, float* position, float* orientation);
void lovrCompoundShapeReplaceShape(CompoundShape* shape, uint32_t index, Shape* child, float* position, float* orientation);
void lovrCompoundShapeRemoveShape(CompoundShape* shape, uint32_t index);
Shape* lovrCompoundShapeGetShape(CompoundShape* shape, uint32_t index);
uint32_t lovrCompoundShapeGetShapeCount(CompoundShape* shape);
void lovrCompoundShapeGetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation);
void lovrCompoundShapeSetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation);
void lovrCompoundShapeAddChild(CompoundShape* shape, Shape* child, float* position, float* orientation);
void lovrCompoundShapeReplaceChild(CompoundShape* shape, uint32_t index, Shape* child, float* position, float* orientation);
void lovrCompoundShapeRemoveChild(CompoundShape* shape, uint32_t index);
Shape* lovrCompoundShapeGetChild(CompoundShape* shape, uint32_t index);
uint32_t lovrCompoundShapeGetChildCount(CompoundShape* shape);
void lovrCompoundShapeGetChildOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation);
void lovrCompoundShapeSetChildOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation);
// These tokens need to exist for Lua bindings
#define lovrSphereShapeDestroy lovrShapeDestroy

View File

@ -181,12 +181,12 @@ void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, floa
for (size_t i = 0; i < count; i++) {
Collider* collider = (Collider*) (uintptr_t) JPH_BodyInterface_GetUserData(world->bodies, hits[i].bodyID);
uint32_t child = 0;
uint32_t shape = 0;
if (collider->shape->type == SHAPE_COMPOUND) {
JPH_SubShapeID id = hits[i].subShapeID2;
JPH_SubShapeID remainder;
shape = JPH_CompoundShape_GetSubShapeIndexFromID((JPH_CompoundShape*) collider->shape, id, &remainder);
child = JPH_CompoundShape_GetSubShapeIndexFromID((JPH_CompoundShape*) collider->shape, id, &remainder);
}
JPH_RVec3 position = {
@ -198,7 +198,7 @@ void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, floa
JPH_Vec3 normal;
JPH_Body_GetWorldSpaceSurfaceNormal(collider->body, hits[i].subShapeID2, &position, &normal);
if (callback(collider, shape, &position.x, &normal.x, userdata)) {
if (callback(collider, &position.x, &normal.x, child, userdata)) {
break;
}
}
@ -323,19 +323,17 @@ Collider* lovrColliderCreate(World* world, Shape* shape, float x, float y, float
uint32_t limit = JPH_PhysicsSystem_GetMaxBodies(world->system);
lovrCheck(count < limit, "Too many colliders!");
if (!shape) shape = state.pointShape;
Collider* collider = lovrCalloc(sizeof(Collider));
collider->ref = 1;
collider->world = world;
collider->shape = shape;
collider->shape = shape ? shape : state.pointShape;
collider->tag = UNTAGGED;
const JPH_RVec3 position = { x, y, z };
const JPH_Quat rotation = { 0.f, 0.f, 0.f, 1.f };
JPH_MotionType type = JPH_MotionType_Dynamic;
JPH_ObjectLayer objectLayer = UNTAGGED * 2 + 1;
JPH_BodyCreationSettings* settings = JPH_BodyCreationSettings_Create3(shape->shape, &position, &rotation, type, objectLayer);
JPH_BodyCreationSettings* settings = JPH_BodyCreationSettings_Create3(collider->shape->shape, &position, &rotation, type, objectLayer);
collider->body = JPH_BodyInterface_CreateBody(world->bodies, settings);
collider->id = JPH_Body_GetID(collider->body);
JPH_BodyCreationSettings_Destroy(settings);
@ -423,8 +421,16 @@ Collider* lovrColliderGetNext(Collider* collider) {
return collider->next;
}
Shape* lovrColliderGetShape(Collider* collider) {
return collider->shape == state.pointShape ? NULL : collider->shape;
Shape* lovrColliderGetShape(Collider* collider, uint32_t child) {
if (collider->shape == state.pointShape) {
return NULL;
}
if (child == ~0u || collider->shape->type != SHAPE_COMPOUND) {
return collider->shape;
}
return lovrCompoundShapeGetChild(collider->shape, child);
}
void lovrColliderSetShape(Collider* collider, Shape* shape) {
@ -829,9 +835,9 @@ void lovrShapeDestroy(void* ref) {
void lovrShapeDestroyData(Shape* shape) {
if (shape->shape) {
if (shape->type == SHAPE_COMPOUND) {
uint32_t count = lovrCompoundShapeGetShapeCount(shape);
uint32_t count = lovrCompoundShapeGetChildCount(shape);
for (uint32_t i = 0; i < count; i++) {
Shape* child = lovrCompoundShapeGetShape(shape, i);
Shape* child = lovrCompoundShapeGetChild(shape, i);
lovrRelease(child, lovrShapeDestroy);
}
}
@ -849,8 +855,22 @@ void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float*
//
}
void lovrShapeGetAABB(Shape* shape, float aabb[6]) {
// TODO
void lovrShapeGetAABB(Shape* shape, float position[3], float orientation[4], float aabb[6]) {
JPH_AABox box;
if (!position && !orientation) {
JPH_Shape_GetLocalBounds(shape->shape, &box);
} else {
JPH_RMatrix4x4 transform;
JPH_Vec3 scale = { 1.f, 1.f, 1.f };
mat4_fromPose(&transform.m11, position, orientation);
JPH_Shape_GetWorldSpaceBounds(shape->shape, &transform, &scale, &box);
}
aabb[0] = box.min.x;
aabb[1] = box.max.x;
aabb[2] = box.min.y;
aabb[3] = box.max.y;
aabb[4] = box.min.z;
aabb[5] = box.max.z;
}
SphereShape* lovrSphereShapeCreate(float radius) {
@ -974,9 +994,9 @@ TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ,
CompoundShape* lovrCompoundShapeCreate(Shape** shapes, vec3 positions, quat orientations, uint32_t count, bool freeze) {
lovrCheck(!freeze || count >= 2, "A frozen CompoundShape must contain at least two shapes");
CompoundShape* parent = lovrCalloc(sizeof(CompoundShape));
parent->ref = 1;
parent->type = SHAPE_COMPOUND;
CompoundShape* shape = lovrCalloc(sizeof(CompoundShape));
shape->ref = 1;
shape->type = SHAPE_COMPOUND;
JPH_CompoundShapeSettings* settings = freeze ?
(JPH_CompoundShapeSettings*) JPH_StaticCompoundShapeSettings_Create() :
@ -991,50 +1011,49 @@ CompoundShape* lovrCompoundShapeCreate(Shape** shapes, vec3 positions, quat orie
}
if (freeze) {
parent->shape = (JPH_Shape*) JPH_StaticCompoundShape_Create((JPH_StaticCompoundShapeSettings*) settings);
shape->shape = (JPH_Shape*) JPH_StaticCompoundShape_Create((JPH_StaticCompoundShapeSettings*) settings);
} else {
parent->shape = (JPH_Shape*) JPH_MutableCompoundShape_Create((JPH_MutableCompoundShapeSettings*) settings);
shape->shape = (JPH_Shape*) JPH_MutableCompoundShape_Create((JPH_MutableCompoundShapeSettings*) settings);
}
JPH_ShapeSettings_Destroy((JPH_ShapeSettings*) settings);
return parent;
return shape;
}
bool lovrCompoundShapeIsFrozen(CompoundShape* shape) {
return JPH_Shape_GetSubType(shape->shape) == JPH_ShapeSubType_StaticCompound;
}
void lovrCompoundShapeAddShape(CompoundShape* shape, Shape* child, float* position, float* orientation) {
void lovrCompoundShapeAddChild(CompoundShape* shape, Shape* child, float* position, float* orientation) {
lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed");
lovrCheck(child->type != SHAPE_COMPOUND, "Currently, nesting compound shapes is not supported");
lovrCheck(child != shape, "Don't put a CompoundShape inside itself! lol");
JPH_Vec3 pos = { position[0], position[1], position[2] };
JPH_Quat rot = { orientation[0], orientation[1], orientation[2], orientation[3] };
JPH_MutableCompoundShape_AddShape((JPH_MutableCompoundShape*) shape->shape, &pos, &rot, child->shape, 0);
lovrRetain(child);
}
void lovrCompoundShapeReplaceShape(CompoundShape* shape, uint32_t index, Shape* child, float* position, float* orientation) {
void lovrCompoundShapeReplaceChild(CompoundShape* shape, uint32_t index, Shape* child, float* position, float* orientation) {
lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed");
lovrCheck(child->type != SHAPE_COMPOUND, "Currently, nesting compound shapes is not supported");
lovrCheck(index < lovrCompoundShapeGetShapeCount(shape), "CompoundShape has no shape at index %d", index + 1);
lovrCheck(child != shape, "Don't put a CompoundShape inside itself! lol");
lovrCheck(index < lovrCompoundShapeGetChildCount(shape), "CompoundShape has no child at index %d", index + 1);
JPH_Vec3 pos = { position[0], position[1], position[2] };
JPH_Quat rot = { orientation[0], orientation[1], orientation[2], orientation[3] };
lovrRelease(lovrCompoundShapeGetChild(shape, index), lovrShapeDestroy);
JPH_MutableCompoundShape_ModifyShape2((JPH_MutableCompoundShape*) shape->shape, index, &pos, &rot, child->shape);
lovrRetain(child);
}
void lovrCompoundShapeRemoveShape(CompoundShape* shape, uint32_t index) {
void lovrCompoundShapeRemoveChild(CompoundShape* shape, uint32_t index) {
lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed");
lovrCheck(index < lovrCompoundShapeGetShapeCount(shape), "CompoundShape has no shape at index %d", index + 1);
Shape* child = lovrCompoundShapeGetShape(shape, index);
lovrCheck(index < lovrCompoundShapeGetChildCount(shape), "CompoundShape has no child at index %d", index + 1);
Shape* child = lovrCompoundShapeGetChild(shape, index);
JPH_MutableCompoundShape_RemoveShape((JPH_MutableCompoundShape*) shape->shape, index);
lovrRelease(child, lovrShapeDestroy);
}
Shape* lovrCompoundShapeGetShape(CompoundShape* shape, uint32_t index) {
if (index < lovrCompoundShapeGetShapeCount(shape)) {
Shape* lovrCompoundShapeGetChild(CompoundShape* shape, uint32_t index) {
if (index < lovrCompoundShapeGetChildCount(shape)) {
const JPH_Shape* child;
JPH_CompoundShape_GetSubShape((JPH_CompoundShape*) shape->shape, index, &child, NULL, NULL, NULL);
return (Shape*) (uintptr_t) JPH_Shape_GetUserData(child);
@ -1043,12 +1062,12 @@ Shape* lovrCompoundShapeGetShape(CompoundShape* shape, uint32_t index) {
}
}
uint32_t lovrCompoundShapeGetShapeCount(CompoundShape* shape) {
uint32_t lovrCompoundShapeGetChildCount(CompoundShape* shape) {
return JPH_CompoundShape_GetNumSubShapes((JPH_CompoundShape*) shape->shape);
}
void lovrCompoundShapeGetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
lovrCheck(index < lovrCompoundShapeGetShapeCount(shape), "CompoundShape has no shape at index %d", index + 1);
void lovrCompoundShapeGetChildOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
lovrCheck(index < lovrCompoundShapeGetChildCount(shape), "CompoundShape has no child at index %d", index + 1);
const JPH_Shape* child;
JPH_Vec3 pos;
JPH_Quat rot;
@ -1058,9 +1077,9 @@ void lovrCompoundShapeGetShapeOffset(CompoundShape* shape, uint32_t index, float
quat_init(orientation, &rot.x);
}
void lovrCompoundShapeSetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
void lovrCompoundShapeSetChildOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
lovrCheck(!lovrCompoundShapeIsFrozen(shape), "CompoundShape is frozen and can not be changed");
lovrCheck(index < lovrCompoundShapeGetShapeCount(shape), "CompoundShape has no shape at index %d", index + 1);
lovrCheck(index < lovrCompoundShapeGetChildCount(shape), "CompoundShape has no child at index %d", index + 1);
JPH_Vec3 pos = { position[0], position[1], position[2] };
JPH_Quat rot = { orientation[0], orientation[1], orientation[2], orientation[3] };
JPH_MutableCompoundShape_ModifyShape((JPH_MutableCompoundShape*) shape->shape, index, &pos, &rot);

View File

@ -76,7 +76,7 @@ static void raycastCallback(void* d, dGeomID a, dGeomID b) {
int count = dCollide(a, b, MAX_CONTACTS, &contact->geom, sizeof(dContact));
for (int i = 0; i < count; i++) {
dContactGeom g = contact[i].geom;
data->shouldStop = callback(collider, 0, g.pos, g.normal, userdata);
data->shouldStop = callback(collider, g.pos, g.normal, 0, userdata);
}
}
@ -524,7 +524,7 @@ Collider* lovrColliderGetNext(Collider* collider) {
return collider->next;
}
Shape* lovrColliderGetShape(Collider* collider) {
Shape* lovrColliderGetShape(Collider* collider, uint32_t child) {
return collider->shape;
}
@ -976,7 +976,7 @@ void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float*
inertia[5] = m.I[9];
}
void lovrShapeGetAABB(Shape* shape, float aabb[6]) {
void lovrShapeGetAABB(Shape* shape, float position[3], float orientation[4], float aabb[6]) {
dGeomGetAABB(shape->id, aabb);
}
@ -1119,31 +1119,31 @@ bool lovrCompoundShapeIsFrozen(CompoundShape* shape) {
return false;
}
void lovrCompoundShapeAddShape(CompoundShape* shape, Shape* child, float* position, float* orientation) {
void lovrCompoundShapeAddChild(CompoundShape* shape, Shape* child, float* position, float* orientation) {
//
}
void lovrCompoundShapeReplaceShape(CompoundShape* shape, uint32_t index, Shape* child, float* position, float* orientation) {
void lovrCompoundShapeReplaceChild(CompoundShape* shape, uint32_t index, Shape* child, float* position, float* orientation) {
//
}
void lovrCompoundShapeRemoveShape(CompoundShape* shape, uint32_t index) {
void lovrCompoundShapeRemoveChild(CompoundShape* shape, uint32_t index) {
//
}
Shape* lovrCompoundShapeGetShape(CompoundShape* shape, uint32_t index) {
Shape* lovrCompoundShapeGetChild(CompoundShape* shape, uint32_t index) {
return NULL;
}
uint32_t lovrCompoundShapeGetShapeCount(CompoundShape* shape) {
uint32_t lovrCompoundShapeGetChildCount(CompoundShape* shape) {
return 0;
}
void lovrCompoundShapeGetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
void lovrCompoundShapeGetChildOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
//
}
void lovrCompoundShapeSetShapeOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
void lovrCompoundShapeSetChildOffset(CompoundShape* shape, uint32_t index, float* position, float* orientation) {
//
}