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