Miloslav Číž 4 жил өмнө
parent
commit
1bf3f9127c
1 өөрчлөгдсөн 104 нэмэгдсэн , 103 устгасан
  1. 104 103
      tinyphysicsengine.h

+ 104 - 103
tinyphysicsengine.h

@@ -187,6 +187,38 @@ static const TPE_Unit TPE_sinTable[TPE_SIN_TABLE_LENGTH] =
 #define TPE_SIN_TABLE_UNIT_STEP\
   (TPE_FRACTIONS_PER_UNIT / (TPE_SIN_TABLE_LENGTH * 4))
 
+TPE_Unit TPE_sqrt(TPE_Unit value)
+{
+  int8_t sign = 1;
+
+  if (value < 0)
+  {
+    sign = -1;
+    value *= -1;
+  }
+
+  uint32_t result = 0;
+  uint32_t a = value;
+  uint32_t b = 1u << 30;
+
+  while (b > a)
+    b >>= 2;
+
+  while (b != 0)
+  {
+    if (a >= result + b)
+    {
+      a -= result + b;
+      result = result +  2 * b;
+    }
+
+    b >>= 2;
+    result >>= 1;
+  }
+
+  return result * sign;
+}
+
 TPE_Unit TPE_sin(TPE_Unit x)
 {
   x = TPE_wrap(x / TPE_SIN_TABLE_UNIT_STEP,TPE_SIN_TABLE_LENGTH * 4);
@@ -218,7 +250,7 @@ TPE_Unit TPE_cos(TPE_Unit x)
   return TPE_sin(x + TPE_FRACTIONS_PER_UNIT / 4);
 }
 
-TPE_initBody(TPE_Body *body)
+void TPE_initBody(TPE_Body *body)
 {
   // TODO
 
@@ -235,49 +267,49 @@ static inline TPE_Unit TPE_nonZero(TPE_Unit x)
   return x + (x == 0);
 }
 
-void TPE_vec3Add(const TPE_Vec4 a, const TPE_Vec4 b, TPE_Vec4 result)
+void TPE_vec3Add(const TPE_Vec4 a, const TPE_Vec4 b, TPE_Vec4 *result)
 {
-  result.x = a.x + b.x;
-  result.y = a.y + b.y;
-  result.z = a.z + b.z;
+  result->x = a.x + b.x;
+  result->y = a.y + b.y;
+  result->z = a.z + b.z;
 }
 
-void TPE_vec4Add(const TPE_Vec4 a, const TPE_Vec4 b, TPE_Vec4 result)
+void TPE_vec4Add(const TPE_Vec4 a, const TPE_Vec4 b, TPE_Vec4 *result)
 {
-  result.x = a.x + b.x;
-  result.y = a.y + b.y;
-  result.z = a.z + b.z;
-  result.w = a.w + b.w;
+  result->x = a.x + b.x;
+  result->y = a.y + b.y;
+  result->z = a.z + b.z;
+  result->w = a.w + b.w;
 }
 
-void TPE_vec3Substract(const TPE_Vec4 a, const TPE_Vec4 b, TPE_Vec4 result)
+void TPE_vec3Substract(const TPE_Vec4 a, const TPE_Vec4 b, TPE_Vec4 *result)
 {
-  result.x = a.x - b.x;
-  result.y = a.y - b.y;
-  result.z = a.z - b.z;
+  result->x = a.x - b.x;
+  result->y = a.y - b.y;
+  result->z = a.z - b.z;
 }
 
-void TPE_vec4Substract(const TPE_Vec4 a, const TPE_Vec4 b, TPE_Vec4 result)
+void TPE_vec4Substract(const TPE_Vec4 a, const TPE_Vec4 b, TPE_Vec4 *result)
 {
-  result.x = a.x - b.x;
-  result.y = a.y - b.y;
-  result.z = a.z - b.z;
-  result.w = a.w - b.w;
+  result->x = a.x - b.x;
+  result->y = a.y - b.y;
+  result->z = a.z - b.z;
+  result->w = a.w - b.w;
 }
 
-void TPE_vec3Multiplay(const TPE_Vec4 v, TPE_Unit f, TPE_Vec4 result)
+void TPE_vec3Multiplay(const TPE_Vec4 v, TPE_Unit f, TPE_Vec4 *result)
 {
-  result.x = (v.x * f) / TPE_FRACTIONS_PER_UNIT;
-  result.y = (v.y * f) / TPE_FRACTIONS_PER_UNIT;
-  result.z = (v.z * f) / TPE_FRACTIONS_PER_UNIT;
+  result->x = (v.x * f) / TPE_FRACTIONS_PER_UNIT;
+  result->y = (v.y * f) / TPE_FRACTIONS_PER_UNIT;
+  result->z = (v.z * f) / TPE_FRACTIONS_PER_UNIT;
 }
 
