Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/embree/common/math/linearspace2.h
9912 views
1
// Copyright 2009-2021 Intel Corporation
2
// SPDX-License-Identifier: Apache-2.0
3
4
#pragma once
5
6
#include "vec2.h"
7
8
namespace embree
9
{
10
////////////////////////////////////////////////////////////////////////////////
11
/// 2D Linear Transform (2x2 Matrix)
12
////////////////////////////////////////////////////////////////////////////////
13
14
template<typename T> struct LinearSpace2
15
{
16
typedef T Vector;
17
typedef typename T::Scalar Scalar;
18
19
/*! default matrix constructor */
20
__forceinline LinearSpace2 ( ) {}
21
22
__forceinline LinearSpace2 ( const LinearSpace2& other ) { vx = other.vx; vy = other.vy; }
23
__forceinline LinearSpace2& operator=( const LinearSpace2& other ) { vx = other.vx; vy = other.vy; return *this; }
24
25
template<typename L1> __forceinline LinearSpace2( const LinearSpace2<L1>& s ) : vx(s.vx), vy(s.vy) {}
26
27
/*! matrix construction from column vectors */
28
__forceinline LinearSpace2(const Vector& vx, const Vector& vy)
29
: vx(vx), vy(vy) {}
30
31
/*! matrix construction from row mayor data */
32
__forceinline LinearSpace2(const Scalar& m00, const Scalar& m01,
33
const Scalar& m10, const Scalar& m11)
34
: vx(m00,m10), vy(m01,m11) {}
35
36
/*! compute the determinant of the matrix */
37
__forceinline const Scalar det() const { return vx.x*vy.y - vx.y*vy.x; }
38
39
/*! compute adjoint matrix */
40
__forceinline const LinearSpace2 adjoint() const { return LinearSpace2(vy.y,-vy.x,-vx.y,vx.x); }
41
42
/*! compute inverse matrix */
43
__forceinline const LinearSpace2 inverse() const { return adjoint()/det(); }
44
45
/*! compute transposed matrix */
46
__forceinline const LinearSpace2 transposed() const { return LinearSpace2(vx.x,vx.y,vy.x,vy.y); }
47
48
/*! returns first row of matrix */
49
__forceinline Vector row0() const { return Vector(vx.x,vy.x); }
50
51
/*! returns second row of matrix */
52
__forceinline Vector row1() const { return Vector(vx.y,vy.y); }
53
54
////////////////////////////////////////////////////////////////////////////////
55
/// Constants
56
////////////////////////////////////////////////////////////////////////////////
57
58
__forceinline LinearSpace2( ZeroTy ) : vx(zero), vy(zero) {}
59
__forceinline LinearSpace2( OneTy ) : vx(one, zero), vy(zero, one) {}
60
61
/*! return matrix for scaling */
62
static __forceinline LinearSpace2 scale(const Vector& s) {
63
return LinearSpace2(s.x, 0,
64
0 , s.y);
65
}
66
67
/*! return matrix for rotation */
68
static __forceinline LinearSpace2 rotate(const Scalar& r) {
69
Scalar s = sin(r), c = cos(r);
70
return LinearSpace2(c, -s,
71
s, c);
72
}
73
74
/*! return closest orthogonal matrix (i.e. a general rotation including reflection) */
75
LinearSpace2 orthogonal() const
76
{
77
LinearSpace2 m = *this;
78
79
// mirrored?
80
Scalar mirror(one);
81
if (m.det() < Scalar(zero)) {
82
m.vx = -m.vx;
83
mirror = -mirror;
84
}
85
86
// rotation
87
for (int i = 0; i < 99; i++) {
88
const LinearSpace2 m_next = 0.5 * (m + m.transposed().inverse());
89
const LinearSpace2 d = m_next - m;
90
m = m_next;
91
// norm^2 of difference small enough?
92
if (max(dot(d.vx, d.vx), dot(d.vy, d.vy)) < 1e-8)
93
break;
94
}
95
96
// rotation * mirror_x
97
return LinearSpace2(mirror*m.vx, m.vy);
98
}
99
100
public:
101
102
/*! the column vectors of the matrix */
103
Vector vx,vy;
104
};
105
106
////////////////////////////////////////////////////////////////////////////////
107
// Unary Operators
108
////////////////////////////////////////////////////////////////////////////////
109
110
template<typename T> __forceinline LinearSpace2<T> operator -( const LinearSpace2<T>& a ) { return LinearSpace2<T>(-a.vx,-a.vy); }
111
template<typename T> __forceinline LinearSpace2<T> operator +( const LinearSpace2<T>& a ) { return LinearSpace2<T>(+a.vx,+a.vy); }
112
template<typename T> __forceinline LinearSpace2<T> rcp ( const LinearSpace2<T>& a ) { return a.inverse(); }
113
114
////////////////////////////////////////////////////////////////////////////////
115
// Binary Operators
116
////////////////////////////////////////////////////////////////////////////////
117
118
template<typename T> __forceinline LinearSpace2<T> operator +( const LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return LinearSpace2<T>(a.vx+b.vx,a.vy+b.vy); }
119
template<typename T> __forceinline LinearSpace2<T> operator -( const LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return LinearSpace2<T>(a.vx-b.vx,a.vy-b.vy); }
120
121
template<typename T> __forceinline LinearSpace2<T> operator*(const typename T::Scalar & a, const LinearSpace2<T>& b) { return LinearSpace2<T>(a*b.vx, a*b.vy); }
122
template<typename T> __forceinline T operator*(const LinearSpace2<T>& a, const T & b) { return b.x*a.vx + b.y*a.vy; }
123
template<typename T> __forceinline LinearSpace2<T> operator*(const LinearSpace2<T>& a, const LinearSpace2<T>& b) { return LinearSpace2<T>(a*b.vx, a*b.vy); }
124
125
template<typename T> __forceinline LinearSpace2<T> operator/(const LinearSpace2<T>& a, const typename T::Scalar & b) { return LinearSpace2<T>(a.vx/b, a.vy/b); }
126
template<typename T> __forceinline LinearSpace2<T> operator/(const LinearSpace2<T>& a, const LinearSpace2<T>& b) { return a * rcp(b); }
127
128
template<typename T> __forceinline LinearSpace2<T>& operator *=( LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return a = a * b; }
129
template<typename T> __forceinline LinearSpace2<T>& operator /=( LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return a = a / b; }
130
131
////////////////////////////////////////////////////////////////////////////////
132
/// Comparison Operators
133
////////////////////////////////////////////////////////////////////////////////
134
135
template<typename T> __forceinline bool operator ==( const LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return a.vx == b.vx && a.vy == b.vy; }
136
template<typename T> __forceinline bool operator !=( const LinearSpace2<T>& a, const LinearSpace2<T>& b ) { return a.vx != b.vx || a.vy != b.vy; }
137
138
////////////////////////////////////////////////////////////////////////////////
139
/// Output Operators
140
////////////////////////////////////////////////////////////////////////////////
141
142
template<typename T> static embree_ostream operator<<(embree_ostream cout, const LinearSpace2<T>& m) {
143
return cout << "{ vx = " << m.vx << ", vy = " << m.vy << "}";
144
}
145
146
/*! Shortcuts for common linear spaces. */
147
typedef LinearSpace2<Vec2f> LinearSpace2f;
148
typedef LinearSpace2<Vec2fa> LinearSpace2fa;
149
}
150
151