3DCoat Core API
The 3DCoat API documentation.
Loading...
Searching...
No Matches
cVec3.h
1#pragma once
2
3template<class Type, int Dim>
4struct cVec;
5class dVec3;
6
10class APICALL COMMS_ALIASING cVec3 {
11public:
12 float x;
13 float y;
14 float z;
15
16 cVec3();
17 explicit cVec3(const float S);
18 cVec3(const float X, const float Y, const float Z);
19 cVec3(const cVec2 &XY, const float Z);
20 cVec3(const dVec3& v);
21 cVec3(const cVec3& v):x(v.x), y(v.y), z(v.z) {}
22
23 void Copy(const float *Src);
24 void SetZero();
25 void SetOne();
26 void SetRandRange1();
27 void Set(const float S);
28 void Set(const float X, const float Y, const float Z);
29 void Set(const cVec2 &XY, const float Z);
30
31 float & operator [] (const int Index);
32 float operator [] (const int Index) const;
33
34 const cVec3 operator - () const;
35
36 cVec3& operator += (const cVec3 &);
37 cVec3& operator -= (const cVec3 &);
38 cVec3& operator *= (const cVec3 &);
39 cVec3& operator *= (const float);
40 cVec3& operator /= (const cVec3 &);
41 cVec3& operator /= (const float);
42
43 void TransformCoordinate(const cMat4 &);
44 void TransformNormal(const cMat4 &);
45 void TransformNormalTransposed(const cMat4 &);
46
47 void Transform(const cMat3 &);
48 cVec3& operator *= (const cMat3 &);
49
50 void Rotate(const cQuat &);
51 void operator *= (const cQuat &);
52
53 void Rotate(const cRotation &);
54 void operator *= (const cRotation &);
55
56 const cVec3 & operator = ( const cVec4 &);
57 inline float distance(const cVec3 &u) const {
58 float dx = u.x - x;
59 float dy = u.y - y;
60 float dz = u.z - z;
61 return cMath::Sqrt(dx * dx + dy * dy + dz * dz);
62 }
63 inline float distanceSq(const cVec3 &u) const {
64 float dx = u.x - x;
65 float dy = u.y - y;
66 float dz = u.z - z;
67 return dx * dx + dy * dy + dz * dz;
68 }
69 float dot(const cVec3 &u) const {
70 return u.x * x + u.y * y + u.z * z;
71 }
72 void cross(const cVec3 &u, const cVec3 &v) {
73 *this=cVec3(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x);
74 }
75
77 // for compatibility with OpenSubdiv ////
78 inline void Clear(void* = 0);
79
80 inline void AddWithWeight(cVec3 const& src, float weight) {
81 x += weight * src.x;
82 y += weight * src.y;
83 z += weight * src.z;
84 }
85 inline void SetPosition(float aX, float aY, float aZ) {
86 x = aX;
87 y = aY;
88 z = aZ;
89 }
90 inline const float* GetPosition() const {
91 return &x;
92 }
93 // for compatibility with OpenSubdiv //
95
96 const cVec3 operator + (const cVec3 &) const;
97 const cVec3 operator - (const cVec3 &) const;
98 const cVec3 operator * (const cVec3 &) const;
99 const cVec3 operator * (const float) const;
100 friend const cVec3 operator * (const float, const cVec3 &);
101 const cVec3 operator / (const cVec3 &) const;
102 const cVec3 operator / (const float) const;
103
104 static const cVec3 Transform(const cVec3 &, const cMat3 &);
105 const cVec3 operator * (const cMat3 &) const;
106
107 static const cVec4 Transform(const cVec3 &, const cMat4 &); // (x, y, z, 1)
108 static const cVec3 TransformCoordinate(const cVec3 &, const cMat4 &);
109 static const cVec3 TransformNormal(const cVec3 &, const cMat4 &);
110 static void TransformCoordinate(cList<cVec3> *, const cMat4 &);
111 static void TransformNormal(cList<cVec3> *, const cMat4 &);
112 static void TransformCoordinate(cVec3 *Array, const int Count, const cMat4 &T);
113 static void TransformNormal(cVec3 *Array, const int Count, const cMat4 &T);
114
115 static const cVec3 Rotate(const cVec3 &, const cQuat &);
116 const cVec3 operator * (const cQuat &) const;
117
118 static const cVec3 Rotate(const cVec3 &, const cRotation &);
119 const cVec3 operator * (const cRotation &) const;
120
121 bool operator == (const cVec3 &) const;
122 bool operator != (const cVec3 &) const;
123 static bool Equals(const cVec3 &, const cVec3 &, const float Eps = cMath::Epsilon);
124
125 float Length() const;
126 float Length2() const;
127 float LengthSq() const;
128 float LengthM() const; //Manhattan distance
129 float Normalize();
130 float Normalize2();
131 float NormalizeSafe(const cVec3 &Fallback = cVec3::AxisZ);
132 bool FixDegenerateNormal();
133 bool FixDenormals();
134 bool IsValid() const;
135 bool IsNormalized(float Eps = cMath::Epsilon) const;
136 bool IsZero(float Eps = cMath::Epsilon) const;
137 void Round();
138
139 static const cVec3 Abs(const cVec3 &);
140 static float Angle(const cVec3 &, const cVec3 &);
141 static float Angle(const cVec3& p1, const cVec3& p2, const cVec3& p3, const cVec3& normal);
142 static float AreaSigned(const cVec3 &t0, const cVec3 &t1, const cVec3 &t2);
143 static const cVec3 BaryCentric(const cVec3 &t0, const cVec3 &t1, const cVec3 &t2, const float f, const float g);
144 static const cVec3 Clamp(const cVec3 &, const cVec3 &, const cVec3 &);
145 static const cVec3 Cross(const cVec3 &, const cVec3 &);
146 void SetCross(const cVec3 &, const cVec3 &);
147 static float Distance(const cVec3 &, const cVec3 &);
148 static float Distance2(const cVec3 &, const cVec3 &);
149 float Distance(const cVec3 &) const;
150 float Distance2(const cVec3 &) const;
151 static float DistanceSq(const cVec3 &, const cVec3 &);
152 static float Dot(const cVec3 &, const cVec3 &);
153 float Dot(const cVec3 &) const;
154 static float Length(const cVec3 &);
155 static float LengthSq(const cVec3 &);
156 static const cVec3 Lerp(const cVec3 &, const cVec3 &, const float);
157 static const cVec3 Lerp05(const cVec3 &, const cVec3 &);
158 static const cVec3 Max(const cVec3 &, const cVec3 &);
159 static const cVec3 Min(const cVec3 &, const cVec3 &);
160 static const cVec3 Normalize(const cVec3 &);
161 static const cVec3 Normalize2(const cVec3 &);
162 static const cVec3 Reflect(const cVec3 &RayDir, const cVec3 &Normal);
163 // @param Eta Ratio of indices of refraction at the surface interface.
164 static const cVec3 Refract(const cVec3 &RayDir, const cVec3 &Normal, const float Eta);
165 static const cVec3 Slerp(const cVec3 &n0, const cVec3 &n1, const float s);
166 static const cVec3 Truncate(const cVec3 &u, const float MaxLen);
167 void Truncate(const float MaxLen);
168 static const cVec3 RandRange1();
169 static const cVec3 RandNormal();
170 static const cVec3 Rand(const cVec3 &Lo, const cVec3 &Hi);
171 static const cVec3 Project(const cVec3 &v1, const cVec3 &v2);
172 static const cVec3 Perpendicular(const cVec3 &v1);
173 float TriProjectionSolidAngle(const cVec3 &a, const cVec3 &b, const cVec3 &c) const;
174
175 static const cVec3 Zero;
176 static const cVec3 One;
177 static const cVec3 Infinity;
178 static const cVec3 AxisX;
179 static const cVec3 AxisY;
180 static const cVec3 AxisZ;
181 static const cVec3 AxisNegX;
182 static const cVec3 AxisNegY;
183 static const cVec3 AxisNegZ;
184
185 int GetDimension() const;
186
187 const float * ToFloatPtr() const;
188 float * ToFloatPtr();
189
190 const cVec2 & ToVec2() const;
191 cVec2 & ToVec2();
192
193 template<class Type>
194 operator cVec<Type, 3> () const;
195
196 const cStr ToString(const int Prec = 2) const;
197
198 const std::string __repr__() const;
199
200 const cAngles ToAngles() const;
201
202 cVec3 GetOrthonormal() const;
203 std::pair<cVec3, cVec3> GetOrthonormalPair() const;
204 void MakeOrthonormalTo(const cVec3& vec);
205
206 void ToPolarXZ(float *Radius, float *Angle) const;
207 static const cVec3 FromPolarXZ(const float Radius, const float Angle);
208 float ToBaryCentric(const cVec3 &t0, const cVec3 &t1, const cVec3 &t2, float &f, float &g) const;
209
210 const cVec3 ToNormal() const;
211 void ToPerps(cVec3 &X, cVec3 &Y) const;
212 const cVec3 ToPerp() const;
213
214 static bool RayTri(const cVec3 &RayOrig, const cVec3 &RayDir, const cVec3 &t0, const cVec3 &t1, const cVec3 &t2, float &u, float &v, float &t, const bool BackFaceCull = false);
215 static bool PointInTriangle(const cVec3 &p, const cVec3 &t0, const cVec3 &t1, const cVec3 &t2);
216
217 std::tuple<float, float, float> __getstate__();
218 void __setstate__(const std::tuple<float, float, float> &state);
219};
220
221// cVec3.ctor : ()
222inline cVec3::cVec3() {
223}
224
225// cVec3.ctor : (const float)
226inline cVec3::cVec3(const float S)
227: x(S), y(S), z(S) {}
228
229// cVec3.ctor : (const float, const float, const float)
230inline cVec3::cVec3(const float X, const float Y, const float Z)
231: x(X), y(Y), z(Z) {}
232
233// cVec3.ctor : (const cVec2 &, const float)
234inline cVec3::cVec3(const cVec2 &XY, const float Z)
235: x(XY.x), y(XY.y), z(Z) {}
236
237// cVec3::SetZero
238inline void cVec3::SetZero() {
239 x = y = z = 0.0f;
240}
241
242// cVec3::SetOne
243inline void cVec3::SetOne() {
244 x = y = z = 1.0f;
245}
246
247// cVec3::SetRandRange1
248inline void cVec3::SetRandRange1() {
249 x = cMath::RandRange1();
250 y = cMath::RandRange1();
251 z = cMath::RandRange1();
252}
253
254// cVec3::Set : void (const float)
255inline void cVec3::Set(const float S) {
256 x = y = z = S;
257}
258
259// cVec3::Set : void (const float, const float, const float)
260inline void cVec3::Set(const float X, const float Y, const float Z) {
261 x = X;
262 y = Y;
263 z = Z;
264}
265
266// cVec3::Set : void (const cVec2 &, const float)
267inline void cVec3::Set(const cVec2 &XY, const float Z) {
268 x = XY.x;
269 y = XY.y;
270 z = Z;
271}
272
273// cVec3::Copy
274inline void cVec3::Copy(const float *Src) {
275 cAssert(Src != nullptr);
276 x = Src[0];
277 y = Src[1];
278 z = Src[2];
279}
280
281// cVec3::operator [] : float & (const int)
282inline float & cVec3::operator [] (const int Index) {
283 cAssert(Index >= 0 && Index < 3);
284 return (&x)[Index];
285}
286
287// cVec3::operator [] : float(const int) const
288inline float cVec3::operator [] (const int Index) const {
289 cAssert(Index >= 0 && Index < 3);
290 return (&x)[Index];
291}
292
293// cVec3::operator - : const cVec3() const
294inline const cVec3 cVec3::operator - () const {
295 return cVec3(-x, -y, -z);
296}
297
298// cVec3::operator += : void (const cVec3 &)
299inline cVec3& cVec3::operator += (const cVec3 &u) {
300 x += u.x;
301 y += u.y;
302 z += u.z;
303 return *this;
304}
305
306// cVec3::operator -= : void (const cVec3 &)
307inline cVec3& cVec3::operator -= (const cVec3 &u) {
308 x -= u.x;
309 y -= u.y;
310 z -= u.z;
311 return *this;
312}
313
314// cVec3::operator *= : void (const cVec3 &)
315inline cVec3& cVec3::operator *= (const cVec3 &u) {
316 x *= u.x;
317 y *= u.y;
318 z *= u.z;
319 return *this;
320}
321
322// cVec3::operator *= : void (const float)
323inline cVec3& cVec3::operator *= (const float s) {
324 x *= s;
325 y *= s;
326 z *= s;
327 return *this;
328}
329
330// cVec3::operator /= : void (const cVec3 &)
331inline cVec3& cVec3::operator /= (const cVec3 &u) {
332 x /= u.x;
333 y /= u.y;
334 z /= u.z;
335 return *this;
336}
337
338// cVec3::operator /= : void (const float)
339inline cVec3& cVec3::operator /= (const float s) {
340 const float is = 1.0f / s;
341 x *= is;
342 y *= is;
343 z *= is;
344 return *this;
345}
346
347inline void cVec3::Clear(void*) {
348 x = y = z = 0.0f;
349}
350// cVec3::operator + : const cVec3(const cVec3 &) const
351inline const cVec3 cVec3::operator + (const cVec3 &u) const {
352 return cVec3(x + u.x, y + u.y, z + u.z);
353}
354
355// cVec3::operator - : const cVec3(const cVec3 &) const
356inline const cVec3 cVec3::operator - (const cVec3 &u) const {
357 return cVec3(x - u.x, y - u.y, z - u.z);
358}
359
360// cVec3::operator * : const cVec3(const cVec3 &) const
361inline const cVec3 cVec3::operator * (const cVec3 &u) const {
362 return cVec3(x * u.x, y * u.y, z * u.z);
363}
364
365// cVec3::operator * : const cVec3(const float) const
366inline const cVec3 cVec3::operator * (const float s) const {
367 return cVec3(x * s, y * s, z * s);
368}
369
370// cVec3::friend operator * : const cVec3(const float, const cVec3 &)
371inline const cVec3 operator * (const float s, const cVec3 &u) {
372 return cVec3(s * u.x, s * u.y, s * u.z);
373}
374
375// cVec3::operator / : const cVec3(const cVec3 &) const
376inline const cVec3 cVec3::operator / (const cVec3 &u) const {
377 return cVec3(x / u.x, y / u.y, z / u.z);
378}
379
380// cVec3::operator / : const cVec3(const float) const
381inline const cVec3 cVec3::operator / (const float s) const {
382 const float is = 1.0f / s;
383 return cVec3(x * is, y * is, z * is);
384}
385
386// cVec3::friend operator / : const cVec3 (const float, const cVec3 &)
387inline const cVec3 operator / (const float s, const cVec3 &u) {
388 return cVec3(s / u.x, s / u.y, s / u.z);
389}
390
391// @todo stability Verify and fixed operator==() for other class with float data.
392// cVec3::operator == : bool(const cVec3 &) const
393inline bool cVec3::operator == (const cVec3 &u) const {
394 return cVec3::Equals( *this, u );
395}
396
397// cVec3::operator != : bool(const cVec3 &) const
398inline bool cVec3::operator != (const cVec3 &u) const {
399 return !cVec3::Equals( *this, u );
400}
401
402// cVec3::Equals : bool(const cVec3 &, const cVec3 &, const float)
403inline bool cVec3::Equals(const cVec3 &u, const cVec3 &v, const float Eps) {
404 if(cMath::Abs(u.x - v.x) > Eps) {
405 return false;
406 }
407 if(cMath::Abs(u.y - v.y) > Eps) {
408 return false;
409 }
410 if(cMath::Abs(u.z - v.z) > Eps) {
411 return false;
412 }
413 return true;
414}
415
416// cVec3::Length : float() const
417inline float cVec3::Length() const {
418 return cMath::Sqrt(x * x + y * y + z * z);
419}
420
421// cVec3::Length2
422inline float cVec3::Length2() const {
423 return cMath::FastSqrt(x * x + y * y + z * z);
424}
425
426// cVec3::LengthM
427inline float cVec3::LengthM() const {
428 return cMath::Abs(x)+cMath::Abs(y)+cMath::Abs(z);
429}
430
431// cVec3::LengthSq : float() const
432inline float cVec3::LengthSq() const {
433 return x * x + y * y + z * z;
434}
435
436// cVec3::Normalize : float()
437inline float cVec3::Normalize() {
438 const float l = Length();
439 if(l > 0.0f) {
440 const float il = 1.0f / l;
441 x *= il;
442 y *= il;
443 z *= il;
444 }
445 return l;
446}
447
448// cVec3::Normalize2
449inline float cVec3::Normalize2() {
450 const float l = x * x + y * y + z * z;
451 if(l > 0.0f) {
452 const float il = 1.0f / cMath::Sqrt(l);
453 x *= il;
454 y *= il;
455 z *= il;
456 }
457 return l;
458}
459
460// cVec3::NormalizeSafe
461inline float cVec3::NormalizeSafe(const cVec3 &Fallback) {
462 const float l = Length();
463 if(l > cMath::EpsilonSq) {
464 const float il = 1.0f / l;
465 x *= il;
466 y *= il;
467 z *= il;
468 cAssert(IsNormalized());
469 return l;
470 }
471
472 *this = Fallback;
473 cAssert(IsNormalized());
474 return 0.0f;
475}
476
477// cVec3::IsValid : bool () const
478inline bool cVec3::IsValid() const {
479 return cMath::IsValid(x) && cMath::IsValid(y) && cMath::IsValid(z);
480}
481
482// cVec3::IsNormalized : bool(const float) const
483inline bool cVec3::IsNormalized(const float Eps) const {
484 return cMath::IsOne(LengthSq(), Eps);
485}
486
487// cVec3::IsZero : bool(const float) const
488inline bool cVec3::IsZero(const float Eps) const {
489 if(!cMath::IsZero(x, Eps)) return false;
490 if(!cMath::IsZero(y, Eps)) return false;
491 if(!cMath::IsZero(z, Eps)) return false;
492 return true;
493}
494
495// cVec3::Round : ()
496inline void cVec3::Round() {
497 x = cMath::Round(x);
498 y = cMath::Round(y);
499 z = cMath::Round(z);
500}
501
502// cVec3::Abs : const cVec3(const cVec3 &)
503inline const cVec3 cVec3::Abs(const cVec3 &u) {
504 return cVec3(cMath::Abs(u.x), cMath::Abs(u.y), cMath::Abs(u.z));
505}
506
507// cVec3::Angle : float(const cVec3 &, const cVec3 &)
508inline float cVec3::Angle(const cVec3 &u, const cVec3 &v) {
509 const float D = cVec3::Dot(u, v);
510 float ll = u.Length() * v.Length();
511 return cMath::Deg(cMath::ACos(D / ll));
512}
513// cVec3::Angle
514inline float cVec3::Angle(const cVec3& p1, const cVec3& p2, const cVec3& p3, const cVec3& normal) {
515 cVec3 d1 = p1 - p2;
516 cVec3 d2 = p3 - p2;
517 d1 -= normal * normal.dot(d1);
518 d2 -= normal * normal.dot(d2);
519 float ang = cMath::Deg(atan2(normal.dot(Cross(d1, d2)), d1.dot(d2)));
520 while (ang < 0.0)ang += 360.0;
521 return ang;
522}
523
524// cVec3::AreaSigned
525inline float cVec3::AreaSigned(const cVec3 &t0, const cVec3 &t1, const cVec3 &t2) {
526 const cVec3 e1 = t1 - t0;
527 const cVec3 e2 = t2 - t0;
528 return Length(Cross(e1, e2)) * 0.5f;
529}
530
531// cVec3::BaryCentric
532inline const cVec3 cVec3::BaryCentric(const cVec3 &t0, const cVec3 &t1, const cVec3 &t2, const float f, const float g) {
533 const cVec3 e1 = t1 - t0;
534 const cVec3 e2 = t2 - t0;
535 return t0 + f * e1 + g * e2;
536}
537
538// cVec3::ToPolarXZ
539inline void cVec3::ToPolarXZ(float *Radius, float *Angle) const {
540 cVec2 t(x, -z);
541 t.ToPolar(Radius, Angle);
542}
543
544// cVec3::FromPolarXZ
545inline const cVec3 cVec3::FromPolarXZ(const float Radius, const float Angle) {
546 cVec2 t = cVec2::FromPolar(Radius, Angle);
547 return cVec3(t.x, 0.0f, -t.y);
548}
549
550// cVec3::ToBaryCentric
551inline float cVec3::ToBaryCentric(const cVec3 &t0, const cVec3 &t1, const cVec3 &t2, float &f, float &g) const {
552 const float A = AreaSigned(t0, t1, t2);
553 if(A != 0) {
554 const float iA = 1.0f / A;
555 f = AreaSigned(t0, *this, t2) * iA;
556 g = AreaSigned(t0, t1, *this) * iA;
557 } else {
558 f = g = 0.0f;
559 }
560 return A;
561}
562
563// cVec3::Clamp
564inline const cVec3 cVec3::Clamp(const cVec3 &u, const cVec3 &bbMin, const cVec3 &bbMax) {
565 cVec3 r;
566 r.x = u.x < bbMin.x ? bbMin.x : (u.x > bbMax.x ? bbMax.x : u.x);
567 r.y = u.y < bbMin.y ? bbMin.y : (u.y > bbMax.y ? bbMax.y : u.y);
568 r.z = u.z < bbMin.z ? bbMin.z : (u.z > bbMax.z ? bbMax.z : u.z);
569 return r;
570}
571
572// cVec3::Cross
573inline const cVec3 cVec3::Cross(const cVec3 &u, const cVec3 &v) {
574 return cVec3(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x);
575}
576// cVec3::SetCross
577inline void cVec3::SetCross(const cVec3 &u, const cVec3 &v) {
578 *this = cVec3(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x);
579}
580
581// cVec3::DistanceSq : float(const cVec3 &, const cVec3 &)
582inline float cVec3::DistanceSq(const cVec3 &u, const cVec3 &v) {
583 float dx = u.x - v.x;
584 float dy = u.y - v.y;
585 float dz = u.z - v.z;
586 return dx * dx + dy * dy + dz * dz;
587}
588
589// cVec3::Distance : float(const cVec3 &, const cVec3 &)
590inline float cVec3::Distance(const cVec3 &u, const cVec3 &v) {
591 float dx = u.x - v.x;
592 float dy = u.y - v.y;
593 float dz = u.z - v.z;
594 return cMath::Sqrt(dx * dx + dy * dy + dz * dz);
595}
596inline float cVec3::Distance2(const cVec3 &u, const cVec3 &v) {
597 float dx = u.x - v.x;
598 float dy = u.y - v.y;
599 float dz = u.z - v.z;
600 return cMath::FastSqrt(dx * dx + dy * dy + dz * dz);
601}
602
603
604// cVec3::Distance : float(const cVec3 &)
605inline float cVec3::Distance(const cVec3 &u) const {
606 float dx = u.x - x;
607 float dy = u.y - y;
608 float dz = u.z - z;
609 return cMath::Sqrt(dx * dx + dy * dy + dz * dz);
610}
611inline float cVec3::Distance2(const cVec3 &u) const {
612 float dx = u.x - x;
613 float dy = u.y - y;
614 float dz = u.z - z;
615 return cMath::FastSqrt(dx * dx + dy * dy + dz * dz);
616}
617
618// cVec3::Dot : float(const cVec3 &, const cVec3 &)
619inline float cVec3::Dot(const cVec3 &u, const cVec3 &v) {
620 return u.x * v.x + u.y * v.y + u.z * v.z;
621}
622
623// cVec3::Dot : float(const cVec3 &)
624inline float cVec3::Dot(const cVec3 &u) const {
625 return u.x * x + u.y * y + u.z * z;
626}
627
628// cVec3::Length : float(const cVec3 &)
629inline float cVec3::Length(const cVec3 &u) {
630 return cMath::Sqrt(u.x * u.x + u.y * u.y + u.z * u.z);
631}
632
633// cVec3::LengthSq : float(const cVec3 &)
634inline float cVec3::LengthSq(const cVec3 &u) {
635 return u.x * u.x + u.y * u.y + u.z * u.z;
636}
637
638// cVec3::Lerp
639inline const cVec3 cVec3::Lerp(const cVec3 &u, const cVec3 &v, const float s) {
640 cVec3 r;
641 r.x = u.x + s * (v.x - u.x);
642 r.y = u.y + s * (v.y - u.y);
643 r.z = u.z + s * (v.z - u.z);
644 return r;
645}
646
647// cVec3::Lerp05 : const cVec3(const cVec3 &, const cVec3 &)
648inline const cVec3 cVec3::Lerp05(const cVec3 &u, const cVec3 &v) {
649 cVec3 r;
650 r.x = 0.5f * (u.x + v.x);
651 r.y = 0.5f * (u.y + v.y);
652 r.z = 0.5f * (u.z + v.z);
653 return r;
654}
655
656// cVec3::Max : const cVec3(const cVec3 &, const cVec3 &)
657inline const cVec3 cVec3::Max(const cVec3 &u, const cVec3 &v) {
658 cVec3 r;
659 r.x = u.x > v.x ? u.x : v.x;
660 r.y = u.y > v.y ? u.y : v.y;
661 r.z = u.z > v.z ? u.z : v.z;
662 return r;
663}
664
665// cVec3::Min : const cVec3(const cVec3 &, const cVec3 &)
666inline const cVec3 cVec3::Min(const cVec3 &u, const cVec3 &v) {
667 cVec3 r;
668 r.x = u.x < v.x ? u.x : v.x;
669 r.y = u.y < v.y ? u.y : v.y;
670 r.z = u.z < v.z ? u.z : v.z;
671 return r;
672}
673
674// cVec3::Normalize
675inline const cVec3 cVec3::Normalize(const cVec3 &u) {
676 float l = cMath::Sqrt(u.x * u.x + u.y * u.y + u.z * u.z);
677 if(l > 0.0f) {
678 float il = 1.0f / l;
679 return cVec3(u.x * il, u.y * il, u.z * il);
680 }
681 return u;
682}
683// cVec3::Normalize
684inline const cVec3 cVec3::Normalize2(const cVec3 &u) {
685 float l = u.x * u.x + u.y * u.y + u.z * u.z;
686 if(l > 0.0f){
687 float il = cMath::FastInvSqrt(l);
688 return cVec3(u.x * il, u.y * il, u.z * il);
689 }
690 return u;
691}
692
693// cVec3::Reflect
694inline const cVec3 cVec3::Reflect(const cVec3 &RayDir, const cVec3 &Normal) {
695 return RayDir - 2.0f * Dot(RayDir, Normal) * Normal;
696}
697
698// cVec3::Refract
699inline const cVec3 cVec3::Refract(const cVec3 &RayDir, const cVec3 &Normal, const float Eta) {
700 float k = 1.0f - Eta * Eta * (1.0f - cMath::Square(Dot(Normal, RayDir)));
701 if(k < 0.0f) return cVec3::Zero;
702 return Eta * RayDir - (Eta * Dot(Normal, RayDir) + cMath::Sqrt(k)) * Normal;
703}
704
705// cVec3::Truncate : (const float)
706inline void cVec3::Truncate(const float MaxLen) {
707 if(MaxLen <= 0) {
708 SetZero();
709 return;
710 }
711 float l = Length();
712 if(l > MaxLen) {
713 float il = MaxLen / l;
714 x *= il;
715 y *= il;
716 z *= il;
717 }
718}
719
720// cVec3::Truncate : (const cVec3 &, ...)
721inline const cVec3 cVec3::Truncate(const cVec3 &u, const float MaxLen) {
722 if(MaxLen <= 0) {
723 return cVec3::Zero;
724 }
725 float l = u.Length();
726 if(l > MaxLen) {
727 float il = MaxLen / l;
728 return cVec3(u.x * il, u.y * il, u.z * il);
729 }
730 return u;
731}
732
733// cVec3::GetDimension : int() const
734inline int cVec3::GetDimension() const {
735 return 3;
736}
737
738// cVec3::ToFloatPtr : const float * () const
739inline const float * cVec3::ToFloatPtr() const {
740 return (const float *)&x;
741}
742
743// cVec3::ToFloatPtr : float * ()
744inline float * cVec3::ToFloatPtr() {
745 return (float *)&x;
746}
747
748// cVec3::ToVec2 : const cVec2 & () const
749inline const cVec2 & cVec3::ToVec2() const {
750 return *reinterpret_cast<const cVec2 *>(this);
751}
752
753// cVec3::ToVec2 : cVec2 & ()
754inline cVec2 & cVec3::ToVec2() {
755 return *reinterpret_cast<cVec2 *>(this);
756}
757
758// cVec3::operator cVec<Type, 3>
759template<class Type>
760cVec3::operator cVec<Type, 3> () const {
761 return cVec<Type, 3>( (Type)x, (Type)y, (Type)z );
762}
763
764// cVec3::ToNormal : const cVec2 () const
765inline const cVec3 cVec3::ToNormal() const {
766 cVec3 u(*this);
767 u.Normalize();
768 return u;
769}
770
771// cVec3::Rand
772inline const cVec3 cVec3::Rand(const cVec3 &Lo, const cVec3 &Hi) {
773 return cVec3(cMath::Rand(Lo.x, Hi.x), cMath::Rand(Lo.y, Hi.y), cMath::Rand(Lo.z, Hi.z));
774}
775
776// cVec3::Project
777inline const cVec3 cVec3::Project(const cVec3 &v1, const cVec3 &v2) {
778 float mul;
779 mul = cVec3::Dot(v1, v2) / cVec3::Dot(v2, v2);
780 return cVec3(mul * v2.x, mul * v2.y, mul * v2.z);
781}
782
783inline float cVec3::TriProjectionSolidAngle(const cVec3 &v1, const cVec3 &v2, const cVec3 &v3) const {
784 cVec3 u(*this);
785 cVec3 a = v1 - u;
786 cVec3 b = v2 - u;
787 cVec3 c = v3 - u;
788 float det = cMath::Abs(a.Dot(Cross(b,c)));
789
790 float al = a.Length();
791 float bl = b.Length(b);
792 float cl = c.Length(c);
793
794 float div = al*bl*cl + a.Dot(b)*cl + a.Dot(c)*bl + b.Dot(c)*al;
795 float at = cMath::ATan(det, div);
796 if(at < 0) {
797 at += cMath::Pi; // If det>0 && div<0 atan2 returns < 0, so add pi.
798 }
799 float omega = 2.0f * at;
800 return omega;
801}
802
803// cVec3::Perpendicular
804inline const cVec3 cVec3::Perpendicular(const cVec3 &v1) {
805 float X = cMath::Abs(v1.x);
806 float Y = cMath::Abs(v1.y);
807 float Z = cMath::Abs(v1.z);
808 if(X>Y && X>Z) {
809 return cVec3::Cross(v1,cVec3(1,0,0));
810 } else if(Y>X && Y>Z) {
811 return cVec3::Cross(v1,cVec3(0,1,0));
812 } else {
813 return cVec3::Cross(v1,cVec3(0,0,1));
814 }
815}
The array template, refer it as coat::list <...> if you are using the Core API.
Definition cList.h:133
The 3D-matrix, refer it as coat::mat3 in the Core API.
Definition cMat3.h:6
The 4D-matrix, refer it as coat::mat4 in the Core API.
Definition cMat4.h:6
Definition cStr.h:6
The 2D-vector, refer it as coat::vec2 in the Core API.
Definition cVec2.h:9
The 3D-vector, refer it as coat::vec3 in the Core API.
Definition cVec3.h:10
The 4D-vector, refer it as coat::vec4 in the Core API.
Definition cVec4.h:9