// Copyright (C) 2002-2006 Nikolaus Gebhardt // This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in irrlicht.h #pragma once #using using namespace System; using namespace System::Runtime::InteropServices; namespace Irrlicht { namespace Core { /// /// Enumeration for intersection relations of 3d objects /// public __value enum IntersectionRelation3D { ISREL3D_FRONT = 0, ISREL3D_BACK, ISREL3D_PLANAR, ISREL3D_SPANNING, ISREL3D_CLIPPED }; /// /// Specifies a two dimensional size. /// public __value class Plane3D { public: // Constructors Plane3D(): Normal(0,1,0) { RecalculateD(Vector3D(0,0,0)); }; Plane3D(Vector3D MPoint, Vector3D Normal) : Normal(Normal) { RecalculateD(MPoint); }; Plane3D(float px, float py, float pz, float nx, float ny, float nz) : Normal(nx, ny, nz) { RecalculateD(Vector3D(px, py, pz)); }; Plane3D(Vector3D point1, Vector3D point2, Vector3D point3) { SetPlane(point1, point2, point3); }; void SetPlane(Vector3D point, Vector3D nvector) { Normal = nvector; Normal.Normalize(); RecalculateD(point); } void SetPlane(Vector3D nvect, float d) { Normal = nvect; D = d; } void SetPlane(Vector3D point1, Vector3D point2, Vector3D point3) { // creates the plane from 3 memberpoints Normal = (point2 - point1).CrossProduct(point3 - point1); Normal.Normalize(); RecalculateD(point1); } /// /// Returns an intersection with a 3d line. /// /// Vector of the line to intersect with. /// Point of the line to intersect with. /// Place to store the intersection point, if there is one. /// Returns true if there was an intersection, false if there was not. bool GetIntersectionWithLine(Vector3D linePoint, Vector3D lineVect, [PARAMFLAG::Out] Vector3D& outIntersection) { float t2 = Normal.DotProduct(lineVect); if (t2 == 0) return false; float t =- (Normal.DotProduct(linePoint) + D) / t2; outIntersection = linePoint + (lineVect * t); return true; } /// /// Returns an intersection with a 3d line, limited between two 3d points. /// /// Point 1 of the line. /// Point 2 of the line. /// Place to store the intersection point, if there is one. /// Returns true if there was an intersection, false if there was not. bool GetIntersectionWithLimitedLine(Vector3D linePoint1, Vector3D linePoint2, [PARAMFLAG::Out] Vector3D& outIntersection) { return ( GetIntersectionWithLine(linePoint1, linePoint2 - linePoint1, outIntersection) && outIntersection.IsBetweenPoints(linePoint1, linePoint2)); } /// /// Classifies the relation of a point to this plane. /// /// Point to classify its relation. /// Returns ISREL3D_FRONT if the point is in front of the plane, /// ISREL3D_BACK if the point is behind of the plane, and /// ISREL3D_PLANAR if the point is within the plane. IntersectionRelation3D ClassifyPointRelation(Vector3D point) { float d = Normal.DotProduct(point) + D; if (d < -ROUNDING_ERROR) return ISREL3D_FRONT; if (d > ROUNDING_ERROR) return ISREL3D_BACK; return ISREL3D_PLANAR; } /// /// Recalculates the distance from origin by applying /// a new member point to the plane. /// void RecalculateD(Vector3D MPoint) { D = - MPoint.DotProduct(Normal); } /// /// Returns a member point of the plane. /// Vector3D GetMemberPoint() { return Normal * -D; } /// /// Tests if there is a intersection between this plane and another /// /// Returns true if there is a intersection. bool ExistsInterSection(Plane3D other) { Vector3D cross = other.Normal.CrossProduct(Normal); return cross.GetLength() > 1e-08f; } /// /// Intersects this plane with another. /// /// Returns true if there is a intersection, false if not. bool GetIntersectionWithPlane(Plane3D other, [PARAMFLAG::Out] Vector3D& outLinePoint, [PARAMFLAG::Out] Vector3D& outLineVect) { double fn00 = Normal.GetLength(); double fn01 = Normal.DotProduct(other.Normal); double fn11 = other.Normal.GetLength(); double det = fn00*fn11 - fn01*fn01; if (mfabs((float)det) < 1e-08f) return false; det = 1.0 / det; double fc0 = (fn11*-D + fn01*other.D) * det; double fc1 = (fn00*-other.D + fn01*D) * det; outLineVect = Normal.CrossProduct(other.Normal); outLinePoint = Normal*(float)fc0 + other.Normal*(float)fc1; return true; } /// /// Returns the intersection point with two other planes if there is one. /// bool GetIntersectionWithPlanes(Plane3D o1, Plane3D o2, [PARAMFLAG::Out] Vector3D& outPoint) { Vector3D linePoint, lineVect; if (GetIntersectionWithPlane(o1, linePoint, lineVect)) return o2.GetIntersectionWithLine(linePoint, lineVect, outPoint); return false; } /// /// Returns if the plane is front of backfacing. Note that this only /// works if the normal is Normalized. /// /// Look direction. /// Returns true if the plane is front facing, which mean it would /// be visible, and false if it is backfacing. bool IsFrontFacting(Vector3D lookDirection) { return Normal.DotProduct(lookDirection) <= 0.0f; } /// /// Returns the distance to a point. Note that this only /// works if the normal is Normalized. /// float GetDistanceTo(Vector3D point) { return point.DotProduct(Normal) + D; } // member variables float D; // distance from origin Vector3D Normal; // normal vector }; } }