// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp #include #include #include #include #define F(a) static_cast(a) namespace Nz { template Plane::Plane(T normalX, T normalY, T normalZ, T D) { Set(normalX, normalY, normalZ, D); } template Plane::Plane(const T plane[4]) { Set(plane); } template Plane::Plane(const Vector3& Normal, T D) { Set(Normal, D); } template Plane::Plane(const Vector3& Normal, const Vector3& point) { Set(Normal, point); } template Plane::Plane(const Vector3& point1, const Vector3& point2, const Vector3& point3) { Set(point1, point2, point3); } template template Plane::Plane(const Plane& plane) { Set(plane); } template T Plane::Distance(const Vector3& point) const { return normal.DotProduct(point) - distance; // ax + by + cd - d = 0. } template T Plane::Distance(T x, T y, T z) const { return Distance(Vector3(x, y, z)); } template Plane& Plane::Set(T normalX, T normalY, T normalZ, T D) { distance = D; normal.Set(normalX, normalY, normalZ); return *this; } template Plane& Plane::Set(const T plane[4]) { normal.Set(plane[0], plane[1], plane[2]); distance = plane[3]; return *this; } template Plane& Plane::Set(const Plane& plane) { std::memcpy(this, &plane, sizeof(Plane)); return *this; } template Plane& Plane::Set(const Vector3& Normal, T D) { distance = D; normal = Normal; return *this; } template Plane& Plane::Set(const Vector3& Normal, const Vector3& point) { normal = Normal; distance = -normal.DotProduct(point); return *this; } template Plane& Plane::Set(const Vector3& point1, const Vector3& point2, const Vector3& point3) { Vector3 edge1 = point2 - point1; Vector3 edge2 = point3 - point1; normal = edge1.CrossProduct(edge2); normal.Normalize(); distance = normal.DotProduct(point3); return *this; } template template Plane& Plane::Set(const Plane& plane) { normal.Set(plane.normal); distance = F(plane.distance); return *this; } template String Plane::ToString() const { StringStream ss; return ss << "Plane(Normal: " << normal.ToString() << "; Distance: " << distance << ')'; } template bool Plane::operator==(const Plane& plane) const { return (normal == plane.normal && NumberEquals(distance, plane.distance)) || (normal == -plane.normal && NumberEquals(distance, -plane.distance)); } template bool Plane::operator!=(const Plane& plane) const { return !operator==(plane); } template Plane Plane::Lerp(const Plane& from, const Plane& to, T interpolation) { #ifdef NAZARA_DEBUG if (interpolation < F(0.0) || interpolation > F(1.0)) { NazaraError("Interpolation must be in range [0..1] (Got " + String::Number(interpolation) + ')'); return Plane(); } #endif Plane plane; plane.distance = Lerp(from.distance, to.distance, interpolation); plane.normal = Vector3::Lerp(from.normal, to.normal, interpolation); plane.normal.Normalize(); return plane; } template Plane Plane::XY() { return Plane(F(0.0), F(0.0), F(1.0), F(0.0)); } template Plane Plane::XZ() { return Plane(F(0.0), F(1.0), F(0.0), F(0.0)); } template Plane Plane::YZ() { return Plane(F(1.0), F(0.0), F(0.0), F(0.0)); } } template std::ostream& operator<<(std::ostream& out, const Nz::Plane& plane) { return out << plane.ToString(); } #undef F #include