Bugfix #4081: support for OpenBSD platform for scons. Big thanks to Nathan Houghton...
[blender-staging.git] / extern / bullet / LinearMath / SimdTransform.h
1 /*
2 Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
3
4 This software is provided 'as-is', without any express or implied warranty.
5 In no event will the authors be held liable for any damages arising from the use of this software.
6 Permission is granted to anyone to use this software for any purpose, 
7 including commercial applications, and to alter it and redistribute it freely, 
8 subject to the following restrictions:
9
10 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
11 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
12 3. This notice may not be removed or altered from any source distribution.
13 */
14
15
16
17 #ifndef SimdTransform_H
18 #define SimdTransform_H
19
20 #include "SimdVector3.h"
21 #include "SimdMatrix3x3.h"
22
23
24
25 class SimdTransform {
26         enum { 
27                 TRANSLATION = 0x01,
28                 ROTATION    = 0x02,
29                 RIGID       = TRANSLATION | ROTATION,  
30                 SCALING     = 0x04,
31                 LINEAR      = ROTATION | SCALING,
32                 AFFINE      = TRANSLATION | LINEAR
33         };
34
35 public:
36         SimdTransform() {}
37
38         //      template <typename Scalar2>
39         //      explicit Transform(const Scalar2 *m) { setValue(m); }
40
41         explicit SIMD_FORCE_INLINE SimdTransform(const SimdQuaternion& q, 
42                 const SimdVector3& c = SimdVector3(SimdScalar(0), SimdScalar(0), SimdScalar(0))) 
43                 : m_basis(q),
44                 m_origin(c),
45                 m_type(RIGID)
46         {}
47
48         explicit SIMD_FORCE_INLINE SimdTransform(const SimdMatrix3x3& b, 
49                 const SimdVector3& c = SimdVector3(SimdScalar(0), SimdScalar(0), SimdScalar(0)), 
50                 unsigned int type = AFFINE)
51                 : m_basis(b),
52                 m_origin(c),
53                 m_type(type)
54         {}
55
56
57                 SIMD_FORCE_INLINE void mult(const SimdTransform& t1, const SimdTransform& t2) {
58                         m_basis = t1.m_basis * t2.m_basis;
59                         m_origin = t1(t2.m_origin);
60                         m_type = t1.m_type | t2.m_type;
61                 }
62
63                 void multInverseLeft(const SimdTransform& t1, const SimdTransform& t2) {
64                         SimdVector3 v = t2.m_origin - t1.m_origin;
65                         if (t1.m_type & SCALING) {
66                                 SimdMatrix3x3 inv = t1.m_basis.inverse();
67                                 m_basis = inv * t2.m_basis;
68                                 m_origin = inv * v;
69                         }
70                         else {
71                                 m_basis = SimdMultTransposeLeft(t1.m_basis, t2.m_basis);
72                                 m_origin = v * t1.m_basis;
73                         }
74                         m_type = t1.m_type | t2.m_type;
75                 }
76
77         SIMD_FORCE_INLINE SimdVector3 operator()(const SimdVector3& x) const
78         {
79                 return SimdVector3(m_basis[0].dot(x) + m_origin[0], 
80                         m_basis[1].dot(x) + m_origin[1], 
81                         m_basis[2].dot(x) + m_origin[2]);
82         }
83
84         SIMD_FORCE_INLINE SimdVector3 operator*(const SimdVector3& x) const
85         {
86                 return (*this)(x);
87         }
88
89         SIMD_FORCE_INLINE SimdMatrix3x3&       getBasis()          { return m_basis; }
90         SIMD_FORCE_INLINE const SimdMatrix3x3& getBasis()    const { return m_basis; }
91
92         SIMD_FORCE_INLINE SimdVector3&         getOrigin()         { return m_origin; }
93         SIMD_FORCE_INLINE const SimdVector3&   getOrigin()   const { return m_origin; }
94
95         SimdQuaternion getRotation() const { 
96                 SimdQuaternion q;
97                 m_basis.getRotation(q);
98                 return q;
99         }
100         template <typename Scalar2>
101                 void setValue(const Scalar2 *m) 
102         {
103                 m_basis.setValue(m);
104                 m_origin.setValue(&m[12]);
105                 m_type = AFFINE;
106         }
107
108         
109         void setFromOpenGLMatrix(const SimdScalar *m)
110         {
111                 m_basis.setFromOpenGLSubMatrix(m);
112                 m_origin[0] = m[12];
113                 m_origin[1] = m[13];
114                 m_origin[2] = m[14];
115         }
116
117         void getOpenGLMatrix(SimdScalar *m) const 
118         {
119                 m_basis.getOpenGLSubMatrix(m);
120                 m[12] = m_origin[0];
121                 m[13] = m_origin[1];
122                 m[14] = m_origin[2];
123                 m[15] = SimdScalar(1.0f);
124         }
125
126         SIMD_FORCE_INLINE void setOrigin(const SimdVector3& origin) 
127         { 
128                 m_origin = origin;
129                 m_type |= TRANSLATION;
130         }
131
132         SIMD_FORCE_INLINE SimdVector3 invXform(const SimdVector3& inVec) const;
133
134
135
136         SIMD_FORCE_INLINE void setBasis(const SimdMatrix3x3& basis)
137         { 
138                 m_basis = basis;
139                 m_type |= LINEAR;
140         }
141
142         SIMD_FORCE_INLINE void setRotation(const SimdQuaternion& q)
143         {
144                 m_basis.setRotation(q);
145                 m_type = (m_type & ~LINEAR) | ROTATION;
146         }
147
148         SIMD_FORCE_INLINE void scale(const SimdVector3& scaling)
149         {
150                 m_basis = m_basis.scaled(scaling);
151                 m_type |= SCALING;
152         }
153
154         void setIdentity()
155         {
156                 m_basis.setIdentity();
157                 m_origin.setValue(SimdScalar(0.0), SimdScalar(0.0), SimdScalar(0.0));
158                 m_type = 0x0;
159         }
160
161         SIMD_FORCE_INLINE bool isIdentity() const { return m_type == 0x0; }
162
163         SimdTransform& operator*=(const SimdTransform& t) 
164         {
165                 m_origin += m_basis * t.m_origin;
166                 m_basis *= t.m_basis;
167                 m_type |= t.m_type; 
168                 return *this;
169         }
170
171         SimdTransform inverse() const
172         { 
173                 if (m_type)
174                 {
175                         SimdMatrix3x3 inv = (m_type & SCALING) ? 
176                                 m_basis.inverse() : 
177                         m_basis.transpose();
178
179                         return SimdTransform(inv, inv * -m_origin, m_type);
180                 }
181
182                 return *this;
183         }
184
185         SimdTransform inverseTimes(const SimdTransform& t) const;  
186
187         SimdTransform operator*(const SimdTransform& t) const;
188
189 private:
190
191         SimdMatrix3x3 m_basis;
192         SimdVector3   m_origin;
193         unsigned int      m_type;
194 };
195
196
197 SIMD_FORCE_INLINE SimdVector3
198 SimdTransform::invXform(const SimdVector3& inVec) const
199 {
200         SimdVector3 v = inVec - m_origin;
201         return (m_basis.transpose() * v);
202 }
203
204 SIMD_FORCE_INLINE SimdTransform 
205 SimdTransform::inverseTimes(const SimdTransform& t) const  
206 {
207         SimdVector3 v = t.getOrigin() - m_origin;
208         if (m_type & SCALING) 
209         {
210                 SimdMatrix3x3 inv = m_basis.inverse();
211                 return SimdTransform(inv * t.getBasis(), inv * v, 
212                         m_type | t.m_type);
213         }
214         else 
215         {
216                 return SimdTransform(m_basis.transposeTimes(t.m_basis),
217                         v * m_basis, m_type | t.m_type);
218         }
219 }
220
221 SIMD_FORCE_INLINE SimdTransform 
222 SimdTransform::operator*(const SimdTransform& t) const
223 {
224         return SimdTransform(m_basis * t.m_basis, 
225                 (*this)(t.m_origin), 
226                 m_type | t.m_type);
227 }       
228
229
230
231 #endif
232
233
234
235
236