1 module ecs_utils.math.vector;
2 
3 import ecs_utils.utils;
4 
5 struct vec2
6 {
7     this(float v) @nogc nothrow
8     {
9         x = v;
10         y = v;
11     }
12     
13     this(float x, float y) @nogc nothrow
14     {
15         this.x = x;
16         this.y = y;
17     }
18 
19     union
20     {
21         struct
22         {
23             float x;
24             float y;
25         }
26         float[2] data;
27     }
28 
29     vec2 opBinary(string op)(vec2 v)
30     {
31         static if (op == "+") return vec2(x + v.x, y + v.y);
32         else static if (op == "-") return vec2(x - v.x, y - v.y);
33         else static if (op == "*") return vec2(x * v.x, y * v.y);
34         else static if (op == "/") return vec2(x / v.x, y / v.y);
35         else static assert(0, "Operator "~op~" not implemented");
36     }
37 
38     vec2 opBinary(string op)(float v)
39     {
40         static if (op == "+") return vec2(x + v, y + v);
41         else static if (op == "-") return vec2(x - v, y - v);
42         else static if (op == "*") return vec2(x * v, y * v);
43         else static if (op == "/") return vec2(x / v, y / v);
44         else static assert(0, "Operator "~op~" not implemented");
45     }
46 
47     vec2 opUnary(string op)()if (op == "-")
48     {
49         return vec2(-x,-y);
50     }
51 
52     ivec2 opCast()
53     {
54         return ivec2(cast(int)x,cast(int)y);
55     }
56 
57     void opOpAssign(string op)(vec2 v)
58     {
59         static if (op == "+")
60         {
61             x += v.x;
62             y += v.y;
63         }
64         else static if (op == "-")
65         {
66             x -= v.x;
67             y -= v.y;
68         }
69         else static if (op == "*")
70         {
71             x *= v.x;
72             y *= v.y;
73         }
74         else static if (op == "/")
75         {
76             x /= v.x;
77             y /= v.y;
78         }
79         else static assert(0, "Operator "~op~" not implemented");
80     }
81 
82     float length2()
83     {
84         return x*x + y*y;
85     }
86 
87     float length()
88     {
89         return sqrtf(length2);
90     }
91 
92     float fastSqrLength()
93     {
94         return rsqrt(length2);
95     }
96 
97     vec2 normalize()
98     {
99         return this * fastSqrLength();
100     }
101 }
102 
103 float dot(vec2 a, vec2 b)
104 {
105     return a.x*b.x + a.y*b.y;
106 }
107 
108 struct vec4
109 {
110     union
111     {
112         struct
113         {
114             float x;
115             float y;
116             float z;
117             float w;
118         }
119         float[4] data;
120     }
121 
122     this(float v) @nogc nothrow
123     {
124         x = v;
125         y = v;
126         z = v;
127         w = v;
128     }
129 
130     this(float x, float y, float z, float w) @nogc nothrow
131     {
132         this.x = x;
133         this.y = y;
134         this.z = z;
135         this.w = w;
136     }
137 
138     vec4 opBinary(string op)(float v)
139     {
140         static if (op == "+") return vec4(x + v, y + v, z + v, w + v);
141         else static if (op == "-") return vec4(x - v, y - v, z - v, w - v);
142         else static if (op == "*") return vec4(x * v, y * v, z * v, w * v);
143         else static if (op == "/") return vec4(x / v, y / v, z / v, w / v);
144         else static assert(0, "Operator "~op~" not implemented");
145     }
146 }
147 
148 struct ivec2
149 {
150     union
151     {
152         struct
153         {
154             int x;
155             int y;
156         }
157         int[2] data;
158     }
159     
160     this(int v) @nogc nothrow
161     {
162         x = v;
163         y = v;
164     }
165 
166     this(int x, int y) @nogc nothrow
167     {
168         this.x = x;
169         this.y = y;
170     }
171 
172     ivec2 opBinary(string op, T)(T v)
173     {
174         static if (op == "+") return ivec2(x + v, y + v);
175         else static if (op == "-") return ivec2(x - v, y - v);
176         else static if (op == "*") return ivec2(x * v, y * v);
177         else static if (op == "/") return ivec2(x / v, y / v);
178         else static assert(0, "Operator "~op~" not implemented");
179     }
180 
181     vec2 opCast()
182     {
183         return vec2(x,y);
184     }
185 }
186 
187 struct ivec4
188 {
189     union
190     {
191         struct
192         {
193             int x;
194             int y;
195             int z;
196             int w;
197         }
198         int[4] data;
199     }
200 
201     this(int v) @nogc nothrow
202     {
203         x = v;
204         y = v;
205         z = v;
206         w = v;
207     }
208     
209     this(int x, int y, int z, int w) @nogc nothrow
210     {
211         this.x = x;
212         this.y = y;
213         this.z = z;
214         this.w = w;
215     }
216 }