~ubuntu-branches/ubuntu/edgy/pouetchess/edgy-updates

« back to all changes in this revision

Viewing changes to src/CVector.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc (mr_pouit)
  • Date: 2006-07-15 15:45:57 UTC
  • Revision ID: james.westby@ubuntu.com-20060715154557-3paxq02hx4od0wm4
Tags: upstream-0.2.0
ImportĀ upstreamĀ versionĀ 0.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2006 by Frederic MARTIN                                 *
 
3
 *   martin-frederic@users.sourceforge.net                                 *
 
4
 *                                                                         *
 
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.                                   *
 
9
 *                                                                         *
 
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.                          *
 
14
 *                                                                         *
 
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
 ***************************************************************************/
 
20
 
 
21
#include "CVector.h"        // CVector4 class.
 
22
 
 
23
#ifndef M_PI
 
24
#define M_PI 3.141592654
 
25
#endif
 
26
 
 
27
CVector4::CVector4()
 
28
{
 
29
   // Initialize the variables to 0.
 
30
        x = y = z = w = 0.0f;
 
31
}
 
32
 
 
33
 
 
34
CVector4::CVector4(float X, float Y, float Z)
 
35
{
 
36
   // Initialize the varibles to the data in X, Y, and Z.
 
37
   x = X;
 
38
   y = Y;
 
39
   z = Z;
 
40
   w = 0.0f;
 
41
}
 
42
 
 
43
 
 
44
CVector4::CVector4(float X, float Y, float Z, float W)
 
45
{
 
46
   // Initialize the varibles to the data in X, Y, and Z.
 
47
   x = X;
 
48
   y = Y;
 
49
   z = Z;
 
50
   w = W;
 
51
}
 
52
 
 
53
 
 
54
CVector4::CVector4(const CVector4 &v)
 
55
{
 
56
   // Initialize this object to v.
 
57
   x = v.x;
 
58
   y = v.y;
 
59
   z = v.z;
 
60
   w = v.w;
 
61
}
 
62
 
 
63
 
 
64
void CVector4::operator =(CVector4 v)
 
65
{
 
66
   // Make this objects x, y, and z equal to the object on the right of the = sign.
 
67
   x = v.x;
 
68
   y = v.y;
 
69
   z = v.z;
 
70
   w = v.w;
 
71
}
 
72
 
 
73
 
 
74
CVector4 CVector4::operator -(CVector4 v)
 
75
{
 
76
   // Return the value of this vector - v.
 
77
   return CVector4(x - v.x, y - v.y, z - v.z);
 
78
}
 
79
 
 
80
 
 
81
CVector4 CVector4::operator +(CVector4 v)
 
82
{
 
83
   // Return the value of this vector + v.
 
84
   return CVector4(x + v.x, y + v.y, z + v.z);
 
85
}
 
86
 
 
87
 
 
88
CVector4 CVector4::operator *(CVector4 v)
 
89
{
 
90
   // Return the value of this vector * v.
 
91
   return CVector4(x * v.x, y * v.y, z * v.z);
 
92
}
 
93
 
 
94
 
 
95
CVector4 CVector4::operator /(CVector4 v)
 
96
{
 
97
   // Return the value of this vector / v.
 
98
   return CVector4(x / v.x, y / v.y, z / v.z);
 
99
}
 
100
 
 
101
 
 
102
CVector4 CVector4::operator +(float f)
 
103
{
 
104
   // Return the value of this vector + f.
 
105
   return CVector4(x + f, y + f, z + f);
 
106
}
 
107
 
 
108
 
 
109
CVector4 CVector4::operator -(float f)
 
110
{
 
111
   // Return the value of this vector - f.
 
112
   return CVector4(x - f, y - f, z - f);
 
113
}
 
114
 
 
115
 
 
116
CVector4 CVector4::operator *(float f)
 
117
{
 
118
   // Return the value of this vector * f.
 
119
   return CVector4(x * f, y * f, z * f);
 
120
}
 
121
 
 
122
 
 
123
CVector4 CVector4::operator /(float f)
 
124
{
 
125
   // Return the value of this vector / f.  We do this by multiplying the recip.
 
126
   f = 1/f;
 
127
 
 
128
   return CVector4(x * f, y * f, z * f);
 
129
}
 
130
 
 
131
 
 
132
void CVector4::operator +=(CVector4 v)
 
133
{
 
134
   // Add this by object v and store results here.
 
135
   x += v.x;
 
136
   y += v.y;
 
137
   z += v.z;
 
138
}
 
139
 
 
140
 
 
141
void CVector4::operator -=(CVector4 v)
 
142
{
 
143
   // Subtract this by object v and store results here.
 
144
   x -= v.x;
 
145
   y -= v.y;
 
146
   z -= v.z;
 
147
}
 
148
 
 
149
 
 
150
void CVector4::operator *=(CVector4 v)
 
