added some unused code
[raymarch.git] / vecs.d
blob7f84a5f8a1402004b7adc8bfcca6a0e3a4e1b0e6
1 module vecs;
4 // ////////////////////////////////////////////////////////////////////////// //
5 // i don't want to create a new module for this
6 ubyte clampToByte(T) (T n) pure nothrow @safe @nogc if (__traits(isIntegral, T)) {
7 //static assert(!__traits(isUnsigned, T), "clampToByte can't process unsigned types");
8 static if (__VERSION__ > 2067) pragma(inline, true);
9 static if (T.sizeof == 2 || T.sizeof == 4) {
10 static if (__traits(isUnsigned, T)) {
11 return cast(ubyte)(n&0xff|(255-((-cast(int)(n < 256))>>24)));
12 } else {
13 n &= -cast(int)(n >= 0);
14 return cast(ubyte)(n|((255-cast(int)n)>>31));
16 } else static if (T.sizeof == 1) {
17 static assert(__traits(isUnsigned, T), "clampToByte: signed byte? no, really?");
18 return cast(ubyte)n;
19 } else {
20 static assert(false, "clampToByte: integer too big");
25 // ////////////////////////////////////////////////////////////////////////// //
26 struct Vec3 {
27 import std.format : FormatSpec;
28 void toString (scope void delegate(const(char)[]) sink, FormatSpec!char fmt) const @trusted {
29 import std.format;
30 sink("Vec3(");
31 sink.formatValue(x, fmt);
32 sink(",");
33 sink.formatValue(y, fmt);
34 sink(",");
35 sink.formatValue(z, fmt);
36 sink(")");
39 nothrow @safe @nogc:
40 float x = 0, y = 0, z = 0;
42 @property float opIndex (size_t idx) const pure {
43 static if (__VERSION__ > 2067) pragma(inline, true);
44 if (idx > 2) assert(0, "invalid index in Vec3 opindex");
45 return (idx == 0 ? x : (idx == 1 ? y : z));
48 @property float opIndexAssign (float v, size_t idx) {
49 static if (__VERSION__ > 2067) pragma(inline, true);
50 if (idx > 2) assert(0, "invalid index in Vec3 opindex");
51 final switch (idx) {
52 case 0: x = v; break;
53 case 1: y = v; break;
54 case 2: z = v; break;
56 return v;
59 ref Vec3 normalize () {
60 //pragma(inline, true);
61 import std.math : sqrt;
62 immutable invlen = 1.0f/sqrt(x*x+y*y+z*z);
63 x *= invlen;
64 y *= invlen;
65 z *= invlen;
66 return this;
69 const pure {
70 static float length (float x, float y) {
71 //pragma(inline, true);
72 import std.math : sqrt;
73 return sqrt(x*x+y*y);
76 static float length (float x, float y, float z) {
77 //pragma(inline, true);
78 import std.math : sqrt;
79 return sqrt(x*x+y*y+z*z);
82 float length () {
83 //pragma(inline, true);
84 import std.math : sqrt;
85 return sqrt(x*x+y*y+z*z);
86 //return length(x, y, z);
89 Vec3 normalized () {
90 //pragma(inline, true);
91 import std.math : sqrt;
92 immutable invlen = 1.0f/sqrt(x*x+y*y+z*z);
93 return Vec3(x*invlen, y*invlen, z*invlen);
96 Vec3 abs () {
97 //pragma(inline, true);
98 import std.math : abs;
99 return Vec3(abs(x), abs(y), abs(z));
102 Vec3 minmax(string op) (in auto ref Vec3 b) if (op == "min" || op == "max") {
103 //pragma(inline, true);
104 mixin("import std.algorithm : "~op~";");
105 return mixin("Vec3("~op~"(x, b.x), "~op~"(y, b.y), "~op~"(z, b.z))");
108 Vec3 minmax(string op) (float v) if (op == "min" || op == "max") {
109 //pragma(inline, true);
110 mixin("import std.algorithm : "~op~";");
111 return mixin("Vec3("~op~"(x, v), "~op~"(y, v), "~op~"(z, v))");
115 alias min = minmax!"min";
116 alias max = minmax!"max";
119 Vec3 opBinary(string op) (in auto ref Vec3 b) if (op == "+" || op == "-" || op == "*" || op == "/") {
120 static if (__VERSION__ > 2067) pragma(inline, true);
121 return mixin("Vec3(x"~op~"b.x, y"~op~"b.y, z"~op~"b.z)");
124 Vec3 opBinary(string op) (in float b) if (op == "+" || op == "-" || op == "*" || op == "/") {
125 static if (__VERSION__ > 2067) pragma(inline, true);
126 return mixin("Vec3(x"~op~"b, y"~op~"b, z"~op~"b)");
129 // cross product (normal to plane containing a and b)
130 Vec3 opBinary(string op : "%") (in auto ref Vec3 b) {
131 static if (__VERSION__ > 2067) pragma(inline, true);
132 return Vec3(y*b.z-z*b.y, z*b.x-x*b.z, x*b.y-y*b.x);
135 float dot() (in auto ref Vec3 b) {
136 static if (__VERSION__ > 2067) pragma(inline, true);
137 return x*b.x+y*b.y+z*b.z;
140 float anglev() (in auto ref Vec3 b) {
141 static if (__VERSION__ > 2067) pragma(inline, true);
142 import std.math : acos;
143 return acos(dot(b)/(length*b.length));
146 // n is normal; normalized! ;-)
147 Vec3 reflect() (in auto ref Vec3 n) {
148 //I - 2.0 * dot(N, I) * N
149 auto res = Vec3(x, y, z);
150 res -= n*(2.0f*n.dot(this));
151 return res;
154 // things like `.xyy`
155 Vec3 opDispatch(string type) ()
156 if (type.length == 3 &&
157 (type[0] == 'x' || type[0] == 'y' || type[0] == 'z') &&
158 (type[1] == 'x' || type[1] == 'y' || type[1] == 'z') &&
159 (type[2] == 'x' || type[2] == 'y' || type[2] == 'z'))
161 static if (__VERSION__ > 2067) pragma(inline, true);
162 return mixin("Vec3("~type[0]~","~type[1]~","~type[2]~")");
166 auto rotx() (float angle) {
167 //pragma(inline, true);
168 float sine = void, cosine = void;
169 asm pure nothrow @trusted @nogc {
170 fld angle;
171 fsincos;
172 fstp [cosine];
173 fstp [sine];
175 return Vec3(x, y*cosine-z*sine, y*sine+z*cosine);
178 auto roty() (float angle) {
179 //pragma(inline, true);
180 float sine = void, cosine = void;
181 asm pure nothrow @trusted @nogc {
182 fld angle;
183 fsincos;
184 fstp [cosine];
185 fstp [sine];
187 return Vec3(x*cosine-z*sine, y, x*sine+z*cosine);
190 auto rotz() (float angle) {
191 //pragma(inline, true);
192 float sine = void, cosine = void;
193 asm pure nothrow @trusted @nogc {
194 fld angle;
195 fsincos;
196 fstp [cosine];
197 fstp [sine];
199 return Vec3(x*cosine-y*sine, x*sine+y*cosine, z);
204 ref Vec3 opOpAssign(string op) (in auto ref Vec3 b) if (op == "+" || op == "-" || op == "*" || op == "/") {
205 static if (__VERSION__ > 2067) pragma(inline, true);
206 mixin("x"~op~"=b.x;");
207 mixin("y"~op~"=b.y;");
208 mixin("z"~op~"=b.z;");
209 return this;
212 ref Vec3 opOpAssign(string op) (float b) if (op == "+" || op == "-" || op == "*" || op == "/") {
213 static if (__VERSION__ > 2067) pragma(inline, true);
214 mixin("x"~op~"=b;");
215 mixin("y"~op~"=b;");
216 mixin("z"~op~"=b;");
217 return this;
220 //static float smoothstep (float x) pure { static if (__VERSION__ > 2067) pragma(inline, true); return x*x*(3-2*x); }