|
|
@ -43,16 +43,15 @@ |
|
|
|
* NOTE 2: Physac requires static C library linkage to avoid dependency on MinGW DLL (-static -lpthread) |
|
|
|
* |
|
|
|
* Use the following code to compile: |
|
|
|
* gcc -o physac_sample.exe physac_sample.c -s $(RAYLIB_DIR)\raylib\raylib_icon -static -lraylib -lpthread \ |
|
|
|
* -lglfw3 -lopengl32 -lgdi32 -lopenal32 -lwinmm -std=c99 -Wl,--subsystem,windows -Wl,-allow-multiple-definition |
|
|
|
* gcc -o $(NAME_PART).exe $(FILE_NAME) -s icon\physac_icon -static -lraylib -lpthread -lopengl32 -lgdi32 -std=c99 |
|
|
|
* |
|
|
|
* VERY THANKS TO: |
|
|
|
* Ramón Santamaria (@raysan5) |
|
|
|
* Ramon Santamaria (github: @raysan5) |
|
|
|
* |
|
|
|
* |
|
|
|
* LICENSE: zlib/libpng |
|
|
|
* |
|
|
|
* Copyright (c) 2016-2017 Victor Fisac |
|
|
|
* Copyright (c) 2016-2017 Victor Fisac (github: @victorfisac) |
|
|
|
* |
|
|
|
* This software is provided "as-is", without any express or implied warranty. In no event |
|
|
|
* will the authors be held liable for any damages arising from the use of this software. |
|
|
@ -235,22 +234,6 @@ PHYSACDEF void ClosePhysics(void); |
|
|
|
|
|
|
|
#if defined(PHYSAC_IMPLEMENTATION) |
|
|
|
|
|
|
|
#if defined(_WIN32) |
|
|
|
// Functions required to query time on Windows |
|
|
|
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); |
|
|
|
int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); |
|
|
|
#elif (defined(__linux__) || defined(__APPLE__) || defined(PLATFORM_WEB)) |
|
|
|
#if _POSIX_C_SOURCE < 199309L |
|
|
|
#undef _POSIX_C_SOURCE |
|
|
|
#define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext. |
|
|
|
#endif |
|
|
|
//#define _DEFAULT_SOURCE // Enables BSD function definitions and C99 POSIX compliance |
|
|
|
#include <sys/time.h> // Required for: timespec |
|
|
|
#include <time.h> // Required for: clock_gettime() |
|
|
|
#include <stdint.h> |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#if !defined(PHYSAC_NO_THREADS) |
|
|
|
#include <pthread.h> // Required for: pthread_t, pthread_create() |
|
|
|
#endif |
|
|
@ -261,8 +244,27 @@ PHYSACDEF void ClosePhysics(void); |
|
|
|
|
|
|
|
#include <stdlib.h> // Required for: malloc(), free(), srand(), rand() |
|
|
|
#include <math.h> // Required for: cosf(), sinf(), fabs(), sqrtf() |
|
|
|
#include <stdint.h> // Required for: uint64_t |
|
|
|
|
|
|
|
#if !defined(PHYSAC_STANDALONE) |
|
|
|
#include "raymath.h" // Required for: Vector2Add(), Vector2Subtract() |
|
|
|
#endif |
|
|
|
|
|
|
|
#include "raymath.h" // Required for: Vector2Add(), Vector2Subtract() |
|
|
|
// Time management functionality |
|
|
|
#if defined(_WIN32) |
|
|
|
// Functions required to query time on Windows |
|
|
|
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); |
|
|
|
int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); |
|
|
|
#elif defined(__linux__) |
|
|
|
#if _POSIX_C_SOURCE < 199309L |
|
|
|
#undef _POSIX_C_SOURCE |
|
|
|
#define _POSIX_C_SOURCE 199309L // Required for CLOCK_MONOTONIC if compiled with c99 without gnu ext. |
|
|
|
#endif |
|
|
|
#include <sys/time.h> // Required for: timespec |
|
|
|
#include <time.h> // Required for: clock_gettime() |
|
|
|
#elif defined(__APPLE__) // macOS also defines __MACH__ |
|
|
|
#include <mach/mach_time.h> // Required for: mach_absolute_time() |
|
|
|
#endif |
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------- |
|
|
|
// Defines and Macros |
|
|
@ -285,12 +287,13 @@ static pthread_t physicsThreadId; // Physics thread id |
|
|
|
#endif |
|
|
|
static unsigned int usedMemory = 0; // Total allocated dynamic memory |
|
|
|
static bool physicsThreadEnabled = false; // Physics thread enabled state |
|
|
|
static double currentTime = 0; // Current time in milliseconds |
|
|
|
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(__linux__) || defined(__APPLE__) || defined(PLATFORM_WEB) |
|
|
|
static double baseTime = 0; // Android and RPI platforms base time |
|
|
|
#endif |
|
|
|
|
|
|
|
static double baseTime = 0; // Offset time for MONOTONIC clock |
|
|
|
static double startTime = 0; // Start time in milliseconds |
|
|
|
static double deltaTime = 0; // Delta time used for physics steps |
|
|
|
static double currentTime = 0; // Current time in milliseconds |
|
|
|
static uint64_t frequency = 0.0; // Hi-res clock frequency |
|
|
|
|
|
|
|
static double accumulator = 0; // Physics time step delta time accumulator |
|
|
|
static unsigned int stepsCount = 0; // Total physics steps processed |
|
|
|
static Vector2 gravityForce = { 0, 9.81f/1000 }; // Physics world gravity force |
|
|
@ -324,8 +327,10 @@ static int Clip(Vector2 normal, float clip, Vector2 *faceA, Vector2 *faceB); |
|
|
|
static bool BiasGreaterThan(float valueA, float valueB); // Check if values are between bias range |
|
|
|
static Vector2 TriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3); // Returns the barycenter of a triangle given by 3 points |
|
|
|
|
|
|
|
static void InitTimer(void); // Initializes hi-resolution timer |
|
|
|
static double GetCurrentTime(void); // Get current time in milliseconds |
|
|
|
static void InitTimer(void); // Initializes hi-resolution MONOTONIC timer |
|
|
|
static uint64_t GetTimeCount(void); // Get hi-res MONOTONIC time measure in seconds |
|
|
|
static double GetCurrentTime(void); // // Get hi-res MONOTONIC time measure in seconds |
|
|
|
|
|
|
|
static int GetRandomNumber(int min, int max); // Returns a random number between min and max (both included) |
|
|
|
|
|
|
|
// Math functions |
|
|
@ -341,10 +346,10 @@ static Vector2 Vector2Add(Vector2 v1, Vector2 v2); |
|
|
|
static Vector2 Vector2Subtract(Vector2 v1, Vector2 v2); // Returns the subtract of two given vectors |
|
|
|
#endif |
|
|
|
|
|
|
|
static Mat2 Mat2Radians(float radians); // Creates a matrix 2x2 from a given radians value |
|
|
|
static kr">inline Mat2 Mat2Radians(float radians); // Creates a matrix 2x2 from a given radians value |
|
|
|
static void Mat2Set(Mat2 *matrix, float radians); // Set values from radians to a created matrix 2x2 |
|
|
|
static Mat2 Mat2Transpose(Mat2 matrix); // Returns the transpose of a given matrix 2x2 |
|
|
|
static Vector2 Mat2MultiplyVector2(Mat2 matrix, Vector2 vector); // Multiplies a vector by a matrix 2x2 |
|
|
|
static kr">inline Mat2 Mat2Transpose(Mat2 matrix); // Returns the transpose of a given matrix 2x2 |
|
|
|
static kr">inline Vector2 Mat2MultiplyVector2(Mat2 matrix, Vector2 vector); // Multiplies a vector by a matrix 2x2 |
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------- |
|
|
|
// Module Functions Definition |
|
|
@ -352,15 +357,15 @@ static Vector2 Mat2MultiplyVector2(Mat2 matrix, Vector2 vector); |
|
|
|
// Initializes physics values, pointers and creates physics loop thread |
|
|
|
PHYSACDEF void InitPhysics(void) |
|
|
|
{ |
|
|
|
#if defined(PHYSAC_DEBUG) |
|
|
|
printf("[PHYSAC] physics module initialized successfully\n"); |
|
|
|
#endif |
|
|
|
|
|
|
|
#if !defined(PHYSAC_NO_THREADS) |
|
|
|
// NOTE: if defined, user will need to create a thread for PhysicsThread function manually |
|
|
|
// Create physics thread using POSIXS thread libraries |
|
|
|
pthread_create(&physicsThreadId, NULL, &PhysicsLoop, NULL); |
|
|
|
#endif |
|
|
|
|
|
|
|
#if defined(PHYSAC_DEBUG) |
|
|
|
printf("[PHYSAC] physics module initialized successfully\n"); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
// Returns true if physics thread is currently enabled |
|
|
@ -1024,7 +1029,7 @@ static PolygonData CreateRectanglePolygon(Vector2 pos, Vector2 size) |
|
|
|
static void *PhysicsLoop(void *arg) |
|
|
|
{ |
|
|
|
#if defined(PHYSAC_DEBUG) |
|
|
|
printf("[PHYSAC] physics thread created with successfully\n"); |
|
|
|
printf("[PHYSAC] physics thread created successfully\n"); |
|
|
|
#endif |
|
|
|
|
|
|
|
// Initialize physics loop thread values |
|
|
@ -1884,42 +1889,56 @@ static Vector2 TriangleBarycenter(Vector2 v1, Vector2 v2, Vector2 v3) |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
// Initializes hi-resolution timer |
|
|
|
// Initializes hi-resolution MONOTONIC timer |
|
|
|
static void InitTimer(void) |
|
|
|
{ |
|
|
|
srand(time(NULL)); // Initialize random seed |
|
|
|
|
|
|
|
#if defined(_WIN32) |
|
|
|
QueryPerformanceFrequency((unsigned long long int *) &frequency); |
|
|
|
#endif |
|
|
|
|
|
|
|
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) |
|
|
|
struct timespec now; |
|
|
|
if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) baseTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; |
|
|
|
#endif |
|
|
|
#if defined(__linux__) |
|
|
|
struct timespec now; |
|
|
|
if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) frequency = 1000000000; |
|
|
|
#endif |
|
|
|
|
|
|
|
startTime = GetCurrentTime(); |
|
|
|
#if defined(__APPLE__) |
|
|
|
mach_timebase_info_data_t timebase; |
|
|
|
mach_timebase_info(&timebase); |
|
|
|
frequency = (timebase.denom*1e9)/timebase.numer; |
|
|
|
#endif |
|
|
|
|
|
|
|
baseTime = GetTimeCount(); // Get MONOTONIC clock time offset |
|
|
|
startTime = GetCurrentTime(); // Get current time |
|
|
|
} |
|
|
|
|
|
|
|
// Get current time in milliseconds |
|
|
|
static double GetCurrentTime(void) |
|
|
|
// Get hi-res MONOTONIC time measure in seconds |
|
|
|
static n">uint64_t GetTimeCount(void) |
|
|
|
{ |
|
|
|
double time = 0; |
|
|
|
|
|
|
|
#if defined(_WIN32) |
|
|
|
unsigned long long int clockFrequency, currentTime; |
|
|
|
|
|
|
|
QueryPerformanceFrequency(&clockFrequency); |
|
|
|
QueryPerformanceCounter(¤tTime); |
|
|
|
uint64_t value; |
|
|
|
|
|
|
|
#if defined(_WIN32) |
|
|
|
QueryPerformanceCounter((unsigned long long int *) &value); |
|
|
|
#endif |
|
|
|
|
|
|
|
time = (double)((double)currentTime/clockFrequency)*1000; |
|
|
|
#endif |
|
|
|
#if defined(__linux__) |
|
|
|
struct timespec now; |
|
|
|
clock_gettime(CLOCK_MONOTONIC, &now); |
|
|
|
value = (uint64_t)now.tv_sec*(uint64_t)1000000000 + (uint64_t)now.tv_nsec; |
|
|
|
#endif |
|
|
|
|
|
|
|
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(__linux__) || defined(__APPLE__) || defined(PLATFORM_WEB) |
|
|
|
struct timespec ts; |
|
|
|
clock_gettime(CLOCK_MONOTONIC, &ts); |
|
|
|
uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec; |
|
|
|
#if defined(__APPLE__) |
|
|
|
value = mach_absolute_time(); |
|
|
|
#endif |
|
|
|
|
|
|
|
time = (double)((double)(temp - baseTime)*1e-6); |
|
|
|
#endif |
|
|
|
return value; |
|
|
|
} |
|
|
|
|
|
|
|
return time; |
|
|
|
// Get current time in milliseconds |
|
|
|
static double GetCurrentTime(void) |
|
|
|
{ |
|
|
|
return (double)(GetTimeCount() - baseTime)/frequency*1000; |
|
|
|
} |
|
|
|
|
|
|
|
// Returns a random number between min and max (both included) |
|
|
@ -2000,6 +2019,7 @@ static inline Vector2 Vector2Add(Vector2 v1, Vector2 v2) |
|
|
|
static inline Vector2 Vector2Subtract(Vector2 v1, Vector2 v2) |
|
|
|
{ |
|
|
|
return (Vector2){ v1.x - v2.x, v1.y - v2.y }; |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
// Creates a matrix 2x2 from a given radians value |
|
|
|