1 module nudsfml.system.vector3;
2 
3 import std.traits;
4 
5 /**
6  * Utility template struct for manipulating 3-dimensional vectors.
7  */
8 struct Vector3(T)
9 	if(isNumeric!(T) || is(T == bool))
10 {
11 	/// X coordinate of the vector.
12 	T x;
13 
14 	/// Y coordinate of the vector.
15 	T y;
16 
17 	/// Z coordinate of the vector.
18 	T z;
19 
20 	/**
21 	 * Construct the vector from its coordinates
22 	 *
23 	 * Params:
24 	 * 		X = X coordinate
25 	 * 		Y = Y coordinate
26 	 * 		Z = Z coordinate
27 	 */
28 	this(T X,T Y,T Z)
29 	{
30 
31 		x = X;
32 		y = Y;
33 		z = Z;
34 
35 	}
36 
37 	/**
38 	 * Construct the vector from another type of vector
39 	 *
40 	 * Params:
41 	 * 	otherVector = Vector to convert.
42 	 */
43 	this(E)(Vector3!(E) otherVector)
44 	{
45 		x = cast(T)(otherVector.x);
46 		y = cast(T)(otherVector.y);
47 		z = cast(T)(otherVector.z);
48 	}
49 
50 	/// Invert the members of the vector.
51 	Vector3!(T) opUnary(string s)() const
52 	if(s == "-")
53 	{
54 		return Vector3!(T)(-x,-y,-z);
55 	}
56 
57 	/// Add/Subtract between two vector3's.
58 	Vector3!(T) opBinary(string op,E)(Vector3!(E) otherVector) const
59 	if(isNumeric!(E) && ((op == "+") || (op == "-")))
60 	{
61 		static if (op == "+")
62 		{
63 			return Vector3!(T)(cast(T)(x+otherVector.x),cast(T)(y+otherVector.y),cast(T)(z + otherVector.z));
64 		}
65 		static if(op == "-")
66 		{
67 			return Vector3!(T)(cast(T)(x-otherVector.x),cast(T)(y-otherVector.y),cast(T)(z - otherVector.z));
68 		}
69 	}
70 
71 	/// Multiply/Divide a Vector3 with a numaric value.
72 	Vector3!(T) opBinary(string op,E)(E num) const
73 	if(isNumeric!(E) && ((op == "*") || (op == "/")))
74 	{
75 		static if (op == "*")
76 		{
77 			return Vector3!(T)(cast(T)(x*num),cast(T)(y*num),cast(T)(z*num));
78 		}
79 		static if(op == "/")
80 		{
81 			return Vector3!(T)(cast(T)(x/num),cast(T)(y/num),cast(T)(z/num));
82 		}
83 	}
84 
85 	/// Assign Add/Subtract with another vector3.
86 	ref Vector3!(T) opOpAssign(string op, E)(Vector3!(E) otherVector)
87 	if(isNumeric!(E) && ((op == "+") || (op == "-")))
88 	{
89 		static if(op == "+")
90 		{
91 			x += otherVector.x;
92 			y += otherVector.y;
93 			z += otherVector.z;
94 			return this;
95 		}
96 		static if(op == "-")
97 		{
98 			x -= otherVector.x;
99 			y -= otherVector.y;
100 			z -= otherVector.z;
101 			return this;
102 		}
103 	}
104 
105 	// Assign Multiply/Divide a Vector3 with a numaric value.
106 	ref Vector3!(T) opOpAssign(string op,E)(E num)
107 	if(isNumeric!(E) && ((op == "*") || (op == "/")))
108 	{
109 		static if(op == "*")
110 		{
111 			x *= num;
112 			y *= num;
113 			z *= num;
114 			return this;
115 		}
116 		static if(op == "/")
117 		{
118 			x /= num;
119 			y /= num;
120 			z /= num;
121 			return this;
122 		}
123 	}
124 
125 	/// Assign the value of another vector whose type can be converted to T.
126 	ref Vector3!(T) opAssign(E)(Vector3!(E) otherVector)
127 	{
128 		x = cast(T)(otherVector.x);
129 		y = cast(T)(otherVector.y);
130 		z = cast(T)(otherVector.z);
131 		return this;
132 	}
133 
134 	/// Compare two vectors for equality.
135 	bool opEquals(E)(const Vector3!(E) otherVector) const
136 	if(isNumeric!(E))
137 	{
138 		return ((x == otherVector.x) && (y == otherVector.y)
139 				&& (z == otherVector.z));
140 	}
141 
142 	/// Output the string representation of the Vector3.
143 	string toString() const
144 	{
145 		import std.conv;
146 		return "X: " ~ text(x) ~ " Y: " ~ text(y) ~ " Z: " ~ text(z);
147 	}
148 }
149 
150 /// Definition of a Vector3 of integers.
151 alias Vector3i = Vector3!(int);
152 
153 /// Definition of a Vector3 of floats.
154 alias Vector3f = Vector3!(float);