00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __SP_MATH_H__
00009 #define __SP_MATH_H__
00010
00011
00012 #include "Base/spStandard.hpp"
00013 #include "Base/spDimensionPoint2D.hpp"
00014 #include "Base/spDimensionRect2D.hpp"
00015 #include "Base/spDimensionLine3D.hpp"
00016 #include "Base/spDimensionVector3D.hpp"
00017 #include "Base/spDimensionTriangle3D.hpp"
00018 #include "Base/spDimensionPlane3D.hpp"
00019 #include "Base/spMathRadianDegree.hpp"
00020 #include "Base/spMaterialColor.hpp"
00021 #include "Base/spMathCore.hpp"
00022
00023 #include <stdlib.h>
00024 #include <vector>
00025
00026
00027 namespace sp
00028 {
00029
00030 namespace dim
00031 {
00032 template <typename T> class matrix4;
00033 typedef matrix4<f32> matrix4f;
00034 }
00035
00036 namespace math
00037 {
00038
00039
00041 template <typename T> inline T getDistance(const dim::point2d<T> &PosA, const dim::point2d<T> &PosB)
00042 {
00043 return sqrt(Pow2(PosB.X - PosA.X) + Pow2(PosB.Y - PosA.Y));
00044 }
00046 template <typename T> inline T getDistance(const dim::vector3d<T> &PosA, const dim::vector3d<T> &PosB)
00047 {
00048 return sqrt(Pow2(PosB.X - PosA.X) + Pow2(PosB.Y - PosA.Y) + Pow2(PosB.Z - PosA.Z));
00049 }
00050
00052 template <typename T> inline T getDistanceSq(const dim::point2d<T> &PosA, const dim::point2d<T> &PosB)
00053 {
00054 return Pow2(PosB.X - PosA.X) + Pow2(PosB.Y - PosA.Y);
00055 }
00057 template <typename T> inline T getDistanceSq(const dim::vector3d<T> &PosA, const dim::vector3d<T> &PosB)
00058 {
00059 return Pow2(PosB.X - PosA.X) + Pow2(PosB.Y - PosA.Y) + Pow2(PosB.Z - PosA.Z);
00060 }
00061
00072 template <typename T> T getAngle(const dim::point2d<T> &A, const dim::point2d<T> &B)
00073 {
00074 const dim::point2d<T> Dir(B - A);
00075 const T Dist = math::getDistance(A, B);
00076
00077 if (Dir.X >= T(0))
00078 {
00079 if (Dir.Y >= T(0))
00080 return math::ASin((B.X - A.X) / Dist);
00081 return T(180) - math::ASin((B.X - A.X) / Dist);
00082 }
00083
00084 if (Dir.Y >= T(0))
00085 return T(360) - math::ASin((A.X - B.X) / Dist);
00086 return T(180) + math::ASin((A.X - B.X) / Dist);
00087 }
00088
00093 template <typename T> T getAngle(const dim::point2d<T> &A, const dim::point2d<T> &B, const T &OffsetAngle)
00094 {
00095 T Angle = getAngle<T>(A, B) - OffsetAngle;
00096
00097 while (Angle > T(180))
00098 Angle -= T(360);
00099 while (Angle < T(-180))
00100 Angle += T(360);
00101
00102 return Angle;
00103 }
00104
00106 template <typename T> inline dim::vector3d<T> getNormalVectorSq(
00107 const dim::vector3d<T> &PosA, const dim::vector3d<T> &PosB, const dim::vector3d<T> &PosC)
00108 {
00109 return (PosA - PosB).cross(PosB - PosC);
00110 }
00111
00113 template <typename T> inline dim::vector3d<T> getNormalVector(
00114 const dim::vector3d<T> &PosA, const dim::vector3d<T> &PosB, const dim::vector3d<T> &PosC)
00115 {
00116 return getNormalVectorSq<T>(PosA, PosB, PosC).normalize();
00117 }
00118
00125 template <typename T> dim::vector3d<T> getBarycentricCoord(
00126 const dim::triangle3d<T> &Triangle, const dim::vector3d<T> &Point)
00127 {
00128 const dim::vector3d<T>& p = Point;
00129 const dim::vector3d<T>& a = Triangle.PointA;
00130 const dim::vector3d<T>& b = Triangle.PointB;
00131 const dim::vector3d<T>& c = Triangle.PointC;
00132
00133
00134 dim::vector3d<T> m = (b - a).cross(c - a);
00135
00136
00137 T nu, nv, ood;
00138
00139
00140 const T x = math::Abs(m.X);
00141 const T y = math::Abs(m.Y);
00142 const T z = math::Abs(m.Z);
00143
00144
00145 if (x >= y && x >= z)
00146 {
00147
00148 nu = math::getTriangleArea2D<T>(p.Y, p.Z, b.Y, b.Z, c.Y, c.Z);
00149 nv = math::getTriangleArea2D<T>(p.Y, p.Z, c.Y, c.Z, a.Y, a.Z);
00150 ood = T(1) / m.X;
00151 }
00152 else if (y >= x && y >= z)
00153 {
00154
00155 nu = math::getTriangleArea2D<T>(p.X, p.Z, b.X, b.Z, c.X, c.Z);
00156 nv = math::getTriangleArea2D<T>(p.X, p.Z, c.X, c.Z, a.X, a.Z);
00157 ood = T(1) / -m.Y;
00158 }
00159 else
00160 {
00161
00162 nu = math::getTriangleArea2D<T>(p.X, p.Y, b.X, b.Y, c.X, c.Y);
00163 nv = math::getTriangleArea2D<T>(p.X, p.Y, c.X, c.Y, a.X, a.Y);
00164 ood = T(1) / m.Z;
00165 }
00166
00167 const T u = nu * ood;
00168 const T v = nv * ood;
00169
00170 return dim::vector3d<T>(u, v, T(1.0) - u - v);
00171 }
00172
00173
00175 template <typename T> void sortContainerConst(
00176 std::vector<T> &ObjectList, bool (*lpFuncCmp)(const T &obj1, const T &obj2))
00177 {
00178 s32 changed, i;
00179
00180 do
00181 {
00182 changed = 0;
00183
00184 for (i = 0; i < ObjectList.size() - 1; ++i)
00185 {
00186 if (!lpFuncCmp(ObjectList[i], ObjectList[i + 1]))
00187 {
00188 changed = 1;
00189 Swap(ObjectList[i], ObjectList[i + 1]);
00190 }
00191 }
00192 }
00193 while (changed);
00194 }
00195
00197 template <typename T> void sortContainer(
00198 std::vector<T> &ObjectList, bool (*lpFuncCmp)(T &obj1, T &obj2))
00199 {
00200 s32 changed, i;
00201
00202 do
00203 {
00204 changed = 0;
00205
00206 for (i = 0; i < ObjectList.size() - 1; ++i)
00207 {
00208 if (!lpFuncCmp(ObjectList[i], ObjectList[i + 1]))
00209 {
00210 changed = 1;
00211 Swap(ObjectList[i], ObjectList[i + 1]);
00212 }
00213 }
00214 }
00215 while (changed);
00216 }
00217
00218
00219
00220
00222 SP_EXPORT void getVertexInterpolation(
00223 const dim::triangle3df &Triangle, const dim::vector3df &Pos, f32 &Vert, f32 &Horz
00224 );
00225
00227 template <class T> T getVertexInterpolation(
00228 const T &VertexA, const T &VertexB, const T &VertexC, const f32 Vert, const f32 Horz)
00229 {
00230 return VertexA + (VertexB - VertexA) * Vert + (VertexC - VertexA) * Horz;
00231 }
00232
00233
00234
00235
00236 SP_EXPORT dim::matrix4f getTangentSpace(
00237 const dim::vector3df PosA, const dim::vector3df PosB, const dim::vector3df PosC,
00238 const dim::point2df MapA, const dim::point2df MapB, const dim::point2df MapC,
00239 dim::vector3df &Tangent, dim::vector3df &Binormal, dim::vector3df &Normal
00240 );
00241
00242
00243
00244
00246 inline dim::vector4df Convert(const video::color &Color)
00247 {
00248 return dim::vector4df(
00249 static_cast<f32>(Color.Red ) / 255,
00250 static_cast<f32>(Color.Green) / 255,
00251 static_cast<f32>(Color.Blue ) / 255,
00252 static_cast<f32>(Color.Alpha) / 255
00253 );
00254 }
00255
00257 inline video::color Convert(const dim::vector4df &Color)
00258 {
00259 return video::color(
00260 static_cast<u8>(Color.X * 255),
00261 static_cast<u8>(Color.Y * 255),
00262 static_cast<u8>(Color.Z * 255),
00263 static_cast<u8>(Color.W * 255)
00264 );
00265 }
00266
00267
00268 }
00269
00270 }
00271
00272
00273 #endif
00274
00275
00276
00277