1 module wavefront.geometry;
2 
3 import std.math;
4 import std.conv;
5 
6 
7 alias Vec2!float Vec2f;
8 alias Vec2!int   Vec2i;
9 alias Vec3!float Vec3f;
10 alias Vec3!int   Vec3i;
11 
12 struct Vec2(T) {
13 	union {
14 		struct { T u, v;};
15 		struct { T x, y;};
16 		T[2] raw;
17 	}
18 
19 	this (T _x, T _y)
20 	{
21 		x = _x;
22 		y = _y;
23 	}
24 
25 	Vec2!T opBinary(string op)(Vec2!T V) if (op == "+")
26 	{
27 		return Vec2!T(x+V.x, y+V.y);
28 	}
29 
30 	Vec2!T opBinary(string op)(Vec2!T V) if (op == "-")
31 	{
32 		return Vec2!T(x-V.x, y-V.y);
33 	}
34 
35 	Vec2!T opBinary(string op)(float f) if (op == "*")
36 	{
37 		return Vec2!T(cast(T)(x*f), cast(T)(y*f));
38 	}
39 
40 	string toString()
41 	{
42 		return "(" ~ to!string(x) ~ ", " ~ to!string(y) ~ ")";
43 	}
44 }
45 
46 struct Vec3(T) {
47 	union {
48 		struct { T x, y, z;};
49 		struct { T ivert, iuv, inorm;}
50 		T[3] raw;
51 	}
52 	
53 	this (T _x, T _y, T _z)
54 	{
55 		x = _x;
56 		y = _y;
57 		z = _z;
58 	}
59 
60 	auto opBinary(string op)(Vec3!T V) if (op == "^")
61 	{
62 		return Vec3(y*V.z-z*V.y, z*V.x-x*V.z, x*V.y-y*V.x);
63 	}
64 
65 	auto opBinary(string op)(Vec3!T V) if (op == "+")
66 	{
67 		return Vec3(x+V.x, x+V.x, z+V.z);
68 	}
69 	
70 	auto opBinary(string op)(Vec3!T V) if (op == "-")
71 	{
72 		return Vec3(x-V.x, y-V.y, z-V.z);
73 	}
74 
75 	auto opBinary(string op)(float f) if (op == "*")
76 	{
77 		return Vec3!T(cast(T)(x*f), cast(T)(y*f), cast(T)(z*f));
78 	}
79 
80 	auto opBinary(string op)(Vec3!T V) if (op == "*")
81 	{
82 		return x*V.x + y*V.y + z*V.z;
83 	}
84 
85 	auto norm ()
86 	{
87 		return sqrt(cast(float)x*x+y*y+z*z);
88 	}
89 
90 	auto normalize (T l=1)
91 	{
92 		this = this * cast(T)(l/norm());
93 		return this;
94 	}
95 
96 	string toString()
97 	{
98 		return "(" ~ to!string(x) ~ ", " ~ to!string(y) ~ ", " ~ to!string(z) ~ ")";
99 	}
100 }