00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __SP_DIMENSION_TRIANGLE3D_H__
00009 #define __SP_DIMENSION_TRIANGLE3D_H__
00010
00011
00012 #include "Base/spStandard.hpp"
00013 #include "Base/spDimensionVector3D.hpp"
00014 #include "Base/spDimensionLine3D.hpp"
00015
00016
00017 namespace sp
00018 {
00019 namespace dim
00020 {
00021
00022
00023 template < typename T, class C = vector3d<T> > class triangle3d
00024 {
00025
00026 public:
00027
00028 triangle3d()
00029 {
00030 }
00031 triangle3d(const C &NewPointA, const C &NewPointB, const C &NewPointC) :
00032 PointA(NewPointA),
00033 PointB(NewPointB),
00034 PointC(NewPointC)
00035 {
00036 }
00037 triangle3d(const triangle3d<T> &Other) :
00038 PointA(Other.PointA),
00039 PointB(Other.PointB),
00040 PointC(Other.PointC)
00041 {
00042 }
00043 triangle3d(const triangle3d<T, C*> &Other) :
00044 PointA(*Other.PointA),
00045 PointB(*Other.PointB),
00046 PointC(*Other.PointC)
00047 {
00048 }
00049 ~triangle3d()
00050 {
00051 }
00052
00053
00054
00055 inline triangle3d<T>& operator = (const triangle3d<T, C*> &other)
00056 {
00057 PointA = *other.PointA; PointB = *other.PointB; PointC = *other.PointC;
00058 return *this;
00059 }
00060
00061 inline triangle3d<T> operator + (const vector3d<T> &Vector) const
00062 {
00063 return triangle3d<T>(PointA + Vector, PointB + Vector, PointC + Vector);
00064 }
00065 inline triangle3d<T>& operator += (const vector3d<T> &Vector)
00066 {
00067 PointA += Vector; PointB += Vector; PointC += Vector; return *this;
00068 }
00069
00070 inline triangle3d<T> operator - (const vector3d<T> &Vector) const
00071 {
00072 return triangle3d<T>(PointA - Vector, PointB - Vector, PointC - Vector);
00073 }
00074 inline triangle3d<T>& operator -= (const vector3d<T> &Vector)
00075 {
00076 PointA -= Vector; PointB -= Vector; PointC -= Vector; return *this;
00077 }
00078
00079 inline triangle3d<T> operator * (const vector3d<T> &Vector) const
00080 {
00081 return triangle3d<T>(PointA*Vector, PointB*Vector, PointC*Vector);
00082 }
00083 inline triangle3d<T>& operator *= (const vector3d<T> &Vector)
00084 {
00085 PointA *= Vector; PointB *= Vector; PointC *= Vector; return *this;
00086 }
00087
00088 inline triangle3d<T> operator / (const vector3d<T> &Vector) const
00089 {
00090 return triangle3d<T>(PointA/Vector, PointB/Vector, PointC/Vector);
00091 }
00092 inline triangle3d<T>& operator /= (const vector3d<T> &Vector)
00093 {
00094 PointA /= Vector; PointB /= Vector; PointC /= Vector; return *this;
00095 }
00096
00097 inline triangle3d<T> operator - () const
00098 {
00099 return triangle3d<T>(-PointA, -PointB, -PointC);
00100 }
00101
00102
00103
00104 inline const vector3d<T> operator [] (s32 i) const
00105 {
00106 switch (i)
00107 {
00108 case 0: return PointA;
00109 case 1: return PointB;
00110 case 2: return PointC;
00111 }
00112 return vector3d<T>();
00113 }
00114
00115 inline vector3d<T>& operator [] (s32 i)
00116 {
00117 return *(&PointA + i);
00118 }
00119
00120
00121
00123 inline vector3d<T> getNormalSq() const
00124 {
00125 return (PointB - PointA).cross(PointC - PointA);
00126 }
00128 inline vector3d<T> getNormal() const
00129 {
00130 return getNormalSq().normalize();
00131 }
00132
00134 inline vector3d<T> getCenter() const
00135 {
00136 return (PointA + PointB + PointC) / 3;
00137 }
00138
00140 inline T getArea() const
00141 {
00142 return getNormalSq().getLength() / 2;
00143 }
00144
00145 inline bool isPointInside(const vector3d<T> &Vector) const
00146 {
00147 return
00148 vector3d<T>::isPointOnSameSide(Vector, PointA, PointB, PointC) &&
00149 vector3d<T>::isPointOnSameSide(Vector, PointB, PointA, PointC) &&
00150 vector3d<T>::isPointOnSameSide(Vector, PointC, PointA, PointB);
00151 }
00152
00153 inline bool isFrontSide() const
00154 {
00155 return (
00156 (PointB.X - PointA.X)*(PointC.Y - PointA.Y) - (PointB.Y - PointA.Y)*(PointC.X - PointA.X)
00157 ) >= (T)0;
00158 }
00159
00166 inline C getBarycentricPoint(const vector3d<T> &Coord) const
00167 {
00168 return PointA*Coord.X + PointB*Coord.Y + PointC*Coord.Z;
00169 }
00170
00171 inline triangle3d<T> getSwaped() const
00172 {
00173 return triangle3d<T>(PointC, PointB, PointA);
00174 }
00175 inline triangle3d<T>& swap()
00176 {
00177 math::Swap(PointA, PointC);
00178 return *this;
00179 }
00180
00181 inline line3d<T> getBox() const
00182 {
00183 line3d<T> TriangleBox;
00184
00185 TriangleBox.Start.X = math::Min(PointA.X, PointB.X, PointC.X);
00186 TriangleBox.Start.Y = math::Min(PointA.Y, PointB.Y, PointC.Y);
00187 TriangleBox.Start.Z = math::Min(PointA.Z, PointB.Z, PointC.Z);
00188
00189 TriangleBox.End.X = math::Max(PointA.X, PointB.X, PointC.X);
00190 TriangleBox.End.Y = math::Max(PointA.Y, PointB.Y, PointC.Y);
00191 TriangleBox.End.Z = math::Max(PointA.Z, PointB.Z, PointC.Z);
00192
00193 return TriangleBox;
00194 }
00195
00196 inline bool equal(const triangle3d<T> &other, f32 Precision = math::ROUNDING_ERROR) const
00197 {
00198 return
00199 PointA.equal(other.PointA, Precision) &&
00200 PointB.equal(other.PointB, Precision) &&
00201 PointC.equal(other.PointC, Precision);
00202 }
00203 inline bool empty() const
00204 {
00205 return PointA.empty() && PointB.empty() && PointC.empty();
00206 }
00207
00208 inline bool isFaceVisible() const
00209 {
00210 return (PointB.X - PointA.X)*(PointC.Y - PointA.Y) - (PointB.Y - PointA.Y)*(PointC.X - PointA.X) >= 0.0f;
00211 }
00212
00213 template <typename T2, class C2> inline triangle3d<T2, C2> cast() const
00214 {
00215 triangle3d<T2, C2> Tri;
00216
00217 Tri.PointA = PointA.cast<T2>();
00218 Tri.PointB = PointB.cast<T2>();
00219 Tri.PointC = PointC.cast<T2>();
00220
00221 return Tri;
00222 }
00223
00224
00225
00226 C PointA, PointB, PointC;
00227
00228 };
00229
00230 typedef triangle3d<s32> triangle3di;
00231 typedef triangle3d<f32> triangle3df;
00232
00233 typedef triangle3d<s32, vector3di*> ptriangle3di;
00234 typedef triangle3d<f32, vector3df*> ptriangle3df;
00235
00236
00237 }
00238
00239 }
00240
00241
00242 #endif
00243
00244
00245
00246