private { import maths.Vec; } struct Plane { alias float flt; union { struct { union { struct { flt A, B, C; } vec3 normal; } flt D; } vec4 equation; } static Plane opCall(flt A, flt B, flt C, flt D, bool normalize = false) { Plane res; res.A = A; res.B = B; res.C = C; res.D = D; if (normalize) { res.normalize(); } return res; } static Plane opCall(vec3 pt, vec3 normal) { Plane res; res.normal = normal; res.D = -pt.dot(normal); return res; } void normalize() { flt lenRec = cast(flt)(1.0 / normal.len); normal *= lenRec; D *= lenRec; } flt distance(vec3 pt) { return normal.dot(pt) + D; } vec3 reflect(vec3 pt) { return pt - normal * distance(pt) * cast(flt)2.0; } vec3 project(vec3 pt) { return pt - normal * distance(pt); } bool intersect(vec3 origin, vec3 dir, inout flt t) { flt numer = (normal.dot(origin)) + D; flt denom = (normal.dot(dir)); t = -numer; t /= denom; if (!(t >= -0.0001)) return false; return true; } void flip() { normal.flip(); D = -D; } void offset(vec3 v) { flt dot = normal.dot(v); D -= dot; } /+void transform(xform x) { normal = x.rotation.xform(normal); offset(x.translation); } void transform(mat4 x) { vec3 p1 = calcPoint; vec3 p2 = normal + p1; p1 = x.xform(p1); p2 = x.xform(p2); *this = Plane(p1, p2-p1); }+/ vec3 calcPoint() { return -normal * D; } }