1 module godot.vector;
2 
3 public import godot.vector2: Vector2, Vector2i;
4 public import godot.vector3: Vector3, Vector3i;
5 public import godot.vector4: Vector4, Vector4i;
6 
7 alias vec2 = Vector2;
8 alias ivec2 = Vector2i;
9 alias vec3 = Vector3;
10 alias ivec3 = Vector3i;
11 alias vec4 = Vector4;
12 alias ivec4 = Vector4i;
13 
14 //
15 // import std.traits;
16 //
17 // /// Vector structure with data accesible with `[N]` or swizzling
18 // struct Vector(T, size_t N) if (isNumeric!T && N > 0)  {
19 //     /// Vector data
20 //     public T[N] data = [ 0 ];
21 //
22 //     /// Alias to allow easy `data` access
23 //     alias data this;
24 //     /// Alias to data type (e.g. float, int)
25 //     alias dataType = T;
26 //     /** 
27 //     Alias to vector type. Can be used to contruct vectors
28 //     of same type
29 //     ---
30 //     auto rvec7 = Vector!(real, 7)(10);
31 //     auto rvec7s = rvec7.VecType(20);
32 //     ---
33 //     */
34 //     alias VecType = Vector!(T, N);
35 //     /// Alias to vector size
36 //     enum size_t size = N;
37 //
38 //     /**
39 //     Constructs Vector from components. If no components present
40 //     vector will be filled with 0
41 //     Example:
42 //     ---
43 //     // Vector can be constructed manually or with aliases
44 //     auto v1 = Vector!(int, 2)(10, 20);
45 //     auto v2 = ivec2(10, 20);
46 //     auto v3 = Vector2i(10, 20);
47 //     auto v4 = Vector2!int(10, 20);
48 //     // Also vector can be given only one value,
49 //     // in that case it'll be filled with that value
50 //     auto v5 = ivec4(13);
51 //     auto v6 = vec4(0.3f);
52 //     // Vector values can be accessed with array slicing,
53 //     // by using color symbols or swizzling
54 //     float v6x = v6.x;
55 //     float v6z = v6.z;
56 //     float[] v6yzx = v6.yzx;
57 //     float v6y = v6[1];
58 //     // Valid vector accessors are:
59 //     // Vector2 - [x, y], [w, h], [u, v]
60 //     // Vector3 - [x, y, z], [w, h, d], [u, v, t], [r, g, b]
61 //     // Vector4 - [x, y, z, w], [r, g, b, a]
62 //     // Other sizes must be accessed with index
63 //     ---
64 //     */
65 //     this(in T val) {
66 //         foreach (i; 0 .. size) { data[i] = val; }
67 //     }
68 //     /// Ditto
69 //     this(in T[N] vals...) {
70 //         data = vals;
71 //     }
72 //
73 //     /* -------------------------------------------------------------------------- */
74 //     /*                         UNARY OPERATIONS OVERRIDES                         */
75 //     /* -------------------------------------------------------------------------- */
76 //     
77 //     /// opBinary x [+, -, *, /, %] y
78 //     auto opBinary(string op, R)(in Vector!(R, N) b) const if ( isNumeric!R ) {
79 //         // assert(/* this !is null && */ b !is null, "\nOP::ERROR nullptr Vector!" ~ size.to!string ~ ".");
80 //         VecType ret = VecType();
81 //         foreach (i; 0 .. size) { mixin( "data[i] = data[i] " ~ op ~ " b.data[i];" ); }
82 //         return ret;
83 //     }
84 //
85 //     /// Ditto
86 //     auto opBinaryRight(string op, R)(in Vector!(R, N) b) const if ( isNumeric!R ) {
87 //         // assert(/* this !is null && */ b !is null, "\nOP::ERROR nullptr Vector!" ~ size.to!string ~ ".");
88 //         VecType ret = VecType();
89 //         foreach (i; 0 .. size) { mixin( "ret[i] = b.data[i] " ~ op ~ " data[i];" ); }
90 //         return ret;
91 //     }
92 //
93 //     /// Ditto
94 //     auto opBinary(string op, R)(in R b) const if ( isNumeric!R ) {
95 //         // assert(this !is null, "\nOP::ERROR nullptr Vector!" ~ size.to!string ~ ".");
96 //         VecType ret = VecType();
97 //         foreach (i; 0 .. size) { mixin( "data[i] = data[i] " ~ op ~ " b;" ); }
98 //         return ret;
99 //     }
100 //
101 //     /// Ditto
102 //     auto opBinaryRight(string op, R)(in R b) const if ( isNumeric!R ) {
103 //         // assert(this !is null, "\nOP::ERROR nullptr Vector!" ~ size.to!string ~ ".");
104 //         VecType ret = VecType();
105 //         foreach (i; 0 .. size) { mixin( "ret[i] = b " ~ op ~ " data[i];" ); }
106 //         return ret;
107 //     }
108 //
109 //     /// opEquals x == y
110 //     bool opEquals(R)(in Vector!(R, size) b) const if ( isNumeric!R ) {
111 //         // assert(/* this !is null && */ b !is null, "\nOP::ERROR nullptr Vector!" ~ size.to!string ~ ".");
112 //         bool eq = true;
113 //         foreach (i; 0 .. size) { eq = eq && data[i] == b.data[i]; }
114 //         return eq;
115 //     }
116 //
117 //     /// opCmp x [< > <= >=] y
118 //     int opCmp(R)(in Vector!(R, N) b) const if ( isNumeric!R ) {
119 //         // assert(/* this !is null && */ b !is null, "\nOP::ERROR nullptr Vector!" ~ size.to!string ~ ".");
120 //         T al = length;
121 //         T bl = b.length;
122 //         if (al == bl) return 0;
123 //         if (al < bl) return -1;
124 //         return 1;
125 //     }
126 //
127 //     /// opUnary [-, +, --, ++] x
128 //     auto opUnary(string op)() if(op == "-"){
129 //         // assert(this !is null, "\nOP::ERROR nullptr Vector!" ~ size.to!string ~ ".");
130 //         VecType ret = VecType();
131 //         if (op == "-")
132 //             foreach (i; 0 .. size) { data[i] = -data[i]; }
133 //         return ret;
134 //     }
135 //     
136 //     /// opOpAssign x [+, -, *, /, %]= y
137 //     auto opOpAssign(string op, R)( in Vector!(R, N) b ) if ( isNumeric!R ) { 
138 //         // assert(/* this !is null && */ b !is null, "\nOP::ERROR nullptr Vector!" ~ size.to!string ~ ".");
139 //         foreach (i; 0 .. size) { mixin( "data[i] = data[i] " ~ op ~ " b.data[i];" ); }
140 //         return this;
141 //     }
142 //     
143 //     /// Ditto
144 //     auto opOpAssign(string op, R)( in R b ) if ( isNumeric!R ) { 
145 //         // assert(this !is null, "\nOP::ERROR nullptr Vector!" ~ size.to!string ~ ".");
146 //         foreach (i; 0 .. size) { mixin( "data[i] = data[i] " ~ op ~ " b;" ); }
147 //         return this;
148 //     }
149 //
150 //     /// Returns hash 
151 //     size_t toHash() const @safe nothrow {
152 //         return typeid(data).getHash(&data);
153 //     }
154 //
155 //     // incredible magic from sily.meta
156 //     // idk how it works but it works awesome
157 //     // and im not going to touch it at all
158 //     static if (N == 2 || N == 3 || N == 4) {
159 //         static if (N == 2) enum AccessString = "x y|w h|u v"; 
160 //         else
161 //         static if (N == 3) enum AccessString = "x y z|w h d|u v t|r g b"; 
162 //         else
163 //         static if (N == 4) enum AccessString = "x y z w|r g b a"; 
164 //
165 //         mixin accessByString!(T, N, "data", AccessString); 
166 //     }
167 //
168 //     /// Returns copy of vector
169 //     public VecType copyof() {
170 //         return VecType(data);
171 //     }
172 //
173 //     /// Returns string representation of vector: `[1.00, 1.00,... , 1.00]`
174 //     public string toString() const {
175 //         import std.conv : to;
176 //         import std.string: format;
177 //         string s;
178 //         s ~= "[";
179 //         foreach (i; 0 .. size) {
180 //             s ~= isFloatingPoint!T ? format("%.2f", data[i]) : format("%d", data[i]);
181 //             if (i != size - 1) s ~= ", ";
182 //         }
183 //         s ~= "]";
184 //         return s;
185 //     }
186 //
187 //     /// Returns pointer to data
188 //     T* ptr() return {
189 //         return data.ptr;
190 //     }
191 //
192 //     /* ------------------------------ Godot Vectors ----------------------------- */
193 //
194 //     static if(N == 2) {
195 //         static if (isFloatingPoint!T) {
196 //             Vector2 godotVector() {
197 //                 return Vector2(data);
198 //             }
199 //         } else {
200 //             Vector2i godotVector() {
201 //                 return Vector2i(data);
202 //             }
203 //         }
204 //     }
205 //
206 //     static if(N == 3) {
207 //         static if (isFloatingPoint!T) {
208 //             Vector3 godotVector() {
209 //                 return Vector3(data);
210 //             }
211 //         } else {
212 //             Vector3i godotVector() {
213 //                 return Vector3i(data);
214 //             }
215 //         }
216 //     }
217 //
218 //     static if(N == 4) {
219 //         static if (isFloatingPoint!T) {
220 //             Vector4 godotVector() {
221 //                 return Vector4(data);
222 //             }
223 //         } else {
224 //             Vector4i godotVector() {
225 //                 return Vector4i(data);
226 //             }
227 //         }
228 //     }
229 //
230 //     /* -------------------------------------------------------------------------- */
231 //     /*                         STATIC GETTERS AND SETTERS                         */
232 //     /* -------------------------------------------------------------------------- */
233 //     
234 //     /// Constructs predefined vector
235 //     static alias zero  = () => VecType(0);
236 //     /// Ditto
237 //     static alias one   = () => VecType(1);
238 //
239 //     static if(isFloatingPoint!T) {
240 //         /// Ditto
241 //         static alias inf   = () => VecType(float.infinity);
242 //     }
243 //
244 //     static if(N == 2) {
245 //         /// Ditto
246 //         static alias left  = () => VecType(-1, 0);
247 //         /// Ditto
248 //         static alias right = () => VecType(1, 0);
249 //         /// Ditto
250 //         static alias up    = () => VecType(0, -1);
251 //         /// Ditto
252 //         static alias down  = () => VecType(0, 1);
253 //     }
254 //
255 //     static if(N == 3) {
256 //         static alias forward = () => VecType(0, 0, -1);
257 //         /// Ditto
258 //         static alias back    = () => VecType(0, 0, 1);
259 //         /// Ditto
260 //         static alias left    = () => VecType(-1, 0, 0);
261 //         /// Ditto
262 //         static alias right   = () => VecType(1, 0, 0);
263 //         /// Ditto
264 //         static alias up      = () => VecType(0, 1, 0);
265 //         /// Ditto
266 //         static alias down    = () => VecType(0, -1, 0);
267 //     }
268 // }