Miloslav Ciz hace 3 años
padre
commit
6c00bcc0e5
Se han modificado 2 ficheros con 70 adiciones y 82 borrados
  1. 8 42
      main.c
  2. 62 40
      tinyphysicsengine.h

+ 8 - 42
main.c

@@ -36,7 +36,7 @@ TPE_Vec3 environmentDistance(TPE_Vec3 p, TPE_Unit distLim)
   r = c; if (p.x == r.x && p.y == r.y && p.z == r.z) return p; \
   d = TPE_DISTANCE(p,r); if (d < dMin) { dMin = d; rMin = r; }
 
-  testShape( TPE_envAABoxInside(p,TPE_vec3(0,0,0),TPE_vec3(8000,6000,8000)) )
+  testShape( TPE_envAABoxInside(p,TPE_vec3(0,0,0),TPE_vec3(16000,6000,16000)) )
   testShape( TPE_envSphere(p,TPE_vec3(2000,-3500,2000),2000) )
   testShape( TPE_envSphere(p,TPE_vec3(-2000,-3500,0),2000) )
 
@@ -154,41 +154,6 @@ void drawBody(TPE_Body *body, uint8_t color)
   }
 }
 
-void drawEnv(TPE_Vec3 p, int stepLength, int steps)
-{
-  TPE_Vec3 p2 = p;
-
-  for (int k = 0; k < steps; ++k)
-  {
-    p2.y = p.y;
-
-    for (int j = 0; j < steps; ++j)
-    {
-      p2.x = p.x;
-
-      for (int i = 0; i < steps; ++i)
-      {
-        TPE_Vec3 p3 = environmentDistance(p2,10000000);
-
-        S3L_Vec4 p4, p5;
-        p4.x = p3.x;
-        p4.y = p3.y;
-        p4.z = p3.z;
-
-        S3L_project3DPointToScreen(p4,sphereScene.camera,&p5);
-
-        draw2DPoint(p5.x,p5.y,100,200,255);
-
-        p2.x += stepLength;
-      }
-
-      p2.y += stepLength;
-    }
-
-    p2.z += stepLength;
-  }
-}
-
 #define SPHERE_VERTEX_COUNT 42
 const S3L_Unit sphereVertices[SPHERE_VERTEX_COUNT * 3] = {
       0,  -512,     0,        // 0
@@ -346,33 +311,35 @@ int main(void)
 TPE_Joint joints[100];
 TPE_Connection connections[100];
 
+#define MASS 200
+
 switch (1)
 {
   case 0:
     TPE_make2Line(joints,connections,1500,512);
-    TPE_bodyInit(bodies,joints,2,connections,1,100);
+    TPE_bodyInit(bodies,joints,2,connections,1,MASS);
     break;
 
   case 1:
     TPE_makeBox(joints,connections,1000,1000,1000,200);
-    TPE_bodyInit(bodies,joints,8,connections,16,100);
+    TPE_bodyInit(bodies,joints,8,connections,16,MASS);
     break;
 
   case 2:
     TPE_makeCenterRect(joints,connections,1300,1000,512);
-    TPE_bodyInit(bodies,joints,5,connections,8,100);
+    TPE_bodyInit(bodies,joints,5,connections,8,MASS);
     break;
 
   case 3:
     TPE_makeCenterBox(joints,connections,1000,1000,1000,512);
     joints[8].sizeDivided *= 3;
     joints[8].sizeDivided /= 2;
-    TPE_bodyInit(bodies,joints,9,connections,18,100);
+    TPE_bodyInit(bodies,joints,9,connections,18,MASS);
     break;
 
   case 4:
     TPE_makeTriangle(joints,connections,2000,512);
-    TPE_bodyInit(bodies,joints,3,connections,3,100);
+    TPE_bodyInit(bodies,joints,3,connections,3,MASS);
     break;
 
   default: break;
@@ -571,7 +538,6 @@ if (state[SDL_SCANCODE_Y])
 else if (state[SDL_SCANCODE_H])
   TPE_bodyAccelerate(bodies,TPE_vec3(0,0,-10));
 
-
 #define SHIFT_STEP 50
 
     if (state[SDL_SCANCODE_P])

+ 62 - 40
tinyphysicsengine.h

@@ -41,6 +41,48 @@ typedef int32_t TPE_Unit;
   #define TPE_LOG(s) ;
 #endif
 
+
+
+#ifndef TPE_LOW_SPEED
+/** Speed, in TPE_Units per ticks, that is considered low (used e.g. for auto
+disabling bodies). */
+  #define TPE_LOW_SPEED 30
+#endif
+
+#ifndef TPE_RESHAPE_TENSION_LIMIT
+/** Tension limit, in TPE_Units, after which a non-soft body will be reshaped.
+Smaller number will keep more stable shapes but will cost more performance. */
+  #define TPE_RESHAPE_TENSION_LIMIT 20
+#endif
+
+#ifndef TPE_RESHAPE_ITERATIONS
+/** How many iterations of reshaping will be performed by the step function if
+the body's shape needs to be reshaped. Greater number will keep shapes more
+stable but will cost some performance. */
+  #define TPE_RESHAPE_ITERATIONS 3
+#endif
+
+#ifndef TPE_DISABLE_AFTER
+/** After how many ticks of low speed should a body be disabled. This mustn't
+be greater than 255. */
+  #define TPE_DISABLE_AFTER 64
+#endif
+
+#ifndef TPE_TENSION_ACCELERATION_DIVIDER
+/** Number by which the base acceleration (TPE_FRACTIONS_PER_UNIT per tick
+squared) caused by the connection tension will be divided. This should be power
+of 2. */
+  #define TPE_TENSION_ACCELERATION_DIVIDER 32
+#endif
+
+#ifndef TPE_TENSION_ACCELERATION_THRESHOLD
+/** Limit within which acceleration caused by connection tension won't be
+  applied. */
+  #define TPE_TENSION_ACCELERATION_THRESHOLD 5
+#endif
+
+
+
 #define TPE_PRINTF_VEC3(v) printf("[%d %d %d]",(v).x,(v).y,(v).z);
 
 typedef struct
@@ -524,46 +566,32 @@ void TPE_worldStep(TPE_World *world)
       len = (len * TPE_FRACTIONS_PER_UNIT) /
         connection->length - TPE_FRACTIONS_PER_UNIT;
 
-bodyTension += len > 0 ? len : -len;
+      bodyTension += len > 0 ? len : -len;
 
-
-      if (  len > 5 || len < -5   ) //len != 0) // TODO: magic
+      if (
+        len > TPE_TENSION_ACCELERATION_THRESHOLD || 
+        len < -1 * TPE_TENSION_ACCELERATION_THRESHOLD)
       {
 
-TPE_vec3Normalize(&dir);
-
-dir.x /= 32;
-dir.y /= 32;
-dir.z /= 32;
-
-if (len < 0)
-{
-  dir.x *= -1;
-  dir.y *= -1;
-  dir.z *= -1;
-}
-
-joint->velocity[0] += dir.x;
-joint->velocity[1] += dir.y;
-joint->velocity[2] += dir.z;
-joint2->velocity[0] -= dir.x;
-joint2->velocity[1] -= dir.y;
-joint2->velocity[2] -= dir.z;
+        TPE_vec3Normalize(&dir);
 
+        dir.x /= TPE_TENSION_ACCELERATION_DIVIDER;
+        dir.y /= TPE_TENSION_ACCELERATION_DIVIDER;
+        dir.z /= TPE_TENSION_ACCELERATION_DIVIDER;
 
-/*
-        dir.x = (dir.x * len) / (2 * TPE_FRACTIONS_PER_UNIT);
-        dir.y = (dir.y * len) / (2 * TPE_FRACTIONS_PER_UNIT);
-        dir.z = (dir.z * len) / (2 * TPE_FRACTIONS_PER_UNIT);
+        if (len < 0)
+        {
+          dir.x *= -1;
+          dir.y *= -1;
+          dir.z *= -1;
+        }
 
         joint->velocity[0] += dir.x;
         joint->velocity[1] += dir.y;
         joint->velocity[2] += dir.z;
-
         joint2->velocity[0] -= dir.x;
         joint2->velocity[1] -= dir.y;
         joint2->velocity[2] -= dir.z;
-*/
       }
 
       connection++;
@@ -575,27 +603,21 @@ joint2->velocity[2] -= dir.z;
 
       bodyTension /= body->connectionCount;
     
-      if (bodyTension > 20)
-      {
-        TPE_bodyReshape(body,world->environmentFunction);
-        TPE_bodyReshape(body,world->environmentFunction);
-//        TPE_bodyReshape(body,world->environmentFunction);
-//        TPE_bodyReshape(body,world->environmentFunction);
-      }
+      if (bodyTension > TPE_RESHAPE_TENSION_LIMIT)
+        for (uint8_t k = 0; k < TPE_RESHAPE_ITERATIONS; ++k) 
+          TPE_bodyReshape(body,world->environmentFunction);
     }
 
-if (body->disableCount >= 64)
+    if (body->disableCount >= TPE_DISABLE_AFTER)
     {
+      TPE_bodyStop(body);
       body->disableCount = 0;
       body->flags |= TPE_BODY_FLAG_DEACTIVATED;
     }
-    else if (TPE_bodyAverageSpeed(body) <= 30) // TODO: magic + optimize
-    {
+    else if (TPE_bodyAverageSpeed(body) <= TPE_LOW_SPEED) // TODO: optimize
       body->disableCount++;
-    }
     else
       body->disableCount = 0;
-
   }
 }