Merged from trunk with revision range 36835-37865,
[blender.git] / intern / decimation / intern / LOD_Quadric.h
1 /*
2  * $Id$
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file decimation/intern/LOD_Quadric.h
30  *  \ingroup decimation
31  */
32
33
34 #ifndef NAN_INCLUDED_LOD_Quadric_h
35 #define NAN_INCLUDED_LOD_Quadric_h
36
37 #include "MT_Vector3.h"
38 #include "MT_Matrix3x3.h"
39
40
41 class LOD_Quadric {
42
43 private:
44     MT_Scalar a2, ab, ac, ad;
45     MT_Scalar     b2, bc, bd;
46     MT_Scalar         c2, cd;
47     MT_Scalar             d2;
48
49     void init(MT_Scalar a, MT_Scalar b, MT_Scalar c, MT_Scalar d);
50
51 public:
52
53     LOD_Quadric(
54         ) {
55                 Clear();
56         };
57
58     LOD_Quadric(
59                 const MT_Vector3 & vec,
60                 const MT_Scalar & offset
61         ) {
62                 a2 = vec[0] *vec[0];
63                 b2 = vec[1] *vec[1];
64                 c2 = vec[2] *vec[2];
65
66                 ab = vec[0]*vec[1];
67                 ac = vec[0]*vec[2];
68                 bc = vec[1]*vec[2];
69
70                 MT_Vector3 temp = vec*offset;
71                 ad = temp[0];
72                 bd = temp[1];
73                 cd = temp[2];
74
75                 d2 = offset*offset;
76         };
77
78                 MT_Matrix3x3 
79         Tensor(
80         ) const {
81                 // return a symmetric matrix 
82
83                 return MT_Matrix3x3(
84                         a2,ab,ac,
85                         ab,b2,bc,
86                         ac,bc,c2
87                 );
88         };
89
90
91                 MT_Vector3
92         Vector(
93         ) const {
94                 return MT_Vector3(ad, bd, cd);
95         };
96
97                 void 
98         Clear(
99                 MT_Scalar val=0.0
100         ) {
101                 a2=ab=ac=ad=b2=bc=bd=c2=cd=d2=val;
102         };
103
104                 LOD_Quadric & 
105         operator=(
106                 const LOD_Quadric& Q
107         ) {
108
109                 a2 = Q.a2;  ab = Q.ab;  ac = Q.ac;  ad = Q.ad;
110                                         b2 = Q.b2;  bc = Q.bc;  bd = Q.bd;
111                                                                 c2 = Q.c2;  cd = Q.cd;  
112                                                                                         d2 = Q.d2;
113                 return *this;
114         };
115                 
116                 LOD_Quadric& 
117         operator+=(
118                 const LOD_Quadric& Q
119         ) {
120                 a2 += Q.a2; ab += Q.ab;  ac += Q.ac;  ad += Q.ad;
121                                         b2 += Q.b2;  bc += Q.bc;  bd += Q.bd;
122                                                                  c2 += Q.c2;  cd += Q.cd;  
123                                                                                           d2 += Q.d2;
124                 return *this;
125         };
126
127                 LOD_Quadric& 
128         operator*=(
129                 const MT_Scalar & s
130         ) {
131                 a2 *= s; ab *= s;  ac *= s;  ad *= s;
132                                         b2 *= s;  bc *= s;  bd *= s;
133                                                                  c2 *= s;  cd *= s;  
134                                                                                           d2 *= s;
135                 return *this;
136         };
137
138
139                 MT_Scalar 
140         Evaluate(
141                 const MT_Vector3 &v
142         ) const {
143                 // compute the LOD_Quadric error
144
145                 return v[0]*v[0]*a2 + 2*v[0]*v[1]*ab + 2*v[0]*v[2]*ac + 2*v[0]*ad
146                   +v[1]*v[1]*b2 + 2*v[1]*v[2]*bc + 2*v[1]*bd
147                   +v[2]*v[2]*c2   + 2*v[2]*cd
148                   + d2;
149         };
150                 
151                 bool 
152         Optimize(
153                 MT_Vector3& v
154         ) const {
155                 
156                 MT_Scalar det = Tensor().determinant();
157                 if (MT_fuzzyZero(det)) {
158                         return false;
159                 }
160                 
161                 v = -((Tensor().inverse()) * Vector());
162                 return true;
163         }; 
164
165 };
166
167 #endif
168