소스 검색

Done adding Rotor3 logic

buckle2000 5 년 전
부모
커밋
c2534ed006
4개의 변경된 파일603개의 추가작업 그리고 449개의 파일을 삭제
  1. 13 4
      dub.json
  2. 4 0
      dub.selections.json
  3. 475 413
      source/raylib.d
  4. 111 32
      source/raymath.d

+ 13 - 4
dub.json

@@ -1,9 +1,18 @@
 {
+	"name": "raylib-d",
+	"description": "D binding for Raylib",
+	"license": "Zlib",
 	"authors": [
 		"ONROUNDIT"
 	],
 	"copyright": "Copyright (c) Ramon Santamaria (@raysan5), Petro Romanovych (@onroundit), Jan Hoenig (@m3m0ry)",
-	"description": "D binding for Raylib",
-	"license": "Zlib",
-	"name": "raylib-d"
-}
+	"configurations": [
+        {
+            "name": "unittest",
+            "dependencies": {
+                "fluent-asserts": "~>0.13.0",
+            }
+        }
+    ],	
+	"targetType": "sourceLibrary"
+}

+ 4 - 0
dub.selections.json

@@ -1,5 +1,9 @@
 {
 	"fileVersion": 1,
 	"versions": {
+		"ddmp": "0.0.1-0.dev.3",
+		"fluent-asserts": "0.13.3",
+		"libdparse": "0.14.0",
+		"stdx-allocator": "2.77.5"
 	}
 }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 475 - 413
source/raylib.d


+ 111 - 32
source/raymath.d

@@ -1,6 +1,13 @@
 import raylib;
 import std.math;
 
+pragma(inline, true):
+
+version (unittest)
+{
+    import fluent.asserts;
+}
+
 mixin template Linear()
 {
     import std.algorithm : canFind, map;
@@ -27,10 +34,45 @@ mixin template Linear()
         return mixin("T(" ~ fragment ~ ")");
     }
 
-    T opBinary(string op)(T rhs) if (["+", "-", "*", "/"].canFind(op))
+    static if (is(T == Rotor3))
     {
-        enum fragment = [FieldNameTuple!T].map!(field => field ~ op ~ "rhs." ~ field).join(",");
-        return mixin("T(" ~ fragment ~ ")");
+        /// Returns a rotor equivalent to first apply p, then apply q
+        Rotor3 opBinary(string op)(Rotor3 q) if (op == "*")
+        {
+            alias p = this;
+            Rotor3 r;
+            r.a = p.a * q.a - p.i * q.i - p.j * q.j - p.k * q.k;
+            r.i = p.i * q.a + p.a * q.i + p.j * q.k - p.k * q.j;
+            r.j = p.j * q.a + p.a * q.j + p.k * q.i - p.i * q.k;
+            r.k = p.k * q.a + p.a * q.k + p.i * q.j - p.j * q.i;
+            return r;
+        }
+
+        Vector3 opBinary(string op)(Vector3 v) if (op == "*")
+        {
+            Vector3 rv;
+            rv.x = a * v.x + xy * v.y - zx * v.z;
+            rv.y = a * v.y + yz * v.z - xy * v.x;
+            rv.z = a * v.z + zx * v.x - yz * v.y;
+            return rv;
+        }
+
+        Vector3 opBinaryRight(string op)(Vector3 v) if (op == "*")
+        {
+            Vector3 vr;
+            vr.x = v.x * a - v.y * xy + v.z * zx;
+            vr.y = v.y * a - v.z * yz + v.x * xy;
+            vr.z = v.z * a - v.x * zx + v.y * yz;
+            return vr;
+        }
+    }
+    else
+    {
+        T opBinary(string op)(T rhs) if (["+", "-"].canFind(op))
+        {
+            enum fragment = [FieldNameTuple!T].map!(field => field ~ op ~ "rhs." ~ field).join(",");
+            return mixin("T(" ~ fragment ~ ")");
+        }
     }
 
     T opBinary(string op)(float rhs) if (["+", "-", "*", "/"].canFind(op))
@@ -46,6 +88,14 @@ mixin template Linear()
     }
 }
 
+unittest
+{
+    Assert.equal(-Vector2(1, 2), Vector2(-1, -2));
+    Assert.equal(Vector3(1, 2, 9) + Vector3(3, 4, 9), Vector3(4, 6, 18));
+    Assert.equal(4.0f - Vector2.zero, Vector2(4, 4));
+    Assert.equal(Vector2.one - 3.0f, Vector2(-2, -2));
+}
+
 import std.traits : FieldNameTuple;
 import std.algorithm : map;
 import std.range : join;
@@ -56,7 +106,7 @@ float length(T)(T v)
     return mixin("sqrt(" ~ fragment ~ ")");
 }
 
-T normalize(T)(T v)
+T normal(T)(T v)
 {
     return v / v.length;
 }
@@ -66,18 +116,25 @@ float distance(T)(T lhs, T rhs)
     return (lhs - rhs).length;
 }
 
