Sfoglia il codice sorgente

Review physac timming system

raysan5 7 anni fa
parent
commit
f44dbf21cf
1 ha cambiato i file con 79 aggiunte e 59 eliminazioni
  1. 79 59
      src/physac.h

+ 79 - 59
src/physac.h

@@ -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 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 inline Mat2 Mat2Transpose(Mat2 matrix);                                                              // Returns the transpose of a given matrix 2x2
+static 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 uint64_t GetTimeCount(void)
 {
-    double time = 0;
-
-    #if defined(_WIN32)
-        unsigned long long int clockFrequency, currentTime;
-
-        QueryPerformanceFrequency(&clockFrequency);
-        QueryPerformanceCounter(&currentTime);
+    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