151
{
 
152
   // Mul this by object v and store results here.
 
153
   x *= v.x;
 
154
   y *= v.y;
 
155
   z *= v.z;
 
156
}
 
157
 
 
158
 
 
159
void CVector4::operator /=(CVector4 v)
 
160
{
 
161
   // Divide this by object v and store results here.
 
162
   x /= v.x;
 
163
   y /= v.y;
 
164
   z /= v.z;
 
165
}
 
166
 
 
167
 
 
168
void CVector4::operator +=(float f)
 
169
{
 
170
   // Add this by object f and store results here.
 
171
   x += f;
 
172
   y += f;
 
173
   z += f;
 
174
}
 
175
 
 
176
 
 
177
void CVector4::operator -=(float f)
 
178
{
 
179
   // Subract this by object f and store results here.
 
180
   x -= f;
 
181
   y -= f;
 
182
   z -= f;
 
183
}
 
184
 
 
185
 
 
186
void CVector4::operator *=(float f)
 
187
{
 
188
   // Multiply this by object f and store results here.
 
189
   x *= f;
 
190
   y *= f;
 
191
   z *= f;
 
192
}
 
193
 
 
194
 
 
195
void CVector4::operator /=(float f)
 
196
{
 
197
   // Divide this by object f and store results here by multiplying by the recip.
 
198
   f = 1/f;
 
199
 
 
200
   x *= f;
 
201
   y *= f;
 
202
   z *= f;
 
203
}
 
204
 
 
205
 
 
206
bool CVector4::operator ==(CVector4 v)
 
207
{
 
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));
 
210
}
 
211
 
 
212
 
 
213
bool CVector4::operator !=(CVector4 v)
 
214
{
 
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));
 
217
}
 
218
 
 
219
 
 
220
void CVector4::CrossProduct(CVector4 v1, CVector4 v2)
 
221
{
 
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));
 
226
}
 
227
 
 
228
 
 
229
void CVector4::CrossProduct3(CVector4 v1, CVector4 v2, CVector4 v3)
 
230
{
 
231
   // Get the cross product of v1, v2, and v3.
 
232
   x = v1.y * v2.z * v3.w +
 
233
       v1.z * v2.w * v3.y +
 
234
       v1.w * v2.y * v3.z - 
 
235
       v1.y * v2.w * v3.z -
 
236
       v1.z * v2.y * v3.w -
 
237
       v1.w * v2.z * v3.y;
 
238
 
 
239
   y = v1.x * v2.w * v3.z +
 
240
       v1.z * v2.x * v3.w +
 
241
       v1.w * v2.z * v3.x -
 
242
       v1.x * v2.z * v3.w -
 
243
       v1.z * v2.w * v3.x -
 
244
       v1.w * v2.x * v3.z;
 
245
 
 
246
   z = v1.x * v2.y * v3.w +
 
247
       v1.y * v2.w * v3.x +
 
248
       v1.w * v2.x * v3.y -
 
249
       v1.x * v2.w * v3.y -
 
250
       v1.y * v2.x * v3.w -
 
251
       v1.w * v2.y * v3.x;
 
252
 
 
253
   w = v1.x * v2.z * v3.y +
 
254
       v1.y * v2.x * v3.z +
 
255
       v1.z * v2.y * v3.x -
 
256
       v1.x * v2.y * v3.z -
 
257
       v1.y * v2.z * v3.x -
 
258
       v1.z * v2.x * v3.y;
 
259
}
 
260
 
 
261
 
 
262
float CVector4::DotProduct3(CVector4 v1)
 
263
{
 
264
   // Get the dot product of v1 and this object and return it.
 
265
   return x * v1.x + y * v1.y + z * v1.z;
 
266
}
 
267
 
 
268
 
 
269
float CVector4::DotProduct4(CVector4 v1)
 
270
{
 
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;
 
273
}
 
274
 
 
275
 
 
276
float CVector4::GetLength()
 
277
{
 
278
   // Return the length for this object.
 
279
   return (float)sqrt((x * x + y * y + z * z));
 
280
}
 
281
 
 
282
 
 
283
void CVector4::Normal()
 
284
{
 
285
   // Reduce this object to a unit vector.
 
286
   float lenght = GetLength();
 
287
 
 
288
   if(lenght == 0.0f)
 
289
      lenght = 1.0f;
 
290
 
 
291
   x = x/lenght;
 
292
   y = y/lenght;
 
293
   z = z/lenght;
 
294
   w = w/lenght;
 
295
}
 
296
 
 
297
 
 
298
void CVector4::Normalize(CVector4 Triangle[])
 
299
{
 
300
   // Normalize a triangle and store results in this object.
 
301
   CVector4 v1, v2;
 
302
 
 
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;
 
307
 
 
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;
 
312
 
 
313
   CrossProduct(v1, v2);
 
314
   Normal();
 
315
}
 
