lovr/src/modules/physics/physics.h

273 lines
13 KiB
C
Raw Normal View History

2017-10-31 08:14:09 +00:00
#include <stdbool.h>
2022-03-31 05:01:51 +00:00
#include <stdint.h>
#include <stddef.h>
2017-05-16 04:59:53 +00:00
2017-05-19 21:04:34 +00:00
#pragma once
#define MAX_CONTACTS 10
#define MAX_TAGS 32
2019-09-07 22:07:07 +00:00
#define NO_TAG ~0u
2017-05-19 21:04:34 +00:00
2022-03-25 19:40:29 +00:00
typedef struct World World;
2018-08-19 04:16:19 +00:00
typedef struct Collider Collider;
typedef struct Shape Shape;
typedef struct Joint Joint;
2018-08-19 04:16:19 +00:00
2017-05-16 21:21:10 +00:00
typedef Shape SphereShape;
2017-05-16 21:37:05 +00:00
typedef Shape BoxShape;
2017-05-16 21:52:41 +00:00
typedef Shape CapsuleShape;
2017-05-16 21:56:20 +00:00
typedef Shape CylinderShape;
2020-09-13 10:34:36 +00:00
typedef Shape MeshShape;
2022-08-12 05:04:59 +00:00
typedef Shape TerrainShape;
2024-04-03 22:03:46 +00:00
typedef Shape CompoundShape;
2017-05-16 21:21:10 +00:00
typedef Joint BallJoint;
2017-06-10 22:13:19 +00:00
typedef Joint DistanceJoint;
2017-05-25 06:51:27 +00:00
typedef Joint HingeJoint;
2017-05-25 07:48:02 +00:00
typedef Joint SliderJoint;
2017-05-19 21:04:34 +00:00
typedef void (*CollisionResolver)(World* world, 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);
2017-05-25 00:40:02 +00:00
2019-02-17 22:39:51 +00:00
bool lovrPhysicsInit(void);
void lovrPhysicsDestroy(void);
2017-05-16 05:02:08 +00:00
2022-03-31 05:01:51 +00:00
// World
2022-03-31 05:32:20 +00:00
typedef struct {
float x, y, z;
float nx, ny, nz;
float depth;
} Contact;
typedef struct {
uint32_t maxColliders;
uint32_t maxColliderPairs;
uint32_t maxContacts;
bool allowSleep;
const char* tags[MAX_TAGS];
uint32_t tagCount;
float gravity[3]; // Deprecated
} WorldInfo;
World* lovrWorldCreate(WorldInfo* info);
2018-02-26 08:59:03 +00:00
void lovrWorldDestroy(void* ref);
2017-06-10 21:05:02 +00:00
void lovrWorldDestroyData(World* world);
uint32_t lovrWorldGetColliderCount(World* world);
uint32_t lovrWorldGetJointCount(World* world);
Collider* lovrWorldEnumerateColliders(World* world, Collider* collider);
Joint* lovrWorldEnumerateJoints(World* world, Joint* joint);
2017-06-10 21:05:02 +00:00
void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata);
void lovrWorldComputeOverlaps(World* world);
int lovrWorldGetNextOverlap(World* world, Shape** a, Shape** b);
int lovrWorldCollide(World* world, Shape* a, Shape* b, float friction, float restitution);
2022-03-31 05:32:20 +00:00
void lovrWorldGetContacts(World* world, Shape* a, Shape* b, Contact contacts[MAX_CONTACTS], uint32_t* count);
2022-03-31 05:01:51 +00:00
void lovrWorldRaycast(World* world, float x1, float y1, float z1, float x2, float y2, float z2, RaycastCallback callback, void* userdata);
bool lovrWorldQueryBox(World* world, float position[3], float size[3], QueryCallback callback, void* userdata);
bool lovrWorldQuerySphere(World* world, float position[3], float radius, QueryCallback callback, void* userdata);
2024-04-05 20:46:05 +00:00
void lovrWorldGetGravity(World* world, float gravity[3]);
void lovrWorldSetGravity(World* world, float gravity[3]);
const char* lovrWorldGetTagName(World* world, uint32_t tag);
void lovrWorldDisableCollisionBetween(World* world, const char* tag1, const char* tag2);
void lovrWorldEnableCollisionBetween(World* world, const char* tag1, const char* tag2);
bool lovrWorldIsCollisionEnabledBetween(World* world, const char* tag1, const char* tag);
// Deprecated
int lovrWorldGetStepCount(World* world);
void lovrWorldSetStepCount(World* world, int iterations);
Get/set World and Joint simulation parameters Tightness parameter is amount of force is exerted on collider to resolve collisions and enforce joint operation. Low values make joints loose, high values make it tight and can cause collider to overshot the joint target. With tightness set to 0 the joint loses its function. Going above 1 puts even more energy into joint oscillations. Tightness parameter is called ERP in ODE manual. The responseTime affects the time constant of physics simulation, both for collisions and for joint inertia. Low responseTime values make simulation tight and fast, higher values make it sluggish. For collisions it affects how fast penetration is resolved, with higher values resulting in spongy objects with more surface penetration and slower collision resolving. For joints the responseTime is similar to inertia, with higher responseTime values resulting in slow oscillations. The oscillation frequency is also affected by collider mass, so responseTime can be used to tweak the joint to get desired frequency with specific collider mass. Values higher than 1 are often desirable, especially for very light objects. Unlike tightness, responseTime is tweaked in orders of magnitude with useful values (depending on mass) being between 10^-8 and 10^8. Both parameters can be applied to World for simulation-wide usage, or specified per-joint in case of distance and ball joints. Other joints don't allow customizing these parameters, and will use World settings instead..
2020-05-29 14:38:32 +00:00
float lovrWorldGetResponseTime(World* world);
void lovrWorldSetResponseTime(World* world, float responseTime);
float lovrWorldGetTightness(World* world);
void lovrWorldSetTightness(World* world, float tightness);
2017-06-10 21:05:02 +00:00
void lovrWorldGetLinearDamping(World* world, float* damping, float* threshold);
void lovrWorldSetLinearDamping(World* world, float damping, float threshold);
void lovrWorldGetAngularDamping(World* world, float* damping, float* threshold);
void lovrWorldSetAngularDamping(World* world, float damping, float threshold);
2017-10-31 08:14:09 +00:00
bool lovrWorldIsSleepingAllowed(World* world);
void lovrWorldSetSleepingAllowed(World* world, bool allowed);
2017-06-10 21:05:02 +00:00
2022-03-31 05:01:51 +00:00
// Collider
Collider* lovrColliderCreate(World* world, Shape* shape, float x, float y, float z);
2018-02-26 08:59:03 +00:00
void lovrColliderDestroy(void* ref);
2017-05-20 04:14:20 +00:00
void lovrColliderDestroyData(Collider* collider);
2023-06-22 19:13:15 +00:00
bool lovrColliderIsDestroyed(Collider* collider);
bool lovrColliderIsEnabled(Collider* collider);
void lovrColliderSetEnabled(Collider* collider, bool enable);
2020-04-30 20:15:36 +00:00
void lovrColliderInitInertia(Collider* collider, Shape* shape);
World* lovrColliderGetWorld(Collider* collider);
Shape* lovrColliderGetShape(Collider* collider, uint32_t child);
void lovrColliderSetShape(Collider* collider, Shape* shape);
2024-04-05 04:41:12 +00:00
void lovrColliderGetShapeOffset(Collider* collider, float* position, float* orientation);
void lovrColliderSetShapeOffset(Collider* collider, float* position, float* orientation);
Joint* lovrColliderEnumerateJoints(Collider* collider, Joint* joint, void** private);
2017-06-10 11:51:09 +00:00
const char* lovrColliderGetTag(Collider* collider);
2019-09-07 22:07:07 +00:00
bool lovrColliderSetTag(Collider* collider, const char* tag);
2017-06-10 11:51:09 +00:00
float lovrColliderGetFriction(Collider* collider);
void lovrColliderSetFriction(Collider* collider, float friction);
float lovrColliderGetRestitution(Collider* collider);
void lovrColliderSetRestitution(Collider* collider, float restitution);
2017-10-31 08:14:09 +00:00
bool lovrColliderIsKinematic(Collider* collider);
void lovrColliderSetKinematic(Collider* collider, bool kinematic);
bool lovrColliderIsSensor(Collider* collider);
void lovrColliderSetSensor(Collider* collider, bool sensor);
2024-04-06 02:05:25 +00:00
bool lovrColliderIsContinuous(Collider* collider);
void lovrColliderSetContinuous(Collider* collider, bool continuous);
float lovrColliderGetGravityScale(Collider* collider);
void lovrColliderSetGravityScale(Collider* collider, float scale);
2017-10-31 08:14:09 +00:00
bool lovrColliderIsSleepingAllowed(Collider* collider);
void lovrColliderSetSleepingAllowed(Collider* collider, bool allowed);
bool lovrColliderIsAwake(Collider* collider);
void lovrColliderSetAwake(Collider* collider, bool awake);
float lovrColliderGetMass(Collider* collider);
void lovrColliderSetMass(Collider* collider, float mass);
void lovrColliderGetMassData(Collider* collider, float* cx, float* cy, float* cz, float* mass, float inertia[6]);
void lovrColliderSetMassData(Collider* collider, float cx, float cy, float cz, float mass, float inertia[6]);
2017-05-20 02:11:58 +00:00
void lovrColliderGetPosition(Collider* collider, float* x, float* y, float* z);
void lovrColliderSetPosition(Collider* collider, float x, float y, float z);
2022-03-31 05:01:51 +00:00
void lovrColliderGetOrientation(Collider* collider, float* orientation);
void lovrColliderSetOrientation(Collider* collider, float* orientation);
2017-05-20 02:11:58 +00:00
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);
void lovrColliderSetAngularVelocity(Collider* collider, float x, float y, float z);
void lovrColliderGetLinearDamping(Collider* collider, float* damping, float* threshold);
void lovrColliderSetLinearDamping(Collider* collider, float damping, float threshold);
void lovrColliderGetAngularDamping(Collider* collider, float* damping, float* threshold);
void lovrColliderSetAngularDamping(Collider* collider, float damping, float threshold);
void lovrColliderApplyForce(Collider* collider, float x, float y, float z);
void lovrColliderApplyForceAtPosition(Collider* collider, float x, float y, float z, float cx, float cy, float cz);
void lovrColliderApplyTorque(Collider* collider, float x, float y, float z);
2024-04-06 02:16:39 +00:00
void lovrColliderApplyLinearImpulse(Collider* collider, float impulse[3]);
void lovrColliderApplyLinearImpulseAtPosition(Collider* collider, float impulse[3], float position[3]);
void lovrColliderApplyAngularImpulse(Collider* collider, float impulse[3]);
2017-05-20 03:51:43 +00:00
void lovrColliderGetLocalCenter(Collider* collider, float* x, float* y, float* z);
2017-05-20 02:11:58 +00:00
void lovrColliderGetLocalPoint(Collider* collider, float wx, float wy, float wz, float* x, float* y, float* z);
void lovrColliderGetWorldPoint(Collider* collider, float x, float y, float z, float* wx, float* wy, float* wz);
void lovrColliderGetLocalVector(Collider* collider, float wx, float wy, float wz, float* x, float* y, float* z);
void lovrColliderGetWorldVector(Collider* collider, float x, float y, float z, float* wx, float* wy, float* wz);
void lovrColliderGetLinearVelocityFromLocalPoint(Collider* collider, float x, float y, float z, float* vx, float* vy, float* vz);
void lovrColliderGetLinearVelocityFromWorldPoint(Collider* collider, float wx, float wy, float wz, float* vx, float* vy, float* vz);
2017-05-25 01:10:39 +00:00
void lovrColliderGetAABB(Collider* collider, float aabb[6]);
2017-05-16 18:17:01 +00:00
2022-03-31 05:01:51 +00:00
// Shapes
typedef enum {
SHAPE_SPHERE,
SHAPE_BOX,
SHAPE_CAPSULE,
SHAPE_CYLINDER,
SHAPE_MESH,
2024-04-03 22:03:46 +00:00
SHAPE_TERRAIN,
SHAPE_COMPOUND
2022-03-31 05:01:51 +00:00
} ShapeType;
2018-02-26 08:59:03 +00:00
void lovrShapeDestroy(void* ref);
2017-05-20 04:24:23 +00:00
void lovrShapeDestroyData(Shape* shape);
2017-05-16 18:17:01 +00:00
ShapeType lovrShapeGetType(Shape* shape);
2017-05-25 00:47:59 +00:00
void lovrShapeGetMass(Shape* shape, float density, float* cx, float* cy, float* cz, float* mass, float inertia[6]);
2024-04-06 20:28:30 +00:00
void lovrShapeGetAABB(Shape* shape, float position[3], float orientation[4], float aabb[6]);
2017-05-16 21:21:10 +00:00
SphereShape* lovrSphereShapeCreate(float radius);
2017-05-16 21:52:41 +00:00
float lovrSphereShapeGetRadius(SphereShape* sphere);
2017-05-16 21:37:05 +00:00
BoxShape* lovrBoxShapeCreate(float w, float h, float d);
void lovrBoxShapeGetDimensions(BoxShape* box, float* w, float* h, float* d);
2017-05-16 21:52:41 +00:00
CapsuleShape* lovrCapsuleShapeCreate(float radius, float length);
2017-05-16 21:52:41 +00:00
float lovrCapsuleShapeGetRadius(CapsuleShape* capsule);
float lovrCapsuleShapeGetLength(CapsuleShape* capsule);
2017-05-16 21:56:20 +00:00
CylinderShape* lovrCylinderShapeCreate(float radius, float length);
2017-05-16 21:56:20 +00:00
float lovrCylinderShapeGetRadius(CylinderShape* cylinder);
float lovrCylinderShapeGetLength(CylinderShape* cylinder);
2022-03-31 05:01:51 +00:00
MeshShape* lovrMeshShapeCreate(int vertexCount, float vertices[], int indexCount, uint32_t indices[]);
2024-04-06 07:12:50 +00:00
TerrainShape* lovrTerrainShapeCreate(float* vertices, uint32_t n, float scaleXZ, float scaleY);
2022-03-31 05:01:51 +00:00
2024-04-04 19:34:49 +00:00
CompoundShape* lovrCompoundShapeCreate(Shape** shapes, float* positions, float* orientations, uint32_t count, bool freeze);
bool lovrCompoundShapeIsFrozen(CompoundShape* shape);
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);
2024-04-03 22:03:46 +00:00
2022-03-31 05:01:51 +00:00
// These tokens need to exist for Lua bindings
#define lovrSphereShapeDestroy lovrShapeDestroy
#define lovrBoxShapeDestroy lovrShapeDestroy
#define lovrCapsuleShapeDestroy lovrShapeDestroy
#define lovrCylinderShapeDestroy lovrShapeDestroy
2020-09-13 10:34:36 +00:00
#define lovrMeshShapeDestroy lovrShapeDestroy
2022-08-12 05:04:59 +00:00
#define lovrTerrainShapeDestroy lovrShapeDestroy
2024-04-03 22:03:46 +00:00
#define lovrCompoundShapeDestroy lovrShapeDestroy
2020-09-13 10:34:36 +00:00
2022-03-31 05:01:51 +00:00
// Joints
typedef enum {
JOINT_BALL,
JOINT_DISTANCE,
JOINT_HINGE,
JOINT_SLIDER
} JointType;
2018-02-26 08:59:03 +00:00
void lovrJointDestroy(void* ref);
void lovrJointDestroyData(Joint* joint);
bool lovrJointIsDestroyed(Joint* joint);
JointType lovrJointGetType(Joint* joint);
Get/set World and Joint simulation parameters Tightness parameter is amount of force is exerted on collider to resolve collisions and enforce joint operation. Low values make joints loose, high values make it tight and can cause collider to overshot the joint target. With tightness set to 0 the joint loses its function. Going above 1 puts even more energy into joint oscillations. Tightness parameter is called ERP in ODE manual. The responseTime affects the time constant of physics simulation, both for collisions and for joint inertia. Low responseTime values make simulation tight and fast, higher values make it sluggish. For collisions it affects how fast penetration is resolved, with higher values resulting in spongy objects with more surface penetration and slower collision resolving. For joints the responseTime is similar to inertia, with higher responseTime values resulting in slow oscillations. The oscillation frequency is also affected by collider mass, so responseTime can be used to tweak the joint to get desired frequency with specific collider mass. Values higher than 1 are often desirable, especially for very light objects. Unlike tightness, responseTime is tweaked in orders of magnitude with useful values (depending on mass) being between 10^-8 and 10^8. Both parameters can be applied to World for simulation-wide usage, or specified per-joint in case of distance and ball joints. Other joints don't allow customizing these parameters, and will use World settings instead..
2020-05-29 14:38:32 +00:00
float lovrJointGetCFM(Joint* joint);
void lovrJointSetCFM(Joint* joint, float cfm);
float lovrJointGetERP(Joint* joint);
void lovrJointSetERP(Joint* joint, float erp);
void lovrJointGetColliders(Joint* joint, Collider** a, Collider** b);
2019-11-12 00:27:30 +00:00
bool lovrJointIsEnabled(Joint* joint);
void lovrJointSetEnabled(Joint* joint, bool enable);
BallJoint* lovrBallJointCreate(Collider* a, Collider* b, float anchor[3]);
void lovrBallJointGetAnchors(BallJoint* joint, float anchor1[3], float anchor2[3]);
void lovrBallJointSetAnchor(BallJoint* joint, float anchor[3]);
Get/set World and Joint simulation parameters Tightness parameter is amount of force is exerted on collider to resolve collisions and enforce joint operation. Low values make joints loose, high values make it tight and can cause collider to overshot the joint target. With tightness set to 0 the joint loses its function. Going above 1 puts even more energy into joint oscillations. Tightness parameter is called ERP in ODE manual. The responseTime affects the time constant of physics simulation, both for collisions and for joint inertia. Low responseTime values make simulation tight and fast, higher values make it sluggish. For collisions it affects how fast penetration is resolved, with higher values resulting in spongy objects with more surface penetration and slower collision resolving. For joints the responseTime is similar to inertia, with higher responseTime values resulting in slow oscillations. The oscillation frequency is also affected by collider mass, so responseTime can be used to tweak the joint to get desired frequency with specific collider mass. Values higher than 1 are often desirable, especially for very light objects. Unlike tightness, responseTime is tweaked in orders of magnitude with useful values (depending on mass) being between 10^-8 and 10^8. Both parameters can be applied to World for simulation-wide usage, or specified per-joint in case of distance and ball joints. Other joints don't allow customizing these parameters, and will use World settings instead..
2020-05-29 14:38:32 +00:00
float lovrBallJointGetResponseTime(Joint* joint);
void lovrBallJointSetResponseTime(Joint* joint, float responseTime);
float lovrBallJointGetTightness(Joint* joint);
void lovrBallJointSetTightness(Joint* joint, float tightness);
2017-06-10 22:13:19 +00:00
DistanceJoint* lovrDistanceJointCreate(Collider* a, Collider* b, float anchor1[3], float anchor2[3]);
void lovrDistanceJointGetAnchors(DistanceJoint* joint, float anchor1[3], float anchor2[3]);
void lovrDistanceJointSetAnchors(DistanceJoint* joint, float anchor1[3], float anchor2[3]);
2017-06-10 22:13:19 +00:00
float lovrDistanceJointGetDistance(DistanceJoint* joint);
void lovrDistanceJointSetDistance(DistanceJoint* joint, float distance);
Get/set World and Joint simulation parameters Tightness parameter is amount of force is exerted on collider to resolve collisions and enforce joint operation. Low values make joints loose, high values make it tight and can cause collider to overshot the joint target. With tightness set to 0 the joint loses its function. Going above 1 puts even more energy into joint oscillations. Tightness parameter is called ERP in ODE manual. The responseTime affects the time constant of physics simulation, both for collisions and for joint inertia. Low responseTime values make simulation tight and fast, higher values make it sluggish. For collisions it affects how fast penetration is resolved, with higher values resulting in spongy objects with more surface penetration and slower collision resolving. For joints the responseTime is similar to inertia, with higher responseTime values resulting in slow oscillations. The oscillation frequency is also affected by collider mass, so responseTime can be used to tweak the joint to get desired frequency with specific collider mass. Values higher than 1 are often desirable, especially for very light objects. Unlike tightness, responseTime is tweaked in orders of magnitude with useful values (depending on mass) being between 10^-8 and 10^8. Both parameters can be applied to World for simulation-wide usage, or specified per-joint in case of distance and ball joints. Other joints don't allow customizing these parameters, and will use World settings instead..
2020-05-29 14:38:32 +00:00
float lovrDistanceJointGetResponseTime(Joint* joint);
void lovrDistanceJointSetResponseTime(Joint* joint, float responseTime);
float lovrDistanceJointGetTightness(Joint* joint);
void lovrDistanceJointSetTightness(Joint* joint, float tightness);
2017-05-25 06:51:27 +00:00
HingeJoint* lovrHingeJointCreate(Collider* a, Collider* b, float anchor[3], float axis[3]);
void lovrHingeJointGetAnchors(HingeJoint* joint, float anchor1[3], float anchor2[3]);
void lovrHingeJointSetAnchor(HingeJoint* joint, float anchor[3]);
void lovrHingeJointGetAxis(HingeJoint* joint, float axis[3]);
void lovrHingeJointSetAxis(HingeJoint* joint, float axis[3]);
2017-06-10 22:13:19 +00:00
float lovrHingeJointGetAngle(HingeJoint* joint);
float lovrHingeJointGetLowerLimit(HingeJoint* joint);
void lovrHingeJointSetLowerLimit(HingeJoint* joint, float limit);
float lovrHingeJointGetUpperLimit(HingeJoint* joint);
void lovrHingeJointSetUpperLimit(HingeJoint* joint, float limit);
2017-05-25 07:48:02 +00:00
SliderJoint* lovrSliderJointCreate(Collider* a, Collider* b, float axis[3]);
void lovrSliderJointGetAxis(SliderJoint* joint, float axis[3]);
void lovrSliderJointSetAxis(SliderJoint* joint, float axis[3]);
2017-06-10 22:13:19 +00:00
float lovrSliderJointGetPosition(SliderJoint* joint);
float lovrSliderJointGetLowerLimit(SliderJoint* joint);
void lovrSliderJointSetLowerLimit(SliderJoint* joint, float limit);
float lovrSliderJointGetUpperLimit(SliderJoint* joint);
void lovrSliderJointSetUpperLimit(SliderJoint* joint, float limit);
2022-03-31 05:01:51 +00:00
// These tokens need to exist for Lua bindings
#define lovrBallJointDestroy lovrJointDestroy
#define lovrDistanceJointDestroy lovrJointDestroy
#define lovrHingeJointDestroy lovrJointDestroy
#define lovrSliderJointDestroy lovrJointDestroy