-void TPE_vec4Multiplay(const TPE_Vec4 v, TPE_Unit f, TPE_Vec4 result)
+void TPE_vec4Multiplay(const TPE_Vec4 v, TPE_Unit f, TPE_Vec4 *result)
 {
-  result.x = (v.x * f) / TPE_FRACTIONS_PER_UNIT;
-  result.y = (v.y * f) / TPE_FRACTIONS_PER_UNIT;
-  result.z = (v.z * f) / TPE_FRACTIONS_PER_UNIT;
-  result.w = (v.w * f) / TPE_FRACTIONS_PER_UNIT;
+  result->x = (v.x * f) / TPE_FRACTIONS_PER_UNIT;
+  result->y = (v.y * f) / TPE_FRACTIONS_PER_UNIT;
+  result->z = (v.z * f) / TPE_FRACTIONS_PER_UNIT;
+  result->w = (v.w * f) / TPE_FRACTIONS_PER_UNIT;
 }
 
 TPE_Unit TPE_vec3Len(TPE_Vec4 v)
@@ -327,45 +359,59 @@ void TPE_vec4Normalize(TPE_Vec4 v)
   v.w = (v.w * TPE_FRACTIONS_PER_UNIT) / l;
 }
 
-void TPE_vec3Project(const TPE_Vec4 v, const TPE_Vec4 base, TPE_Vec4 result)
+void TPE_vec3Project(const TPE_Vec4 v, const TPE_Vec4 base, TPE_Vec4 *result)
 {
   TPE_Unit p = TPE_vec3DotProduct(v,base);
 
-  result.x = (p * base.x) / TPE_FRACTIONS_PER_UNIT;
-  result.y = (p * base.y) / TPE_FRACTIONS_PER_UNIT;
-  result.z = (p * base.z) / TPE_FRACTIONS_PER_UNIT;
+  result->x = (p * base.x) / TPE_FRACTIONS_PER_UNIT;
+  result->y = (p * base.y) / TPE_FRACTIONS_PER_UNIT;
+  result->z = (p * base.z) / TPE_FRACTIONS_PER_UNIT;
 }
 