-T dot(T)(T lhs, T rhs)
+float dot(T)(T lhs, T rhs)
 {
-    return lhs * rhs;
+    enum fragment = [FieldNameTuple!T].map!(field => "lhs." ~ field ~ "*" ~ "rhs." ~ field).join(
+                "+");
+    return mixin(fragment);
 }
 
 unittest
 {
-    assert(-Vector2(1, 2) == Vector2(-1, -2));
-    assert(Vector3(1, 2, 9) + Vector3(3, 4, 9) == Vector3(4, 6, 18));
-    assert(4.0f - Vector2.zero == Vector2(4, 4));
-    assert(Vector2.one - 3.0f == Vector2(-2, -2));
-    assert(Vector2(3, 4).length == 5.0);
+    Assert.equal(Vector2(3, 4).length, 5);
+    Assert.equal(cast(const) Vector2(-3, 4).normal, Vector2(-3. / 5., 4. / 5.));
+    Assert.equal(cast(immutable) Vector2(9, 8).distance(Vector2(-3, 3)), 13);
+    Assert.equal(Vector3(2, 3, 4).dot(Vector3(4, 5, 6)), 47);
+    Assert.equal(Vector2.one.length, sqrt(2.0f));
+}
+
+unittest
+{
+    Assert.equal(Rotor3(1, 2, 3, 4), Rotor3(1, Bivector3(2, 3, 4)));
 }
 
 /// Mix `amount` of `lhs` with `1-amount` of `rhs`
@@ -89,17 +146,12 @@ T lerp(T)(T lhs, T rhs, float amount)
     return lhs + amount * (rhs - lhs);
 }
 
+/// angle betwenn vector and x-axis (+y +x -> positive)
 float angle(Vector2 v)
 {
     return atan2(v.y, v.x);
 }
 
-/// Rotate on imaginary plane
-Vector2 rotate(Vector2 lhs, Vector2 rhs)
-{
-    return Vector2(lhs.x * rhs.x - lhs.y * rhs.y, lhs.x * rhs.y + lhs.y * rhs.x);
-}
-
 Vector2 rotate(Vector2 v, float angle)
 {
     return Vector2(v.x * cos(angle) - v.y * sin(angle), v.x * sin(angle) + v.y * cos(angle));
@@ -107,22 +159,24 @@ Vector2 rotate(Vector2 v, float angle)
 
 Vector2 slide(Vector2 v, Vector2 along)
 {
-    return along.normalize * dot(v, along);
+    return along.normal * dot(v, along);
 }
 
 Bivector2 wedge(Vector2 lhs, Vector2 rhs)
 {
-    return Bivector2(lhs.x * rhs.y - lhs.y * rhs.x);
+    Bivector2 result = {xy: lhs.x * rhs.y - lhs.y * rhs.x};
+    return result;
 }
 
 // dfmt off
 Bivector3 wedge(Vector3 lhs, Vector3 rhs)
 {
-    return Bivector3(
-        lhs.y * rhs.z - lhs.z * rhs.y,
-        lhs.z * rhs.x - lhs.x * rhs.z,
-        lhs.x * rhs.y - lhs.y * rhs.x,
-    );
+    Bivector3 result = {
+        xy: lhs.x * rhs.y - lhs.y * rhs.x,
+        yz: lhs.y * rhs.z - lhs.z * rhs.y,
+        zx: lhs.z * rhs.x - lhs.x * rhs.z,
+    };
+    return result;
 }
 
 Vector3 transform(Vector3 v, Matrix4 mat)
@@ -142,14 +196,39 @@ Vector3 cross(Vector3 lhs, Vector3 rhs)
     return Vector3(v.yz, v.zx, v.xy);
 }
 
-// TODO implement rotor3
-// Vector3 rotate(Vector3 v, Rotor3 r) {
-//     return ;
-// }
+unittest {
+    // TODO
+}
+
+/// Returns a unit rotor that rotates `from` to `to`
+Rotor3 rotation(Vector3 from, Vector3 to)
+{
+    return Rotor3(1 + dot(to, from), wedge(to, from)).normal;
+}
+
+Rotor3 rotation(float angle, Bivector3 plane)
+{
+    return Rotor3(cos(angle / 2.0f), -sin(angle / 2.0f) * plane);
+}
+
+/// Rotate q by p
+Rotor3 rotate(Rotor3 p, Rotor3 q)
+{
+    return p * q * p.reverse;
+}
+
+/// Rotate v by r
+Vector3 rotate(Rotor3 r, Vector3 v)
+{
+    return r * v * r.reverse;
+}
+
+Rotor3 reverse(Rotor3 r)
+{
+    return Rotor3(r.a, -r.b);
+}
 
 unittest
 {
-    import std.format;
-    const v = Vector2.one;
-    assert(v.length == sqrt(2.0f), "%s %s".format(v,v.length));
-}
+    // TODO
+}

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.