summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorraysan5 <[email protected]>2021-08-15 12:52:12 +0200
committerraysan5 <[email protected]>2021-08-15 12:52:12 +0200
commit760cfd361e055326cf459812855d8dd83129c132 (patch)
tree53707d6bea4856a82a3ff786b45c160c28a5cf70
parent092435d51c7cbb94105d0b2b34156e0bf28d5980 (diff)
downloadraylib-760cfd361e055326cf459812855d8dd83129c132.tar.gz
raylib-760cfd361e055326cf459812855d8dd83129c132.zip
REVIEWED: `PHYSACDEF` definition and C++ issues #1918
-rw-r--r--src/extras/physac.h347
1 files changed, 169 insertions, 178 deletions
diff --git a/src/extras/physac.h b/src/extras/physac.h
index 7bcdb0f4..642c25a7 100644
--- a/src/extras/physac.h
+++ b/src/extras/physac.h
@@ -16,16 +16,9 @@
* If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation.
*
-* #define PHYSAC_STATIC (defined by default)
-* The generated implementation will stay private inside implementation file and all
-* internal symbols and functions will only be visible inside that file.
-*
* #define PHYSAC_DEBUG
* Show debug traces log messages about physic bodies creation/destruction, physic system errors,
-* some calculations results and NULL reference exceptions
-*
-* #define PHYSAC_DEFINE_VECTOR2_TYPE
-* Forces library to define struct Vector2 data type (float x; float y)
+* some calculations results and NULL reference exceptions.
*
* #define PHYSAC_AVOID_TIMMING_SYSTEM
* Disables internal timming system, used by UpdatePhysics() to launch timmed physic steps,
@@ -79,14 +72,8 @@
#if !defined(PHYSAC_H)
#define PHYSAC_H
-#if defined(PHYSAC_STATIC)
- #define PHYSACDEF static // Functions just visible to module including this file
-#else
- #if defined(__cplusplus)
- #define PHYSACDEF extern "C" // Functions visible from other files (no name mangling of functions in C++)
- #else
- #define PHYSACDEF extern // Functions visible from other files
- #endif
+#ifndef PHYSACDEF
+ #define PHYSACDEF // We are building or using physac as a static library
#endif
// Allow custom memory allocators
@@ -127,7 +114,7 @@ typedef enum PhysicsShapeType { PHYSICS_CIRCLE = 0, PHYSICS_POLYGON } PhysicsSha
// Previously defined to be used in PhysicsShape struct as circular dependencies
typedef struct PhysicsBodyData *PhysicsBody;
-#if defined(PHYSAC_DEFINE_VECTOR2_TYPE)
+#if !defined(RL_VECTOR2_TYPE)
// Vector2 type
typedef struct Vector2 {
float x;
@@ -192,13 +179,13 @@ typedef struct PhysicsManifoldData {
float staticFriction; // Mixed static friction during collision
} PhysicsManifoldData, *PhysicsManifold;
-#if defined(__cplusplus)
-extern "C" { // Prevents name mangling of functions
-#endif
-
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
+
+#if defined(__cplusplus)
+extern "C" { // Prevents name mangling of functions
+#endif
// Physics system management
PHYSACDEF void InitPhysics(void); // Initializes physics system
PHYSACDEF void UpdatePhysics(void); // Update physics system
@@ -225,7 +212,6 @@ PHYSACDEF int GetPhysicsBodiesCount(void);
PHYSACDEF int GetPhysicsShapeType(int index); // Returns the physics body shape type (PHYSICS_CIRCLE or PHYSICS_POLYGON)
PHYSACDEF int GetPhysicsShapeVerticesCount(int index); // Returns the amount of vertices of a physics body shape
PHYSACDEF Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex); // Returns transformed position of a body shape (body position + vertex transformed position)
-
#if defined(__cplusplus)
}
#endif
@@ -253,11 +239,17 @@ PHYSACDEF Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex);
#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
// Time management functionality
- #include <time.h> // Required for: time(), clock_gettime()
+ #include <time.h> // Required for: time(), clock_gettime()
#if defined(_WIN32)
+ #if defined(__cplusplus)
+ extern "C" { // Prevents name mangling of functions
+ #endif
// Functions required to query time on Windows
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
+ #if defined(__cplusplus)
+ }
+ #endif
#endif
#if defined(__linux__) || defined(__FreeBSD__)
#if _POSIX_C_SOURCE < 199309L
@@ -366,7 +358,7 @@ static Vector2 MathTriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3);
//----------------------------------------------------------------------------------
// Initializes physics values, pointers and creates physics loop thread
-PHYSACDEF void InitPhysics(void)
+void InitPhysics(void)
{
#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
// Initialize high resolution timer
@@ -377,21 +369,21 @@ PHYSACDEF void InitPhysics(void)
}
// Sets physics global gravity force
-PHYSACDEF void SetPhysicsGravity(float x, float y)
+void SetPhysicsGravity(float x, float y)
{
gravityForce.x = x;
gravityForce.y = y;
}
// Creates a new circle physics body with generic parameters
-PHYSACDEF PhysicsBody CreatePhysicsBodyCircle(Vector2 pos, float radius, float density)
+PhysicsBody CreatePhysicsBodyCircle(Vector2 pos, float radius, float density)
{
PhysicsBody body = CreatePhysicsBodyPolygon(pos, radius, PHYSAC_DEFAULT_CIRCLE_VERTICES, density);
return body;
}
// Creates a new rectangle physics body with generic parameters
-PHYSACDEF PhysicsBody CreatePhysicsBodyRectangle(Vector2 pos, float width, float height, float density)
+PhysicsBody CreatePhysicsBodyRectangle(Vector2 pos, float width, float height, float density)
{
// NOTE: Make sure body data is initialized to 0
PhysicsBody body = (PhysicsBody)PHYSAC_CALLOC(sizeof(PhysicsBodyData), 1);
@@ -469,7 +461,7 @@ PHYSACDEF PhysicsBody CreatePhysicsBodyRectangle(Vector2 pos, float width, float
}
// Creates a new polygon physics body with generic parameters
-PHYSACDEF PhysicsBody CreatePhysicsBodyPolygon(Vector2 pos, float radius, int sides, float density)
+PhysicsBody CreatePhysicsBodyPolygon(Vector2 pos, float radius, int sides, float density)
{
PhysicsBody body = (PhysicsBody)PHYSAC_MALLOC(sizeof(PhysicsBodyData));
usedMemory += sizeof(PhysicsBodyData);
@@ -551,19 +543,19 @@ PHYSACDEF PhysicsBody CreatePhysicsBodyPolygon(Vector2 pos, float radius, int si
}
// Adds a force to a physics body
-PHYSACDEF void PhysicsAddForce(PhysicsBody body, Vector2 force)
+void PhysicsAddForce(PhysicsBody body, Vector2 force)
{
if (body != NULL) body->force = MathVector2Add(body->force, force);
}
// Adds an angular force to a physics body
-PHYSACDEF void PhysicsAddTorque(PhysicsBody body, float amount)
+void PhysicsAddTorque(PhysicsBody body, float amount)
{
if (body != NULL) body->torque += amount;
}
// Shatters a polygon shape physics body to little physics bodies with explosion force
-PHYSACDEF void PhysicsShatter(PhysicsBody body, Vector2 position, float force)
+void PhysicsShatter(PhysicsBody body, Vector2 position, float force)
{
if (body != NULL)
{
@@ -700,13 +692,13 @@ PHYSACDEF void PhysicsShatter(PhysicsBody body, Vector2 position, float force)
}
// Returns the current amount of created physics bodies
-PHYSACDEF int GetPhysicsBodiesCount(void)
+int GetPhysicsBodiesCount(void)
{
return physicsBodiesCount;
}
// Returns a physics body of the bodies pool at a specific index
-PHYSACDEF PhysicsBody GetPhysicsBody(int index)
+PhysicsBody GetPhysicsBody(int index)
{
PhysicsBody body = NULL;
@@ -722,7 +714,7 @@ PHYSACDEF PhysicsBody GetPhysicsBody(int index)
}
// Returns the physics body shape type (PHYSICS_CIRCLE or PHYSICS_POLYGON)
-PHYSACDEF int GetPhysicsShapeType(int index)
+int GetPhysicsShapeType(int index)
{
int result = -1;
@@ -739,7 +731,7 @@ PHYSACDEF int GetPhysicsShapeType(int index)
}
// Returns the amount of vertices of a physics body shape
-PHYSACDEF int GetPhysicsShapeVerticesCount(int index)
+int GetPhysicsShapeVerticesCount(int index)
{
int result = 0;
@@ -764,7 +756,7 @@ PHYSACDEF int GetPhysicsShapeVerticesCount(int index)
}
// Returns transformed position of a body shape (body position + vertex transformed position)
-PHYSACDEF Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex)
+Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex)
{
Vector2 position = { 0.0f, 0.0f };
@@ -791,7 +783,7 @@ PHYSACDEF Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex)
}
// Sets physics body shape transform based on radians parameter
-PHYSACDEF void SetPhysicsBodyRotation(PhysicsBody body, float radians)
+void SetPhysicsBodyRotation(PhysicsBody body, float radians)
{
if (body != NULL)
{
@@ -802,7 +794,7 @@ PHYSACDEF void SetPhysicsBodyRotation(PhysicsBody body, float radians)
}
// Unitializes and destroys a physics body
-PHYSACDEF void DestroyPhysicsBody(PhysicsBody body)
+void DestroyPhysicsBody(PhysicsBody body)
{
if (body != NULL)
{
@@ -844,7 +836,7 @@ PHYSACDEF void DestroyPhysicsBody(PhysicsBody body)
}
// Destroys created physics bodies and manifolds and resets global values
-PHYSACDEF void ResetPhysics(void)
+void ResetPhysics(void)
{
if (physicsBodiesCount > 0)
{
@@ -886,7 +878,7 @@ PHYSACDEF void ResetPhysics(void)
}
// Unitializes physics pointers and exits physics loop thread
-PHYSACDEF void ClosePhysics(void)
+void ClosePhysics(void)
{
// Unitialize physics manifolds dynamic memory allocations
if (physicsManifoldsCount > 0)
@@ -912,91 +904,98 @@ PHYSACDEF void ClosePhysics(void)
else TRACELOG("[PHYSAC] Physics module closed successfully\n");
}
-//----------------------------------------------------------------------------------
-// Module Internal Functions Definition
-//----------------------------------------------------------------------------------
-// Finds a valid index for a new physics body initialization
-static int FindAvailableBodyIndex()
+// Update physics system
+// Physics steps are launched at a fixed time step if enabled
+void UpdatePhysics(void)
{
- int index = -1;
- for (int i = 0; i < PHYSAC_MAX_BODIES; i++)
- {
- int currentId = i;
+#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
+ static double deltaTimeAccumulator = 0.0;
- // Check if current id already exist in other physics body
- for (unsigned int k = 0; k < physicsBodiesCount; k++)
- {
- if (bodies[k]->id == currentId)
- {
- currentId++;
- break;
- }
- }
+ // Calculate current time (ms)
+ currentTime = GetCurrentTime();
- // If it is not used, use it as new physics body id
- if (currentId == (int)i)
- {
- index = (int)i;
- break;
- }
+ // Calculate current delta time (ms)
+ const double delta = currentTime - startTime;
+
+ // Store the time elapsed since the last frame began
+ deltaTimeAccumulator += delta;
+
+ // Fixed time stepping loop
+ while (deltaTimeAccumulator >= deltaTime)
+ {
+ UpdatePhysicsStep();
+ deltaTimeAccumulator -= deltaTime;
}
- return index;
+ // Record the starting of this frame
+ startTime = currentTime;
+#else
+ UpdatePhysicsStep();
+#endif
}
-// Creates a default polygon shape with max vertex distance from polygon pivot
-static PhysicsVertexData CreateDefaultPolygon(float radius, int sides)
+void SetPhysicsTimeStep(double delta)
{
- PhysicsVertexData data = { 0 };
- data.vertexCount = sides;
+ deltaTime = delta;
+}
- // Calculate polygon vertices positions
- for (unsigned int i = 0; i < data.vertexCount; i++)
- {
- data.positions[i].x = (float)cosf(360.0f/sides*i*PHYSAC_DEG2RAD)*radius;
- data.positions[i].y = (float)sinf(360.0f/sides*i*PHYSAC_DEG2RAD)*radius;
- }
+//----------------------------------------------------------------------------------
+// Module Internal Functions Definition
+//----------------------------------------------------------------------------------
+#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
+// Initializes hi-resolution MONOTONIC timer
+static void InitTimerHiRes(void)
+{
+#if defined(_WIN32)
+ QueryPerformanceFrequency((unsigned long long int *) &frequency);
+#endif
- // Calculate polygon faces normals
- for (int i = 0; i < (int)data.vertexCount; i++)
- {
- int nextIndex = (((i + 1) < sides) ? (i + 1) : 0);
- Vector2 face = MathVector2Subtract(data.positions[nextIndex], data.positions[i]);
+#if defined(__EMSCRIPTEN__) || defined(__linux__)
+ struct timespec now;
+ if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) frequency = 1000000000;
+#endif
- data.normals[i] = CLITERAL(Vector2){ face.y, -face.x };
- MathVector2Normalize(&data.normals[i]);
- }
+#if defined(__APPLE__)
+ mach_timebase_info_data_t timebase;
+ mach_timebase_info(&timebase);
+ frequency = (timebase.denom*1e9)/timebase.numer;
+#endif
- return data;
+ baseClockTicks = (double)GetClockTicks(); // Get MONOTONIC clock time offset
+ startTime = GetCurrentTime(); // Get current time in milliseconds
}
-// Creates a rectangle polygon shape based on a min and max positions
-static PhysicsVertexData CreateRectanglePolygon(Vector2 pos, Vector2 size)
+// Get hi-res MONOTONIC time measure in clock ticks
+static unsigned long long int GetClockTicks(void)
{
- PhysicsVertexData data = { 0 };
- data.vertexCount = 4;
+ unsigned long long int value = 0;
- // Calculate polygon vertices positions
- data.positions[0] = CLITERAL(Vector2){ pos.x + size.x/2, pos.y - size.y/2 };
- data.positions[1] = CLITERAL(Vector2){ pos.x + size.x/2, pos.y + size.y/2 };
- data.positions[2] = CLITERAL(Vector2){ pos.x - size.x/2, pos.y + size.y/2 };
- data.positions[3] = CLITERAL(Vector2){ pos.x - size.x/2, pos.y - size.y/2 };
+#if defined(_WIN32)
+ QueryPerformanceCounter((unsigned long long int *) &value);
+#endif
- // Calculate polygon faces normals
- for (unsigned int i = 0; i < data.vertexCount; i++)
- {
- int nextIndex = (((i + 1) < data.vertexCount) ? (i + 1) : 0);
- Vector2 face = MathVector2Subtract(data.positions[nextIndex], data.positions[i]);
+#if defined(__linux__)
+ struct timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ value = (unsigned long long int)now.tv_sec*(unsigned long long int)1000000000 + (unsigned long long int)now.tv_nsec;
+#endif
- data.normals[i] = CLITERAL(Vector2){ face.y, -face.x };
- MathVector2Normalize(&data.normals[i]);
- }
+#if defined(__APPLE__)
+ value = mach_absolute_time();
+#endif
- return data;
+ return value;
}
+// Get current time in milliseconds
+static double GetCurrentTime(void)
+{
+ return (double)(GetClockTicks() - baseClockTicks)/frequency*1000;
+}
+#endif // !PHYSAC_AVOID_TIMMING_SYSTEM
+
// Update physics step (dynamics, collisions and position corrections)
-void UpdatePhysicsStep(void)
+static void UpdatePhysicsStep(void)
{
// Clear previous generated collisions information
for (int i = (int)physicsManifoldsCount - 1; i >= 0; i--)
@@ -1098,39 +1097,84 @@ void UpdatePhysicsStep(void)
}
}
-// Update physics system
-// Physics steps are launched at a fixed time step if enabled
-PHYSACDEF void UpdatePhysics(void)
+// Finds a valid index for a new physics body initialization
+static int FindAvailableBodyIndex()
{
-#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
- static double deltaTimeAccumulator = 0.0;
+ int index = -1;
+ for (int i = 0; i < PHYSAC_MAX_BODIES; i++)
+ {
+ int currentId = i;
- // Calculate current time (ms)
- currentTime = GetCurrentTime();
+ // Check if current id already exist in other physics body
+ for (unsigned int k = 0; k < physicsBodiesCount; k++)
+ {
+ if (bodies[k]->id == currentId)
+ {
+ currentId++;
+ break;
+ }
+ }
- // Calculate current delta time (ms)
- const double delta = currentTime - startTime;
+ // If it is not used, use it as new physics body id
+ if (currentId == (int)i)
+ {
+ index = (int)i;
+ break;
+ }
+ }
- // Store the time elapsed since the last frame began
- deltaTimeAccumulator += delta;
+ return index;
+}
- // Fixed time stepping loop
- while (deltaTimeAccumulator >= deltaTime)
+// Creates a default polygon shape with max vertex distance from polygon pivot
+static PhysicsVertexData CreateDefaultPolygon(float radius, int sides)
+{
+ PhysicsVertexData data = { 0 };
+ data.vertexCount = sides;
+
+ // Calculate polygon vertices positions
+ for (unsigned int i = 0; i < data.vertexCount; i++)
{
- UpdatePhysicsStep();
- deltaTimeAccumulator -= deltaTime;
+ data.positions[i].x = (float)cosf(360.0f/sides*i*PHYSAC_DEG2RAD)*radius;
+ data.positions[i].y = (float)sinf(360.0f/sides*i*PHYSAC_DEG2RAD)*radius;
}
- // Record the starting of this frame
- startTime = currentTime;
-#else
- UpdatePhysicsStep();
-#endif
+ // Calculate polygon faces normals
+ for (int i = 0; i < (int)data.vertexCount; i++)
+ {
+ int nextIndex = (((i + 1) < sides) ? (i + 1) : 0);
+ Vector2 face = MathVector2Subtract(data.positions[nextIndex], data.positions[i]);
+
+ data.normals[i] = CLITERAL(Vector2){ face.y, -face.x };
+ MathVector2Normalize(&data.normals[i]);
+ }
+
+ return data;
}
-PHYSACDEF void SetPhysicsTimeStep(double delta)
+// Creates a rectangle polygon shape based on a min and max positions
+static PhysicsVertexData CreateRectanglePolygon(Vector2 pos, Vector2 size)
{
- deltaTime = delta;
+ PhysicsVertexData data = { 0 };
+ data.vertexCount = 4;
+
+ // Calculate polygon vertices positions
+ data.positions[0] = CLITERAL(Vector2){ pos.x + size.x/2, pos.y - size.y/2 };
+ data.positions[1] = CLITERAL(Vector2){ pos.x + size.x/2, pos.y + size.y/2 };
+ data.positions[2] = CLITERAL(Vector2){ pos.x - size.x/2, pos.y + size.y/2 };
+ data.positions[3] = CLITERAL(Vector2){ pos.x - size.x/2, pos.y - size.y/2 };
+
+ // Calculate polygon faces normals
+ for (unsigned int i = 0; i < data.vertexCount; i++)
+ {
+ int nextIndex = (((i + 1) < data.vertexCount) ? (i + 1) : 0);
+ Vector2 face = MathVector2Subtract(data.positions[nextIndex], data.positions[i]);
+
+ data.normals[i] = CLITERAL(Vector2){ face.y, -face.x };
+ MathVector2Normalize(&data.normals[i]);
+ }
+
+ return data;
}
// Finds a valid index for a new manifold initialization
@@ -1844,59 +1888,6 @@ static Vector2 MathTriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3)
return result;
}
-#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
-// Initializes hi-resolution MONOTONIC timer
-static void InitTimerHiRes(void)
-{
-#if defined(_WIN32)
- QueryPerformanceFrequency((unsigned long long int *) &frequency);
-#endif
-
-#if defined(__EMSCRIPTEN__) || defined(__linux__)
- struct timespec now;
- if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) frequency = 1000000000;
-#endif
-
-#if defined(__APPLE__)
- mach_timebase_info_data_t timebase;
- mach_timebase_info(&timebase);
- frequency = (timebase.denom*1e9)/timebase.numer;
-#endif
-
- baseClockTicks = (double)GetClockTicks(); // Get MONOTONIC clock time offset
- startTime = GetCurrentTime(); // Get current time in milliseconds
-}
-
-// Get hi-res MONOTONIC time measure in clock ticks
-static unsigned long long int GetClockTicks(void)
-{
- unsigned long long int value = 0;
-
-#if defined(_WIN32)
- QueryPerformanceCounter((unsigned long long int *) &value);
-#endif
-
-#if defined(__linux__)
- struct timespec now;
- clock_gettime(CLOCK_MONOTONIC, &now);
- value = (unsigned long long int)now.tv_sec*(unsigned long long int)1000000000 + (unsigned long long int)now.tv_nsec;
-#endif
-
-#if defined(__APPLE__)
- value = mach_absolute_time();
-#endif
-
- return value;
-}
-
-// Get current time in milliseconds
-static double GetCurrentTime(void)
-{
- return (double)(GetClockTicks() - baseClockTicks)/frequency*1000;
-}
-#endif // !PHYSAC_AVOID_TIMMING_SYSTEM
-
-
// Returns the cross product of a vector and a value
static inline Vector2 MathVector2Product(Vector2 vector, float value)
{