-TPE_Unit TPE_sqrt(TPE_Unit value)
+void TPE_getVelocitiesAfterCollision(
+  TPE_Unit *v1,
+  TPE_Unit *v2,
+  TPE_Unit m1,
+  TPE_Unit m2,
+  TPE_Unit elasticity
+)
 {
-  int8_t sign = 1;
+  /* in the following a lot of TPE_FRACTIONS_PER_UNIT cancel out, feel free to
+     check if confused */
 
-  if (value < 0)
+  #define ANTI_OVERFLOW 30000
+  #define ANTI_OVERFLOW_SCALE 128
+
+  uint8_t overflowDanger = m1 > ANTI_OVERFLOW || *v1 > ANTI_OVERFLOW ||
+    m2 > ANTI_OVERFLOW || *v2 > ANTI_OVERFLOW;
+
+  if (overflowDanger)
   {
-    sign = -1;
-    value *= -1;
+    m1 = (m1 != 0) ? TPE_nonZero(m1 / ANTI_OVERFLOW_SCALE) : 0;
+    m2 = (m2 != 0) ? TPE_nonZero(m2 / ANTI_OVERFLOW_SCALE) : 0;
+    *v1 = (*v1 != 0) ? TPE_nonZero(*v1 / ANTI_OVERFLOW_SCALE) : 0;
+    *v2 = (*v2 != 0) ? TPE_nonZero(*v2 / ANTI_OVERFLOW_SCALE) : 0;
   }
 
-  uint32_t result = 0;
-  uint32_t a = value;
-  uint32_t b = 1u << 30;
+  TPE_Unit m1Pm2 = m1 + m2;
+  TPE_Unit v2Mv1 = *v2 - *v1;
 
-  while (b > a)
-    b >>= 2;
+  TPE_Unit m1v1Pm2v2 = ((m1 * *v1) + (m2 * *v2));
 
-  while (b != 0)
-  {
-    if (a >= result + b)
-    {
-      a -= result + b;
-      result = result +  2 * b;
-    }
+  *v1 = (((elasticity * m2 / TPE_FRACTIONS_PER_UNIT) * v2Mv1)
+    + m1v1Pm2v2) / m1Pm2;
 
-    b >>= 2;
-    result >>= 1;
+  *v2 = (((elasticity * m1 / TPE_FRACTIONS_PER_UNIT) * -1 * v2Mv1)
+    + m1v1Pm2v2) / m1Pm2;
+
+  if (overflowDanger)
+  {
+    *v1 *= ANTI_OVERFLOW_SCALE;
+    *v2 *= ANTI_OVERFLOW_SCALE;
   }
 
-  return result * sign;
+  #undef ANTI_OVERFLOW
+  #undef ANTI_OVERFLOW_SCALE
 }
 
 void TPE_resolvePointCollision(
@@ -388,14 +434,14 @@ void TPE_resolvePointCollision(
 
   // add lin. and rot. velocities to get the overall vel. of both points:
 
-  TPE_vec4Add(linVelocity1,rotVelocity1,v1);
-  TPE_vec4Add(linVelocity2,rotVelocity2,v2);
+  TPE_vec4Add(linVelocity1,rotVelocity1,&v1);
+  TPE_vec4Add(linVelocity2,rotVelocity2,&v2);
 
   /* project both of these velocities to the collision normal as we'll apply
      the collision equation only in the direction of this normal: */
 
-  TPE_vec3Project(v1,collisionNormal,v1New);
-  TPE_vec3Project(v2,collisionNormal,v2New);
+  TPE_vec3Project(v1,collisionNormal,&v1New);
+  TPE_vec3Project(v2,collisionNormal,&v2New);
 
   // get the velocities of the components
 
@@ -407,8 +453,8 @@ void TPE_resolvePointCollision(
      will now be in the collision plane), we'll later add back the updated
      velocity to it */
 
-  TPE_vec4Substract(v1,v1New,v1); 
-  TPE_vec4Substract(v2,v2New,v2); 
+  TPE_vec4Substract(v1,v1New,&v1); 
+  TPE_vec4Substract(v2,v2New,&v2); 
 
   // apply the 1D collision equation to velocities along the normal:
 
@@ -434,51 +480,6 @@ void TPE_resolvePointCollision(
 // TODO
 }
 
-void TPE_getVelocitiesAfterCollision(
-  TPE_Unit *v1,
-  TPE_Unit *v2,
-  TPE_Unit m1,
-  TPE_Unit m2,
-  TPE_Unit elasticity
-)
-{
-  /* in the following a lot of TPE_FRACTIONS_PER_UNIT cancel out, feel free to
-     check if confused */
-
-  #define ANTI_OVERFLOW 30000
-  #define ANTI_OVERFLOW_SCALE 128
-
-  uint8_t overflowDanger = m1 > ANTI_OVERFLOW || *v1 > ANTI_OVERFLOW ||
-    m2 > ANTI_OVERFLOW || *v2 > ANTI_OVERFLOW;
-
-  if (overflowDanger)
-  {
-    m1 = (m1 != 0) ? TPE_nonZero(m1 / ANTI_OVERFLOW_SCALE) : 0;
-    m2 = (m2 != 0) ? TPE_nonZero(m2 / ANTI_OVERFLOW_SCALE) : 0;
-    *v1 = (*v1 != 0) ? TPE_nonZero(*v1 / ANTI_OVERFLOW_SCALE) : 0;
-    *v2 = (*v2 != 0) ? TPE_nonZero(*v2 / ANTI_OVERFLOW_SCALE) : 0;
-  }
-
-  TPE_Unit m1Pm2 = m1 + m2;
-  TPE_Unit v2Mv1 = *v2 - *v1;
-
-  TPE_Unit m1v1Pm2v2 = ((m1 * *v1) + (m2 * *v2));
-
-  *v1 = (((elasticity * m2 / TPE_FRACTIONS_PER_UNIT) * v2Mv1)
-    + m1v1Pm2v2) / m1Pm2;
-
-  *v2 = (((elasticity * m1 / TPE_FRACTIONS_PER_UNIT) * -1 * v2Mv1)
-    + m1v1Pm2v2) / m1Pm2;
-
-  if (overflowDanger)
-  {
-    *v1 *= ANTI_OVERFLOW_SCALE;
-    *v2 *= ANTI_OVERFLOW_SCALE;
-  }
-
-  #undef ANTI_OVERFLOW
-  #undef ANTI_OVERFLOW_SCALE
-}
 
 
 #endif // guard