1
/***************************************************************************
2
* Copyright (C) 2006 by Frederic MARTIN *
3
* martin-frederic@users.sourceforge.net *
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU General Public License as published by *
7
* the Free Software Foundation; either version 2 of the License, or *
8
* (at your option) any later version. *
10
* This program is distributed in the hope that it will be useful, *
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13
* GNU General Public License for more details. *
15
* You should have received a copy of the GNU General Public License *
16
* along with this program; if not, write to the *
17
* Free Software Foundation, Inc., *
18
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19
***************************************************************************/
21
#include "CVector.h" // CVector4 class.
24
#define M_PI 3.141592654
29
// Initialize the variables to 0.
34
CVector4::CVector4(float X, float Y, float Z)
36
// Initialize the varibles to the data in X, Y, and Z.
44
CVector4::CVector4(float X, float Y, float Z, float W)
46
// Initialize the varibles to the data in X, Y, and Z.
54
CVector4::CVector4(const CVector4 &v)
56
// Initialize this object to v.
64
void CVector4::operator =(CVector4 v)
66
// Make this objects x, y, and z equal to the object on the right of the = sign.
74
CVector4 CVector4::operator -(CVector4 v)
76
// Return the value of this vector - v.
77
return CVector4(x - v.x, y - v.y, z - v.z);
81
CVector4 CVector4::operator +(CVector4 v)
83
// Return the value of this vector + v.
84
return CVector4(x + v.x, y + v.y, z + v.z);
88
CVector4 CVector4::operator *(CVector4 v)
90
// Return the value of this vector * v.
91
return CVector4(x * v.x, y * v.y, z * v.z);
95
CVector4 CVector4::operator /(CVector4 v)
97
// Return the value of this vector / v.
98
return CVector4(x / v.x, y / v.y, z / v.z);
102
CVector4 CVector4::operator +(float f)
104
// Return the value of this vector + f.
105
return CVector4(x + f, y + f, z + f);
109
CVector4 CVector4::operator -(float f)
111
// Return the value of this vector - f.
112
return CVector4(x - f, y - f, z - f);
116
CVector4 CVector4::operator *(float f)
118
// Return the value of this vector * f.
119
return CVector4(x * f, y * f, z * f);
123
CVector4 CVector4::operator /(float f)
125
// Return the value of this vector / f. We do this by multiplying the recip.
128
return CVector4(x * f, y * f, z * f);
132
void CVector4::operator +=(CVector4 v)
134
// Add this by object v and store results here.
141
void CVector4::operator -=(CVector4 v)
143
// Subtract this by object v and store results here.
150
void CVector4::operator *=(CVector4 v)
152
// Mul this by object v and store results here.
159
void CVector4::operator /=(CVector4 v)
161
// Divide this by object v and store results here.
168
void CVector4::operator +=(float f)
170
// Add this by object f and store results here.
177
void CVector4::operator -=(float f)
179
// Subract this by object f and store results here.
186
void CVector4::operator *=(float f)
188
// Multiply this by object f and store results here.
195
void CVector4::operator /=(float f)
197
// Divide this by object f and store results here by multiplying by the recip.
206
bool CVector4::operator ==(CVector4 v)
208
// Return true if all equal each other, false if one or more don't.
209
return ((x == v.x) && (y== v.y) && (z == v.z));
213
bool CVector4::operator !=(CVector4 v)
215
// Return true if one or all don't equal each other, false if they equal.
216
return !((x == v.x) && (y== v.y) && (z == v.z));
220
void CVector4::CrossProduct(CVector4 v1, CVector4 v2)
222
// Get the cross product of v1 and v2 and store it in this vector.
223
x = ((v1.y * v2.z) - (v1.z * v2.y));
224
y = ((v1.z * v2.x) - (v1.x * v2.z));
225
z = ((v1.x * v2.y) - (v1.y * v2.x));
229
void CVector4::CrossProduct3(CVector4 v1, CVector4 v2, CVector4 v3)
231
// Get the cross product of v1, v2, and v3.
232
x = v1.y * v2.z * v3.w +
239
y = v1.x * v2.w * v3.z +
246
z = v1.x * v2.y * v3.w +
253
w = v1.x * v2.z * v3.y +
262
float CVector4::DotProduct3(CVector4 v1)
264
// Get the dot product of v1 and this object and return it.
265
return x * v1.x + y * v1.y + z * v1.z;
269
float CVector4::DotProduct4(CVector4 v1)
271
// Get the dot product of v1 and this object and return it.
272
return x * v1.x + y * v1.y + z * v1.z + w * v1.w;
276
float CVector4::GetLength()
278
// Return the length for this object.
279
return (float)sqrt((x * x + y * y + z * z));
283
void CVector4::Normal()
285
// Reduce this object to a unit vector.
286
float lenght = GetLength();
298
void CVector4::Normalize(CVector4 Triangle[])
300
// Normalize a triangle and store results in this object.
303
v1.x = Triangle[0].x - Triangle[1].x;
304
v1.y = Triangle[0].y - Triangle[1].y;
305
v1.z = Triangle[0].z - Triangle[1].z;
306
v1.w = Triangle[0].w - Triangle[1].w;
308
v2.x = Triangle[1].x - Triangle[2].x;
309
v2.y = Triangle[1].y - Triangle[2].y;
310
v2.z = Triangle[1].z - Triangle[2].z;
311
v2.w = Triangle[1].w - Triangle[2].w;
313
CrossProduct(v1, v2);
318
void CVector4::CalculateTangentVector(CVector4 Point1, CVector4 Point2, CVector4 Point3,
319
CVector4 NormalOfA, CTexCoord P1Tex, CTexCoord P2Tex,
322
// Get the vector between point 1 and point 2.
323
CVector4 VectorAB = Point2 - Point1;
325
// Get the vector between point 1 and point 3.
326
CVector4 VectorAC = Point3 - Point1;
328
// Compute the components of the vectors to the vertex normal of the first point.
329
CVector4 ProjAB = VectorAB - (NormalOfA * NormalOfA.DotProduct4(VectorAB));
330
CVector4 ProjAC = VectorAC - (NormalOfA * NormalOfA.DotProduct4(VectorAC));
332
// Calculate the tu difference of point 2 and 1 then of point 3 and 1.
333
float TexCoorUAB = P2Tex.tu - P1Tex.tu;
334
float TexCoorUAC = P3Tex.tu - P1Tex.tu;
336
// Calculate the tv difference of point 2 and 1 then of point 3 and 1.
337
float TexCoorVAB = P2Tex.tv - P1Tex.tv;
338
float TexCoorVAC = P3Tex.tv - P1Tex.tv;
340
// Switch the sign if the u of point 1 and 3 * v of 1 and 2 is greater than u of 1 and 2 *
341
// v of point 1 and 3.
342
if((TexCoorUAC * TexCoorVAB) > (TexCoorUAB * TexCoorVAC))
344
TexCoorUAC = -TexCoorUAC;
345
TexCoorUAB = -TexCoorUAB;
348
// Calculate the tangent vector, normalize it, then return it (the normal values).
349
CVector4 Tangent = (ProjAB * TexCoorUAC) - (ProjAC * TexCoorUAB);
356
void CVector4::ExtendVertexPos(CVector4 currentVertex, CVector4 lightPos, float Extend)
358
CVector4 lightDir; // Direction of the light to the vertex position.
359
CVector4 newPos; // New extended vertex position to make up the shadow volume.
361
// Get the light direction from the vertex position and the light position.
362
lightDir = currentVertex - lightPos;
364
// Now that we know where its going we add it to the position of the light so
365
// we get the correct, new position. We multiply it by a passed it value to
366
// give the volume some distance or things won't come out quite as we want.
367
newPos = lightPos + lightDir * Extend;
376
void CVector4::ExtendVertexPos(CVector4 lightPos, float Extend)
378
CVector4 lightDir; // Direction of the light to the vertex position.
379
CVector4 newPos; // New extended vertex position to make up the shadow volume.
381
// Get the light direction from the vertex position and the light position.
382
lightDir = CVector4(x, y, z, w) - lightPos;
384
// Now that we know where its going we add it to the position of the light so
385
// we get the correct, new position. We multiply it by a passed it value to
386
// give the volume some distance or things won't come out quite as we want.
387
newPos = lightPos + lightDir * Extend;
396
CVector4 CVector4::GetRotatedX(double angle)
398
float sinAngle = (float)sin(M_PI * angle / 180);
399
float cosAngle = (float)cos(M_PI * angle / 180);
401
return CVector4(x, y * cosAngle - z * sinAngle, y * sinAngle + z * cosAngle, w);
405
CVector4 CVector4::GetRotatedY(double angle)
407
float sinAngle = (float)sin(M_PI * angle / 180);
408
float cosAngle = (float)cos(M_PI * angle / 180);
410
return CVector4(x * cosAngle + z * sinAngle, y, -x * sinAngle + z * cosAngle, w);
414
CVector4 CVector4::GetRotatedZ(double angle)
416
float sinAngle = (float)sin(M_PI * angle / 180);
417
float cosAngle = (float)cos(M_PI * angle / 180);
419
return CVector4(x * cosAngle - y * sinAngle, x * sinAngle + y * cosAngle, z, w);
423
CVector4 CVector4::GetRotatedAxis(double angle, CVector4 axis)
425
if(angle == 0.0) return(*this);
429
CVector4 RotationRow1, RotationRow2, RotationRow3;
431
double newAngle = M_PI * angle / 180;
432
float sinAngle = (float)sin(newAngle);
433
float cosAngle = (float)cos(newAngle);
434
float oneSubCos = 1.0f - cosAngle;
436
RotationRow1.x = (axis.x) * (axis.x) + cosAngle * (1 - (axis.x) * (axis.x));
437
RotationRow1.y = (axis.x) * (axis.y) * (oneSubCos) - sinAngle * axis.z;
438
RotationRow1.z = (axis.x) * (axis.z) * (oneSubCos) + sinAngle * axis.y;
440
RotationRow2.x = (axis.x) * (axis.y) * (oneSubCos) + sinAngle * axis.z;
441
RotationRow2.y = (axis.y) * (axis.y) + cosAngle * (1 - (axis.y) * (axis.y));
442
RotationRow2.z = (axis.y) * (axis.z) * (oneSubCos) - sinAngle * axis.x;
444
RotationRow3.x = (axis.x) * (axis.z) * (oneSubCos) - sinAngle * axis.y;
445
RotationRow3.y = (axis.y) * (axis.z) * (oneSubCos) + sinAngle * axis.x;
446
RotationRow3.z = (axis.z) * (axis.z) + cosAngle * (1 - (axis.z) * (axis.z));
448
return CVector4(this->DotProduct3(RotationRow1),
449
this->DotProduct3(RotationRow2),
450
this->DotProduct3(RotationRow3));
454
void CVector4::CalculateBinormalVector(CVector4 tangent, CVector4 normal)
456
this->CrossProduct(tangent, normal);
460
void CVector4::ClampTo01()
462
CVector4 temp(x, y, z, w);
464
temp = temp * 0.5f + CVector4(0.5f, 0.5f, 0.5f);