3template<
class Type,
int Dim>
10class APICALL COMMS_ALIASING
cVec3 {
17 explicit cVec3(
const float S);
18 cVec3(
const float X,
const float Y,
const float Z);
20 cVec3(
const dVec3& v);
21 cVec3(
const cVec3& v):x(v.x), y(v.y), z(v.z) {}
23 void Copy(
const float *Src);
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);
31 float & operator [] (
const int Index);
32 float operator [] (
const int Index)
const;
34 const cVec3 operator - ()
const;
39 cVec3& operator *= (
const float);
41 cVec3& operator /= (
const float);
43 void TransformCoordinate(
const cMat4 &);
44 void TransformNormal(
const cMat4 &);
45 void TransformNormalTransposed(
const cMat4 &);
47 void Transform(
const cMat3 &);
50 void Rotate(
const cQuat &);
51 void operator *= (
const cQuat &);
53 void Rotate(
const cRotation &);
54 void operator *= (
const cRotation &);
57 inline float distance(
const cVec3 &u)
const {
61 return cMath::Sqrt(dx * dx + dy * dy + dz * dz);
63 inline float distanceSq(
const cVec3 &u)
const {
67 return dx * dx + dy * dy + dz * dz;
69 float dot(
const cVec3 &u)
const {
70 return u.x * x + u.y * y + u.z * z;
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);
78 inline void Clear(
void* = 0);
80 inline void AddWithWeight(
cVec3 const& src,
float weight) {
85 inline void SetPosition(
float aX,
float aY,
float aZ) {
90 inline const float* GetPosition()
const {
99 const cVec3 operator * (
const float)
const;
100 friend const cVec3 operator * (
const float,
const cVec3 &);
102 const cVec3 operator / (
const float)
const;
112 static void TransformCoordinate(
cVec3 *Array,
const int Count,
const cMat4 &T);
113 static void TransformNormal(
cVec3 *Array,
const int Count,
const cMat4 &T);
115 static const cVec3 Rotate(
const cVec3 &,
const cQuat &);
116 const cVec3 operator * (
const cQuat &)
const;
118 static const cVec3 Rotate(
const cVec3 &,
const cRotation &);
119 const cVec3 operator * (
const cRotation &)
const;
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);
125 float Length()
const;
126 float Length2()
const;
127 float LengthSq()
const;
128 float LengthM()
const;
131 float NormalizeSafe(
const cVec3 &Fallback = cVec3::AxisZ);
132 bool FixDegenerateNormal();
134 bool IsValid()
const;
135 bool IsNormalized(
float Eps = cMath::Epsilon)
const;
136 bool IsZero(
float Eps = cMath::Epsilon)
const;
140 static float Angle(
const cVec3 &,
const cVec3 &);
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);
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 &);
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();
172 static const cVec3 Perpendicular(
const cVec3 &v1);
173 float TriProjectionSolidAngle(
const cVec3 &a,
const cVec3 &b,
const cVec3 &c)
const;
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;
185 int GetDimension()
const;
187 const float * ToFloatPtr()
const;
188 float * ToFloatPtr();
190 const cVec2 & ToVec2()
const;
194 operator cVec<Type, 3> ()
const;
196 const cStr ToString(
const int Prec = 2)
const;
198 const std::string __repr__()
const;
200 const cAngles ToAngles()
const;
202 cVec3 GetOrthonormal()
const;
203 std::pair<cVec3, cVec3> GetOrthonormalPair()
const;
204 void MakeOrthonormalTo(
const cVec3& vec);
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;
210 const cVec3 ToNormal()
const;
212 const cVec3 ToPerp()
const;
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);
217 std::tuple<float, float, float> __getstate__();
218 void __setstate__(
const std::tuple<float, float, float> &state);
222inline cVec3::cVec3() {
226inline cVec3::cVec3(
const float S)
230inline cVec3::cVec3(
const float X,
const float Y,
const float Z)
234inline cVec3::cVec3(
const cVec2 &XY,
const float Z)
235: x(XY.x), y(XY.y), z(Z) {}
238inline void cVec3::SetZero() {
243inline void cVec3::SetOne() {
248inline void cVec3::SetRandRange1() {
249 x = cMath::RandRange1();
250 y = cMath::RandRange1();
251 z = cMath::RandRange1();
255inline void cVec3::Set(
const float S) {
260inline void cVec3::Set(
const float X,
const float Y,
const float Z) {
267inline void cVec3::Set(
const cVec2 &XY,
const float Z) {
274inline void cVec3::Copy(
const float *Src) {
275 cAssert(Src !=
nullptr);
282inline float & cVec3::operator [] (
const int Index) {
283 cAssert(Index >= 0 && Index < 3);
288inline float cVec3::operator [] (
const int Index)
const {
289 cAssert(Index >= 0 && Index < 3);
294inline const cVec3 cVec3::operator - ()
const {
295 return cVec3(-x, -y, -z);
299inline cVec3& cVec3::operator += (
const cVec3 &u) {
307inline cVec3& cVec3::operator -= (
const cVec3 &u) {
315inline cVec3& cVec3::operator *= (
const cVec3 &u) {
323inline cVec3& cVec3::operator *= (
const float s) {
331inline cVec3& cVec3::operator /= (
const cVec3 &u) {
339inline cVec3& cVec3::operator /= (
const float s) {
340 const float is = 1.0f / s;
347inline void cVec3::Clear(
void*) {
351inline const cVec3 cVec3::operator + (
const cVec3 &u)
const {
352 return cVec3(x + u.x, y + u.y, z + u.z);
356inline const cVec3 cVec3::operator - (
const cVec3 &u)
const {
357 return cVec3(x - u.x, y - u.y, z - u.z);
361inline const cVec3 cVec3::operator * (
const cVec3 &u)
const {
362 return cVec3(x * u.x, y * u.y, z * u.z);
366inline const cVec3 cVec3::operator * (
const float s)
const {
367 return cVec3(x * s, y * s, z * s);
371inline const cVec3 operator * (
const float s,
const cVec3 &u) {
372 return cVec3(s * u.x, s * u.y, s * u.z);
376inline const cVec3 cVec3::operator / (
const cVec3 &u)
const {
377 return cVec3(x / u.x, y / u.y, z / u.z);
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);
387inline const cVec3 operator / (
const float s,
const cVec3 &u) {
388 return cVec3(s / u.x, s / u.y, s / u.z);
393inline bool cVec3::operator == (
const cVec3 &u)
const {
394 return cVec3::Equals( *
this, u );
398inline bool cVec3::operator != (
const cVec3 &u)
const {
399 return !cVec3::Equals( *
this, u );
403inline bool cVec3::Equals(
const cVec3 &u,
const cVec3 &v,
const float Eps) {
404 if(cMath::Abs(u.x - v.x) > Eps) {
407 if(cMath::Abs(u.y - v.y) > Eps) {
410 if(cMath::Abs(u.z - v.z) > Eps) {
417inline float cVec3::Length()
const {
418 return cMath::Sqrt(x * x + y * y + z * z);
422inline float cVec3::Length2()
const {
423 return cMath::FastSqrt(x * x + y * y + z * z);
427inline float cVec3::LengthM()
const {
428 return cMath::Abs(x)+cMath::Abs(y)+cMath::Abs(z);
432inline float cVec3::LengthSq()
const {
433 return x * x + y * y + z * z;
437inline float cVec3::Normalize() {
438 const float l = Length();
440 const float il = 1.0f / l;
449inline float cVec3::Normalize2() {
450 const float l = x * x + y * y + z * z;
452 const float il = 1.0f / cMath::Sqrt(l);
461inline float cVec3::NormalizeSafe(
const cVec3 &Fallback) {
462 const float l = Length();
463 if(l > cMath::EpsilonSq) {
464 const float il = 1.0f / l;
468 cAssert(IsNormalized());
473 cAssert(IsNormalized());
478inline bool cVec3::IsValid()
const {
479 return cMath::IsValid(x) && cMath::IsValid(y) && cMath::IsValid(z);
483inline bool cVec3::IsNormalized(
const float Eps)
const {
484 return cMath::IsOne(LengthSq(), Eps);
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;
496inline void cVec3::Round() {
503inline const cVec3 cVec3::Abs(
const cVec3 &u) {
504 return cVec3(cMath::Abs(u.x), cMath::Abs(u.y), cMath::Abs(u.z));
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));
514inline float cVec3::Angle(
const cVec3& p1,
const cVec3& p2,
const cVec3& p3,
const cVec3& normal) {
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;
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;
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;
539inline void cVec3::ToPolarXZ(
float *Radius,
float *Angle)
const {
541 t.ToPolar(Radius, Angle);
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);
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);
554 const float iA = 1.0f / A;
555 f = AreaSigned(t0, *
this, t2) * iA;
556 g = AreaSigned(t0, t1, *
this) * iA;
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);
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);
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);
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;
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);
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);
605inline float cVec3::Distance(
const cVec3 &u)
const {
609 return cMath::Sqrt(dx * dx + dy * dy + dz * dz);
611inline float cVec3::Distance2(
const cVec3 &u)
const {
615 return cMath::FastSqrt(dx * dx + dy * dy + dz * dz);
619inline float cVec3::Dot(
const cVec3 &u,
const cVec3 &v) {
620 return u.x * v.x + u.y * v.y + u.z * v.z;
624inline float cVec3::Dot(
const cVec3 &u)
const {
625 return u.x * x + u.y * y + u.z * z;
629inline float cVec3::Length(
const cVec3 &u) {
630 return cMath::Sqrt(u.x * u.x + u.y * u.y + u.z * u.z);
634inline float cVec3::LengthSq(
const cVec3 &u) {
635 return u.x * u.x + u.y * u.y + u.z * u.z;
639inline const cVec3 cVec3::Lerp(
const cVec3 &u,
const cVec3 &v,
const float s) {
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);
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);
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;
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;
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);
679 return cVec3(u.x * il, u.y * il, u.z * il);
684inline const cVec3 cVec3::Normalize2(
const cVec3 &u) {
685 float l = u.x * u.x + u.y * u.y + u.z * u.z;
687 float il = cMath::FastInvSqrt(l);
688 return cVec3(u.x * il, u.y * il, u.z * il);
694inline const cVec3 cVec3::Reflect(
const cVec3 &RayDir,
const cVec3 &Normal) {
695 return RayDir - 2.0f * Dot(RayDir, Normal) * Normal;
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;
706inline void cVec3::Truncate(
const float MaxLen) {
713 float il = MaxLen / l;
721inline const cVec3 cVec3::Truncate(
const cVec3 &u,
const float MaxLen) {
725 float l = u.Length();
727 float il = MaxLen / l;
728 return cVec3(u.x * il, u.y * il, u.z * il);
734inline int cVec3::GetDimension()
const {
739inline const float * cVec3::ToFloatPtr()
const {
740 return (
const float *)&x;
744inline float * cVec3::ToFloatPtr() {
749inline const cVec2 & cVec3::ToVec2()
const {
750 return *
reinterpret_cast<const cVec2 *
>(
this);
754inline cVec2 & cVec3::ToVec2() {
755 return *
reinterpret_cast<cVec2 *
>(
this);
760cVec3::operator cVec<Type, 3> ()
const {
761 return cVec<Type, 3>( (Type)x, (Type)y, (Type)z );
765inline const cVec3 cVec3::ToNormal()
const {
773 return cVec3(cMath::Rand(Lo.x, Hi.x), cMath::Rand(Lo.y, Hi.y), cMath::Rand(Lo.z, Hi.z));
779 mul = cVec3::Dot(v1, v2) / cVec3::Dot(v2, v2);
780 return cVec3(mul * v2.x, mul * v2.y, mul * v2.z);
783inline float cVec3::TriProjectionSolidAngle(
const cVec3 &v1,
const cVec3 &v2,
const cVec3 &v3)
const {
788 float det = cMath::Abs(a.Dot(Cross(b,c)));
790 float al = a.Length();
791 float bl = b.Length(b);
792 float cl = c.Length(c);
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);
799 float omega = 2.0f * at;
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);
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));
813 return cVec3::Cross(v1,
cVec3(0,0,1));
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
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