1 /*!
2 * \file
3 * \ingroup misc_utils
4 * \brief Handles some math function for vectors.
5 */
6 #ifndef VMATH_H
7 #define VMATH_H
8 #include <math.h>
9 #include <string.h>
10 #ifdef MAP_EDITOR
11 #include "map_editor/misc.h"
12 #else
13 #include "misc.h"
14 #endif
15
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19
20 // Compute a rotation matrix for a rotation around the X axis
21 #define MAT3_ROT_X(mat,angle) \
22 (mat[0]=1.0,mat[3]=0.0 ,mat[6]=0.0 ,\
23 mat[1]=0.0,mat[4]=cosf(angle),mat[7]=-sinf(angle),\
24 mat[2]=0.0,mat[5]=-mat[7] ,mat[8]=mat[4] )
25
26 // Compute a rotation matrix for a rotation around the Y axis
27 #define MAT3_ROT_Y(mat,angle) \
28 (mat[0]=cosf(angle),mat[3]=0.0,mat[6]=sinf(angle),\
29 mat[1]=0.0 ,mat[4]=1.0,mat[7]=0.0 ,\
30 mat[2]=-mat[6] ,mat[5]=0.0,mat[8]=mat[0] )
31
32 // Compute a rotation matrix for a rotation around the Z axis
33 #define MAT3_ROT_Z(mat,angle) \
34 (mat[0]=cosf(angle),mat[3]=-sinf(angle),mat[6]=0.0,\
35 mat[1]=-mat[3] ,mat[4]=mat[0] ,mat[7]=0.0,\
36 mat[2]=0.0 ,mat[5]=0.0 ,mat[8]=1.0)
37
38 // Multiply a vector by a rotation matrix
39 #define MAT3_VECT3_MULT(res,mat,vect) \
40 ((res)[0]=mat[0]*(vect)[0]+mat[3]*(vect)[1]+mat[6]*(vect)[2],\
41 (res)[1]=mat[1]*(vect)[0]+mat[4]*(vect)[1]+mat[7]*(vect)[2],\
42 (res)[2]=mat[2]*(vect)[0]+mat[5]*(vect)[1]+mat[8]*(vect)[2])
43
44 // Multiply two rotation matrices
45 #define MAT3_MULT(res,mat1,mat2) \
46 (MAT3_VECT3_MULT(&res[0],mat1,&mat2[0]),\
47 MAT3_VECT3_MULT(&res[3],mat1,&mat2[3]),\
48 MAT3_VECT3_MULT(&res[6],mat1,&mat2[6]))
49
50 /*!
51 * \name Vector item names.
52 */
53 /*! @{ */
54 typedef enum {
55 X = 0,
56 Y = 1,
57 Z = 2,
58 W = 3
59 } vector_item;
60 /*! @} */
61
62 /*!
63 * VECTOR4 is used for normal, bounding box etc. calculating using SSE, SSE2 and SSE3.
64 */
65 typedef float VECTOR4[4];
66 /*!
67 * VECTOR3 is used for normal, bounding box etc. calculating without SIMD.
68 */
69 typedef float VECTOR3[3];
70 /*!
71 * VECTOR4I is used as a selection mask.
72 */
73 typedef int VECTOR4I[4];
74 /*!
75 * VECTOR3I is used as a selection mask.
76 */
77 typedef int VECTOR3I[3];
78 /*!
79 * VECTOR3D is the same as VECTOR3 but with double precision.
80 */
81 typedef double VECTOR3D[3];
82 /*!
83 * SHORT_VEC3 is used for normal calculating using little memory.
84 */
85 typedef short SHORT_VEC3[3];
86 /*!
87 * TEXTCOORD2 is used for texture coordinates.
88 */
89 typedef float TEXTCOORD2[2];
90 /*!
91 * MATRIX4x4 is used for translation and rotation.
92 */
93 typedef float MATRIX4x4[16];
94 /*!
95 * MATRIX4x4D is the same as MATRIX4x4 but with double precision.
96 */
97 typedef double MATRIX4x4D[16];
98 /*!
99 * \ingroup misc_utils
100 * \brief Vector add.
101 *
102 * Calculating vector add of two vectors of three floats.
103 * \paran v1 The return value.
104 * \param v2 Value one.
105 * \param v3 Value two.
106 *
107 * \callgraph
108 */
VAdd(VECTOR3 v1,const VECTOR3 v2,const VECTOR3 v3)109 static __inline__ void VAdd(VECTOR3 v1, const VECTOR3 v2, const VECTOR3 v3)
110 {
111 v1[X] = v2[X] + v3[X];
112 v1[Y] = v2[Y] + v3[Y];
113 v1[Z] = v2[Z] + v3[Z];
114 }
115
116 /*!
117 * \ingroup misc_utils
118 * \brief Vector add.
119 *
120 * Calculating vector add of two vectors of three floats.
121 * \paran v1 Value one and The return value.
122 * \param v2 Value two.
123 *
124 * \callgraph
125 */
VAddEq(VECTOR3 v1,const VECTOR3 v2)126 static __inline__ void VAddEq(VECTOR3 v1, const VECTOR3 v2)
127 {
128 v1[X] += v2[X];
129 v1[Y] += v2[Y];
130 v1[Z] += v2[Z];
131 }
132
133 /*!
134 * \ingroup misc_utils
135 * \brief Vector min.
136 *
137 * Calculating vector min of two vectors of three floats.
138 * \paran v1 The return value.
139 * \param v2 Value one.
140 * \param v3 Value two.
141 *
142 * \callgraph
143 */
VMin(VECTOR3 v1,const VECTOR3 v2,const VECTOR3 v3)144 static __inline__ void VMin(VECTOR3 v1, const VECTOR3 v2, const VECTOR3 v3)
145 {
146 v1[X] = min2f(v2[X], v3[X]);
147 v1[Y] = min2f(v2[Y], v3[Y]);
148 v1[Z] = min2f(v2[Z], v3[Z]);
149 }
150
151 /*!
152 * \ingroup misc_utils
153 * \brief Vector max.
154 *
155 * Calculating vector max of two vectors of three floats.
156 * \paran v1 The return value.
157 * \param v2 Value one.
158 * \param v3 Value two.
159 *
160 * \callgraph
161 */
VMax(VECTOR3 v1,const VECTOR3 v2,const VECTOR3 v3)162 static __inline__ void VMax(VECTOR3 v1, const VECTOR3 v2, const VECTOR3 v3)
163 {
164 v1[X] = max2f(v2[X], v3[X]);
165 v1[Y] = max2f(v2[Y], v3[Y]);
166 v1[Z] = max2f(v2[Z], v3[Z]);
167 }
168
169 /*!
170 * \ingroup misc_utils
171 * \brief Vector min.
172 *
173 * Calculating vector min of two vectors of four floats.
174 * \paran v1 The return value.
175 * \param v2 Value one.
176 * \param v3 Value two.
177 *
178 * \callgraph
179 */
VMin4(VECTOR4 v1,const VECTOR4 v2,const VECTOR4 v3)180 static __inline__ void VMin4(VECTOR4 v1, const VECTOR4 v2, const VECTOR4 v3)
181 {
182 v1[X] = min2f(v2[X], v3[X]);
183 v1[Y] = min2f(v2[Y], v3[Y]);
184 v1[Z] = min2f(v2[Z], v3[Z]);
185 v1[W] = min2f(v2[W], v3[W]);
186 }
187
188 /*!
189 * \ingroup misc_utils
190 * \brief Vector max.
191 *
192 * Calculating vector max of two vectors of four floats.
193 * \paran v1 The return value.
194 * \param v2 Value one.
195 * \param v3 Value two.
196 *
197 * \callgraph
198 */
VMax4(VECTOR4 v1,const VECTOR4 v2,const VECTOR4 v3)199 static __inline__ void VMax4(VECTOR4 v1, const VECTOR4 v2, const VECTOR4 v3)
200 {
201 v1[X] = max2f(v2[X], v3[X]);
202 v1[Y] = max2f(v2[Y], v3[Y]);
203 v1[Z] = max2f(v2[Z], v3[Z]);
204 v1[W] = max2f(v2[W], v3[W]);
205 }
206
207 /*!
208 * \ingroup misc_utils
209 * \brief Vector sub.
210 *
211 * Calculating vector sub of two vectors of three floats.
212 * \paran v1 The return value.
213 * \param v2 Value one.
214 * \param v3 Value two.
215 *
216 * \callgraph
217 */
VSub(VECTOR3 v1,const VECTOR3 v2,const VECTOR3 v3)218 static __inline__ void VSub(VECTOR3 v1, const VECTOR3 v2, const VECTOR3 v3)
219 {
220 v1[X] = v2[X] - v3[X];
221 v1[Y] = v2[Y] - v3[Y];
222 v1[Z] = v2[Z] - v3[Z];
223 }
224
225 /*!
226 * \ingroup misc_utils
227 * \brief Vector mul.
228 *
229 * Calculating vector sub of two vectors of four floats.
230 * \paran v1 The return value.
231 * \param v2 Value one.
232 * \param v3 Value two.
233 *
234 * \callgraph
235 */
VMul4(VECTOR4 v1,const VECTOR4 v2,const VECTOR4 v3)236 static __inline__ void VMul4(VECTOR4 v1, const VECTOR4 v2, const VECTOR4 v3)
237 {
238 v1[X] = v2[X] * v3[X];
239 v1[Y] = v2[Y] * v3[Y];
240 v1[Z] = v2[Z] * v3[Z];
241 v1[W] = v2[W] * v3[W];
242 }
243
244 /*!
245 * \ingroup misc_utils
246 * \brief Vector sum of four vectors.
247 *
248 * Calculating vector sum of four vectors of four floats.
249 * \paran v1 The return value.
250 * \param v2 Value one.
251 * \param v3 Value two.
252 * \param v4 Value three.
253 * \param v5 Value four.
254 *
255 * \callgraph
256 */
VSum4x4(VECTOR4 v1,const VECTOR4 v2,const VECTOR4 v3,const VECTOR4 v4,const VECTOR4 v5)257 static __inline__ void VSum4x4(VECTOR4 v1, const VECTOR4 v2, const VECTOR4 v3, const VECTOR4 v4, const VECTOR4 v5)
258 {
259 v1[X] = v2[X] + v2[Y] + v2[Z] + v2[W];
260 v1[Y] = v3[X] + v3[Y] + v3[Z] + v3[W];
261 v1[Z] = v4[X] + v4[Y] + v4[Z] + v4[W];
262 v1[W] = v5[X] + v5[Y] + v5[Z] + v5[W];
263 }
264
265 /*!
266 * \ingroup misc_utils
267 * \brief Vector select.
268 *
269 * Calculating vector select of two vector of three floats from a mask of three ints.
270 * \paran v1 The return value.
271 * \param v2 Value one.
272 * \param v3 Value two.
273 * \param mask The selection mask.
274 *
275 * \callgraph
276 */
VSelect(VECTOR3 v1,const VECTOR3 v2,const VECTOR3 v3,const VECTOR3I mask)277 static __inline__ void VSelect(VECTOR3 v1, const VECTOR3 v2, const VECTOR3 v3, const VECTOR3I mask)
278 {
279 v1[X] = mask[X] ? v2[X] : v3[X];
280 v1[Y] = mask[Y] ? v2[Y] : v3[Y];
281 v1[Z] = mask[Z] ? v2[Z] : v3[Z];
282 }
283
284 /*!
285 * \ingroup misc_utils
286 * \brief Vector invert select.
287 *
288 * Calculating vector select of two vector of three floats from an inverted mask of three ints.
289 * \paran v1 The return value.
290 * \param v2 Value one.
291 * \param v3 Value two.
292 * \param mask The selection mask.
293 *
294 * \callgraph
295 */
VInvertSelect(VECTOR3 v1,const VECTOR3 v2,const VECTOR3 v3,const VECTOR3I mask)296 static __inline__ void VInvertSelect(VECTOR3 v1, const VECTOR3 v2, const VECTOR3 v3, const VECTOR3I mask)
297 {
298 v1[X] = !mask[X] ? v2[X] : v3[X];
299 v1[Y] = !mask[Y] ? v2[Y] : v3[Y];
300 v1[Z] = !mask[Z] ? v2[Z] : v3[Z];
301 }
302
303 /*!
304 * \ingroup misc_utils
305 * \brief Vector select.
306 *
307 * Calculating vector select of two vector of four floats from a mask of four ints.
308 * \paran v1 The return value.
309 * \param v2 Value one.
310 * \param v3 Value two.
311 * \param mask The selection mask.
312 *
313 * \callgraph
314 */
VSelect4(VECTOR4 v1,const VECTOR4 v2,const VECTOR4 v3,const VECTOR4I mask)315 static __inline__ void VSelect4(VECTOR4 v1, const VECTOR4 v2, const VECTOR4 v3, const VECTOR4I mask)
316 {
317 v1[X] = mask[X] == 0 ? v2[X] : v3[X];
318 v1[Y] = mask[Y] == 0 ? v2[Y] : v3[Y];
319 v1[Z] = mask[Z] == 0 ? v2[Z] : v3[Z];
320 v1[W] = mask[W] == 0 ? v2[W] : v3[W];
321 }
322
323 /*!
324 * \ingroup misc_utils
325 * \brief Vector invert select.
326 *
327 * Calculating vector select of two vector of four floats from an inverted mask of four ints.
328 * \paran v1 The return value.
329 * \param v2 Value one.
330 * \param v3 Value two.
331 * \param mask The selection mask.
332 *
333 * \callgraph
334 */
VInvertSelect4(VECTOR4 v1,const VECTOR4 v2,const VECTOR4 v3,const VECTOR4I mask)335 static __inline__ void VInvertSelect4(VECTOR4 v1, const VECTOR4 v2, const VECTOR4 v3, const VECTOR4I mask)
336 {
337 v1[X] = mask[X] != 0 ? v2[X] : v3[X];
338 v1[Y] = mask[Y] != 0 ? v2[Y] : v3[Y];
339 v1[Z] = mask[Z] != 0 ? v2[Z] : v3[Z];
340 v1[W] = mask[W] != 0 ? v2[W] : v3[W];
341 }
342
343 /*!
344 * \ingroup misc_utils
345 * \brief Vector abs.
346 *
347 * Calculating vector abs of a vector of three floats.
348 * \paran v1 The return value.
349 * \param v2 Input value.
350 *
351 * \callgraph
352 */
VAbs(VECTOR3 v1,const VECTOR3 v2)353 static __inline__ void VAbs(VECTOR3 v1, const VECTOR3 v2)
354 {
355 v1[X] = fabs(v2[X]);
356 v1[Y] = fabs(v2[Y]);
357 v1[Z] = fabs(v2[Z]);
358 }
359
360 /*!
361 * \ingroup misc_utils
362 * \brief Vector scale.
363 *
364 * Calculating vector scale of a vector of three floats and a float value.
365 * \paran v1 The return value.
366 * \param v2 Input value.
367 * \param v3 Scale value.
368 *
369 * \callgraph
370 */
VScale(VECTOR3 v1,const VECTOR3 v2,float v3)371 static __inline__ void VScale(VECTOR3 v1, const VECTOR3 v2, float v3)
372 {
373 v1[X] = v2[X] * v3;
374 v1[Y] = v2[Y] * v3;
375 v1[Z] = v2[Z] * v3;
376 }
377
378 /*!
379 * \ingroup misc_utils
380 * \brief Vector cmp le.
381 *
382 * Calculating vector cmp le of two vectors of three floats.
383 * \paran v1 The return value.
384 * \param v2 Input value.
385 *
386 * \callgraph
387 */
VCmpLE(const VECTOR3 v1,const VECTOR3 v2)388 static __inline__ int VCmpLE(const VECTOR3 v1, const VECTOR3 v2)
389 {
390 int ret;
391 ret = 0;
392 ret += v1[X] < v2[X] ? 1 : 0;
393 ret += v1[Y] < v2[Y] ? 2 : 0;
394 ret += v1[Z] < v2[Z] ? 4 : 0;
395 return ret;
396 }
397
398 /*!
399 * \ingroup misc_utils
400 * \brief Vector cmp le.
401 *
402 * Calculating vector cmp le of two vectors of four floats.
403 * \paran v1 The return value.
404 * \param v2 Input value.
405 *
406 * \callgraph
407 */
VCmpLE4(const VECTOR4 v1,const VECTOR4 v2)408 static __inline__ int VCmpLE4(const VECTOR4 v1, const VECTOR4 v2)
409 {
410 int ret;
411 ret = 0;
412 ret += v1[X] < v2[X] ? 1 : 0;
413 ret += v1[Y] < v2[Y] ? 2 : 0;
414 ret += v1[Z] < v2[Z] ? 4 : 0;
415 ret += v1[W] < v2[W] ? 8 : 0;
416 return ret;
417 }
418
419 /*!
420 * \ingroup misc_utils
421 * \brief Vector assign.
422 *
423 * Assign v2 to v1. Both vectors are three floats.
424 * \paran v1 The return value.
425 * \param v2 Value one.
426 *
427 * \callgraph
428 */
VAssign(VECTOR3 v1,const VECTOR3 v2)429 static __inline__ void VAssign(VECTOR3 v1, const VECTOR3 v2)
430 {
431 memcpy(v1, v2, sizeof(VECTOR3));
432 }
433
434 /*!
435 * \ingroup misc_utils
436 * \brief Vector assign.
437 *
438 * Assign v2[X..Z] to v1[X..Z] and vw to v1[W]. Vector v2 are three floats,
439 * vector v1 are four floats.
440 * \paran v1 The return value.
441 * \param v2 Value one.
442 * \param vw W-value.
443 *
444 * \callgraph
445 */
VAssign4(VECTOR4 v1,const VECTOR3 v2,const float vw)446 static __inline__ void VAssign4(VECTOR4 v1, const VECTOR3 v2, const float vw)
447 {
448 memcpy(v1, v2, sizeof(VECTOR3));
449 v1[W] = vw;
450 }
451
452 /*!
453 * \ingroup misc_utils
454 * \brief Vector construction.
455 *
456 * Makes a vector of thre floats.
457 * \paran v1 The return value.
458 * \param v_x X value of the vector.
459 * \param v_y Y value of the vector.
460 * \param v_z Z value of the vector.
461 *
462 * \callgraph
463 */
VMake(VECTOR3 v1,const float v_x,const float v_y,const float v_z)464 static __inline__ void VMake(VECTOR3 v1, const float v_x, const float v_y, const float v_z)
465 {
466 v1[X] = v_x;
467 v1[Y] = v_y;
468 v1[Z] = v_z;
469 }
470
471 /*!
472 * \ingroup misc_utils
473 * \brief Vector construction.
474 *
475 * Makes a vector of three ints.
476 * \paran v1 The return value.
477 * \param v_x X value of the vector.
478 * \param v_y Y value of the vector.
479 * \param v_z Z value of the vector.
480 *
481 * \callgraph
482 */
VMakeI(VECTOR3I v1,const int v_x,const int v_y,const int v_z)483 static __inline__ void VMakeI(VECTOR3I v1, const int v_x, const int v_y, const int v_z)
484 {
485 v1[X] = v_x;
486 v1[Y] = v_y;
487 v1[Z] = v_z;
488 }
489
490 /*!
491 * \ingroup misc_utils
492 * \brief Vector fill.
493 *
494 * Makes a vector of thre floats.
495 * \paran v1 The return value.
496 * \param f X, Y and Z value of the vector.
497 *
498 * \callgraph
499 */
VFill(VECTOR3 v1,float f)500 static __inline__ void VFill(VECTOR3 v1, float f)
501 {
502 v1[X] = f;
503 v1[Y] = f;
504 v1[Z] = f;
505 }
506
507 /*!
508 * \ingroup misc_utils
509 * \brief Vector fill.
510 *
511 * Makes a vector of four floats.
512 * \paran v1 The return value.
513 * \param f X, Y, Z and W value of the vector.
514 *
515 * \callgraph
516 */
VFill4(VECTOR4 v1,float f)517 static __inline__ void VFill4(VECTOR4 v1, float f)
518 {
519 v1[X] = f;
520 v1[Y] = f;
521 v1[Z] = f;
522 v1[W] = f;
523 }
524
525 /*!
526 * \ingroup misc_utils
527 * \brief Vector normalize.
528 *
529 * Normalize vector of three floats.
530 * \paran v1 The return value.
531 * \param v2 Input value.
532 *
533 * \callgraph
534 */
Normalize(VECTOR3 v1,const VECTOR3 v2)535 static __inline__ void Normalize(VECTOR3 v1, const VECTOR3 v2)
536 {
537 float n;
538 n = v2[X] * v2[X] + v2[Y] * v2[Y] + v2[Z] * v2[Z];
539 n = sqrt(n);
540 v1[X] = v2[X] / n;
541 v1[Y] = v2[Y] / n;
542 v1[Z] = v2[Z] / n;
543 }
544
545 /*!
546 * \ingroup misc_utils
547 * \brief Vector float to signed short conversion.
548 *
549 * Converts vector of three floats to vector of three signed shorts
550 * by multiplying the floats with 32767.0f and then truncation them.
551 * \paran v1 The return value.
552 * \param v2 Input value.
553 *
554 * \callgraph
555 */
VAssignS3(SHORT_VEC3 v1,const VECTOR3 v2)556 static __inline__ void VAssignS3(SHORT_VEC3 v1, const VECTOR3 v2)
557 {
558 v1[X] = (short) (v2[X]*32767.0f);
559 v1[Y] = (short) (v2[Y]*32767.0f);
560 v1[Z] = (short) (v2[Z]*32767.0f);
561 }
562
563 /*!
564 * \ingroup misc_utils
565 * \brief Vector cross product.
566 *
567 * Calculating vector cross product of two vectors of three floats.
568 * \paran v1 The return value.
569 * \param v2 Value one.
570 * \param v3 Value two.
571 *
572 * \callgraph
573 */
VCross(VECTOR3 v1,const VECTOR3 v2,const VECTOR3 v3)574 static __inline__ void VCross(VECTOR3 v1, const VECTOR3 v2, const VECTOR3 v3)
575 {
576 VECTOR3 tmp;
577
578 tmp[X] = v2[Y] * v3[Z] - v2[Z] * v3[Y];
579 tmp[Y] = v2[Z] * v3[X] - v2[X] * v3[Z];
580 tmp[Z] = v2[X] * v3[Y] - v2[Y] * v3[X];
581
582 VAssign(v1, tmp);
583 }
584
585 /*!
586 * \ingroup misc_utils
587 * \brief Vector dot product.
588 *
589 * Calculating vector dot product of two vectors of three floats.
590 * \param v2 Value one.
591 * \param v3 Value two.
592 * \retval float The vector dot product.
593 *
594 * \callgraph
595 */
VDot(const VECTOR3 v2,const VECTOR3 v3)596 static __inline__ float VDot(const VECTOR3 v2, const VECTOR3 v3)
597 {
598 return v2[X]*v3[X] + v2[Y]*v3[Y] + v2[Z]*v3[Z];
599 }
600
601 /*!
602 * \ingroup misc_utils
603 * \brief Vector dot product.
604 *
605 * Calculating vector dot product of two vectors of four floats.
606 * \param v2 Value one.
607 * \param v3 Value two.
608 * \retval float The vector dot product.
609 *
610 * \callgraph
611 */
VDot4(const VECTOR4 v2,const VECTOR4 v3)612 static __inline__ float VDot4(const VECTOR4 v2, const VECTOR4 v3)
613 {
614 return v2[X]*v3[X] + v2[Y]*v3[Y] + v2[Z]*v3[Z] + v2[W]*v3[W];
615 }
616
VExtract(const VECTOR3 v1,int number)617 static __inline__ float VExtract(const VECTOR3 v1, int number)
618 {
619 return v1[number];
620 }
621
VExtract4(const VECTOR4 v1,int number)622 static __inline__ float VExtract4(const VECTOR4 v1, int number)
623 {
624 return v1[number];
625 }
626
calc_rotation_and_translation_matrix(MATRIX4x4 matrix,float trans_x,float trans_y,float trans_z,float rot_x,float rot_y,float rot_z)627 static __inline__ void calc_rotation_and_translation_matrix(MATRIX4x4 matrix, float trans_x, float trans_y, float trans_z, float rot_x, float rot_y, float rot_z)
628 {
629 glPushMatrix();
630 glLoadIdentity();
631 glTranslatef(trans_x, trans_y, trans_z);
632 glRotatef(rot_z, 0.0f, 0.0f, 1.0f);
633 glRotatef(rot_x, 1.0f, 0.0f, 0.0f);
634 glRotatef(rot_y, 0.0f, 1.0f, 0.0f);
635 glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
636 glPopMatrix();
637 }
638
639 void calculate_Light_Matrix(int useBodyVec, double nearDist,
640 const VECTOR3D lightDir, const MATRIX4x4D ModelViewMatrix,
641 const MATRIX4x4D ProjectionMatrix, MATRIX4x4D lightView,
642 MATRIX4x4D lightProjection);
643
644 #ifdef __cplusplus
645 } // extern "C"
646 #endif
647
648 #endif
649