ai_vector.h
1 /*
2  * Arnold API header file
3  * Copyright (c) 1998-2009 Marcos Fajardo, (c) 2009-2013 Solid Angle SL
4  */
5 
11 #pragma once
12 #include "ai_constants.h"
13 #include "ai_types.h"
14 #include "ai_api.h"
15 #include <math.h>
16 
30 struct AtPoint
31 {
32  float x, y, z;
33 
34  AtPoint operator+(const AtPoint& p) const
35  {
36  AtPoint temp;
37  temp.x = x + p.x;
38  temp.y = y + p.y;
39  temp.z = z + p.z;
40  return temp;
41  }
42 
43  AtPoint& operator+=(const AtPoint& p)
44  {
45  x += p.x;
46  y += p.y;
47  z += p.z;
48  return *this;
49  }
50 
51  AtPoint operator+(float f) const
52  {
53  AtPoint temp;
54  temp.x = x + f;
55  temp.y = y + f;
56  temp.z = z + f;
57  return temp;
58  }
59 
60  AtPoint& operator+=(float f)
61  {
62  x += f;
63  y += f;
64  z += f;
65  return *this;
66  }
67 
68  AtPoint operator-(const AtPoint& p) const
69  {
70  AtPoint temp;
71  temp.x = x - p.x;
72  temp.y = y - p.y;
73  temp.z = z - p.z;
74  return temp;
75  }
76 
77  AtPoint& operator-=(const AtPoint& p)
78  {
79  x -= p.x;
80  y -= p.y;
81  z -= p.z;
82  return *this;
83  }
84 
85  AtPoint operator-(float f) const
86  {
87  AtPoint temp;
88  temp.x = x - f;
89  temp.y = y - f;
90  temp.z = z - f;
91  return temp;
92  }
93 
94  AtPoint& operator-=(float f)
95  {
96  x -= f;
97  y -= f;
98  z -= f;
99  return *this;
100  }
101 
102  AtPoint operator-() const
103  {
104  AtPoint temp;
105  temp.x = -x;
106  temp.y = -y;
107  temp.z = -z;
108  return temp;
109  }
110 
111  AtPoint operator*(const AtPoint& p) const
112  {
113  AtPoint temp;
114  temp.x = x * p.x;
115  temp.y = y * p.y;
116  temp.z = z * p.z;
117  return temp;
118  }
119 
120  AtPoint operator*=(const AtPoint& p)
121  {
122  x *= p.x;
123  y *= p.y;
124  z *= p.z;
125  return *this;
126  }
127 
128  AtPoint operator*(float f) const
129  {
130  AtPoint temp;
131  temp.x = x * f;
132  temp.y = y * f;
133  temp.z = z * f;
134  return temp;
135  }
136 
137  AtPoint operator*=(float f)
138  {
139  x *= f;
140  y *= f;
141  z *= f;
142  return *this;
143  }
144 
145  AtPoint operator/(const AtPoint& p) const
146  {
147  AtPoint temp;
148  temp.x = x / p.x;
149  temp.y = y / p.y;
150  temp.z = z / p.z;
151  return temp;
152  }
153 
154  AtPoint operator/=(const AtPoint& p)
155  {
156  x /= p.x;
157  y /= p.y;
158  z /= p.z;
159  return *this;
160  }
161 
162  AtPoint operator/(float f) const
163  {
164  AtPoint temp;
165  float inv = 1.0f / f;
166  temp.x = x * inv;
167  temp.y = y * inv;
168  temp.z = z * inv;
169  return temp;
170  }
171 
172  AtPoint operator/=(float f)
173  {
174  float inv = 1.0f / f;
175  x *= inv;
176  y *= inv;
177  z *= inv;
178  return *this;
179  }
180 
181  bool operator==(const AtPoint& p) const
182  {
183  return (x == p.x && y == p.y && z == p.z);
184  }
185 
186  bool operator!=(const AtPoint& p) const
187  {
188  return !(*this == p);
189  }
190 
191  AtPoint& operator=(float f)
192  {
193  x = f;
194  y = f;
195  z = f;
196  return *this;
197  }
198 
199  float& operator[](unsigned int i)
200  {
201  return *(&x + i); // no bounds checking!
202  }
203 
204  const float& operator[](unsigned int i) const
205  {
206  return *(&x + i); // no bounds checking!
207  }
208 
209  friend AtPoint operator*(float f, const AtPoint& p);
210  friend AtPoint operator+(float f, const AtPoint& p);
211  friend AtPoint operator-(float f, const AtPoint& p);
212 };
213 
214 inline AtPoint operator*(float f, const AtPoint& p)
215 {
216  return p * f;
217 }
218 
219 inline AtPoint operator+(float f, const AtPoint& p)
220 {
221  return p + f;
222 }
223 
224 inline AtPoint operator-(float f, const AtPoint& p)
225 {
226  AtPoint temp;
227  temp.x = f - p.x;
228  temp.y = f - p.y;
229  temp.z = f - p.z;
230  return temp;
231 }
232 
236 struct AtPoint2
237 {
238  float x, y;
239 
240  AtPoint2 operator+(const AtPoint2& p) const
241  {
242  AtPoint2 temp;
243  temp.x = x + p.x;
244  temp.y = y + p.y;
245  return temp;
246  }
247 
248  AtPoint2& operator+=(const AtPoint2& p)
249  {
250  x += p.x;
251  y += p.y;
252  return *this;
253  }
254 
255  AtPoint2 operator+(float f) const
256  {
257  AtPoint2 temp;
258  temp.x = x + f;
259  temp.y = y + f;
260  return temp;
261  }
262 
263  AtPoint2& operator+=(float f)
264  {
265  x += f;
266  y += f;
267  return *this;
268  }
269 
270  AtPoint2 operator-(const AtPoint2& p) const
271  {
272  AtPoint2 temp;
273  temp.x = x - p.x;
274  temp.y = y - p.y;
275  return temp;
276  }
277 
278  AtPoint2& operator-=(const AtPoint2& p)
279  {
280  x -= p.x;
281  y -= p.y;
282  return *this;
283  }
284 
285  AtPoint2 operator-(float f) const
286  {
287  AtPoint2 temp;
288  temp.x = x - f;
289  temp.y = y - f;
290  return temp;
291  }
292 
293  AtPoint2& operator-=(float f)
294  {
295  x -= f;
296  y -= f;
297  return *this;
298  }
299 
300  AtPoint2 operator-() const
301  {
302  AtPoint2 temp;
303  temp.x = -x;
304  temp.y = -y;
305  return temp;
306  }
307 
308  AtPoint2 operator*(const AtPoint2& p) const
309  {
310  AtPoint2 temp;
311  temp.x = x * p.x;
312  temp.y = y * p.y;
313  return temp;
314  }
315 
316  AtPoint2 operator*=(const AtPoint2& p)
317  {
318  x *= p.x;
319  y *= p.y;
320  return *this;
321  }
322 
323  AtPoint2 operator*(float f) const
324  {
325  AtPoint2 temp;
326  temp.x = x * f;
327  temp.y = y * f;
328  return temp;
329  }
330 
331  AtPoint2 operator*=(float f)
332  {
333  x *= f;
334  y *= f;
335  return *this;
336  }
337 
338  AtPoint2 operator/(const AtPoint2& p) const
339  {
340  AtPoint2 temp;
341  temp.x = x / p.x;
342  temp.y = y / p.y;
343  return temp;
344  }
345 
346  AtPoint2 operator/=(const AtPoint2& p)
347  {
348  x /= p.x;
349  y /= p.y;
350  return *this;
351  }
352 
353  AtPoint2 operator/(float f) const
354  {
355  AtPoint2 temp;
356  float inv = 1.0f / f;
357  temp.x = x * inv;
358  temp.y = y * inv;
359  return temp;
360  }
361 
362  AtPoint2 operator/=(float f)
363  {
364  float inv = 1.0f / f;
365  x *= inv;
366  y *= inv;
367  return *this;
368  }
369 
370  bool operator==(const AtPoint2& p) const
371  {
372  return (x == p.x && y == p.y);
373  }
374 
375  bool operator!=(const AtPoint2& p) const
376  {
377  return !(*this == p);
378  }
379 
380  AtPoint2& operator=(float f)
381  {
382  x = f;
383  y = f;
384  return *this;
385  }
386 
387  float& operator[](unsigned int i)
388  {
389  return *(&x + i); // no bounds checking!
390  }
391 
392  const float& operator[](unsigned int i) const
393  {
394  return *(&x + i); // no bounds checking!
395  }
396 
397  friend AtPoint2 operator*(float f, const AtPoint2& p);
398  friend AtPoint2 operator+(float f, const AtPoint2& p);
399  friend AtPoint2 operator-(float f, const AtPoint2& p);
400 };
401 
402 inline AtPoint2 operator*(float f, const AtPoint2& p)
403 {
404  return p * f;
405 }
406 
407 inline AtPoint2 operator+(float f, const AtPoint2& p)
408 {
409  return p + f;
410 }
411 
412 inline AtPoint2 operator-(float f, const AtPoint2& p)
413 {
414  AtPoint2 temp;
415  temp.x = f - p.x;
416  temp.y = f - p.y;
417  return temp;
418 }
419 
423 struct AtHPoint
424 {
425  float x, y, z, w;
426 };
427 
431 typedef AtPoint AtVector;
433 /*\}*/
434 
438 #define AI_X 0
439 #define AI_Y 1
440 #define AI_Z 2
441 /*\}*/
442 
443 
444 
452 inline void AiV2Create(AtVector2& vout, float x, float y)
453 {
454  vout.x = x;
455  vout.y = y;
456 }
457 
461 inline float AiV2Dot(const AtVector2& v1, const AtVector2& v2)
462 {
463  return v1.x * v2.x + v1.y * v2.y;
464 }
465 
469 inline float AiV2Length(const AtVector2& v1)
470 {
471  return sqrtf(v1.x * v1.x + v1.y * v1.y);
472 }
473 
477 inline float AiV2Dist(const AtPoint2& p1, const AtPoint2& p2)
478 {
479  return sqrtf(SQR(p1.x-p2.x) + SQR(p1.y - p2.y));
480 }
481 
486 inline AtVector2 AiV2Lerp(float t, const AtVector2& lo, const AtVector2& hi)
487 {
488  AtVector2 out;
489  out.x = LERP(t, lo.x, hi.x);
490  out.y = LERP(t, lo.y, hi.y);
491  return out;
492 }
493 
497 inline AtVector2 AiV2Clamp(const AtVector2& in, float lo, float hi)
498 {
499  AtVector2 out;
500  out.x = CLAMP(in.x, lo, hi);
501  out.y = CLAMP(in.y, lo, hi);
502  return out;
503 }
504 
505 /*\}*/
506 
507 
508 
516 inline float AiV3Length(const AtVector& a)
517 {
518  return sqrtf(a.x*a.x + a.y*a.y + a.z*a.z);
519 }
520 
524 inline float AiV3Dot(const AtVector& a, const AtVector& b)
525 {
526  return a.x*b.x + a.y*b.y + a.z*b.z;
527 }
528 
532 inline float AiV3Dist(const AtVector& a, const AtVector& b)
533 {
534  return sqrtf(SQR(a.x-b.x) + SQR(a.y-b.y) + SQR(a.z-b.z));
535 }
536 
540 inline float AiV3Dist2(const AtVector& a, const AtVector& b)
541 {
542  return SQR(a.x-b.x) + SQR(a.y-b.y) + SQR(a.z-b.z);
543 }
544 
548 inline float AiV3DistPlane(const AtPoint& x, const AtPoint& p, const AtVector& n)
549 {
550  return AiV3Dot(x, n) - AiV3Dot(p, n);
551 }
552 
556 inline AtVector AiV3Cross(const AtVector& a, const AtVector& b)
557 {
558  AtVector out;
559  out.x = a.y * b.z - a.z * b.y;
560  out.y = a.z * b.x - a.x * b.z;
561  out.z = a.x * b.y - a.y * b.x;
562  return out;
563 }
564 
569 {
570  float tmp = AiV3Length(a);
571  if (tmp != 0)
572  tmp = 1 / tmp;
573  AtVector out;
574  out.x = a.x * tmp;
575  out.y = a.y * tmp;
576  out.z = a.z * tmp;
577  return out;
578 }
579 
584 inline AtVector AiV3Lerp(float t, const AtVector& lo, const AtVector& hi)
585 {
586  AtVector out;
587  out.x = LERP(t, lo.x, hi.x);
588  out.y = LERP(t, lo.y, hi.y);
589  out.z = LERP(t, lo.z, hi.z);
590  return out;
591 }
592 
596 inline AtVector AiV3Clamp(const AtVector& in, float lo, float hi)
597 {
598  AtVector out;
599  out.x = CLAMP(in.x, lo, hi);
600  out.y = CLAMP(in.y, lo, hi);
601  out.z = CLAMP(in.z, lo, hi);
602  return out;
603 }
604 
608 inline AtVector AiV3Min(const AtVector& a, const AtVector& b)
609 {
610  AtVector out;
611  out.x = MIN(a.x, b.x);
612  out.y = MIN(a.y, b.y);
613  out.z = MIN(a.z, b.z);
614  return out;
615 }
616 
620 inline AtVector AiV3Max(const AtVector& a, const AtVector& b)
621 {
622  AtVector out;
623  out.x = MAX(a.x, b.x);
624  out.y = MAX(a.y, b.y);
625  out.z = MAX(a.z, b.z);
626  return out;
627 }
628 
632 inline AtVector ABS(const AtVector& a)
633 {
634  AtVector out = { ABS(a.x), ABS(a.y), ABS(a.z) };
635  return out;
636 }
637 
641 inline AtVector AiBerpXYZ(float a, float b, const AtVector& p0, const AtVector& p1, const AtVector& p2)
642 {
643  float c = 1 - (a + b);
644  return c*p0 + a*p1 + b*p2;
645 }
646 
650 AI_API bool AiV3Exists(const AtVector& a);
651 
655 inline bool AiV3Equal(const AtVector& a, const AtVector& b)
656 {
657  return (a.x==b.x) && (a.y==b.y) && (a.z==b.z);
658 }
659 
663 inline bool AiV3IsSmall(const AtVector& a, float epsilon = AI_EPSILON)
664 {
665  return ABS(a.x) < epsilon && ABS(a.y) < epsilon && ABS(a.z) < epsilon;
666 }
667 
671 inline bool AiV3IsZero(const AtVector& a)
672 {
673  return AiV3IsSmall(a);
674 }
675 
679 inline void AiV3RotateToFrame(AtVector& a, const AtVector& u, const AtVector& v, const AtVector& w)
680 {
681  a = u * a.x + v * a.y + w * a.z;
682 }
683 
687 inline void AiBerpUV(float a, float b, float u0, float v0, float u1, float v1, float u2, float v2, float* u, float* v)
688 {
689  float c = 1.0f - (a + b);
690  *u = c * u0 + a * u1 + b * u2;
691  *v = c * v0 + a * v1 + b * v2;
692 }
693 
694 /*\}*/
695 
703 inline void AiV4Create(AtHPoint& vout, float x, float y, float z, float w)
704 {
705  vout.x = x;
706  vout.y = y;
707  vout.z = z;
708  vout.w = w;
709 }
710 
714 inline void AiV4CreatePoint(AtHPoint& pout, const AtVector& v)
715 {
716  pout.x = v.x;
717  pout.y = v.y;
718  pout.z = v.z;
719  pout.w = 1.0f;
720 }
721 
725 inline void AiV4CreateVector(AtHPoint& vout, const AtVector& v)
726 {
727  vout.x = v.x;
728  vout.y = v.y;
729  vout.z = v.z;
730  vout.w = 0.0f;
731 }
732 
736 inline void AiV4Add(AtHPoint& vout, const AtHPoint& v1, const AtHPoint& v2)
737 {
738  vout.x = v1.x + v2.x;
739  vout.y = v1.y + v2.y;
740  vout.z = v1.z + v2.z;
741  vout.w = v1.w + v2.w;
742 }
743 
747 inline void AiV4Sub(AtHPoint& vout, const AtHPoint& v1, const AtHPoint& v2)
748 {
749  vout.x = v1.x - v2.x;
750  vout.y = v1.y - v2.y;
751  vout.z = v1.z - v2.z;
752  vout.w = v1.w - v2.w;
753 }
754 
758 inline void AiV4Scale(AtHPoint& vout, const AtHPoint& vin, float k)
759 {
760  vout.x = vin.x * k;
761  vout.y = vin.y * k;
762  vout.z = vin.z * k;
763  vout.w = vin.w * k;
764 }
765 
769 inline void AiV4Neg(AtHPoint& vout, const AtHPoint& vin)
770 {
771  vout.x = -vin.x;
772  vout.y = -vin.y;
773  vout.z = -vin.z;
774  vout.w = -vin.w;
775 }
776 
780 inline void AiV4Project(AtVector& vout, const AtHPoint& vin)
781 {
782  if (vin.w != 0)
783  {
784  float f = 1.0f / vin.w;
785  vout.x = vin.x * f;
786  vout.y = vin.y * f;
787  vout.z = vin.z * f;
788  }
789  else
790  {
791  vout.x = 0;
792  vout.y = 0;
793  vout.z = 0;
794  }
795 }
796 
797 /*\}*/
798 
803 inline void AiV2Add(AtVector2& out, const AtVector2& v1, const AtVector2& v2)
804 {
805  out = v1 + v2;
806 }
807 
808 inline void AiV2Sub(AtVector2& out, const AtVector2& v1, const AtVector2& v2)
809 {
810  out = v1 - v2;
811 }
812 
813 inline void AiV2Scale(AtVector2& out, const AtVector2& v1, float k)
814 {
815  out = v1 * k;
816 }
817 
818 inline void AiV2Lerp(AtVector2& out, float t, const AtVector2& lo, const AtVector2& hi)
819 {
820  out = AiV2Lerp(t, lo, hi);
821 }
822 
823 inline void AiV2Clamp(AtVector2& out, const AtVector2& in, float lo, float hi)
824 {
825  out = AiV2Clamp(in, lo, hi);
826 }
827 inline void AiV3Cross(AtVector& out, const AtVector& a, const AtVector& b)
828 {
829  out = AiV3Cross(a, b);
830 }
831 
832 inline void AiV3Normalize(AtVector& out, const AtVector& in)
833 {
834  out = AiV3Normalize(in);
835 }
836 
837 inline void AiV3Lerp(AtVector& out, float t, const AtVector& lo, const AtVector& hi)
838 {
839  out = AiV3Lerp(t, lo, hi);
840 }
841 
842 inline void AiV3Min(AtVector& out, const AtVector& a, const AtVector& b)
843 {
844  out = AiV3Min(a, b);
845 }
846 
847 inline void AiV3Max(AtVector& out, const AtVector& a, const AtVector& b)
848 {
849  out = AiV3Max(a, b);
850 }
851 
852 inline void AiV3Clamp(AtVector& out, const AtVector& in, float lo, float hi)
853 {
854  out = AiV3Clamp(in, lo, hi);
855 }
856 
857 inline void AiBerpXYZ(float a, float b, const AtVector& p0, const AtVector& p1, const AtVector& p2, AtVector& out)
858 {
859  out = AiBerpXYZ(a, b, p0, p1, p2);
860 }
861 
862 inline void AiV3Create(AtVector& vout, float x, float y, float z)
863 {
864  vout.x = x;
865  vout.y = y;
866  vout.z = z;
867 }
868 
869 inline void AiV3Copy(AtVector& vout, const AtVector& vin)
870 {
871  vout = vin;
872 }
873 
874 inline void AiV3Add(AtVector& vout, const AtVector& v1, const AtVector& v2)
875 {
876  vout = v1 + v2;
877 }
878 
879 inline void AiV3Sub(AtVector& vout, const AtVector& v1, const AtVector& v2)
880 {
881  vout = v1 - v2;
882 }
883 
884 inline void AiV3AddScalar(AtVector& vout, const AtVector& vin, float k)
885 {
886  vout = vin + k;
887 }
888 
889 inline void AiV3SubScalar(AtVector& vout, const AtVector& vin, float k)
890 {
891  vout = vin - k;
892 }
893 
894 inline void AiV3Scale(AtVector& vout, const AtVector& vin, float k)
895 {
896  vout = vin * k;
897 }
898 
899 inline void AiV3Neg(AtVector& vout, const AtVector& vin)
900 {
901  vout = -vin;
902 }
903 
904 inline void AiV3Invert(AtVector& vout, const AtVector& vin)
905 {
906  vout.x = 1.0f / vin.x;
907  vout.y = 1.0f / vin.y;
908  vout.z = 1.0f / vin.z;
909 }
910 
911 inline void AiV3Mult(AtVector& vout, const AtVector& v1, const AtVector& v2)
912 {
913  vout = v1 * v2;
914 }
915 
916 inline void AiV3Div(AtVector& vout, const AtVector& v1, const AtVector& v2)
917 {
918  vout = v1 / v2;
919 }
920 
921 inline void AiV3Midpoint(AtPoint& pout, const AtVector& v1, const AtVector& v2)
922 {
923  pout = (v1 + v2) * 0.5f;
924 }
925 
926 inline void AiV3ProjectPointOnLine(AtPoint& pout, const AtPoint& o, const AtVector& dir, const AtPoint& p)
927 {
928  pout = o + dir * AiV3Dot(dir, p - o);
929 }
930 
931 inline void AiV3RayPoint(AtPoint& pout, const AtPoint& origin, const AtVector& dir, double t)
932 {
933  pout.x = (float) (origin.x + dir.x * t);
934  pout.y = (float) (origin.y + dir.y * t);
935  pout.z = (float) (origin.z + dir.z * t);
936 }
937 
938 #define AiV3isZero AiV3IsSmall // the wrong spelling is deprecated
939 
940 /*\}*/
941 
942 
946 AI_API AtPoint AI_P3_ZERO;
947 AI_API AtVector AI_V3_ZERO;
948 AI_API AtVector AI_V3_HALF;
949 AI_API AtVector AI_V3_ONE;
950 AI_API AtVector AI_V3_X;
951 AI_API AtVector AI_V3_Y;
952 AI_API AtVector AI_V3_Z;
953 AI_API AtVector AI_V3_NEGX;
954 AI_API AtVector AI_V3_NEGY;
955 AI_API AtVector AI_V3_NEGZ;
956 AI_API AtPoint2 AI_P2_ZERO;
957 AI_API AtPoint2 AI_P2_ONE;
958 /*\}*/
959 
960 /*\}*/

© 2009-2013 Solid Angle SL · all rights reserved · www.solidangle.com