IcePoint.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. /**
  3. * Contains code for 3D vectors.
  4. * \file IcePoint.cpp
  5. * \author Pierre Terdiman
  6. * \date April, 4, 2000
  7. */
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  10. /**
  11. * 3D point.
  12. *
  13. * The name is "Point" instead of "Vector" since a vector is N-dimensional, whereas a point is an implicit "vector of dimension 3".
  14. * So the choice was between "Point" and "Vector3", the first one looked better (IMHO).
  15. *
  16. * Some people, then, use a typedef to handle both points & vectors using the same class: typedef Point Vector3;
  17. * This is bad since it opens the door to a lot of confusion while reading the code. I know it may sounds weird but check this out:
  18. *
  19. * \code
  20. * Point P0,P1 = some 3D points;
  21. * Point Delta = P1 - P0;
  22. * \endcode
  23. *
  24. * This compiles fine, although you should have written:
  25. *
  26. * \code
  27. * Point P0,P1 = some 3D points;
  28. * Vector3 Delta = P1 - P0;
  29. * \endcode
  30. *
  31. * Subtle things like this are not caught at compile-time, and when you find one in the code, you never know whether it's a mistake
  32. * from the author or something you don't get.
  33. *
  34. * One way to handle it at compile-time would be to use different classes for Point & Vector3, only overloading operator "-" for vectors.
  35. * But then, you get a lot of redundant code in thoses classes, and basically it's really a lot of useless work.
  36. *
  37. * Another way would be to use homogeneous points: w=1 for points, w=0 for vectors. That's why the HPoint class exists. Now, to store
  38. * your model's vertices and in most cases, you really want to use Points to save ram.
  39. *
  40. * \class Point
  41. * \author Pierre Terdiman
  42. * \version 1.0
  43. */
  44. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  45. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  46. // Precompiled Header
  47. #include "Stdafx.h"
  48. using namespace IceMaths;
  49. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  50. /**
  51. * Creates a positive unit random vector.
  52. * \return Self-reference
  53. */
  54. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  55. Point& Point::PositiveUnitRandomVector()
  56. {
  57. x = UnitRandomFloat();
  58. y = UnitRandomFloat();
  59. z = UnitRandomFloat();
  60. Normalize();
  61. return *this;
  62. }
  63. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. /**
  65. * Creates a unit random vector.
  66. * \return Self-reference
  67. */
  68. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. Point& Point::UnitRandomVector()
  70. {
  71. x = UnitRandomFloat() - 0.5f;
  72. y = UnitRandomFloat() - 0.5f;
  73. z = UnitRandomFloat() - 0.5f;
  74. Normalize();
  75. return *this;
  76. }
  77. // Cast operator
  78. // WARNING: not inlined
  79. Point::operator HPoint() const { return HPoint(x, y, z, 0.0f); }
  80. Point& Point::Refract(const Point& eye, const Point& n, float refractindex, Point& refracted)
  81. {
  82. // Point EyePt = eye position
  83. // Point p = current vertex
  84. // Point n = vertex normal
  85. // Point rv = refracted vector
  86. // Eye vector - doesn't need to be normalized
  87. Point Env;
  88. Env.x = eye.x - x;
  89. Env.y = eye.y - y;
  90. Env.z = eye.z - z;
  91. float NDotE = n|Env;
  92. float NDotN = n|n;
  93. NDotE /= refractindex;
  94. // Refracted vector
  95. refracted = n*NDotE - Env*NDotN;
  96. return *this;
  97. }
  98. Point& Point::ProjectToPlane(const Plane& p)
  99. {
  100. *this-= (p.d + (*this|p.n))*p.n;
  101. return *this;
  102. }
  103. void Point::ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const
  104. {
  105. projected = HPoint(x, y, z, 1.0f) * mat;
  106. projected.w = 1.0f / projected.w;
  107. projected.x*=projected.w;
  108. projected.y*=projected.w;
  109. projected.z*=projected.w;
  110. projected.x *= halfrenderwidth; projected.x += halfrenderwidth;
  111. projected.y *= -halfrenderheight; projected.y += halfrenderheight;
  112. }
  113. void Point::SetNotUsed()
  114. {
  115. // We use a particular integer pattern : 0xffffffff everywhere. This is a NAN.
  116. x = y = z = FR(0xffffffff);
  117. }
  118. BOOL Point::IsNotUsed() const
  119. {
  120. if(IR(x)!=0xffffffff) return FALSE;
  121. if(IR(y)!=0xffffffff) return FALSE;
  122. if(IR(z)!=0xffffffff) return FALSE;
  123. return TRUE;
  124. }
  125. Point& Point::Mult(const Matrix3x3& mat, const Point& a)
  126. {
  127. x = a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2];
  128. y = a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2];
  129. z = a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2];
  130. return *this;
  131. }
  132. Point& Point::Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2)
  133. {
  134. x = a1.x * mat1.m[0][0] + a1.y * mat1.m[0][1] + a1.z * mat1.m[0][2] + a2.x * mat2.m[0][0] + a2.y * mat2.m[0][1] + a2.z * mat2.m[0][2];
  135. y = a1.x * mat1.m[1][0] + a1.y * mat1.m[1][1] + a1.z * mat1.m[1][2] + a2.x * mat2.m[1][0] + a2.y * mat2.m[1][1] + a2.z * mat2.m[1][2];
  136. z = a1.x * mat1.m[2][0] + a1.y * mat1.m[2][1] + a1.z * mat1.m[2][2] + a2.x * mat2.m[2][0] + a2.y * mat2.m[2][1] + a2.z * mat2.m[2][2];
  137. return *this;
  138. }
  139. Point& Point::Mac(const Matrix3x3& mat, const Point& a)
  140. {
  141. x += a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2];
  142. y += a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2];
  143. z += a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2];
  144. return *this;
  145. }
  146. Point& Point::TransMult(const Matrix3x3& mat, const Point& a)
  147. {
  148. x = a.x * mat.m[0][0] + a.y * mat.m[1][0] + a.z * mat.m[2][0];
  149. y = a.x * mat.m[0][1] + a.y * mat.m[1][1] + a.z * mat.m[2][1];
  150. z = a.x * mat.m[0][2] + a.y * mat.m[1][2] + a.z * mat.m[2][2];
  151. return *this;
  152. }
  153. Point& Point::Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos)
  154. {
  155. x = r.x * rotpos.m[0][0] + r.y * rotpos.m[0][1] + r.z * rotpos.m[0][2] + linpos.x;
  156. y = r.x * rotpos.m[1][0] + r.y * rotpos.m[1][1] + r.z * rotpos.m[1][2] + linpos.y;
  157. z = r.x * rotpos.m[2][0] + r.y * rotpos.m[2][1] + r.z * rotpos.m[2][2] + linpos.z;
  158. return *this;
  159. }
  160. Point& Point::InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos)
  161. {
  162. float sx = r.x - linpos.x;
  163. float sy = r.y - linpos.y;
  164. float sz = r.z - linpos.z;
  165. x = sx * rotpos.m[0][0] + sy * rotpos.m[1][0] + sz * rotpos.m[2][0];
  166. y = sx * rotpos.m[0][1] + sy * rotpos.m[1][1] + sz * rotpos.m[2][1];
  167. z = sx * rotpos.m[0][2] + sy * rotpos.m[1][2] + sz * rotpos.m[2][2];
  168. return *this;
  169. }