78 #if defined(BUILD_LIBTYPE_SHARED)
79 #define PHYSACDEF __declspec(dllexport)
80 #elif defined(USE_LIBTYPE_SHARED)
81 #define PHYSACDEF __declspec(dllimport)
91 #define PHYSAC_MALLOC(size) malloc(size)
94 #define PHYSAC_CALLOC(size, n) calloc(size, n)
97 #define PHYSAC_FREE(ptr) free(ptr)
103#define PHYSAC_MAX_BODIES 64
104#define PHYSAC_MAX_MANIFOLDS 4096
105#define PHYSAC_MAX_VERTICES 24
106#define PHYSAC_DEFAULT_CIRCLE_VERTICES 24
108#define PHYSAC_COLLISION_ITERATIONS 100
109#define PHYSAC_PENETRATION_ALLOWANCE 0.05f
110#define PHYSAC_PENETRATION_CORRECTION 0.4f
112#define PHYSAC_PI 3.14159265358979323846f
113#define PHYSAC_DEG2RAD (PHYSAC_PI/180.0f)
118#if defined(__STDC__) && __STDC_VERSION__ >= 199901L
127#if !defined(RL_VECTOR2_TYPE)
196#if defined(__cplusplus)
225#if defined(__cplusplus)
237#if defined(PHYSAC_IMPLEMENTATION)
240#if defined(PHYSAC_DEBUG)
242 #define TRACELOG(...) printf(__VA_ARGS__)
244 #define TRACELOG(...) (void)0;
250#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
254 #if defined(__cplusplus)
258 int __stdcall QueryPerformanceCounter(
unsigned long long int *lpPerformanceCount);
259 int __stdcall QueryPerformanceFrequency(
unsigned long long int *lpFrequency);
260 #if defined(__cplusplus)
264 #if defined(__linux__) || defined(__FreeBSD__)
265 #if _POSIX_C_SOURCE < 199309L
266 #undef _POSIX_C_SOURCE
267 #define _POSIX_C_SOURCE 199309L
269 #include <sys/time.h>
271 #if defined(__APPLE__)
272 #include <mach/mach_time.h>
278#if defined(__cplusplus)
279 #define CLITERAL(type) type
281 #define CLITERAL(type) (type)
287#define PHYSAC_MIN(a,b) (((a)<(b))?(a):(b))
288#define PHYSAC_MAX(a,b) (((a)>(b))?(a):(b))
289#define PHYSAC_FLT_MAX 3.402823466e+38f
290#define PHYSAC_EPSILON 0.000001f
291#define PHYSAC_K 1.0f/3.0f
292#define PHYSAC_VECTOR_ZERO CLITERAL(Vector2){ 0.0f, 0.0f }
297static double deltaTime = 1.0/60.0/10.0 * 1000;
299#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
301static double baseClockTicks = 0.0;
302static unsigned long long int frequency = 0;
303static double startTime = 0.0;
304static double currentTime = 0.0;
309static unsigned int physicsBodiesCount = 0;
311static unsigned int physicsManifoldsCount = 0;
313static Vector2 gravityForce = { 0.0f, 9.81f };
316static unsigned int usedMemory = 0;
321#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
323static void InitTimerHiRes(
void);
324static unsigned long long int GetClockTicks(
void);
325static double GetCurrentTime(
void);
328static void UpdatePhysicsStep(
void);
330static int FindAvailableBodyIndex();
331static int FindAvailableManifoldIndex();
344static void IntegratePhysicsForces(
PhysicsBody body);
345static void IntegratePhysicsVelocity(
PhysicsBody body);
354static float MathVector2SqrLen(
Vector2 vector);
356static inline float MathVector2SqrDistance(
Vector2 v1,
Vector2 v2);
357static void MathVector2Normalize(
Vector2 *vector);
360static Matrix2x2 MathMatFromRadians(
float radians);
373#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
378 TRACELOG(
"[PHYSAC] Physics module initialized successfully\n");
402 int id = FindAvailableBodyIndex();
415 Vector2 center = { 0.0f, 0.0f };
417 float inertia = 0.0f;
426 float D = MathVector2CrossProduct(p1, p2);
427 float triangleArea = D/2;
429 area += triangleArea;
432 center.x += triangleArea*PHYSAC_K*(p1.
x + p2.
x);
433 center.y += triangleArea*PHYSAC_K*(p1.
y + p2.
y);
435 float intx2 = p1.
x*p1.
x + p2.
x*p1.
x + p2.
x*p2.
x;
436 float inty2 = p1.
y*p1.
y + p2.
y*p1.
y + p2.
y*p2.
y;
437 inertia += (0.25f*PHYSAC_K*D)*(intx2 + inty2);
440 center.x *= 1.0f/area;
441 center.y *= 1.0f/area;
451 body->
mass = density*area;
453 body->
inertia = density*inertia;
463 bodies[physicsBodiesCount] = body;
464 physicsBodiesCount++;
466 TRACELOG(
"[PHYSAC] Physic body created successfully (id: %i)\n", body->
id);
468 else TRACELOG(
"[PHYSAC] Physic body could not be created, PHYSAC_MAX_BODIES reached\n");
479 int id = FindAvailableBodyIndex();
486 body->
velocity = PHYSAC_VECTOR_ZERO;
487 body->
force = PHYSAC_VECTOR_ZERO;
497 Vector2 center = { 0.0f, 0.0f };
499 float inertia = 0.0f;
508 float cross = MathVector2CrossProduct(position1, position2);
509 float triangleArea = cross/2;
511 area += triangleArea;
514 center.
x += triangleArea*PHYSAC_K*(position1.
x + position2.
x);
515 center.
y += triangleArea*PHYSAC_K*(position1.
y + position2.
y);
517 float intx2 = position1.
x*position1.
x + position2.
x*position1.
x + position2.
x*position2.
x;
518 float inty2 = position1.
y*position1.
y + position2.
y*position1.
y + position2.
y*position2.
y;
519 inertia += (0.25f*PHYSAC_K*cross)*(intx2 + inty2);
522 center.
x *= 1.0f/area;
523 center.
y *= 1.0f/area;
533 body->
mass = density*area;
535 body->
inertia = density*inertia;
545 bodies[physicsBodiesCount] = body;
546 physicsBodiesCount++;
548 TRACELOG(
"[PHYSAC] Physic body created successfully (id: %i)\n", body->
id);
550 else TRACELOG(
"[PHYSAC] Physics body could not be created, PHYSAC_MAX_BODIES reached\n");
558 if (body !=
NULL) body->
force = MathVector2Add(body->
force, force);
575 bool collision =
false;
577 for (
unsigned int i = 0; i < vertexData.
vertexCount; i++)
581 unsigned int nextIndex = (((i + 1) < vertexData.
vertexCount) ? (i + 1) : 0);
585 float alpha = ((positionB.
y - positionC.
y)*(position.
x - positionC.
x) + (positionC.
x - positionB.
x)*(position.
y - positionC.
y))/
586 ((positionB.
y - positionC.
y)*(positionA.
x - positionC.
x) + (positionC.
x - positionB.
x)*(positionA.
y - positionC.
y));
588 float beta = ((positionC.
y - positionA.
y)*(position.
x - positionC.
x) + (positionA.
x - positionC.
x)*(position.
y - positionC.
y))/
589 ((positionB.
y - positionC.
y)*(positionA.
x - positionC.
x) + (positionC.
x - positionB.
x)*(positionA.
y - positionC.
y));
591 float gamma = 1.0f - alpha - beta;
593 if ((alpha > 0.0f) && (beta > 0.0f) & (gamma > 0.0f))
606 for (
int i = 0; i < count; i++) vertices[i] = vertexData.
positions[i];
611 for (
int i = 0; i < count; i++)
613 int nextIndex = (((i + 1) < count) ? (i + 1) : 0);
614 Vector2 center = MathTriangleBarycenter(vertices[i], vertices[nextIndex], PHYSAC_VECTOR_ZERO);
615 center = MathVector2Add(bodyPos, center);
616 Vector2 offset = MathVector2Subtract(center, bodyPos);
623 vertexData.
positions[0] = MathVector2Subtract(vertices[i], offset);
624 vertexData.
positions[1] = MathVector2Subtract(vertices[nextIndex], offset);
625 vertexData.
positions[2] = MathVector2Subtract(position, center);
636 for (
unsigned int j = 0; j < vertexData.
vertexCount; j++)
638 unsigned int nextVertex = (((j + 1) < vertexData.
vertexCount) ? (j + 1) : 0);
642 MathVector2Normalize(&vertexData.
normals[j]);
650 center = PHYSAC_VECTOR_ZERO;
652 float inertia = 0.0f;
661 float D = MathVector2CrossProduct(p1, p2);
662 float triangleArea = D/2;
664 area += triangleArea;
667 center.
x += triangleArea*PHYSAC_K*(p1.
x + p2.
x);
668 center.
y += triangleArea*PHYSAC_K*(p1.
y + p2.
y);
670 float intx2 = p1.
x*p1.
x + p2.
x*p1.
x + p2.
x*p2.
x;
671 float inty2 = p1.
y*p1.
y + p2.
y*p1.
y + p2.
y*p2.
y;
672 inertia += (0.25f*PHYSAC_K*D)*(intx2 + inty2);
675 center.
x *= 1.0f/area;
676 center.
y *= 1.0f/area;
688 Vector2 forceDirection = MathVector2Subtract(MathVector2Add(pointA, MathVector2Add(vertexData.
positions[0], pointB)), body->
position);
689 MathVector2Normalize(&forceDirection);
690 forceDirection.
x *= force;
691 forceDirection.
y *= force;
701 else TRACELOG(
"[PHYSAC] WARNING: PhysicsShatter: NULL physic body\n");
707 return physicsBodiesCount;
715 if (index < (
int)physicsBodiesCount)
717 body = bodies[index];
719 if (body ==
NULL)
TRACELOG(
"[PHYSAC] WARNING: GetPhysicsBody: NULL physic body\n");
721 else TRACELOG(
"[PHYSAC] WARNING: Physic body index is out of bounds\n");
731 if (index < (
int)physicsBodiesCount)
736 else TRACELOG(
"[PHYSAC] WARNING: GetPhysicsShapeType: NULL physic body\n");
738 else TRACELOG(
"[PHYSAC] WARNING: Physic body index is out of bounds\n");
748 if (index < (
int)physicsBodiesCount)
761 else TRACELOG(
"[PHYSAC] WARNING: GetPhysicsShapeVerticesCount: NULL physic body\n");
763 else TRACELOG(
"[PHYSAC] WARNING: Physic body index is out of bounds\n");
771 Vector2 position = { 0.0f, 0.0f };
790 else TRACELOG(
"[PHYSAC] WARNING: GetPhysicsShapeVertex: NULL physic body\n");
814 for (
unsigned int i = 0; i < physicsBodiesCount; i++)
816 if (bodies[i]->
id ==
id)
825 TRACELOG(
"[PHYSAC] WARNING: Requested body (id: %i) can not be found\n",
id);
832 bodies[index] =
NULL;
835 for (
unsigned int i = index; i < physicsBodiesCount; i++)
837 if ((i + 1) < physicsBodiesCount) bodies[i] = bodies[i + 1];
841 physicsBodiesCount--;
843 TRACELOG(
"[PHYSAC] Physic body destroyed successfully (id: %i)\n",
id);
845 else TRACELOG(
"[PHYSAC] WARNING: DestroyPhysicsBody: NULL physic body\n");
851 if (physicsBodiesCount > 0)
854 for (
int i = physicsBodiesCount - 1; i >= 0; i--)
866 physicsBodiesCount = 0;
869 if (physicsManifoldsCount > 0)
872 for (
int i = physicsManifoldsCount - 1; i >= 0; i--)
876 if (manifold !=
NULL)
884 physicsManifoldsCount = 0;
887 TRACELOG(
"[PHYSAC] Physics module reseted successfully\n");
894 if (physicsManifoldsCount > 0)
896 for (
int i = physicsManifoldsCount - 1; i >= 0; i--) DestroyPhysicsManifold(contacts[i]);
900 if (physicsBodiesCount > 0)
906 if ((physicsBodiesCount > 0) || (usedMemory != 0))
908 TRACELOG(
"[PHYSAC] WARNING: Physics module closed with unallocated bodies (BODIES: %i, MEMORY: %i bytes)\n", physicsBodiesCount, usedMemory);
910 else if ((physicsManifoldsCount > 0) || (usedMemory != 0))
912 TRACELOG(
"[PHYSAC] WARNING: Pysics module closed with unallocated manifolds (MANIFOLDS: %i, MEMORY: %i bytes)\n", physicsManifoldsCount, usedMemory);
914 else TRACELOG(
"[PHYSAC] Physics module closed successfully\n");
921#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
922 static double deltaTimeAccumulator = 0.0;
925 currentTime = GetCurrentTime();
928 const double delta = currentTime - startTime;
931 deltaTimeAccumulator += delta;
934 while (deltaTimeAccumulator >= deltaTime)
937 deltaTimeAccumulator -= deltaTime;
941 startTime = currentTime;
955#if !defined(PHYSAC_AVOID_TIMMING_SYSTEM)
957static void InitTimerHiRes(
void)
960 QueryPerformanceFrequency((
unsigned long long int *) &frequency);
963#if defined(__EMSCRIPTEN__) || defined(__linux__)
965 if (clock_gettime(CLOCK_MONOTONIC, &now) == 0) frequency = 1000000000;
968#if defined(__APPLE__)
969 mach_timebase_info_data_t timebase;
970 mach_timebase_info(&timebase);
971 frequency = (timebase.denom*1e9)/timebase.numer;
974 baseClockTicks = (
double)GetClockTicks();
975 startTime = GetCurrentTime();
979static unsigned long long int GetClockTicks(
void)
981 unsigned long long int value = 0;
984 QueryPerformanceCounter((
unsigned long long int *) &value);
987#if defined(__linux__)
989 clock_gettime(CLOCK_MONOTONIC, &now);
990 value = (
unsigned long long int)now.tv_sec*(
unsigned long long int)1000000000 + (
unsigned long long int)now.tv_nsec;
993#
if defined(__APPLE__)
994 value = mach_absolute_time();
1001static double GetCurrentTime(
void)
1003 return (
double)(GetClockTicks() - baseClockTicks)/frequency*1000;
1008static void UpdatePhysicsStep(
void)
1011 for (
int i = (
int)physicsManifoldsCount - 1; i >= 0; i--)
1014 if (manifold !=
NULL) DestroyPhysicsManifold(manifold);
1018 for (
unsigned int i = 0; i < physicsBodiesCount; i++)
1025 for (
unsigned int i = 0; i < physicsBodiesCount; i++)
1031 for (
unsigned int j = i + 1; j < physicsBodiesCount; j++)
1040 SolvePhysicsManifold(manifold);
1061 for (
unsigned int i = 0; i < physicsBodiesCount; i++)
1064 if (body !=
NULL) IntegratePhysicsForces(body);
1068 for (
unsigned int i = 0; i < physicsManifoldsCount; i++)
1071 if (manifold !=
NULL) InitializePhysicsManifolds(manifold);
1077 for (
unsigned int j = 0; j < physicsManifoldsCount; j++)
1080 if (manifold !=
NULL) IntegratePhysicsImpulses(manifold);
1085 for (
unsigned int i = 0; i < physicsBodiesCount; i++)
1088 if (body !=
NULL) IntegratePhysicsVelocity(body);
1092 for (
unsigned int i = 0; i < physicsManifoldsCount; i++)
1095 if (manifold !=
NULL) CorrectPhysicsPositions(manifold);
1099 for (
unsigned int i = 0; i < physicsBodiesCount; i++)
1104 body->
force = PHYSAC_VECTOR_ZERO;
1111static int FindAvailableBodyIndex()
1119 for (
unsigned int k = 0; k < physicsBodiesCount; k++)
1121 if (bodies[k]->
id == currentId)
1129 if (currentId == (
int)i)
1146 for (
unsigned int i = 0; i < data.
vertexCount; i++)
1155 int nextIndex = (((i + 1) < sides) ? (i + 1) : 0);
1159 MathVector2Normalize(&data.
normals[i]);
1178 for (
unsigned int i = 0; i < data.
vertexCount; i++)
1180 int nextIndex = (((i + 1) < data.
vertexCount) ? (i + 1) : 0);
1184 MathVector2Normalize(&data.
normals[i]);
1191static int FindAvailableManifoldIndex()
1199 for (
unsigned int k = 0; k < physicsManifoldsCount; k++)
1201 if (contacts[k]->
id == currentId)
1225 int id = FindAvailableManifoldIndex();
1230 manifold->
bodyA = a;
1231 manifold->
bodyB = b;
1233 manifold->
normal = PHYSAC_VECTOR_ZERO;
1234 manifold->
contacts[0] = PHYSAC_VECTOR_ZERO;
1235 manifold->
contacts[1] = PHYSAC_VECTOR_ZERO;
1242 contacts[physicsManifoldsCount] = manifold;
1243 physicsManifoldsCount++;
1245 else TRACELOG(
"[PHYSAC] Physic manifold could not be created, PHYSAC_MAX_MANIFOLDS reached\n");
1253 if (manifold !=
NULL)
1255 int id = manifold->
id;
1258 for (
unsigned int i = 0; i < physicsManifoldsCount; i++)
1260 if (contacts[i]->
id ==
id)
1267 if (index == -1)
return;
1272 contacts[index] =
NULL;
1275 for (
unsigned int i = index; i < physicsManifoldsCount; i++)
1277 if ((i + 1) < physicsManifoldsCount) contacts[i] = contacts[i + 1];
1281 physicsManifoldsCount--;
1283 else TRACELOG(
"[PHYSAC] WARNING: DestroyPhysicsManifold: NULL physic manifold\n");
1322 if ((bodyA ==
NULL) || (bodyB ==
NULL))
return;
1327 float distSqr = MathVector2SqrLen(normal);
1331 if (distSqr >= radius*radius)
1337 float distance = sqrtf(distSqr);
1340 if (distance == 0.0f)
1363 if ((bodyA ==
NULL) || (bodyB ==
NULL))
return;
1369 center = MathMatVector2Product(MathMatTranspose(bodyB->
shape.
transform), MathVector2Subtract(center, bodyB->
position));
1373 float separation = -PHYSAC_FLT_MAX;
1377 for (
unsigned int i = 0; i < vertexData.
vertexCount; i++)
1379 float currentSeparation = MathVector2DotProduct(vertexData.
normals[i], MathVector2Subtract(center, vertexData.
positions[i]));
1381 if (currentSeparation > bodyA->
shape.
radius)
return;
1383 if (currentSeparation > separation)
1385 separation = currentSeparation;
1392 int nextIndex = (((faceNormal + 1) < (
int)vertexData.
vertexCount) ? (faceNormal + 1) : 0);
1396 if (separation < PHYSAC_EPSILON)
1407 float dot1 = MathVector2DotProduct(MathVector2Subtract(center, v1), MathVector2Subtract(v2, v1));
1408 float dot2 = MathVector2DotProduct(MathVector2Subtract(center, v2), MathVector2Subtract(v1, v2));
1416 Vector2 normal = MathVector2Subtract(v1, center);
1418 MathVector2Normalize(&normal);
1419 manifold->
normal = normal;
1421 v1 = MathVector2Add(v1, bodyB->
position);
1424 else if (dot2 <= 0.0f)
1429 Vector2 normal = MathVector2Subtract(v2, center);
1431 v2 = MathVector2Add(v2, bodyB->
position);
1434 MathVector2Normalize(&normal);
1435 manifold->
normal = normal;
1441 if (MathVector2DotProduct(MathVector2Subtract(center, v1), normal) > bodyA->
shape.
radius)
return;
1456 if ((bodyA ==
NULL) || (bodyB ==
NULL))
return;
1458 manifold->
bodyA = bodyB;
1459 manifold->
bodyB = bodyA;
1460 SolveCircleToPolygon(manifold);
1477 float penetrationA = FindAxisLeastPenetration(&faceA, bodyA, bodyB);
1478 if (penetrationA >= 0.0f)
return;
1482 float penetrationB = FindAxisLeastPenetration(&faceB, bodyB, bodyA);
1483 if (penetrationB >= 0.0f)
return;
1485 int referenceIndex = 0;
1493 if (penetrationA >= (penetrationB*0.95f + penetrationA*0.01f))
1497 referenceIndex = faceA;
1503 referenceIndex = faceB;
1509 FindIncidentFace(&incidentFace[0], &incidentFace[1], refPoly, incPoly, referenceIndex);
1514 referenceIndex = (((referenceIndex + 1) < (
int)refData.
vertexCount) ? (referenceIndex + 1) : 0);
1518 v1 = MathMatVector2Product(refPoly.
transform, v1);
1520 v2 = MathMatVector2Product(refPoly.
transform, v2);
1524 Vector2 sidePlaneNormal = MathVector2Subtract(v2, v1);
1525 MathVector2Normalize(&sidePlaneNormal);
1528 Vector2 refFaceNormal = { sidePlaneNormal.
y, -sidePlaneNormal.
x };
1529 float refC = MathVector2DotProduct(refFaceNormal, v1);
1530 float negSide = MathVector2DotProduct(sidePlaneNormal, v1)*-1;
1531 float posSide = MathVector2DotProduct(sidePlaneNormal, v2);
1534 if (MathVector2Clip(
CLITERAL(
Vector2){ -sidePlaneNormal.
x, -sidePlaneNormal.
y }, &incidentFace[0], &incidentFace[1], negSide) < 2)
return;
1535 if (MathVector2Clip(sidePlaneNormal, &incidentFace[0], &incidentFace[1], posSide) < 2)
return;
1541 int currentPoint = 0;
1542 float separation = MathVector2DotProduct(refFaceNormal, incidentFace[0]) - refC;
1543 if (separation <= 0.0f)
1545 manifold->
contacts[currentPoint] = incidentFace[0];
1551 separation = MathVector2DotProduct(refFaceNormal, incidentFace[1]) - refC;
1553 if (separation <= 0.0f)
1555 manifold->
contacts[currentPoint] = incidentFace[1];
1567static void IntegratePhysicsForces(
PhysicsBody body)
1576 body->
velocity.
x += (float)(gravityForce.
x*(deltaTime/1000/2.0));
1577 body->
velocity.
y += (float)(gravityForce.
y*(deltaTime/1000/2.0));
1589 if ((bodyA ==
NULL) || (bodyB ==
NULL))
return;
1605 Vector2 radiusV = { 0.0f, 0.0f };
1611 if (MathVector2SqrLen(radiusV) < (MathVector2SqrLen(
CLITERAL(
Vector2){ (float)(gravityForce.
x*deltaTime/1000), (
float)(gravityForce.
y*deltaTime/1000) }) + PHYSAC_EPSILON)) manifold->
restitution = 0;
1621 if ((bodyA ==
NULL) || (bodyB ==
NULL))
return;
1626 bodyA->
velocity = PHYSAC_VECTOR_ZERO;
1627 bodyB->
velocity = PHYSAC_VECTOR_ZERO;
1638 Vector2 radiusV = { 0.0f, 0.0f };
1643 float contactVelocity = MathVector2DotProduct(radiusV, manifold->
normal);
1646 if (contactVelocity > 0.0f)
return;
1648 float raCrossN = MathVector2CrossProduct(radiusA, manifold->
normal);
1649 float rbCrossN = MathVector2CrossProduct(radiusB, manifold->
normal);
1654 float impulse = -(1.0f + manifold->
restitution)*contactVelocity;
1655 impulse /= inverseMassSum;
1679 Vector2 tangent = { radiusV.
x - (manifold->
normal.
x*MathVector2DotProduct(radiusV, manifold->
normal)), radiusV.
y - (manifold->
normal.
y*MathVector2DotProduct(radiusV, manifold->
normal)) };
1680 MathVector2Normalize(&tangent);
1683 float impulseTangent = -MathVector2DotProduct(radiusV, tangent);
1684 impulseTangent /= inverseMassSum;
1687 float absImpulseTangent = (
float)fabs(impulseTangent);
1690 if (absImpulseTangent <= PHYSAC_EPSILON)
return;
1693 Vector2 tangentImpulse = { 0.0f, 0.0f };
1694 if (absImpulseTangent < impulse*manifold->staticFriction) tangentImpulse =
CLITERAL(
Vector2){ tangent.
x*impulseTangent, tangent.
y*impulseTangent };
1717static void IntegratePhysicsVelocity(
PhysicsBody body)
1727 IntegratePhysicsForces(body);
1736 if ((bodyA ==
NULL) || (bodyB ==
NULL))
return;
1738 Vector2 correction = { 0.0f, 0.0f };
1758 float bestProjection = -PHYSAC_FLT_MAX;
1759 Vector2 bestVertex = { 0.0f, 0.0f };
1762 for (
unsigned int i = 0; i < data.
vertexCount; i++)
1765 float projection = MathVector2DotProduct(vertex, dir);
1767 if (projection > bestProjection)
1769 bestVertex = vertex;
1770 bestProjection = projection;
1780 float bestDistance = -PHYSAC_FLT_MAX;
1786 for (
unsigned int i = 0; i < dataA.
vertexCount; i++)
1794 normal = MathMatVector2Product(buT, transNormal);
1801 vertex = MathMatVector2Product(shapeA.
transform, vertex);
1802 vertex = MathVector2Add(vertex, shapeA.
body->
position);
1803 vertex = MathVector2Subtract(vertex, shapeB.
body->
position);
1804 vertex = MathMatVector2Product(buT, vertex);
1807 float distance = MathVector2DotProduct(normal, MathVector2Subtract(support, vertex));
1810 if (distance > bestDistance)
1812 bestDistance = distance;
1817 *faceIndex = bestIndex;
1818 return bestDistance;
1830 referenceNormal = MathMatVector2Product(ref.
transform, referenceNormal);
1831 referenceNormal = MathMatVector2Product(MathMatTranspose(inc.
transform), referenceNormal);
1834 int incidentFace = 0;
1835 float minDot = PHYSAC_FLT_MAX;
1837 for (
unsigned int i = 0; i < incData.
vertexCount; i++)
1839 float dot = MathVector2DotProduct(referenceNormal, incData.
normals[i]);
1851 incidentFace = (((incidentFace + 1) < (
int)incData.
vertexCount) ? (incidentFace + 1) : 0);
1860 Vector2 out[2] = { *faceA, *faceB };
1863 float distanceA = MathVector2DotProduct(normal, *faceA) - clip;
1864 float distanceB = MathVector2DotProduct(normal, *faceB) - clip;
1867 if (distanceA <= 0.0f) out[sp++] = *faceA;
1868 if (distanceB <= 0.0f) out[sp++] = *faceB;
1871 if ((distanceA*distanceB) < 0.0f)
1874 float alpha = distanceA/(distanceA - distanceB);
1876 Vector2 delta = MathVector2Subtract(*faceB, *faceA);
1879 out[sp] = MathVector2Add(out[sp], delta);
1893 Vector2 result = { 0.0f, 0.0f };
1895 result.
x = (v1.
x + v2.
x + v3.
x)/3;
1896 result.
y = (v1.
y + v2.
y + v3.
y)/3;
1902static inline Vector2 MathVector2Product(
Vector2 vector,
float value)
1904 Vector2 result = { -value*vector.
y, value*vector.
x };
1909static inline float MathVector2CrossProduct(
Vector2 v1,
Vector2 v2)
1911 return (v1.
x*v2.
y - v1.
y*v2.
x);
1915static inline float MathVector2SqrLen(
Vector2 vector)
1917 return (vector.
x*vector.
x + vector.
y*vector.
y);
1923 return (v1.
x*v2.
x + v1.
y*v2.
y);
1927static inline float MathVector2SqrDistance(
Vector2 v1,
Vector2 v2)
1929 Vector2 dir = MathVector2Subtract(v1, v2);
1930 return MathVector2DotProduct(dir, dir);
1934static void MathVector2Normalize(
Vector2 *vector)
1936 float length, ilength;
1939 length = sqrtf(aux.
x*aux.
x + aux.
y*aux.
y);
1941 if (length == 0) length = 1.0f;
1943 ilength = 1.0f/length;
1945 vector->
x *= ilength;
1946 vector->
y *= ilength;
1964static Matrix2x2 MathMatFromRadians(
float radians)
1966 float cos = cosf(radians);
1967 float sin = sinf(radians);
1969 Matrix2x2 result = { cos, -sin, sin, cos };
#define PHYSAC_COLLISION_ITERATIONS
PHYSACDEF void SetPhysicsTimeStep(double delta)
#define PHYSAC_MAX_BODIES
PHYSACDEF PhysicsBody CreatePhysicsBodyCircle(Vector2 pos, float radius, float density)
struct PhysicsBodyData * PhysicsBody
PHYSACDEF int GetPhysicsBodiesCount(void)
PHYSACDEF void SetPhysicsGravity(float x, float y)
#define PHYSAC_DEFAULT_CIRCLE_VERTICES
PHYSACDEF void UpdatePhysics(void)
struct PhysicsManifoldData * PhysicsManifold
PHYSACDEF int GetPhysicsShapeVerticesCount(int index)
PHYSACDEF void InitPhysics(void)
PHYSACDEF void SetPhysicsBodyRotation(PhysicsBody body, float radians)
PHYSACDEF void PhysicsShatter(PhysicsBody body, Vector2 position, float force)
PHYSACDEF void DestroyPhysicsBody(PhysicsBody body)
PHYSACDEF void PhysicsAddTorque(PhysicsBody body, float amount)
#define PHYSAC_MAX_MANIFOLDS
PHYSACDEF void ClosePhysics(void)
#define PHYSAC_MAX_VERTICES
PHYSACDEF PhysicsBody CreatePhysicsBodyRectangle(Vector2 pos, float width, float height, float density)
PHYSACDEF PhysicsBody GetPhysicsBody(int index)
#define PHYSAC_PENETRATION_CORRECTION
PHYSACDEF Vector2 GetPhysicsShapeVertex(PhysicsBody body, int vertex)
PHYSACDEF void ResetPhysics(void)
#define PHYSACDEF
Physac v1.1 - 2D Physics library for videogames.
#define PHYSAC_MALLOC(size)
PHYSACDEF PhysicsBody CreatePhysicsBodyPolygon(Vector2 pos, float radius, int sides, float density)
#define PHYSAC_PENETRATION_ALLOWANCE
PHYSACDEF int GetPhysicsShapeType(int index)
#define PHYSAC_CALLOC(size, n)
PHYSACDEF void PhysicsAddForce(PhysicsBody body, Vector2 force)
#define TRACELOG(level,...)
unsigned int contactsCount
PhysicsVertexData vertexData
Vector2 positions[PHYSAC_MAX_VERTICES]
Vector2 normals[PHYSAC_MAX_VERTICES]