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