blueloveTH hace 2 años
padre
commit
d06a146fb2
Se han modificado 1 ficheros con 40 adiciones y 17 borrados
  1. 40 17
      src/linalg.cpp

+ 40 - 17
src/linalg.cpp

@@ -41,8 +41,8 @@ namespace pkpy{
         });
         });
 
 
 
 
-// https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/Math/Mathf.cs#L309
-static float SmoothDamp(float current, float target, float& currentVelocity, float smoothTime, float maxSpeed, float deltaTime)
+// https://github.com/Unity-Technologies/UnityCsReference/blob/master/Runtime/Export/Math/Vector2.cs#L289
+static Vec2 SmoothDamp(Vec2 current, Vec2 target, PyVec2& currentVelocity, float smoothTime, float maxSpeed, float deltaTime)
 {
 {
     // Based on Game Programming Gems 4 Chapter 1.10
     // Based on Game Programming Gems 4 Chapter 1.10
     smoothTime = std::max(0.0001F, smoothTime);
     smoothTime = std::max(0.0001F, smoothTime);
@@ -50,26 +50,50 @@ static float SmoothDamp(float current, float target, float& currentVelocity, flo
 
 
     float x = omega * deltaTime;
     float x = omega * deltaTime;
     float exp = 1.0F / (1.0F + x + 0.48F * x * x + 0.235F * x * x * x);
     float exp = 1.0F / (1.0F + x + 0.48F * x * x + 0.235F * x * x * x);
-    float change = current - target;
-    float originalTo = target;
+
+    float change_x = current.x - target.x;
+    float change_y = current.y - target.y;
+    Vec2 originalTo = target;
 
 
     // Clamp maximum speed
     // Clamp maximum speed
     float maxChange = maxSpeed * smoothTime;
     float maxChange = maxSpeed * smoothTime;
-    change = std::clamp(change, -maxChange, maxChange);
-    target = current - change;
 
 
-    float temp = (currentVelocity + omega * change) * deltaTime;
-    currentVelocity = (currentVelocity - omega * temp) * exp;
-    float output = target + (change + temp) * exp;
+    float maxChangeSq = maxChange * maxChange;
+    float sqDist = change_x * change_x + change_y * change_y;
+    if (sqDist > maxChangeSq)
+    {
+        float mag = std::sqrt(sqDist);
+        change_x = change_x / mag * maxChange;
+        change_y = change_y / mag * maxChange;
+    }
+
+    target.x = current.x - change_x;
+    target.y = current.y - change_y;
+
+    float temp_x = (currentVelocity.x + omega * change_x) * deltaTime;
+    float temp_y = (currentVelocity.y + omega * change_y) * deltaTime;
+
+    currentVelocity.x = (currentVelocity.x - omega * temp_x) * exp;
+    currentVelocity.y = (currentVelocity.y - omega * temp_y) * exp;
+
+    float output_x = target.x + (change_x + temp_x) * exp;
+    float output_y = target.y + (change_y + temp_y) * exp;
 
 
     // Prevent overshooting
     // Prevent overshooting
-    if (originalTo - current > 0.0F == output > originalTo)
+    float origMinusCurrent_x = originalTo.x - current.x;
+    float origMinusCurrent_y = originalTo.y - current.y;
+    float outMinusOrig_x = output_x - originalTo.x;
+    float outMinusOrig_y = output_y - originalTo.y;
+
+    if (origMinusCurrent_x * outMinusOrig_x + origMinusCurrent_y * outMinusOrig_y > 0)
     {
     {
-        output = originalTo;
-        currentVelocity = (output - originalTo) / deltaTime;
-    }
+        output_x = originalTo.x;
+        output_y = originalTo.y;
 
 
-    return output;
+        currentVelocity.x = (output_x - originalTo.x) / deltaTime;
+        currentVelocity.y = (output_y - originalTo.y) / deltaTime;
+    }
+    return Vec2(output_x, output_y);
 }
 }
 
 
     void PyVec2::_register(VM* vm, PyObject* mod, PyObject* type){
     void PyVec2::_register(VM* vm, PyObject* mod, PyObject* type){
@@ -94,9 +118,8 @@ static float SmoothDamp(float current, float target, float& currentVelocity, flo
             float smooth_time = CAST_F(args[3]);
             float smooth_time = CAST_F(args[3]);
             float max_speed = CAST_F(args[4]);
             float max_speed = CAST_F(args[4]);
             float delta_time = CAST_F(args[5]);
             float delta_time = CAST_F(args[5]);
-            float x = SmoothDamp(current.x, target.x, current_velocity.x, smooth_time, max_speed, delta_time);
-            float y = SmoothDamp(current.y, target.y, current_velocity.y, smooth_time, max_speed, delta_time);
-            return VAR(Vec2(x, y));
+            Vec2 ret = SmoothDamp(current, target, current_velocity, smooth_time, max_speed, delta_time);
+            return VAR(ret);
         });
         });
 
 
         // @staticmethod
         // @staticmethod