CVector.cpp
上传用户:jinmajixie
上传日期:2022-07-12
资源大小:435k
文件大小:11k
源码类别:

OpenGL

开发平台:

Visual C++

  1. /*
  2.    Class Name:
  3.       CVector.
  4.    Created by:
  5.       Allen Sherrod (Programming Ace of www.UltimateGameProgramming.com).
  6.    Description:
  7.       This class represents a 3D point for a vertex's x, y, z.
  8. */
  9. #include"main.h"        // CVector class.
  10. #ifndef M_PI
  11. #define M_PI 3.141592654
  12. #endif M_PI
  13. /*******************************************************************************
  14. * VECTOR
  15. *******************************************************************************/
  16. CVector::CVector()
  17. {
  18.    // Initialize the variables to 0.
  19.    x = y = z = 0.0;
  20. }
  21. CVector::CVector(float X, float Y, float Z)
  22. {
  23.    // Initialize the varibles to the data in X, Y, and Z.
  24.    x = X;
  25.    y = Y;
  26.    z = Z;
  27. }
  28. CVector::CVector(const CVector &v)
  29. {
  30.    // Initialize this object to v.
  31.    x = v.x;
  32.    y = v.y;
  33.    z = v.z;
  34. }
  35. void CVector::operator =(CVector v)
  36. {
  37.    // Make this objects x, y, and z equal to the object on the right of the = sign.
  38.    x = v.x;
  39.    y = v.y;
  40.    z = v.z;
  41. }
  42. void CVector::operator =(float f)
  43. {
  44.    // Make this objects x, y, and z equal to the object on the right of the = sign.
  45.    x = f;
  46.    y = f;
  47.    z = f;
  48. }
  49. CVector CVector::operator -(CVector v)
  50. {
  51.    // Return the value of this vector - v.
  52.    return CVector(x - v.x, y - v.y, z - v.z);
  53. }
  54. CVector CVector::operator +(CVector v)
  55. {
  56.    // Return the value of this vector + v.
  57.    return CVector(x + v.x, y + v.y, z + v.z);
  58. }
  59. CVector CVector::operator *(CVector v)
  60. {
  61.    // Return the value of this vector * v.
  62.    return CVector(x * v.x, y * v.y, z * v.z);
  63. }
  64. CVector CVector::operator /(CVector v)
  65. {
  66.    // Return the value of this vector / v.
  67.    return CVector(x / v.x, y / v.y, z / v.z);
  68. }
  69. CVector CVector::operator +(float f)
  70. {
  71.    // Return the value of this vector + f.
  72.    return CVector(x + f, y + f, z + f);
  73. }
  74. CVector CVector::operator -(float f)
  75. {
  76.    // Return the value of this vector - f.
  77.    return CVector(x - f, y - f, z - f);
  78. }
  79. CVector CVector::operator *(float f)
  80. {
  81.    // Return the value of this vector * f.
  82.    return CVector(x * f, y * f, z * f);
  83. }
  84. CVector CVector::operator /(float f)
  85. {
  86.    // Return the value of this vector / f.  We do this by multiplying the recip.
  87.    f = 1/f;
  88.    return CVector(x * f, y * f, z * f);
  89. }
  90. void CVector::operator +=(CVector v)
  91. {
  92.    // Add this by object v and store results here.
  93.    x += v.x;
  94.    y += v.y;
  95.    z += v.z;
  96. }
  97. void CVector::operator -=(CVector v)
  98. {
  99.    // Subtract this by object v and store results here.
  100.    x -= v.x;
  101.    y -= v.y;
  102.    z -= v.z;
  103. }
  104. void CVector::operator *=(CVector v)
  105. {
  106.    // Mul this by object v and store results here.
  107.    x *= v.x;
  108.    y *= v.y;
  109.    z *= v.z;
  110. }
  111. void CVector::operator /=(CVector v)
  112. {
  113.    // Divide this by object v and store results here.
  114.    x /= v.x;
  115.    y /= v.y;
  116.    z /= v.z;
  117. }
  118. void CVector::operator +=(float f)
  119. {
  120.    // Add this by object f and store results here.
  121.    x += f;
  122.    y += f;
  123.    z += f;
  124. }
  125. void CVector::operator -=(float f)
  126. {
  127.    // Subract this by object f and store results here.
  128.    x -= f;
  129.    y -= f;
  130.    z -= f;
  131. }
  132. void CVector::operator *=(float f)
  133. {
  134.    // Multiply this by object f and store results here.
  135.    x *= f;
  136.    y *= f;
  137.    z *= f;
  138. }
  139. void CVector::operator /=(float f)
  140. {
  141.    // Divide this by object f and store results here by multiplying by the recip.
  142.    f = 1/f;
  143.    x *= f;
  144.    y *= f;
  145.    z *= f;
  146. }
  147. bool CVector::operator >(CVector v)
  148. {
  149.    return (GetLength() > v.GetLength());
  150. }
  151. bool CVector::operator <(CVector v)
  152. {
  153.    return (GetLength() < v.GetLength());
  154. }
  155. bool CVector::operator >(float f)
  156. {
  157.    return (GetLength() > f);
  158. }
  159. bool CVector::operator <(float f)
  160. {
  161.    return (GetLength() < f);
  162. }
  163. bool CVector::operator ==(CVector v)
  164. {
  165.    // Return true if all equal each other, false if one or more don't.
  166.    return ((x == v.x) && (y== v.y) && (z == v.z));
  167. }
  168. bool CVector::operator !=(CVector v)
  169. {
  170.    // Return true if one or all don't equal each other, false if they equal.
  171.    return !((x == v.x) && (y== v.y) && (z == v.z));
  172. }
  173. void CVector::CrossProduct(CVector v1, CVector v2)
  174. {
  175.    // Get the cross product of v1 and v2 and store it in this vector.
  176.    x = ((v1.y * v2.z) - (v1.z * v2.y));
  177.    y = ((v1.z * v2.x) - (v1.x * v2.z));
  178.    z = ((v1.x * v2.y) - (v1.y * v2.x));
  179. }
  180. void CVector::CrossProduct3(CVector v1, CVector v2, CVector v3)
  181. {
  182.    // Get the cross product of v1, v2, and v3.
  183.    x = v1.y * v2.z +
  184.        v1.z * v3.y +
  185.        v2.y * v3.z - 
  186.        v1.y * v3.z -
  187.        v1.z * v2.y -
  188.        v2.z * v3.y;
  189.    y = v1.x * v3.z +
  190.        v1.z * v2.x +
  191.        v2.z * v3.x -
  192.        v1.x * v2.z -
  193.        v1.z * v3.x -
  194.        v2.x * v3.z;
  195.    z = v1.x * v2.y +
  196.        v1.y * v3.x +
  197.        v2.x * v3.y -
  198.        v1.x * v3.y -
  199.        v1.y * v2.x -
  200.        v2.y * v3.x;
  201. }
  202. float CVector::DotProduct3(CVector v1)
  203. {
  204.    // Get the dot product of v1 and this object and return it.
  205.    return x * v1.x + y * v1.y + z * v1.z;
  206. }
  207. float CVector::GetLength()
  208. {
  209.    // Return the length for this object.
  210.    return (float)sqrt((x * x + y * y + z * z));
  211. }
  212. void CVector::Normal()
  213. {
  214.    // Reduce this object to a unit vector.
  215.    float length = GetLength();
  216.    if(length == 0.0f)
  217.       length = 1.0f;
  218.    x = x/length;
  219.    y = y/length;
  220.    z = z/length;
  221. }
  222. CVector CVector::Normalized()
  223. {
  224. float length = GetLength();
  225. if(length == 0.0f) length = 1.0f;
  226. CVector result;
  227. result.x = x / length;
  228. result.y = y / length;
  229. result.z = z / length;
  230. return result;
  231. }
  232. void CVector::Normalize(CVector Triangle[])
  233. {
  234.    // Normalize a triangle and store results in this object.
  235.    CVector v1, v2;
  236.    v1.x = Triangle[0].x - Triangle[1].x;
  237.    v1.y = Triangle[0].y - Triangle[1].y;
  238.    v1.z = Triangle[0].z - Triangle[1].z;
  239.    v2.x = Triangle[1].x - Triangle[2].x;
  240.    v2.y = Triangle[1].y - Triangle[2].y;
  241.    v2.z = Triangle[1].z - Triangle[2].z;
  242.    CrossProduct(v1, v2);
  243.    Normal();
  244. }
  245. /*
  246. void CVector::CalculateTangentVector(CVector Point1, CVector Point2, CVector Point3,
  247.                                       CVector NormalOfA, CTexCoord P1Tex, CTexCoord P2Tex,
  248.                                       CTexCoord P3Tex)
  249. {
  250.    // Get the vector between point 1 and point 2.
  251.    CVector VectorAB = Point2 - Point1;
  252.    // Get the vector between point 1 and point 3.
  253. CVector VectorAC = Point3 - Point1;
  254.    // Compute the components of the vectors to the vertex normal of the first point.
  255.    CVector ProjAB = VectorAB - (NormalOfA * NormalOfA.DotProduct3(VectorAB));
  256.    CVector ProjAC = VectorAC - (NormalOfA * NormalOfA.DotProduct3(VectorAC));
  257.    // Calculate the tu difference of point 2 and 1 then of point 3 and 1.
  258.    float TexCoorUAB = P2Tex.tu - P1Tex.tu;
  259.    float TexCoorUAC = P3Tex.tu - P1Tex.tu;
  260. // Calculate the tv difference of point 2 and 1 then of point 3 and 1.
  261.    float TexCoorVAB = P2Tex.tv - P1Tex.tv;
  262.    float TexCoorVAC = P3Tex.tv - P1Tex.tv;
  263.    // Switch the sign if the u of point 1 and 3 * v of 1 and 2 is greater than u of 1 and 2 *
  264.    // v of point 1 and 3.
  265.    if((TexCoorUAC * TexCoorVAB) > (TexCoorUAB * TexCoorVAC))
  266.       {
  267.          TexCoorUAC = -TexCoorUAC;
  268.          TexCoorUAB = -TexCoorUAB;
  269.       }
  270.    // Calculate the tangent vector, normalize it, then return it (the normal values).
  271.    CVector Tangent = (ProjAB * TexCoorUAC) - (ProjAC * TexCoorUAB);
  272.    Tangent.Normal();
  273.    *this += Tangent;
  274. }
  275. */
  276. void CVector::ExtendVertexPos(CVector currentVertex, CVector lightPos, float Extend)
  277. {
  278.     CVector lightDir;  // Direction of the light to the vertex position.
  279.     CVector newPos;    // New extended vertex position to make up the shadow volume.
  280.     // Get the light direction from the vertex position and the light position.
  281.     lightDir = currentVertex - lightPos;
  282.     // Now that we know where its going we add it to the position of the light so
  283.     // we get the correct, new position.  We multiply it by a passed it value to
  284.     // give the volume some distance or things won't come out quite as we want.
  285.     newPos = lightPos + lightDir * Extend;
  286.     x = newPos.x;
  287.     y = newPos.y;
  288.     z = newPos.z;
  289. }
  290. void CVector::ExtendVertexPos(CVector lightPos, float Extend)
  291. {
  292.     CVector lightDir;  // Direction of the light to the vertex position.
  293.     CVector newPos;    // New extended vertex position to make up the shadow volume.
  294.     // Get the light direction from the vertex position and the light position.
  295.     lightDir = CVector(x, y, z) - lightPos;
  296.     // Now that we know where its going we add it to the position of the light so
  297.     // we get the correct, new position.  We multiply it by a passed it value to
  298.     // give the volume some distance or things won't come out quite as we want.
  299.     newPos = lightPos + lightDir * Extend;
  300.     x = newPos.x;
  301.     y = newPos.y;
  302.     z = newPos.z;
  303. }
  304. CVector CVector::GetRotatedX(double angle)
  305. {
  306.    float sinAngle = (float)sin(M_PI * angle / 180);
  307. float cosAngle = (float)cos(M_PI * angle / 180);
  308. return CVector(x, y * cosAngle - z * sinAngle, y * sinAngle + z * cosAngle);
  309. }
  310. CVector CVector::GetRotatedY(double angle)
  311. {
  312.    float sinAngle = (float)sin(M_PI * angle / 180);
  313. float cosAngle = (float)cos(M_PI * angle / 180);
  314. return CVector(x * cosAngle + z * sinAngle, y, -x * sinAngle + z * cosAngle);
  315. }
  316. CVector CVector::GetRotatedZ(double angle)
  317. {
  318.    float sinAngle = (float)sin(M_PI * angle / 180);
  319. float cosAngle = (float)cos(M_PI * angle / 180);
  320. return CVector(x * cosAngle - y * sinAngle, x * sinAngle + y * cosAngle, z);
  321. }
  322. CVector CVector::GetRotatedAxis(double angle, CVector axis)
  323. {
  324. if(angle == 0.0) return(*this);
  325.    axis.Normal();
  326. CVector RotationRow1, RotationRow2, RotationRow3;
  327.    double newAngle = M_PI * angle / 180;
  328. float sinAngle = (float)sin(newAngle);
  329. float cosAngle = (float)cos(newAngle);
  330. float oneSubCos = 1.0f - cosAngle;
  331. RotationRow1.x = (axis.x) * (axis.x) + cosAngle * (1 - (axis.x) * (axis.x));
  332. RotationRow1.y = (axis.x) * (axis.y) * (oneSubCos) - sinAngle * axis.z;
  333. RotationRow1.z = (axis.x) * (axis.z) * (oneSubCos) + sinAngle * axis.y;
  334. RotationRow2.x = (axis.x) * (axis.y) * (oneSubCos) + sinAngle * axis.z;
  335. RotationRow2.y = (axis.y) * (axis.y) + cosAngle * (1 - (axis.y) * (axis.y));
  336. RotationRow2.z = (axis.y) * (axis.z) * (oneSubCos) - sinAngle * axis.x;
  337. RotationRow3.x = (axis.x) * (axis.z) * (oneSubCos) - sinAngle * axis.y;
  338. RotationRow3.y = (axis.y) * (axis.z) * (oneSubCos) + sinAngle * axis.x;
  339. RotationRow3.z = (axis.z) * (axis.z) + cosAngle * (1 - (axis.z) * (axis.z));
  340. return CVector(this->DotProduct3(RotationRow1),
  341.                    this->DotProduct3(RotationRow2),
  342.                    this->DotProduct3(RotationRow3));
  343. }
  344. void CVector::CalculateBinormalVector(CVector tangent, CVector normal)
  345. {
  346.    this->CrossProduct(tangent, normal);
  347. }
  348. void CVector::ClampTo01()
  349. {
  350.    CVector temp(x, y, z);
  351.    temp.Normal();
  352.    temp = temp * 0.5f + CVector(0.5f, 0.5f, 0.5f);
  353.    x = temp.x;
  354.    y = temp.y;
  355.    z = temp.z;
  356. }
  357. // Copyright September 2003
  358. // All Rights Reserved!
  359. // Allen Sherrod
  360. // ProgrammingAce@UltimateGameProgramming.com
  361. // www.UltimateGameProgramming.com