Loading...
Searching...
No Matches
triangle3d.h
Go to the documentation of this file.
// Copyright (C) 2002-2012 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __IRR_TRIANGLE_3D_H_INCLUDED__
#define __IRR_TRIANGLE_3D_H_INCLUDED__
#include "vector3d.h"
#include "line3d.h"
#include "plane3d.h"
#include "aabbox3d.h"
namespace irr
{
namespace core
{
template <class T>
class triangle3d
{
public:
triangle3d() {}
triangle3d(vector3d<T> v1, vector3d<T> v2, vector3d<T> v3) : pointA(v1), pointB(v2), pointC(v3) {}
bool operator==(const triangle3d<T>& other) const
{
return other.pointA==pointA && other.pointB==pointB && other.pointC==pointC;
}
bool operator!=(const triangle3d<T>& other) const
{
return !(*this==other);
}
bool isTotalInsideBox(const aabbox3d<T>& box) const
{
return (box.isPointInside(pointA) &&
box.isPointInside(pointB) &&
box.isPointInside(pointC));
}
bool isTotalOutsideBox(const aabbox3d<T>& box) const
{
return ((pointA.X > box.MaxEdge.X && pointB.X > box.MaxEdge.X && pointC.X > box.MaxEdge.X) ||
(pointA.Y > box.MaxEdge.Y && pointB.Y > box.MaxEdge.Y && pointC.Y > box.MaxEdge.Y) ||
(pointA.Z > box.MaxEdge.Z && pointB.Z > box.MaxEdge.Z && pointC.Z > box.MaxEdge.Z) ||
(pointA.X < box.MinEdge.X && pointB.X < box.MinEdge.X && pointC.X < box.MinEdge.X) ||
(pointA.Y < box.MinEdge.Y && pointB.Y < box.MinEdge.Y && pointC.Y < box.MinEdge.Y) ||
(pointA.Z < box.MinEdge.Z && pointB.Z < box.MinEdge.Z && pointC.Z < box.MinEdge.Z));
}
core::vector3d<T> closestPointOnTriangle(const core::vector3d<T>& p) const
{
const core::vector3d<T> rab = line3d<T>(pointA, pointB).getClosestPoint(p);
const core::vector3d<T> rbc = line3d<T>(pointB, pointC).getClosestPoint(p);
const core::vector3d<T> rca = line3d<T>(pointC, pointA).getClosestPoint(p);
const T d1 = rab.getDistanceFrom(p);
const T d2 = rbc.getDistanceFrom(p);
const T d3 = rca.getDistanceFrom(p);
if (d1 < d2)
return d1 < d3 ? rab : rca;
return d2 < d3 ? rbc : rca;
}
/*
\param p Point to test. Assumes that this point is already
on the plane of the triangle.
\return True if the point is inside the triangle, otherwise false. */
bool isPointInside(const vector3d<T>& p) const
{
vector3d<f64> af64((f64)pointA.X, (f64)pointA.Y, (f64)pointA.Z);
vector3d<f64> bf64((f64)pointB.X, (f64)pointB.Y, (f64)pointB.Z);
vector3d<f64> cf64((f64)pointC.X, (f64)pointC.Y, (f64)pointC.Z);
vector3d<f64> pf64((f64)p.X, (f64)p.Y, (f64)p.Z);
return (isOnSameSide(pf64, af64, bf64, cf64) &&
isOnSameSide(pf64, bf64, af64, cf64) &&
isOnSameSide(pf64, cf64, af64, bf64));
}
bool isPointInsideFast(const vector3d<T>& p) const
{
const vector3d<T> a = pointC - pointA;
const vector3d<T> b = pointB - pointA;
const vector3d<T> c = p - pointA;
const f64 dotAA = a.dotProduct( a);
const f64 dotAB = a.dotProduct( b);
const f64 dotAC = a.dotProduct( c);
const f64 dotBB = b.dotProduct( b);
const f64 dotBC = b.dotProduct( c);
// get coordinates in barycentric coordinate system
const f64 invDenom = 1/(dotAA * dotBB - dotAB * dotAB);
const f64 u = (dotBB * dotAC - dotAB * dotBC) * invDenom;
const f64 v = (dotAA * dotBC - dotAB * dotAC ) * invDenom;
// We count border-points as inside to keep downward compatibility.
// Rounding-error also needed for some test-cases.
return (u > -ROUNDING_ERROR_f32) && (v >= 0) && (u + v < 1+ROUNDING_ERROR_f32);
}
bool getIntersectionWithLimitedLine(const line3d<T>& line,
vector3d<T>& outIntersection) const
{
return getIntersectionWithLine(line.start,
line.getVector(), outIntersection) &&
outIntersection.isBetweenPoints(line.start, line.end);
}
bool getIntersectionWithLine(const vector3d<T>& linePoint,
const vector3d<T>& lineVect, vector3d<T>& outIntersection) const
{
if (getIntersectionOfPlaneWithLine(linePoint, lineVect, outIntersection))
return isPointInside(outIntersection);
return false;
}
bool getIntersectionOfPlaneWithLine(const vector3d<T>& linePoint,
const vector3d<T>& lineVect, vector3d<T>& outIntersection) const
{
// Work with f64 to get more precise results (makes enough difference to be worth the casts).
const vector3d<f64> linePointf64(linePoint.X, linePoint.Y, linePoint.Z);
const vector3d<f64> lineVectf64(lineVect.X, lineVect.Y, lineVect.Z);
vector3d<f64> outIntersectionf64;
core::triangle3d<irr::f64> trianglef64(vector3d<f64>((f64)pointA.X, (f64)pointA.Y, (f64)pointA.Z)
,vector3d<f64>((f64)pointB.X, (f64)pointB.Y, (f64)pointB.Z)
, vector3d<f64>((f64)pointC.X, (f64)pointC.Y, (f64)pointC.Z));
const vector3d<irr::f64> normalf64 = trianglef64.getNormal().normalize();
f64 t2;
if ( core::iszero ( t2 = normalf64.dotProduct(lineVectf64) ) )
return false;
f64 d = trianglef64.pointA.dotProduct(normalf64);
f64 t = -(normalf64.dotProduct(linePointf64) - d) / t2;
outIntersectionf64 = linePointf64 + (lineVectf64 * t);
outIntersection.X = (T)outIntersectionf64.X;
outIntersection.Y = (T)outIntersectionf64.Y;
outIntersection.Z = (T)outIntersectionf64.Z;
return true;
}
vector3d<T> getNormal() const
{
return (pointB - pointA).crossProduct(pointC - pointA);
}
bool isFrontFacing(const vector3d<T>& lookDirection) const
{
const vector3d<T> n = getNormal().normalize();
const f32 d = (f32)n.dotProduct(lookDirection);
return F32_LOWER_EQUAL_0(d);
}
plane3d<T> getPlane() const
{
return plane3d<T>(pointA, pointB, pointC);
}
T getArea() const
{
return (pointB - pointA).crossProduct(pointC - pointA).getLength() * 0.5f;
}
void set(const core::vector3d<T>& a, const core::vector3d<T>& b, const core::vector3d<T>& c)
{
pointA = a;
pointB = b;
pointC = c;
}
vector3d<T> pointA;
vector3d<T> pointB;
vector3d<T> pointC;
private:
// Using f64 instead of <T> to avoid integer overflows when T=int (maybe also less floating point troubles).
bool isOnSameSide(const vector3d<f64>& p1, const vector3d<f64>& p2,
const vector3d<f64>& a, const vector3d<f64>& b) const
{
vector3d<f64> bminusa = b - a;
vector3d<f64> cp1 = bminusa.crossProduct(p1 - a);
vector3d<f64> cp2 = bminusa.crossProduct(p2 - a);
f64 res = cp1.dotProduct(cp2);
if ( res < 0 )
{
// This catches some floating point troubles.
// Unfortunately slightly expensive and we don't really know the best epsilon for iszero.
vector3d<f64> cp1 = bminusa.normalize().crossProduct((p1 - a).normalize());
if ( core::iszero(cp1.X, (f64)ROUNDING_ERROR_f32)
&& core::iszero(cp1.Y, (f64)ROUNDING_ERROR_f32)
&& core::iszero(cp1.Z, (f64)ROUNDING_ERROR_f32) )
{
res = 0.f;
}
}
return (res >= 0.0f);
}
};
typedef triangle3d<f32> triangle3df;
typedef triangle3d<s32> triangle3di;
} // end namespace core
} // end namespace irr
#endif
aabbox3d.h
irr::core::aabbox3d
Axis aligned bounding box in 3d dimensional space.
Definition aabbox3d.h:22
irr::core::aabbox3d::MaxEdge
vector3d< T > MaxEdge
The far edge.
Definition aabbox3d.h:320
irr::core::aabbox3d::MinEdge
vector3d< T > MinEdge
The near edge.
Definition aabbox3d.h:317
irr::core::aabbox3d::isPointInside
bool isPointInside(const vector3d< T > &p) const
Determines if a point is within this box.
Definition aabbox3d.h:201
irr::core::line3d
3D line between two points with intersection methods.
Definition line3d.h:19
irr::core::line3d::start
vector3d< T > start
Start point of line.
Definition line3d.h:130
irr::core::line3d::getClosestPoint
vector3d< T > getClosestPoint(const vector3d< T > &point) const
Get the closest point on this line to a point.
Definition line3d.h:89
irr::core::line3d::getVector
vector3d< T > getVector() const
Get vector of line.
Definition line3d.h:71
irr::core::line3d::end
vector3d< T > end
End point of line.
Definition line3d.h:132
irr::core::plane3d
Template plane class with some intersection testing methods.
Definition plane3d.h:34
irr::core::triangle3d
3d triangle template class for doing collision detection and other things.
Definition triangle3d.h:21
irr::core::triangle3d< f32 >::pointC
vector3d< f32 > pointC
Definition triangle3d.h:241
irr::core::triangle3d::getIntersectionWithLimitedLine
bool getIntersectionWithLimitedLine(const line3d< T > &line, vector3d< T > &outIntersection) const
Get an intersection with a 3d line.
Definition triangle3d.h:136
irr::core::triangle3d< f32 >::pointB
vector3d< f32 > pointB
Definition triangle3d.h:240
irr::core::triangle3d::triangle3d
triangle3d()
Constructor for an all 0 triangle.
Definition triangle3d.h:25
irr::core::triangle3d::triangle3d
triangle3d(vector3d< T > v1, vector3d< T > v2, vector3d< T > v3)
Constructor for triangle with given three vertices.
Definition triangle3d.h:27
irr::core::triangle3d::getPlane
plane3d< T > getPlane() const
Get the plane of this triangle.
Definition triangle3d.h:218
irr::core::triangle3d::getIntersectionWithLine
bool getIntersectionWithLine(const vector3d< T > &linePoint, const vector3d< T > &lineVect, vector3d< T > &outIntersection) const
Get an intersection with a 3d line.
Definition triangle3d.h:154
irr::core::triangle3d::getIntersectionOfPlaneWithLine
bool getIntersectionOfPlaneWithLine(const vector3d< T > &linePoint, const vector3d< T > &lineVect, vector3d< T > &outIntersection) const
Calculates the intersection between a 3d line and the plane the triangle is on.
Definition triangle3d.h:169
irr::core::triangle3d::isPointInsideFast
bool isPointInsideFast(const vector3d< T > &p) const
Check if a point is inside the triangle (border-points count also as inside).
Definition triangle3d.h:108
irr::core::triangle3d::operator!=
bool operator!=(const triangle3d< T > &other) const
Inequality operator.
Definition triangle3d.h:36
irr::core::triangle3d::isTotalInsideBox
bool isTotalInsideBox(const aabbox3d< T > &box) const
Determines if the triangle is totally inside a bounding box.
Definition triangle3d.h:44
irr::core::triangle3d::isFrontFacing
bool isFrontFacing(const vector3d< T > &lookDirection) const
Test if the triangle would be front or backfacing from any point.
Definition triangle3d.h:210
irr::core::triangle3d::closestPointOnTriangle
core::vector3d< T > closestPointOnTriangle(const core::vector3d< T > &p) const
Get the closest point on a triangle to a point on the same plane.
Definition triangle3d.h:68
irr::core::triangle3d::operator==
bool operator==(const triangle3d< T > &other) const
Equality operator.
Definition triangle3d.h:30
irr::core::triangle3d::isPointInside
bool isPointInside(const vector3d< T > &p) const
Check if a point is inside the triangle (border-points count also as inside).
Definition triangle3d.h:89
irr::core::triangle3d::isTotalOutsideBox
bool isTotalOutsideBox(const aabbox3d< T > &box) const
Determines if the triangle is totally outside a bounding box.
Definition triangle3d.h:54
irr::core::triangle3d< f32 >::pointA
vector3d< f32 > pointA
Definition triangle3d.h:239
irr::core::triangle3d::getNormal
vector3d< T > getNormal() const
Get the normal of the triangle.
Definition triangle3d.h:199
irr::core::triangle3d::set
void set(const core::vector3d< T > &a, const core::vector3d< T > &b, const core::vector3d< T > &c)
sets the triangle's points
Definition triangle3d.h:231
irr::core::triangle3d::getArea
T getArea() const
Get the area of the triangle.
Definition triangle3d.h:224
irr::core::vector3d
3d vector template class with lots of operators and methods.
Definition vector3d.h:23
irr::core::vector3d::crossProduct
vector3d< T > crossProduct(const vector3d< T > &p) const
Calculates the cross product with another vector.
Definition vector3d.h:147
irr::core::vector3d::X
T X
X coordinate of the vector.
Definition vector3d.h:408
irr::core::vector3d::normalize
vector3d< T > & normalize()
Normalizes the vector.
Definition vector3d.h:168
irr::core::vector3d::getDistanceFrom
T getDistanceFrom(const vector3d< T > &other) const
Get distance from another point.
Definition vector3d.h:132
irr::core::vector3d::isBetweenPoints
bool isBetweenPoints(const vector3d< T > &begin, const vector3d< T > &end) const
Returns if this vector interpreted as a point is on a line between two other points.
Definition vector3d.h:157
irr::core::vector3d::Z
T Z
Z coordinate of the vector.
Definition vector3d.h:414
irr::core::vector3d::dotProduct
T dotProduct(const vector3d< T > &other) const
Get the dot product with another vector.
Definition vector3d.h:125
irr::core::vector3d::Y
T Y
Y coordinate of the vector.
Definition vector3d.h:411
F32_LOWER_EQUAL_0
#define F32_LOWER_EQUAL_0(n)
Definition irrMath.h:386
line3d.h
irr::core
Basic classes such as vectors, planes, arrays, lists, and so on can be found in this namespace.
Definition aabbox3d.h:15
irr::core::triangle3df
triangle3d< f32 > triangle3df
Typedef for a f32 3d triangle.
Definition triangle3d.h:270
irr::core::triangle3di
triangle3d< s32 > triangle3di
Typedef for an integer 3d triangle.
Definition triangle3d.h:273
irr::core::ROUNDING_ERROR_f32
const f32 ROUNDING_ERROR_f32
Definition irrMath.h:49
irr::core::iszero
bool iszero(const f64 a, const f64 tolerance=ROUNDING_ERROR_f64)
returns if a equals zero, taking rounding errors into account
Definition irrMath.h:270
irr
Everything in the Irrlicht Engine can be found in this namespace.
Definition aabbox3d.h:13
irr::f32
float f32
32 bit floating point variable.
Definition irrTypes.h:104
irr::f64
double f64
64 bit floating point variable.
Definition irrTypes.h:108
plane3d.h
vector3d.h
- Irrlicht Engine Documentation © 2003-2012 by Nikolaus Gebhardt. Generated on for Irrlicht 3D Engine by Doxygen 1.15.0