211 lines
6.3 KiB
C++
211 lines
6.3 KiB
C++
// 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 <mscorlib.dll>
|
|
using namespace System;
|
|
using namespace System::Runtime::InteropServices;
|
|
|
|
|
|
namespace Irrlicht
|
|
{
|
|
namespace Core
|
|
{
|
|
/// <summary>
|
|
/// Enumeration for intersection relations of 3d objects
|
|
/// </summary>
|
|
public __value enum IntersectionRelation3D
|
|
{
|
|
ISREL3D_FRONT = 0,
|
|
ISREL3D_BACK,
|
|
ISREL3D_PLANAR,
|
|
ISREL3D_SPANNING,
|
|
ISREL3D_CLIPPED
|
|
};
|
|
|
|
/// <summary>
|
|
/// Specifies a two dimensional size.
|
|
/// </summary>
|
|
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);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Returns an intersection with a 3d line.
|
|
/// </summary>
|
|
/// <param name="lineVect"> Vector of the line to intersect with.</param>
|
|
/// <param name="linePoint"> Point of the line to intersect with.</param>
|
|
/// <param name="outIntersection"> Place to store the intersection point, if there is one.</param>
|
|
/// <returns> 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns an intersection with a 3d line, limited between two 3d points.
|
|
/// </summary>
|
|
/// <param name="linePoint1"> Point 1 of the line.</param>
|
|
/// <param name="linePoint2"> Point 2 of the line.</param>
|
|
/// <param name="outIntersection"> Place to store the intersection point, if there is one.</param>
|
|
/// <returns> Returns true if there was an intersection, false if there was not.</returns>
|
|
bool GetIntersectionWithLimitedLine(Vector3D linePoint1,
|
|
Vector3D linePoint2, [PARAMFLAG::Out] Vector3D& outIntersection)
|
|
{
|
|
return ( GetIntersectionWithLine(linePoint1, linePoint2 - linePoint1, outIntersection) &&
|
|
outIntersection.IsBetweenPoints(linePoint1, linePoint2));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Classifies the relation of a point to this plane.
|
|
/// </summary>
|
|
/// <param name="point"> Point to classify its relation.</param>
|
|
/// <returns> 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.</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recalculates the distance from origin by applying
|
|
/// a new member point to the plane.
|
|
/// </summary>
|
|
void RecalculateD(Vector3D MPoint)
|
|
{
|
|
D = - MPoint.DotProduct(Normal);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a member point of the plane.
|
|
/// </summary>
|
|
Vector3D GetMemberPoint()
|
|
{
|
|
return Normal * -D;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tests if there is a intersection between this plane and another
|
|
/// </summary>
|
|
/// <returns> Returns true if there is a intersection.</returns>
|
|
bool ExistsInterSection(Plane3D other)
|
|
{
|
|
Vector3D cross = other.Normal.CrossProduct(Normal);
|
|
return cross.GetLength() > 1e-08f;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Intersects this plane with another.
|
|
/// </summary>
|
|
/// <returns> Returns true if there is a intersection, false if not.</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the intersection point with two other planes if there is one.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns if the plane is front of backfacing. Note that this only
|
|
/// works if the normal is Normalized.
|
|
/// </summary>
|
|
/// <param name="lookDirection"> Look direction.</param>
|
|
/// <returns> Returns true if the plane is front facing, which mean it would
|
|
/// be visible, and false if it is backfacing.</returns>
|
|
bool IsFrontFacting(Vector3D lookDirection)
|
|
{
|
|
return Normal.DotProduct(lookDirection) <= 0.0f;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the distance to a point. Note that this only
|
|
/// works if the normal is Normalized.
|
|
/// </summary>
|
|
float GetDistanceTo(Vector3D point)
|
|
{
|
|
return point.DotProduct(Normal) + D;
|
|
}
|
|
|
|
// member variables
|
|
|
|
float D; // distance from origin
|
|
Vector3D Normal; // normal vector
|
|
};
|
|
|
|
}
|
|
} |