MTek-GDL 0.100.4-muffintrap
Loading...
Searching...
No Matches
ccVector.h
1//__________________________________________________________________________________//
2// __ __ _ //
3// \ \ / / | | //
4// ___ __\ \ / /__ ___| |_ ___ _ __ //
5// / __/ __\ \/ / _ \/ __| __/ _ \| '__| //
6// | (_| (__ \ / __/ (__| || (_) | | //
7// \___\___| \/ \___|\___|\__\___/|_| v1.1 //
8// //
9// 2015 - 2017 \ Job Talle (jobtalle@hotmail.com) //
10//__________________________________________________________________________________//
11// //
12// ccVector has been dedicated to the public domain. //
13// //
14// Anyone is free to copy, modify, publish, use, compile, sell, or distribute this //
15// software, either in source code form or as a compiled binary, for any purpose, //
16// commercial or non - commercial, and by any means. //
17//__________________________________________________________________________________//
18
19#ifndef CC_VECTOR
20#define CC_VECTOR
21
22#ifdef __cplusplus
23extern "C"
24{
25#endif
26
27#include <math.h>
28#include <string.h>
29
30#ifdef _DEBUG
31#include <assert.h>
32#endif
33
34#ifndef inline
35#ifdef _MSC_VER
36#define inline __inline
37#endif
38#endif
39
40// Concatenation utility
41
42#define CAT2_(a, b) a##b
43#define CAT2(a, b) CAT2_(a, b)
44
45// Number type
46
47typedef float ccvType;
48
49// Used math functions
50
51#define CCV_COS cosf
52#define CCV_SIN sinf
53#define CCV_TAN tanf
54#define CCV_ACOS acosf
55#define CCV_SQRT sqrtf
56#define CCV_ABS fabsf
57#define CCV_EPSILON ((ccvType)0.0001)
58
59// Type names
60
61#define CCV_VEC_TYPENAME(dim) vec##dim
62#define CCV_QUAT_TYPENAME quat
63#define CCV_MAT_TYPENAME(dim) mat##dim##x##dim
64
65// Function names
66
67#define CCV_FUNC_VEC_ZERO(dim) CAT2(CCV_VEC_TYPENAME(dim), Zero)
68#define CCV_FUNC_VEC_NEGATE(dim) CAT2(CCV_VEC_TYPENAME(dim), Negate)
69#define CCV_FUNC_VEC_ISZERO(dim) CAT2(CCV_VEC_TYPENAME(dim), IsZero)
70#define CCV_FUNC_VEC_ADD(dim) CAT2(CCV_VEC_TYPENAME(dim), Add)
71#define CCV_FUNC_VEC_SUBTRACT(dim) CAT2(CCV_VEC_TYPENAME(dim), Subtract)
72#define CCV_FUNC_VEC_MULTIPLY(dim) CAT2(CCV_VEC_TYPENAME(dim), Multiply)
73#define CCV_FUNC_VEC_DOTPRODUCT(dim) CAT2(CCV_VEC_TYPENAME(dim), DotProduct)
74#define CCV_FUNC_VEC_LENGTH(dim) CAT2(CCV_VEC_TYPENAME(dim), Length)
75#define CCV_FUNC_VEC_NORMALIZE(dim) CAT2(CCV_VEC_TYPENAME(dim), Normalize)
76#define CCV_FUNC_VEC_REFLECT(dim) CAT2(CCV_VEC_TYPENAME(dim), Reflect)
77#define CCV_FUNC_VEC_ORTHOGONAL(dim) CAT2(CCV_VEC_TYPENAME(dim), Orthogonal)
78#define CCV_FUNC_VEC_CROSS_PRODUCT(dim) CAT2(CCV_VEC_TYPENAME(dim), CrossProduct)
79#define CCV_FUNC_VEC_MIX(dim) CAT2(CCV_VEC_TYPENAME(dim), Mix)
80#define CCV_FUNC_VEC_NEW(dim) CAT2(CCV_VEC_TYPENAME(dim), New)
81#define CCV_FUNC_VEC_EQUAL(dim) CAT2(CCV_VEC_TYPENAME(dim), Equal)
82
83#define CCV_FUNC_QUAT_IDENTITY CAT2(CCV_QUAT_TYPENAME, Identity)
84#define CCV_FUNC_QUAT_ROTATE CAT2(CCV_QUAT_TYPENAME, Rotate)
85#define CCV_FUNC_QUAT_MULTIPLY CAT2(CCV_QUAT_TYPENAME, Multiply)
86#define CCV_FUNC_QUAT_ADD_ROTATION CAT2(CCV_QUAT_TYPENAME, AddRotation)
87#define CCV_FUNC_QUAT_MULTIPLY_VECTOR CAT2(CCV_QUAT_TYPENAME, MultiplyVector)
88#define CCV_FUNC_QUAT_ADD CAT2(CCV_QUAT_TYPENAME, Add)
89#define CCV_FUNC_QUAT_SUBTRACT CAT2(CCV_QUAT_TYPENAME, Subtract)
90#define CCV_FUNC_QUAT_SCALE CAT2(CCV_QUAT_TYPENAME, Scale)
91#define CCV_FUNC_QUAT_MIX CAT2(CCV_QUAT_TYPENAME, Mix)
92
93#define CCV_FUNC_MAT_ZERO(dim) CAT2(CCV_MAT_TYPENAME(dim), Zero)
94#define CCV_FUNC_MAT_ISZERO(dim) CAT2(CCV_MAT_TYPENAME(dim), IsZero)
95#define CCV_FUNC_MAT_ADD(dim) CAT2(CCV_MAT_TYPENAME(dim), Add)
96#define CCV_FUNC_MAT_SUBTRACT(dim) CAT2(CCV_MAT_TYPENAME(dim), Subtract)
97#define CCV_FUNC_MAT_COPY(dim) CAT2(CCV_MAT_TYPENAME(dim), Copy)
98#define CCV_FUNC_MAT_IDENTITY(dim) CAT2(CCV_MAT_TYPENAME(dim), Identity)
99#define CCV_FUNC_MAT_MULTIPLY_SCALAR(dim) CAT2(CCV_MAT_TYPENAME(dim), MultiplyScalar)
100#define CCV_FUNC_MAT_MULTIPLY_VECTOR(dim) CAT2(CCV_MAT_TYPENAME(dim), MultiplyVector)
101#define CCV_FUNC_MAT_MULTIPLY_MATRIX(dim) CAT2(CCV_MAT_TYPENAME(dim), MultiplyMatrix)
102#define CCV_FUNC_MAT_GET_ROW(dim) CAT2(CCV_MAT_TYPENAME(dim), GetRow)
103#define CCV_FUNC_MAT_GET_COL(dim) CAT2(CCV_MAT_TYPENAME(dim), GetCol)
104#define CCV_FUNC_MAT_DEMOTE(dim) CAT2(CCV_MAT_TYPENAME(dim), Demote)
105#define CCV_FUNC_MAT_TRANSPOSE(dim) CAT2(CCV_MAT_TYPENAME(dim), Transpose)
106#define CCV_FUNC_MAT_SET_ROTATION(dim) CAT2(CCV_MAT_TYPENAME(dim), SetRotation)
107#define CCV_FUNC_MAT_ROTATE(dim) CAT2(CCV_MAT_TYPENAME(dim), Rotate)
108#define CCV_FUNC_MAT_SET_ROTATION_2D(dim) CAT2(CCV_MAT_TYPENAME(dim), SetRotation2D)
109#define CCV_FUNC_MAT_ROTATE_2D(dim) CAT2(CCV_MAT_TYPENAME(dim), Rotate2D)
110#define CCV_FUNC_MAT_SET_ROTATION_X(dim) CAT2(CCV_MAT_TYPENAME(dim), SetRotationX)
111#define CCV_FUNC_MAT_SET_ROTATION_Y(dim) CAT2(CCV_MAT_TYPENAME(dim), SetRotationY)
112#define CCV_FUNC_MAT_SET_ROTATION_Z(dim) CAT2(CCV_MAT_TYPENAME(dim), SetRotationZ)
113#define CCV_FUNC_MAT_ROTATE_X(dim) CAT2(CCV_MAT_TYPENAME(dim), RotateX)
114#define CCV_FUNC_MAT_ROTATE_Y(dim) CAT2(CCV_MAT_TYPENAME(dim), RotateY)
115#define CCV_FUNC_MAT_ROTATE_Z(dim) CAT2(CCV_MAT_TYPENAME(dim), RotateZ)
116#define CCV_FUNC_MAT_SET_TRANSLATION(dim) CAT2(CCV_MAT_TYPENAME(dim), SetTranslation)
117#define CCV_FUNC_MAT_TRANSLATE(dim) CAT2(CCV_MAT_TYPENAME(dim), Translate)
118#define CCV_FUNC_MAT_SET_SCALE(dim) CAT2(CCV_MAT_TYPENAME(dim), SetScale)
119#define CCV_FUNC_MAT_SCALE(dim) CAT2(CCV_MAT_TYPENAME(dim), Scale)
120#define CCV_FUNC_MAT_SET_SCALE_2D(dim) CAT2(CCV_MAT_TYPENAME(dim), SetScale2D)
121#define CCV_FUNC_MAT_SCALE_2D(dim) CAT2(CCV_MAT_TYPENAME(dim), Scale2D)
122#define CCV_FUNC_MAT_INVERSE(dim) CAT2(CCV_MAT_TYPENAME(dim), Inverse)
123#define CCV_FUNC_MAT_PERSPECTIVE(dim) CAT2(CCV_MAT_TYPENAME(dim), Perspective)
124#define CCV_FUNC_MAT_LOOK_AT(dim) CAT2(CCV_MAT_TYPENAME(dim), LookAt)
125#define CCV_FUNC_MAT_EQUAL(dim) CAT2(CCV_MAT_TYPENAME(dim), Equal)
126
127// Type definitions
128
129#define CCV_DEFINE_VEC_TYPE(dim)
130
131#define CCV_DEFINE_MAT_TYPE(dim) \
132 typedef ccvType CCV_MAT_TYPENAME(dim)[dim][dim];
133
134// Vector operations
135
136#define CCV_DEFINE_VEC_ZERO(dim) \
137 static inline CCV_VEC_TYPENAME(dim) CCV_FUNC_VEC_ZERO(dim)(void) { \
138 CCV_VEC_TYPENAME(dim) v; \
139 memset(&v, 0, sizeof(CCV_VEC_TYPENAME(dim))); \
140 return v; \
141 }
142
143#define CCV_DEFINE_VEC_NEGATE(dim) \
144 static inline CCV_VEC_TYPENAME(dim) CCV_FUNC_VEC_NEGATE(dim)(const CCV_VEC_TYPENAME(dim) v) { \
145 CCV_VEC_TYPENAME(dim) r; \
146 unsigned int i; \
147 for(i = 0; i < dim; ++i) \
148 r.v[i] = -v.v[i]; \
149 return r; \
150 }
151
152#define CCV_DEFINE_VEC_ISZERO(dim) \
153 static inline int CCV_FUNC_VEC_ISZERO(dim)(const CCV_VEC_TYPENAME(dim) v) { \
154 unsigned int i; \
155 for(i = 0; i < dim; ++i) \
156 if(v.v[i] != 0) return 0; \
157 return 1; \
158 }
159
160#define CCV_DEFINE_VEC_ADD(dim) \
161 static inline CCV_VEC_TYPENAME(dim) CCV_FUNC_VEC_ADD(dim)(const CCV_VEC_TYPENAME(dim) a, const CCV_VEC_TYPENAME(dim) b) { \
162 CCV_VEC_TYPENAME(dim) v; \
163 unsigned int i; \
164 for(i = 0; i < dim; ++i) \
165 v.v[i] = a.v[i] + b.v[i]; \
166 return v; \
167 }
168
169#define CCV_DEFINE_VEC_SUBTRACT(dim) \
170 static inline CCV_VEC_TYPENAME(dim) CCV_FUNC_VEC_SUBTRACT(dim)(const CCV_VEC_TYPENAME(dim) a, const CCV_VEC_TYPENAME(dim) b) { \
171 CCV_VEC_TYPENAME(dim) v; \
172 unsigned int i; \
173 for(i = 0; i < dim; ++i) \
174 v.v[i] = a.v[i] - b.v[i]; \
175 return v; \
176 }
177
178#define CCV_DEFINE_VEC_MULTIPLY(dim) \
179 static inline CCV_VEC_TYPENAME(dim) CCV_FUNC_VEC_MULTIPLY(dim)(CCV_VEC_TYPENAME(dim) v, const ccvType n) { \
180 unsigned int i; \
181 for(i = 0; i < dim; ++i) \
182 v.v[i] *= n; \
183 return v; \
184 }
185
186#define CCV_DEFINE_VEC_DOTPRODUCT(dim) \
187 static inline ccvType CCV_FUNC_VEC_DOTPRODUCT(dim)(const CCV_VEC_TYPENAME(dim) a, const CCV_VEC_TYPENAME(dim) b) { \
188 unsigned int i; \
189 ccvType result = 0; \
190 for(i = 0; i < dim; ++i) \
191 result += a.v[i] * b.v[i]; \
192 return result; \
193 }
194
195#define CCV_DEFINE_VEC_LENGTH(dim) \
196 static inline ccvType CCV_FUNC_VEC_LENGTH(dim)(const CCV_VEC_TYPENAME(dim) v) { \
197 unsigned int i; \
198 ccvType squaredResult = 0; \
199 for(i = 0; i < dim; ++i) \
200 squaredResult += v.v[i] * v.v[i]; \
201 return (ccvType)CCV_SQRT(squaredResult); \
202 }
203
204#define CCV_DEFINE_VEC_NORMALIZE(dim) \
205 static inline CCV_VEC_TYPENAME(dim) CCV_FUNC_VEC_NORMALIZE(dim)(CCV_VEC_TYPENAME(dim) v) { \
206 return CCV_FUNC_VEC_MULTIPLY(dim)(v, 1 / CCV_FUNC_VEC_LENGTH(dim)(v)); \
207 }
208
209#define CCV_DEFINE_VEC_REFLECT(dim) \
210 static inline CCV_VEC_TYPENAME(dim) CCV_FUNC_VEC_REFLECT(dim)(const CCV_VEC_TYPENAME(dim) n, const CCV_VEC_TYPENAME(dim) r) { \
211 return CCV_FUNC_VEC_SUBTRACT(dim)(r, CCV_FUNC_VEC_MULTIPLY(dim)(n, 2 * CCV_FUNC_VEC_DOTPRODUCT(dim)(n, r))); \
212 }
213
214#define CCV_DEFINE_VEC_MIX(dim) \
215 static inline CCV_VEC_TYPENAME(dim) CCV_FUNC_VEC_MIX(dim)(const CCV_VEC_TYPENAME(dim) a, const CCV_VEC_TYPENAME(dim) b, const ccvType f) { \
216 return CCV_FUNC_VEC_ADD(dim)(a, CCV_FUNC_VEC_MULTIPLY(dim)(CCV_FUNC_VEC_SUBTRACT(dim)(b, a), f)); \
217 }
218
219#define CCV_DEFINE_VEC_EQUAL(dim) \
220 static inline int CCV_FUNC_VEC_EQUAL(dim)(const CCV_VEC_TYPENAME(dim) a, const CCV_VEC_TYPENAME(dim) b) { \
221 unsigned int i; \
222 for(i = 0; i < dim; ++i) \
223 if(a.v[i] != b.v[i]) \
224 return 0; \
225 return 1; \
226 }
227
228// Matrix operations
229
230#define CCV_DEFINE_MAT_ZERO(dim) \
231 static inline void CCV_FUNC_MAT_ZERO(dim)(CCV_MAT_TYPENAME(dim) m) { \
232 memset(m, 0, sizeof(ccvType)* dim * dim); \
233 }
234
235#define CCV_DEFINE_MAT_ISZERO(dim) \
236 static inline int CCV_FUNC_MAT_ISZERO(dim)(CCV_MAT_TYPENAME(dim) m) { \
237 unsigned int row = 0; \
238 unsigned int col = 0; \
239 for(col = 0; col < dim; ++col) \
240 for(row = 0; row < dim; ++row) \
241 if(m[row][col] != 0) return 0; \
242 return 1; \
243 }
244
245#define CCV_DEFINE_MAT_ADD(dim) \
246 static inline void CCV_FUNC_MAT_ADD(dim)(CCV_MAT_TYPENAME(dim) m, const CCV_MAT_TYPENAME(dim) a, const CCV_MAT_TYPENAME(dim) b) { \
247 unsigned int row = 0; \
248 unsigned int col = 0; \
249 for(col = 0; col < dim; ++col) \
250 for(row = 0; row < dim; ++row) \
251 m[row][col] = a[row][col] + b[row][col]; \
252 }
253
254#define CCV_DEFINE_MAT_SUBTRACT(dim) \
255 static inline void CCV_FUNC_MAT_SUBTRACT(dim)(CCV_MAT_TYPENAME(dim) m, const CCV_MAT_TYPENAME(dim) a, const CCV_MAT_TYPENAME(dim) b) { \
256 unsigned int row = 0; \
257 unsigned int col = 0; \
258 for(col = 0; col < dim; ++col) \
259 for(row = 0; row < dim; ++row) \
260 m[row][col] = a[row][col] - b[row][col]; \
261 }
262
263#define CCV_DEFINE_MAT_COPY(dim) \
264 static inline void CCV_FUNC_MAT_COPY(dim)(CCV_MAT_TYPENAME(dim) dest, const CCV_MAT_TYPENAME(dim) source) { \
265 memcpy(dest, source, sizeof(ccvType) * dim * dim); \
266 }
267
268#define CCV_DEFINE_MAT_IDENTITY(dim) \
269 static inline void CCV_FUNC_MAT_IDENTITY(dim)(CCV_MAT_TYPENAME(dim) m) { \
270 unsigned int i; \
271 CCV_FUNC_MAT_ZERO(dim)(m); \
272 for(i = 0; i < dim; ++i) \
273 m[i][i] = 1; \
274 }
275
276#define CCV_DEFINE_MAT_MULTIPLY_SCALAR(dim) \
277 static inline void CCV_FUNC_MAT_MULTIPLY_SCALAR(dim)(CCV_MAT_TYPENAME(dim) m, const ccvType n) { \
278 unsigned int row = 0; \
279 unsigned int col = 0; \
280 for(col = 0; col < dim; ++col) \
281 for(row = 0; row < dim; ++row) m[row][col] *= n; \
282 }
283
284#define CCV_DEFINE_MAT_MULTIPLY_VECTOR(dim) \
285 static inline CCV_VEC_TYPENAME(dim) CCV_FUNC_MAT_MULTIPLY_VECTOR(dim)(const CCV_MAT_TYPENAME(dim) a, const CCV_VEC_TYPENAME(dim) b) { \
286 CCV_VEC_TYPENAME(dim) v; \
287 unsigned int i, j; \
288 for(i = 0; i < dim; ++i) { \
289 v.v[i] = a[0][i] * b.v[0]; \
290 for(j = 1; j < dim; ++j) \
291 v.v[i] += a[j][i] * b.v[j]; \
292 } \
293 return v; \
294 }
295
296#define CCV_DEFINE_MAT_MULTIPLY_MATRIX(dim) \
297 static inline void CCV_FUNC_MAT_MULTIPLY_MATRIX(dim)(CCV_MAT_TYPENAME(dim) m, const CCV_MAT_TYPENAME(dim) a, const CCV_MAT_TYPENAME(dim) b) { \
298 unsigned int i, j, k; \
299 for(j = 0; j < dim; ++j) \
300 for(i = 0; i < dim; ++i) { \
301 m[i][j] = a[i][0] * b[0][j]; \
302 for(k = 1; k < dim; ++k) \
303 m[i][j] += a[i][k] * b[k][j]; \
304 } \
305 }
306
307#define CCV_DEFINE_MAT_GET_ROW(dim) \
308 static inline CCV_VEC_TYPENAME(dim) CCV_FUNC_MAT_GET_ROW(dim)(CCV_MAT_TYPENAME(dim) m, const unsigned int n) { \
309 CCV_VEC_TYPENAME(dim) v; \
310 unsigned int i; \
311 for(i = 0; i < dim; ++i) \
312 v.v[i] = m[i][n]; \
313 return v; \
314 }
315
316#define CCV_DEFINE_MAT_GET_COL(dim) \
317 static inline CCV_VEC_TYPENAME(dim) CCV_FUNC_MAT_GET_COL(dim)(CCV_MAT_TYPENAME(dim) m, const unsigned int n) { \
318 CCV_VEC_TYPENAME(dim) v; \
319 memcpy(v.v, m[n], sizeof(ccvType)* dim); \
320 return v; \
321 }
322
323#define CCV_DEFINE_MAT_TRANSPOSE(dim) \
324 static inline void CCV_FUNC_MAT_TRANSPOSE(dim)(CCV_MAT_TYPENAME(dim) m, CCV_MAT_TYPENAME(dim) n) { \
325 unsigned int i, j; \
326 for(j = 0; j < dim; ++j) \
327 for(i = 0; i < dim; ++i) \
328 m[i][j] = n[j][i]; \
329 }
330
331#define CCV_DEFINE_MAT_EQUAL(dim) \
332 static inline int CCV_FUNC_MAT_EQUAL(dim)(CCV_MAT_TYPENAME(dim) a, CCV_MAT_TYPENAME(dim) b) { \
333 unsigned int i, j; \
334 for(j = 0; j < dim; ++j) \
335 for(i = 0; i < dim; ++i) \
336 if(a[i][j] != b[i][j]) \
337 return 0; \
338 return 1; \
339 }
340
341#define CCV_DEFINE_MAT_DEMOTE(dimTarget, dimSource) \
342 static inline void CCV_FUNC_MAT_DEMOTE(dimSource)(CCV_MAT_TYPENAME(dimTarget) m, CCV_MAT_TYPENAME(dimSource) n) { \
343 unsigned int i, j; \
344 for(j = 0; j < dimTarget; ++j) \
345 for(i = 0; i < dimTarget; ++i) \
346 m[i][j] = n[i][j]; \
347 }
348
349// Definition calls
350
351#define CCV_DEFINE_VEC(dim) \
352 CCV_DEFINE_VEC_TYPE(dim) \
353 CCV_DEFINE_VEC_ZERO(dim) \
354 CCV_DEFINE_VEC_NEGATE(dim) \
355 CCV_DEFINE_VEC_ISZERO(dim) \
356 CCV_DEFINE_VEC_ADD(dim) \
357 CCV_DEFINE_VEC_SUBTRACT(dim) \
358 CCV_DEFINE_VEC_MULTIPLY(dim) \
359 CCV_DEFINE_VEC_DOTPRODUCT(dim) \
360 CCV_DEFINE_VEC_LENGTH(dim) \
361 CCV_DEFINE_VEC_NORMALIZE(dim) \
362 CCV_DEFINE_VEC_REFLECT(dim) \
363 CCV_DEFINE_VEC_MIX(dim) \
364 CCV_DEFINE_VEC_EQUAL(dim)
365
366#define CCV_DEFINE_MAT(dim) \
367 CCV_DEFINE_VEC_TYPE(dim) \
368 CCV_DEFINE_MAT_TYPE(dim) \
369 CCV_DEFINE_MAT_ZERO(dim) \
370 CCV_DEFINE_MAT_ISZERO(dim) \
371 CCV_DEFINE_MAT_ADD(dim) \
372 CCV_DEFINE_MAT_SUBTRACT(dim) \
373 CCV_DEFINE_MAT_COPY(dim) \
374 CCV_DEFINE_MAT_IDENTITY(dim) \
375 CCV_DEFINE_MAT_MULTIPLY_SCALAR(dim) \
376 CCV_DEFINE_MAT_MULTIPLY_VECTOR(dim) \
377 CCV_DEFINE_MAT_MULTIPLY_MATRIX(dim) \
378 CCV_DEFINE_MAT_GET_ROW(dim) \
379 CCV_DEFINE_MAT_GET_COL(dim) \
380 CCV_DEFINE_MAT_TRANSPOSE(dim) \
381 CCV_DEFINE_MAT_EQUAL(dim)
382
383// Vector type override
384
385typedef union {
386 ccvType v[2];
387 struct { ccvType x, y; };
389
390typedef union {
391 ccvType v[3];
392 union {
393 struct {
394 union {
395 struct { ccvType x, y; };
396 union {
397 CCV_VEC_TYPENAME(2) xy;
398 };
399 };
400 ccvType z;
401 };
402 struct {
403 ccvType _x;
404 CCV_VEC_TYPENAME(2) yz;
405 };
406 };
408
409typedef union {
410 ccvType v[4];
411 union {
412 struct {
413 union {
414 struct {
415 union {
416 struct { ccvType x, y; };
417 CCV_VEC_TYPENAME(2) xy;
418 };
419 union {
420 struct { ccvType z, w; };
421 CCV_VEC_TYPENAME(2) zw;
422 };
423 };
424 struct {
425 ccvType _x;
426 CCV_VEC_TYPENAME(2) yz;
427 ccvType _w;
428 };
429 };
430 };
431 struct {
432 union {
433 struct {
434 union {
435 CCV_VEC_TYPENAME(3) xyz;
436 };
437 ccvType __w;
438 };
439 struct {
440 ccvType __x;
441 CCV_VEC_TYPENAME(3) yzw;
442 };
443 };
444 };
445 };
447
448typedef CCV_VEC_TYPENAME(4) CCV_QUAT_TYPENAME;
449
450// Define 2d, 3d and 4d vectors and matrices
451
452CCV_DEFINE_VEC(2)
453CCV_DEFINE_VEC(3)
454CCV_DEFINE_VEC(4)
455
456CCV_DEFINE_MAT(2)
457CCV_DEFINE_MAT(3)
458CCV_DEFINE_MAT(4)
459
460CCV_DEFINE_MAT_DEMOTE(2, 3)
461CCV_DEFINE_MAT_DEMOTE(3, 4)
462
463// Define n-dimensional vector type
464
465#undef CCV_DEFINE_VEC_TYPE
466#define CCV_DEFINE_VEC_TYPE(dim) \
467 typedef struct { \
468 ccvType v[dim]; \
469 } CCV_VEC_TYPENAME(dim);
470
471// Shorthand transformation multiplier
472
473#define CCV_APPLY_MATRIX(dim, operation) { \
474 CCV_MAT_TYPENAME(dim) buffer, multiply; \
475 operation; \
476 CCV_FUNC_MAT_COPY(dim)(buffer, m); \
477 CCV_FUNC_MAT_MULTIPLY_MATRIX(dim)(m, buffer, multiply); \
478 }
479
480// Define vector utilities
481
482static inline CCV_VEC_TYPENAME(2) CCV_FUNC_VEC_ORTHOGONAL(2)(const CCV_VEC_TYPENAME(2) a)
483{
484 CCV_VEC_TYPENAME(2) v;
485
486 v.x = -a.y;
487 v.y = a.x;
488
489 return v;
490}
491
492static inline CCV_VEC_TYPENAME(2) CCV_FUNC_VEC_NEW(2)(const ccvType x, const ccvType y)
493{
494 CCV_VEC_TYPENAME(2) v;
495
496 v.x = x;
497 v.y = y;
498
499 return v;
500}
501
502static inline CCV_VEC_TYPENAME(3) CCV_FUNC_VEC_CROSS_PRODUCT(3)(const CCV_VEC_TYPENAME(3) a, const CCV_VEC_TYPENAME(3) b)
503{
504 CCV_VEC_TYPENAME(3) v;
505
506 v.x = a.y * b.z - a.z * b.y;
507 v.y = a.z * b.x - a.x * b.z;
508 v.z = a.x * b.y - a.y * b.x;
509
510 return v;
511}
512
513static inline CCV_VEC_TYPENAME(3) CCV_FUNC_VEC_NEW(3)(const ccvType x, const ccvType y, const ccvType z)
514{
515 CCV_VEC_TYPENAME(3) v;
516
517 v.x = x;
518 v.y = y;
519 v.z = z;
520
521 return v;
522}
523
524static inline CCV_VEC_TYPENAME(4) CCV_FUNC_VEC_NEW(4)(const ccvType x, const ccvType y, const ccvType z, const ccvType w)
525{
526 CCV_VEC_TYPENAME(4) v;
527
528 v.x = x;
529 v.y = y;
530 v.z = z;
531 v.w = w;
532
533 return v;
534}
535
536// Define quaternion operations
537
538static inline CCV_QUAT_TYPENAME CCV_FUNC_QUAT_IDENTITY()
539{
540 CCV_QUAT_TYPENAME q;
541
542 q.x = q.y = q.z = 0;
543 q.w = 1;
544
545 return q;
546}
547
548static inline CCV_QUAT_TYPENAME CCV_FUNC_QUAT_ROTATE(CCV_VEC_TYPENAME(3) axis, ccvType radians)
549{
550 CCV_QUAT_TYPENAME q;
551 ccvType s = CCV_SIN(radians * (ccvType)0.5);
552
553 q.xyz = CCV_FUNC_VEC_MULTIPLY(3)(axis, s);
554 q.w = CCV_COS(radians * (ccvType)0.5);
555
556 return q;
557}
558
559static inline CCV_QUAT_TYPENAME CCV_FUNC_QUAT_MULTIPLY(const CCV_QUAT_TYPENAME a, const CCV_QUAT_TYPENAME b)
560{
561 CCV_QUAT_TYPENAME r;
562 CCV_VEC_TYPENAME(3) w;
563
564 r.xyz = CCV_FUNC_VEC_CROSS_PRODUCT(3)(a.xyz, b.xyz);
565 w = CCV_FUNC_VEC_MULTIPLY(3)(a.xyz, b.w);
566 r.xyz = CCV_FUNC_VEC_ADD(3)(r.xyz, w);
567 w = CCV_FUNC_VEC_MULTIPLY(3)(b.xyz, a.w);
568 r.xyz = CCV_FUNC_VEC_ADD(3)(r.xyz, w);
569
570 r.w = a.w * b.w - CCV_FUNC_VEC_DOTPRODUCT(3)(a.xyz, b.xyz);
571
572 return r;
573}
574
575static inline CCV_QUAT_TYPENAME CCV_FUNC_QUAT_ADD_ROTATION(CCV_QUAT_TYPENAME q, CCV_VEC_TYPENAME(3) axis, ccvType radians)
576{
577 return CCV_FUNC_QUAT_MULTIPLY(q, CCV_FUNC_QUAT_ROTATE(axis, radians));
578}
579
580static inline CCV_VEC_TYPENAME(3) CCV_FUNC_QUAT_MULTIPLY_VECTOR(const CCV_QUAT_TYPENAME q, const CCV_VEC_TYPENAME(3) p)
581{
582 CCV_VEC_TYPENAME(3) t = CCV_FUNC_VEC_MULTIPLY(3)(CCV_FUNC_VEC_CROSS_PRODUCT(3)(q.xyz, p), 2);
583
584 return CCV_FUNC_VEC_ADD(3)(CCV_FUNC_VEC_ADD(3)(p, CCV_FUNC_VEC_MULTIPLY(3)(t, q.w)), CCV_FUNC_VEC_CROSS_PRODUCT(3)(q.xyz, t));
585}
586
587static inline CCV_QUAT_TYPENAME CCV_FUNC_QUAT_ADD(const CCV_QUAT_TYPENAME a, const CCV_QUAT_TYPENAME b)
588{
589 return CCV_FUNC_VEC_ADD(4)(a, b);
590}
591
592static inline CCV_QUAT_TYPENAME CCV_FUNC_QUAT_SUBTRACT(const CCV_QUAT_TYPENAME a, const CCV_QUAT_TYPENAME b)
593{
594 return CCV_FUNC_VEC_SUBTRACT(4)(a, b);
595}
596
597static inline CCV_QUAT_TYPENAME CCV_FUNC_QUAT_SCALE(const CCV_QUAT_TYPENAME q, const ccvType n)
598{
599 return CCV_FUNC_VEC_MULTIPLY(4)(q, n);
600}
601
602static inline CCV_QUAT_TYPENAME CCV_FUNC_QUAT_MIX(const CCV_QUAT_TYPENAME a, const CCV_QUAT_TYPENAME b, const ccvType f)
603{
604 ccvType cosHalfTheta = CCV_FUNC_VEC_DOTPRODUCT(4)(a, b);
605
606 if(CCV_ABS(cosHalfTheta) >= 1)
607 return a;
608 else {
609 ccvType sinHalfTheta = CCV_SQRT(1 - cosHalfTheta * cosHalfTheta);
610
611 if(CCV_ABS(sinHalfTheta) < CCV_EPSILON)
612 return CCV_FUNC_VEC_NORMALIZE(4)(CCV_FUNC_VEC_MIX(4)(a, b, (ccvType)0.5));
613 else
614 return CCV_FUNC_VEC_NORMALIZE(4)(CCV_FUNC_VEC_MIX(4)(a, b, CCV_SIN(f * CCV_ACOS(cosHalfTheta)) / sinHalfTheta));
615 }
616}
617
618// Define rotation methods
619
620#define CCV_SET_ROTATION_2D() \
621 m[0][0] = (ccvType)CCV_COS(r); \
622 m[0][1] = (ccvType)CCV_SIN(r); \
623 m[1][0] = -m[0][1]; \
624 m[1][1] = m[0][0]
625
626static inline void CCV_FUNC_MAT_SET_ROTATION(2)(CCV_MAT_TYPENAME(2) m, const ccvType r)
627{
628 CCV_SET_ROTATION_2D();
629}
630
631static inline void CCV_FUNC_MAT_ROTATE(2)(CCV_MAT_TYPENAME(2) m, const ccvType r) CCV_APPLY_MATRIX(2, CCV_FUNC_MAT_SET_ROTATION(2)(multiply, r));
632
633static inline void CCV_FUNC_MAT_SET_ROTATION_2D(2)(CCV_MAT_TYPENAME(3) m, const ccvType r)
634{
635 CCV_FUNC_MAT_ZERO(3)(m);
636
637 CCV_SET_ROTATION_2D();
638 m[2][2] = 1;
639}
640
641static inline void CCV_FUNC_MAT_ROTATE_2D(3)(CCV_MAT_TYPENAME(3) m, const ccvType r) CCV_APPLY_MATRIX(3, CCV_FUNC_MAT_SET_ROTATION_2D(2)(multiply, r));
642
643#define CCV_SET_ROTATION_3D_X() \
644 m[0][0] = 1; \
645 m[0][1] = 0; \
646 m[0][2] = 0; \
647 m[1][0] = 0; \
648 m[1][1] = (ccvType)CCV_COS(r); \
649 m[1][2] = (ccvType)CCV_SIN(r); \
650 m[2][0] = 0; \
651 m[2][1] = -m[1][2]; \
652 m[2][2] = m[1][1]
653
654#define CCV_SET_ROTATION_3D_Y() \
655 m[0][0] = (ccvType)CCV_COS(r); \
656 m[0][1] = 0; \
657 m[1][0] = 0; \
658 m[1][1] = 1; \
659 m[1][2] = 0; \
660 m[2][0] = (ccvType)CCV_SIN(r); \
661 m[0][2] = -m[2][0]; \
662 m[2][1] = 0; \
663 m[2][2] = m[0][0]
664
665#define CCV_SET_ROTATION_3D_Z() \
666 m[0][0] = (ccvType)CCV_COS(r); \
667 m[0][1] = (ccvType)CCV_SIN(r); \
668 m[0][2] = 0; \
669 m[1][0] = -m[0][1]; \
670 m[1][1] = m[0][0]; \
671 m[1][2] = 0; \
672 m[2][0] = 0; \
673 m[2][1] = 0; \
674 m[2][2] = 1
675
676static inline void CCV_FUNC_MAT_SET_ROTATION_X(3)(CCV_MAT_TYPENAME(3) m, const ccvType r)
677{
678 CCV_SET_ROTATION_3D_X();
679}
680
681static inline void CCV_FUNC_MAT_SET_ROTATION_Y(3)(CCV_MAT_TYPENAME(3) m, const ccvType r)
682{
683 CCV_SET_ROTATION_3D_Y();
684}
685
686static inline void CCV_FUNC_MAT_SET_ROTATION_Z(3)(CCV_MAT_TYPENAME(3) m, const ccvType r)
687{
688 CCV_SET_ROTATION_3D_Z();
689}
690
691static inline void CCV_FUNC_MAT_ROTATE_X(3)(CCV_MAT_TYPENAME(3) m, const ccvType r) CCV_APPLY_MATRIX(3, CCV_FUNC_MAT_SET_ROTATION_X(3)(multiply, r))
692
693static inline void CCV_FUNC_MAT_ROTATE_Y(3)(CCV_MAT_TYPENAME(3) m, const ccvType r) CCV_APPLY_MATRIX(3, CCV_FUNC_MAT_SET_ROTATION_Y(3)(multiply, r))
694
695static inline void CCV_FUNC_MAT_ROTATE_Z(3)(CCV_MAT_TYPENAME(3) m, const ccvType r) CCV_APPLY_MATRIX(3, CCV_FUNC_MAT_SET_ROTATION_Z(3)(multiply, r))
696
697static inline void CCV_FUNC_MAT_SET_ROTATION_X(4)(CCV_MAT_TYPENAME(4) m, const ccvType r)
698{
699 CCV_FUNC_MAT_ZERO(4)(m);
700
701 CCV_SET_ROTATION_3D_X();
702 m[3][3] = 1;
703}
704
705static inline void CCV_FUNC_MAT_SET_ROTATION_Y(4)(CCV_MAT_TYPENAME(4) m, const ccvType r)
706{
707 CCV_FUNC_MAT_ZERO(4)(m);
708
709 CCV_SET_ROTATION_3D_Y();
710 m[3][3] = 1;
711}
712
713static inline void CCV_FUNC_MAT_SET_ROTATION_Z(4)(CCV_MAT_TYPENAME(4) m, const ccvType r)
714{
715 CCV_FUNC_MAT_ZERO(4)(m);
716
717 CCV_SET_ROTATION_3D_Z();
718 m[3][3] = 1;
719}
720
721static inline void CCV_FUNC_MAT_ROTATE_X(4)(CCV_MAT_TYPENAME(4) m, const ccvType r) CCV_APPLY_MATRIX(4, CCV_FUNC_MAT_SET_ROTATION_X(4)(multiply, r))
722
723static inline void CCV_FUNC_MAT_ROTATE_Y(4)(CCV_MAT_TYPENAME(4) m, const ccvType r) CCV_APPLY_MATRIX(4, CCV_FUNC_MAT_SET_ROTATION_Y(4)(multiply, r))
724
725static inline void CCV_FUNC_MAT_ROTATE_Z(4)(CCV_MAT_TYPENAME(4) m, const ccvType r) CCV_APPLY_MATRIX(4, CCV_FUNC_MAT_SET_ROTATION_Z(4)(multiply, r))
726
727// Define translation methods
728
729static inline void CCV_FUNC_MAT_SET_TRANSLATION(3)(CCV_MAT_TYPENAME(3) m, const CCV_VEC_TYPENAME(2) v)
730{
731 CCV_FUNC_MAT_IDENTITY(3)(m);
732
733 m[2][0] = v.x;
734 m[2][1] = v.y;
735}
736
737static inline void CCV_FUNC_MAT_TRANSLATE(3)(CCV_MAT_TYPENAME(3) m, const CCV_VEC_TYPENAME(2) v) CCV_APPLY_MATRIX(3, CCV_FUNC_MAT_SET_TRANSLATION(3)(multiply, v))
738
739static inline void CCV_FUNC_MAT_SET_TRANSLATION(4)(CCV_MAT_TYPENAME(4) m, const CCV_VEC_TYPENAME(3) v)
740{
741 CCV_FUNC_MAT_IDENTITY(4)(m);
742
743 m[3][0] = v.x;
744 m[3][1] = v.y;
745 m[3][2] = v.z;
746}
747
748static inline void CCV_FUNC_MAT_TRANSLATE(4)(CCV_MAT_TYPENAME(4) m, const CCV_VEC_TYPENAME(3) v) CCV_APPLY_MATRIX(4, CCV_FUNC_MAT_SET_TRANSLATION(4)(multiply, v))
749
750// Define scaling methods
751
752static inline void CCV_FUNC_MAT_SET_SCALE(2)(CCV_MAT_TYPENAME(2) m, const ccvType scale)
753{
754 m[0][0] = m[1][1] = scale;
755 m[1][0] = m[0][1] = 0;
756}
757
758static inline void CCV_FUNC_MAT_SCALE(2)(CCV_MAT_TYPENAME(2) m, const ccvType scale) CCV_APPLY_MATRIX(2, CCV_FUNC_MAT_SET_SCALE(2)(multiply, scale))
759
760static inline void CCV_FUNC_MAT_SET_SCALE_2D(3)(CCV_MAT_TYPENAME(3) m, const ccvType scale)
761{
762 CCV_FUNC_MAT_ZERO(3)(m);
763
764 m[2][2] = 1;
765 m[0][0] = m[1][1] = scale;
766}
767
768static inline void CCV_FUNC_MAT_SCALE_2D(3)(CCV_MAT_TYPENAME(3) m, const ccvType scale) CCV_APPLY_MATRIX(3, CCV_FUNC_MAT_SET_SCALE_2D(3)(multiply, scale))
769
770static inline void CCV_FUNC_MAT_SET_SCALE(3)(CCV_MAT_TYPENAME(3) m, const ccvType scale)
771{
772 CCV_FUNC_MAT_ZERO(3)(m);
773
774 m[0][0] = m[1][1] = m[2][2] = scale;
775}
776
777static inline void CCV_FUNC_MAT_SCALE(3)(CCV_MAT_TYPENAME(3) m, const ccvType scale) CCV_APPLY_MATRIX(3, CCV_FUNC_MAT_SET_SCALE(3)(multiply, scale))
778
779static inline void CCV_FUNC_MAT_SET_SCALE(4)(CCV_MAT_TYPENAME(4) m, const ccvType scale)
780{
781 CCV_FUNC_MAT_ZERO(4)(m);
782
783 m[3][3] = 1;
784 m[0][0] = m[1][1] = m[2][2] = scale;
785}
786
787static inline void CCV_FUNC_MAT_SCALE(4)(CCV_MAT_TYPENAME(4) m, const ccvType scale) CCV_APPLY_MATRIX(4, CCV_FUNC_MAT_SET_SCALE(4)(multiply, scale))
788
789// Inverse matrix
790
791static inline void CCV_FUNC_MAT_INVERSE(3)(CCV_MAT_TYPENAME(3) t, CCV_MAT_TYPENAME(3) m)
792{
793 ccvType s[3][3];
794 ccvType idet;
795
796 s[0][0] = m[1][1] * m[2][2] - m[2][1] * m[1][2];
797 s[1][0] = - m[0][1] * m[2][2] + m[2][1] * m[0][2];
798 s[2][0] = m[0][1] * m[1][2] - m[1][1] * m[0][2];
799 s[0][1] = - m[1][0] * m[2][2] + m[1][2] * m[2][0];
800 s[1][1] = m[0][0] * m[2][2] - m[0][2] * m[2][0];
801 s[2][1] = - m[0][0] * m[1][2] + m[0][2] * m[1][0];
802 s[0][2] = m[1][0] * m[2][1] - m[1][1] * m[2][0];
803 s[1][2] = - m[0][0] * m[2][1] + m[0][1] * m[2][0];
804 s[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0];
805
806 idet = m[0][0] * s[0][0] + m[1][0] * s[1][0] + m[2][0] * s[2][0];
807#ifdef _DEBUG
808 assert(idet != 0);
809#endif
810 idet = 1 / idet;
811
812 t[0][0] = s[0][0] * idet;
813 t[1][0] = s[0][1] * idet;
814 t[2][0] = s[0][2] * idet;
815 t[0][1] = s[1][0] * idet;
816 t[1][1] = s[1][1] * idet;
817 t[2][1] = s[1][2] * idet;
818 t[0][2] = s[2][0] * idet;
819 t[1][2] = s[2][1] * idet;
820 t[2][2] = s[2][2] * idet;
821}
822
823static inline void CCV_FUNC_MAT_INVERSE(4)(CCV_MAT_TYPENAME(4) t, CCV_MAT_TYPENAME(4) m)
824{
825 ccvType s[6];
826 ccvType c[6];
827 ccvType idet;
828
829 s[0] = m[0][0] * m[1][1] - m[1][0] * m[0][1];
830 s[1] = m[0][0] * m[1][2] - m[1][0] * m[0][2];
831 s[2] = m[0][0] * m[1][3] - m[1][0] * m[0][3];
832 s[3] = m[0][1] * m[1][2] - m[1][1] * m[0][2];
833 s[4] = m[0][1] * m[1][3] - m[1][1] * m[0][3];
834 s[5] = m[0][2] * m[1][3] - m[1][2] * m[0][3];
835
836 c[0] = m[2][0] * m[3][1] - m[3][0] * m[2][1];
837 c[1] = m[2][0] * m[3][2] - m[3][0] * m[2][2];
838 c[2] = m[2][0] * m[3][3] - m[3][0] * m[2][3];
839 c[3] = m[2][1] * m[3][2] - m[3][1] * m[2][2];
840 c[4] = m[2][1] * m[3][3] - m[3][1] * m[2][3];
841 c[5] = m[2][2] * m[3][3] - m[3][2] * m[2][3];
842
843 idet = s[0] * c[5] - s[1] * c[4] + s[2] * c[3] + s[3] * c[2] - s[4] * c[1] + s[5] * c[0];
844#ifdef _DEBUG
845 assert(idet != 0);
846#endif
847 idet = 1 / idet;
848
849 t[0][0] = (m[1][1] * c[5] - m[1][2] * c[4] + m[1][3] * c[3]) * idet;
850 t[0][1] = (-m[0][1] * c[5] + m[0][2] * c[4] - m[0][3] * c[3]) * idet;
851 t[0][2] = (m[3][1] * s[5] - m[3][2] * s[4] + m[3][3] * s[3]) * idet;
852 t[0][3] = (-m[2][1] * s[5] + m[2][2] * s[4] - m[2][3] * s[3]) * idet;
853
854 t[1][0] = (-m[1][0] * c[5] + m[1][2] * c[2] - m[1][3] * c[1]) * idet;
855 t[1][1] = (m[0][0] * c[5] - m[0][2] * c[2] + m[0][3] * c[1]) * idet;
856 t[1][2] = (-m[3][0] * s[5] + m[3][2] * s[2] - m[3][3] * s[1]) * idet;
857 t[1][3] = (m[2][0] * s[5] - m[2][2] * s[2] + m[2][3] * s[1]) * idet;
858
859 t[2][0] = (m[1][0] * c[4] - m[1][1] * c[2] + m[1][3] * c[0]) * idet;
860 t[2][1] = (-m[0][0] * c[4] + m[0][1] * c[2] - m[0][3] * c[0]) * idet;
861 t[2][2] = (m[3][0] * s[4] - m[3][1] * s[2] + m[3][3] * s[0]) * idet;
862 t[2][3] = (-m[2][0] * s[4] + m[2][1] * s[2] - m[2][3] * s[0]) * idet;
863
864 t[3][0] = (-m[1][0] * c[3] + m[1][1] * c[1] - m[1][2] * c[0]) * idet;
865 t[3][1] = (m[0][0] * c[3] - m[0][1] * c[1] + m[0][2] * c[0]) * idet;
866 t[3][2] = (-m[3][0] * s[3] + m[3][1] * s[1] - m[3][2] * s[0]) * idet;
867 t[3][3] = (m[2][0] * s[3] - m[2][1] * s[1] + m[2][2] * s[0]) * idet;
868}
869
870// Projection matrix
871
872static inline void CCV_FUNC_MAT_PERSPECTIVE(4)(CCV_MAT_TYPENAME(4) m, ccvType angle, ccvType aspect, ccvType zNear, ccvType zFar)
873{
874 ccvType a = CCV_TAN(angle * (ccvType)0.5);
875
876#ifdef _DEBUG
877 assert(aspect != 0);
878 assert(a != 0);
879#endif
880
881 a = 1 / a;
882
883 m[0][0] = a / aspect;
884 m[0][1] = 0;
885 m[0][2] = 0;
886 m[0][3] = 0;
887
888 m[1][0] = 0;
889 m[1][1] = a;
890 m[1][2] = 0;
891 m[1][3] = 0;
892
893 m[2][0] = 0;
894 m[2][1] = 0;
895 m[2][2] = -((zFar + zNear) / (zFar - zNear));
896 m[2][3] = -1;
897
898 m[3][0] = 0;
899 m[3][1] = 0;
900 m[3][2] = -((2 * zFar * zNear) / (zFar - zNear));
901 m[3][3] = 0;
902}
903
904// Modelview matrix
905
906static inline void CCV_FUNC_MAT_LOOK_AT(4)(CCV_MAT_TYPENAME(4) m, CCV_VEC_TYPENAME(3) from, CCV_VEC_TYPENAME(3) to, CCV_VEC_TYPENAME(3) up)
907{
908 unsigned int i;
909 CCV_VEC_TYPENAME(3) f = CCV_FUNC_VEC_NORMALIZE(3)(CCV_FUNC_VEC_SUBTRACT(3)(to, from));
910 CCV_VEC_TYPENAME(3) s = CCV_FUNC_VEC_NORMALIZE(3)(CCV_FUNC_VEC_CROSS_PRODUCT(3)(f, up));
911 CCV_VEC_TYPENAME(3) t = CCV_FUNC_VEC_CROSS_PRODUCT(3)(s, f);
912
913 m[0][0] = s.x;
914 m[0][1] = t.x;
915 m[0][2] = -f.x;
916 m[0][3] = 0;
917
918 m[1][0] = s.y;
919 m[1][1] = t.y;
920 m[1][2] = -f.y;
921 m[1][3] = 0;
922
923 m[2][0] = s.z;
924 m[2][1] = t.z;
925 m[2][2] = -f.z;
926 m[2][3] = 0;
927
928 for(i = 0; i < 3; ++i) {
929 CCV_VEC_TYPENAME(3) r = CCV_FUNC_MAT_GET_ROW(4)(m, i).xyz;
930 m[3][i] = -CCV_FUNC_VEC_DOTPRODUCT(3)(r, from);
931 }
932
933 m[3][3] = 1;
934}
935
936#ifdef __cplusplus
937}
938#endif
939
940#endif
Definition ccVector.h:385