1 /* -----------------------------------------------------------------------------
2 
3 	Copyright (c) 2006 Simon Brown                          si@sjbrown.co.uk
4 
5 	Permission is hereby granted, free of charge, to any person obtaining
6 	a copy of this software and associated documentation files (the
7 	"Software"), to	deal in the Software without restriction, including
8 	without limitation the rights to use, copy, modify, merge, publish,
9 	distribute, sublicense, and/or sell copies of the Software, and to
10 	permit persons to whom the Software is furnished to do so, subject to
11 	the following conditions:
12 
13 	The above copyright notice and this permission notice shall be included
14 	in all copies or substantial portions of the Software.
15 
16 	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 	OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 	MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 	IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 	CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 	TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 	SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 
24    -------------------------------------------------------------------------- */
25 
26 #ifndef SQUISH_MATHS_H
27 #define SQUISH_MATHS_H
28 
29 #include <cmath>
30 #include <algorithm>
31 #include "config.h"
32 
33 namespace squish {
34 
35 class Vec3
36 {
37 public:
38 	typedef Vec3 const& Arg;
39 
Vec3()40 	Vec3()
41 	{
42 	}
43 
Vec3(float s)44 	explicit Vec3( float s )
45 	{
46 		m_x = s;
47 		m_y = s;
48 		m_z = s;
49 	}
50 
Vec3(float x,float y,float z)51 	Vec3( float x, float y, float z )
52 	{
53 		m_x = x;
54 		m_y = y;
55 		m_z = z;
56 	}
57 
X()58 	float X() const { return m_x; }
Y()59 	float Y() const { return m_y; }
Z()60 	float Z() const { return m_z; }
61 
62 	Vec3 operator-() const
63 	{
64 		return Vec3( -m_x, -m_y, -m_z );
65 	}
66 
67 	Vec3& operator+=( Arg v )
68 	{
69 		m_x += v.m_x;
70 		m_y += v.m_y;
71 		m_z += v.m_z;
72 		return *this;
73 	}
74 
75 	Vec3& operator-=( Arg v )
76 	{
77 		m_x -= v.m_x;
78 		m_y -= v.m_y;
79 		m_z -= v.m_z;
80 		return *this;
81 	}
82 
83 	Vec3& operator*=( Arg v )
84 	{
85 		m_x *= v.m_x;
86 		m_y *= v.m_y;
87 		m_z *= v.m_z;
88 		return *this;
89 	}
90 
91 	Vec3& operator*=( float s )
92 	{
93 		m_x *= s;
94 		m_y *= s;
95 		m_z *= s;
96 		return *this;
97 	}
98 
99 	Vec3& operator/=( Arg v )
100 	{
101 		m_x /= v.m_x;
102 		m_y /= v.m_y;
103 		m_z /= v.m_z;
104 		return *this;
105 	}
106 
107 	Vec3& operator/=( float s )
108 	{
109 		float t = 1.0f/s;
110 		m_x *= t;
111 		m_y *= t;
112 		m_z *= t;
113 		return *this;
114 	}
115 
116 	friend Vec3 operator+( Arg left, Arg right )
117 	{
118 		Vec3 copy( left );
119 		return copy += right;
120 	}
121 
122 	friend Vec3 operator-( Arg left, Arg right )
123 	{
124 		Vec3 copy( left );
125 		return copy -= right;
126 	}
127 
128 	friend Vec3 operator*( Arg left, Arg right )
129 	{
130 		Vec3 copy( left );
131 		return copy *= right;
132 	}
133 
134 	friend Vec3 operator*( Arg left, float right )
135 	{
136 		Vec3 copy( left );
137 		return copy *= right;
138 	}
139 
140 	friend Vec3 operator*( float left, Arg right )
141 	{
142 		Vec3 copy( right );
143 		return copy *= left;
144 	}
145 
146 	friend Vec3 operator/( Arg left, Arg right )
147 	{
148 		Vec3 copy( left );
149 		return copy /= right;
150 	}
151 
152 	friend Vec3 operator/( Arg left, float right )
153 	{
154 		Vec3 copy( left );
155 		return copy /= right;
156 	}
157 
Dot(Arg left,Arg right)158 	friend float Dot( Arg left, Arg right )
159 	{
160 		return left.m_x*right.m_x + left.m_y*right.m_y + left.m_z*right.m_z;
161 	}
162 
Min(Arg left,Arg right)163 	friend Vec3 Min( Arg left, Arg right )
164 	{
165 		return Vec3(
166 			std::min( left.m_x, right.m_x ),
167 			std::min( left.m_y, right.m_y ),
168 			std::min( left.m_z, right.m_z )
169 		);
170 	}
171 
Max(Arg left,Arg right)172 	friend Vec3 Max( Arg left, Arg right )
173 	{
174 		return Vec3(
175 			std::max( left.m_x, right.m_x ),
176 			std::max( left.m_y, right.m_y ),
177 			std::max( left.m_z, right.m_z )
178 		);
179 	}
180 
Truncate(Arg v)181 	friend Vec3 Truncate( Arg v )
182 	{
183 		return Vec3(
184 			v.m_x > 0.0f ? std::floor( v.m_x ) : std::ceil( v.m_x ),
185 			v.m_y > 0.0f ? std::floor( v.m_y ) : std::ceil( v.m_y ),
186 			v.m_z > 0.0f ? std::floor( v.m_z ) : std::ceil( v.m_z )
187 		);
188 	}
189 
190 private:
191 	float m_x;
192 	float m_y;
193 	float m_z;
194 };
195 
LengthSquared(Vec3::Arg v)196 inline float LengthSquared( Vec3::Arg v )
197 {
198 	return Dot( v, v );
199 }
200 
201 class Sym3x3
202 {
203 public:
Sym3x3()204 	Sym3x3()
205 	{
206 	}
207 
Sym3x3(float s)208 	Sym3x3( float s )
209 	{
210 		for( int i = 0; i < 6; ++i )
211 			m_x[i] = s;
212 	}
213 
214 	float operator[]( int index ) const
215 	{
216 		return m_x[index];
217 	}
218 
219 	float& operator[]( int index )
220 	{
221 		return m_x[index];
222 	}
223 
224 private:
225 	float m_x[6];
226 };
227 
228 Sym3x3 ComputeWeightedCovariance( int n, Vec3 const* points, float const* weights );
229 Vec3 ComputePrincipleComponent( Sym3x3 const& matrix );
230 
231 } // namespace squish
232 
233 #endif // ndef SQUISH_MATHS_H
234