316
 
 
317
 
 
318
void CVector4::CalculateTangentVector(CVector4 Point1, CVector4 Point2, CVector4 Point3,
 
319
                                                                          CVector4 NormalOfA, CTexCoord P1Tex, CTexCoord P2Tex,
 
320
                                                                          CTexCoord P3Tex)
 
321
{
 
322
        // Get the vector between point 1 and point 2.
 
323
        CVector4 VectorAB = Point2 - Point1;
 
324
 
 
325
        // Get the vector between point 1 and point 3.
 
326
        CVector4 VectorAC = Point3 - Point1;
 
327
 
 
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));
 
331
 
 
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;
 
335
 
 
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;
 
339
 
 
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))
 
343
        {
 
344
                TexCoorUAC = -TexCoorUAC;
 
345
                TexCoorUAB = -TexCoorUAB;
 
346
        }
 
347
 
 
348
        // Calculate the tangent vector, normalize it, then return it (the normal values).
 
349
        CVector4 Tangent = (ProjAB * TexCoorUAC) - (ProjAC * TexCoorUAB);
 
350
        Tangent.Normal();
 
351
 
 
352
        *this += Tangent;
 
353
}
 
354
 
 
355
 
 
356
void CVector4::ExtendVertexPos(CVector4 currentVertex, CVector4 lightPos, float Extend)
 
357
{
 
358
    CVector4 lightDir;  // Direction of the light to the vertex position.
 
359
    CVector4 newPos;    // New extended vertex position to make up the shadow volume.
 
360
 
 
361
    // Get the light direction from the vertex position and the light position.
 
362
    lightDir = currentVertex - lightPos;
 
363
 
 
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;
 
368
 
 
369
    x = newPos.x;
 
370
    y = newPos.y;
 
371
    z = newPos.z;
 
372
    w = newPos.w;
 
373
}
 
374
 
 
375
 
 
376
void CVector4::ExtendVertexPos(CVector4 lightPos, float Extend)
 
377
{
 
378
    CVector4 lightDir;  // Direction of the light to the vertex position.
 
379
    CVector4 newPos;    // New extended vertex position to make up the shadow volume.
 
380
 
 
381
    // Get the light direction from the vertex position and the light position.
 
382
    lightDir = CVector4(x, y, z, w) - lightPos;
 
383
 
 
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;
 
388
 
 
389
    x = newPos.x;
 
390
    y = newPos.y;
 
391
    z = newPos.z;
 
392
    w = newPos.w;
 
393
}
 
394
 
 
395
 
 
396
CVector4 CVector4::GetRotatedX(double angle)
 
397
{
 
398
   float sinAngle = (float)sin(M_PI * angle / 180);
 
399
        float cosAngle = (float)cos(M_PI * angle / 180);
 
400
 
 
401
        return CVector4(x, y * cosAngle - z * sinAngle, y * sinAngle + z * cosAngle, w);
 
402
}
 
403
 
 
404
 
 
405
CVector4 CVector4::GetRotatedY(double angle)
 
406
{
 
407
   float sinAngle = (float)sin(M_PI * angle / 180);
 
408
        float cosAngle = (float)cos(M_PI * angle / 180);
 
409
 
 
410
        return CVector4(x * cosAngle + z * sinAngle, y, -x * sinAngle + z * cosAngle, w);
 
411
}
 
412
 
 
413
 
 
414
CVector4 CVector4::GetRotatedZ(double angle)
 
415
{
 
416
   float sinAngle = (float)sin(M_PI * angle / 180);
 
417
        float cosAngle = (float)cos(M_PI * angle / 180);
 
418
 
 
419
        return CVector4(x * cosAngle - y * sinAngle, x * sinAngle + y * cosAngle, z, w);
 
420
}
 
421
 
 
422
 
 
423
CVector4 CVector4::GetRotatedAxis(double angle, CVector4 axis)
 
424
{
 
425
        if(angle == 0.0) return(*this);
 
426
 
 
427
   axis.Normal();
 
428
 
 
429
        CVector4 RotationRow1, RotationRow2, RotationRow3;
 
430
 
 
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;
 
435
 
 
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;
 
439
 
 
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;
 
443
        
 
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));
 
447
 
 
448
        return CVector4(this->DotProduct3(RotationRow1),
 
449
                   this->DotProduct3(RotationRow2),
 
450
                   this->DotProduct3(RotationRow3));
 
451
}
 
452
 
 
453
 
 
454
void CVector4::CalculateBinormalVector(CVector4 tangent, CVector4 normal)
 
455
{
 
456
   this->CrossProduct(tangent, normal);
 
457
}
 
458
 
 
459
 
 
460
void CVector4::ClampTo01()
 
461
{
 
462
   CVector4 temp(x, y, z, w);
 
463
   temp.Normal();
 
464
   temp = temp * 0.5f + CVector4(0.5f, 0.5f, 0.5f);
 
465
 
 
466
   x = temp.x;
 
467
   y = temp.y;
 
468
   z = temp.z;
 
469
}