OpenClonk
StdMeshMatrix Class Reference

#include <StdMeshMath.h>

Public Member Functions

float & operator() (int i, int j)
 
float operator() (int i, int j) const
 
float Determinant () const
 
StdMeshTransformation Decompose () const
 
const float * data () const
 

Static Public Member Functions

static StdMeshMatrix Zero ()
 
static StdMeshMatrix Identity ()
 
static StdMeshMatrix Inverse (const StdMeshMatrix &mat)
 
static StdMeshMatrix Translate (float dx, float dy, float dz)
 
static StdMeshMatrix Scale (float sx, float sy, float sz)
 
static StdMeshMatrix Rotate (float angle, float rx, float ry, float rz)
 
static StdMeshMatrix Transform (const StdMeshTransformation &transform)
 
static StdMeshMatrix TransformInverse (const StdMeshTransformation &transform)
 
static StdMeshMatrix LookAt (const StdMeshVector &eye, const StdMeshVector &center, const StdMeshVector &up)
 

Static Public Attributes

static const int NColumns = 4
 
static const int NRows = 3
 

Detailed Description

Definition at line 89 of file StdMeshMath.h.

Member Function Documentation

◆ data()

const float* StdMeshMatrix::data ( ) const
inline

Definition at line 111 of file StdMeshMath.h.

111 { return &a[0][0]; }

Referenced by C4ShaderCall::SetUniformMatrix3x4().

Here is the caller graph for this function:

◆ Decompose()

StdMeshTransformation StdMeshMatrix::Decompose ( ) const

Definition at line 442 of file StdMeshMath.cpp.

443 {
444  // Extract the scale part of the matrix
445  const float sx = sqrt(a[0][0]*a[0][0] + a[1][0]*a[1][0] + a[2][0]*a[2][0]);
446  const float sy = sqrt(a[0][1]*a[0][1] + a[1][1]*a[1][1] + a[2][1]*a[2][1]);
447  const float sz = sqrt(a[0][2]*a[0][2] + a[1][2]*a[1][2] + a[2][2]*a[2][2]);
448 
449  // What remains is the rotation part
450  // TODO: This can be optimized by not doing the full matrix multiplication
451  StdMeshMatrix rot = Scale(1.0f/sx, 1.0f/sy, 1.0f/sz) * *this;
452 
453  // Note that this does not work for skew matrices -- we cannot
454  // represent skews in StdMeshTransformation
455  const float cos_angle = 0.5f * (rot.a[0][0] + rot.a[1][1] + rot.a[2][2] - 1.0f);
456 
457  const float rdx = rot.a[2][1] - rot.a[1][2];
458  const float rdy = rot.a[0][2] - rot.a[2][0];
459  const float rdz = rot.a[1][0] - rot.a[0][1];
460  const float det = sqrt(rdx*rdx + rdy*rdy + rdz*rdz);
461 
462  const float rx = (rot.a[2][1] - rot.a[1][2]) / det;
463  const float ry = (rot.a[0][2] - rot.a[2][0]) / det;
464  const float rz = (rot.a[1][0] - rot.a[0][1]) / det;
465 
466  StdMeshTransformation trans;
467  trans.scale.x = sx;
468  trans.scale.y = sy;
469  trans.scale.z = sz;
470  trans.rotate = StdMeshQuaternion::AngleAxis(acos(cos_angle), StdMeshVector::Translate(rx, ry, rz));
471  trans.translate.x = a[0][3];
472  trans.translate.y = a[1][3];
473  trans.translate.z = a[2][3];
474 
475  return trans;
476 }
static StdMeshMatrix Scale(float sx, float sy, float sz)
static StdMeshQuaternion AngleAxis(float theta, const StdMeshVector &axis)
Definition: StdMeshMath.cpp:72
StdMeshVector translate
Definition: StdMeshMath.h:76
StdMeshQuaternion rotate
Definition: StdMeshMath.h:75
StdMeshVector scale
Definition: StdMeshMath.h:74
static StdMeshVector Translate(float dx, float dy, float dz)
Definition: StdMeshMath.cpp:38

References a, StdMeshQuaternion::AngleAxis(), StdMeshTransformation::rotate, StdMeshTransformation::scale, Scale(), StdMeshVector::Translate(), StdMeshTransformation::translate, StdMeshVector::x, StdMeshVector::y, and StdMeshVector::z.

Here is the call graph for this function:

◆ Determinant()

float StdMeshMatrix::Determinant ( ) const

Definition at line 358 of file StdMeshMath.cpp.

359 {
360  return a[0][0]*a[1][1]*a[2][2] + a[0][1]*a[1][2]*a[2][0] + a[0][2]*a[1][0]*a[2][1]
361  - a[0][0]*a[1][2]*a[2][1] - a[0][1]*a[1][0]*a[2][2] - a[0][2]*a[1][1]*a[2][0];
362 }

Referenced by Inverse(), and CStdGL::PerformMesh().

Here is the caller graph for this function:

◆ Identity()

StdMeshMatrix StdMeshMatrix::Identity ( )
static

Definition at line 183 of file StdMeshMath.cpp.

184 {
185  StdMeshMatrix m;
186  m.a[0][0] = 1.0f; m.a[0][1] = 0.0f; m.a[0][2] = 0.0f; m.a[0][3] = 0.0f;
187  m.a[1][0] = 0.0f; m.a[1][1] = 1.0f; m.a[1][2] = 0.0f; m.a[1][3] = 0.0f;
188  m.a[2][0] = 0.0f; m.a[2][1] = 0.0f; m.a[2][2] = 1.0f; m.a[2][3] = 0.0f;
189  return m;
190 }

Referenced by C4Object::DrawFaceImpl(), StdSubMeshInstance::LoadFacesForCompletion(), CStdGL::PerformMesh(), C4Draw::RenderMesh(), StdMeshInstance::ReorderFaces(), StdMeshUpdate::Update(), and StdMeshInstance::UpdateBoneTransforms().

Here is the caller graph for this function:

◆ Inverse()

StdMeshMatrix StdMeshMatrix::Inverse ( const StdMeshMatrix mat)
static

Definition at line 192 of file StdMeshMath.cpp.

193 {
194  StdMeshMatrix m;
195 
196  const float det = mat.Determinant();
197  assert(det != 0.0f);
198 
199  m.a[0][0] = (mat.a[1][1]*mat.a[2][2] - mat.a[1][2]*mat.a[2][1]) / det;
200  m.a[1][0] = (mat.a[1][2]*mat.a[2][0] - mat.a[1][0]*mat.a[2][2]) / det;
201  m.a[2][0] = (mat.a[1][0]*mat.a[2][1] - mat.a[1][1]*mat.a[2][0]) / det;
202 
203  m.a[0][1] = (mat.a[0][2]*mat.a[2][1] - mat.a[0][1]*mat.a[2][2]) / det;
204  m.a[1][1] = (mat.a[0][0]*mat.a[2][2] - mat.a[0][2]*mat.a[2][0]) / det;
205  m.a[2][1] = (mat.a[0][1]*mat.a[2][0] - mat.a[0][0]*mat.a[2][1]) / det;
206 
207  m.a[0][2] = (mat.a[0][1]*mat.a[1][2] - mat.a[0][2]*mat.a[1][1]) / det;
208  m.a[1][2] = (mat.a[0][2]*mat.a[1][0] - mat.a[0][0]*mat.a[1][2]) / det;
209  m.a[2][2] = (mat.a[0][0]*mat.a[1][1] - mat.a[0][1]*mat.a[1][0]) / det;
210 
211  m.a[0][3] = (mat.a[0][1]*mat.a[1][3]*mat.a[2][2]
212  + mat.a[0][2]*mat.a[1][1]*mat.a[2][3]
213  + mat.a[0][3]*mat.a[1][2]*mat.a[2][1]
214  - mat.a[0][1]*mat.a[1][2]*mat.a[2][3]
215  - mat.a[0][2]*mat.a[1][3]*mat.a[2][1]
216  - mat.a[0][3]*mat.a[1][1]*mat.a[2][2]) / det;
217 
218  m.a[1][3] = (mat.a[0][0]*mat.a[1][2]*mat.a[2][3]
219  + mat.a[0][2]*mat.a[1][3]*mat.a[2][0]
220  + mat.a[0][3]*mat.a[1][0]*mat.a[2][2]
221  - mat.a[0][0]*mat.a[1][3]*mat.a[2][2]
222  - mat.a[0][2]*mat.a[1][0]*mat.a[2][3]
223  - mat.a[0][3]*mat.a[1][2]*mat.a[2][0]) / det;
224 
225  m.a[2][3] = (mat.a[0][0]*mat.a[1][3]*mat.a[2][1]
226  + mat.a[0][1]*mat.a[1][0]*mat.a[2][3]
227  + mat.a[0][3]*mat.a[1][1]*mat.a[2][0]
228  - mat.a[0][0]*mat.a[1][1]*mat.a[2][3]
229  - mat.a[0][1]*mat.a[1][3]*mat.a[2][0]
230  - mat.a[0][3]*mat.a[1][0]*mat.a[2][1]) / det;
231 
232  return m;
233 }
float Determinant() const

References Determinant().

Referenced by CStdGL::SetupMultiBlt(), and StdMeshInstance::UpdateBoneTransforms().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LookAt()

StdMeshMatrix StdMeshMatrix::LookAt ( const StdMeshVector eye,
const StdMeshVector center,
const StdMeshVector up 
)
static

Definition at line 340 of file StdMeshMath.cpp.

341 {
342  // See http://stackoverflow.com/questions/349050/calculating-a-lookat-matrix
343  StdMeshVector z = eye - center;
344  z.Normalize();
345 
347  x.Normalize();
348 
350 
351  StdMeshMatrix m;
352  m.a[0][0] = x.x; m.a[0][1] = x.y; m.a[0][2] = x.z; m.a[0][3] = -x.x*eye.x - x.y*eye.y - x.z*eye.z;
353  m.a[1][0] = y.x; m.a[1][1] = y.y; m.a[1][2] = y.z; m.a[1][3] = -y.x*eye.x - y.y*eye.y - y.z*eye.z;
354  m.a[2][0] = z.x; m.a[2][1] = z.y; m.a[2][2] = z.z; m.a[2][3] = -z.x*eye.x - z.y*eye.y - z.z*eye.z;
355  return m;
356 }
#define z
void Normalize()
Definition: StdMeshMath.cpp:56
static StdMeshVector Cross(const StdMeshVector &lhs, const StdMeshVector &rhs)
Definition: StdMeshMath.cpp:47

References StdMeshVector::Cross(), StdMeshVector::Normalize(), StdMeshVector::x, StdMeshVector::y, z, and StdMeshVector::z.

Referenced by CStdGL::PerformMesh().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator()() [1/2]

float& StdMeshMatrix::operator() ( int  i,
int  j 
)
inline

Definition at line 105 of file StdMeshMath.h.

105 { return a[i][j]; }

◆ operator()() [2/2]

float StdMeshMatrix::operator() ( int  i,
int  j 
) const
inline

Definition at line 106 of file StdMeshMath.h.

106 { return a[i][j]; }

◆ Rotate()

StdMeshMatrix StdMeshMatrix::Rotate ( float  angle,
float  rx,
float  ry,
float  rz 
)
static

Definition at line 253 of file StdMeshMath.cpp.

254 {
255  StdMeshMatrix m;
256 
257  // We do normalize the rx,ry,rz vector here: This is only required for
258  // precalculations anyway, thus not time-critical.
259  float abs = sqrt(rx*rx+ry*ry+rz*rz);
260  rx/=abs; ry/=abs; rz/=abs;
261  float c = cos(angle), s = sin(angle);
262 
263  m.a[0][0] = rx*rx*(1-c)+c; m.a[0][1] = rx*ry*(1-c)-rz*s; m.a[0][2] = rx*rz*(1-c)+ry*s; m.a[0][3] = 0.0f;
264  m.a[1][0] = ry*rx*(1-c)+rz*s; m.a[1][1] = ry*ry*(1-c)+c; m.a[1][2] = ry*rz*(1-c)-rx*s; m.a[1][3] = 0.0f;
265  m.a[2][0] = rz*rx*(1-c)-ry*s; m.a[2][1] = ry*rz*(1-c)+rx*s; m.a[2][2] = rz*rz*(1-c)+c; m.a[2][3] = 0.0f;
266  return m;
267 }
#define s

References s.

Referenced by C4Object::DrawFaceImpl().

Here is the caller graph for this function:

◆ Scale()

StdMeshMatrix StdMeshMatrix::Scale ( float  sx,
float  sy,
float  sz 
)
static

Definition at line 244 of file StdMeshMath.cpp.

245 {
246  StdMeshMatrix m;
247  m.a[0][0] = sx; m.a[0][1] = 0.0f; m.a[0][2] = 0.0f; m.a[0][3] = 0.0f;
248  m.a[1][0] = 0.0f; m.a[1][1] = sy; m.a[1][2] = 0.0f; m.a[1][3] = 0.0f;
249  m.a[2][0] = 0.0f; m.a[2][1] = 0.0f; m.a[2][2] = sz; m.a[2][3] = 0.0f;
250  return m;
251 }

Referenced by Decompose(), C4Object::DrawFaceImpl(), CStdGL::PerformMesh(), and OgreToClonk::TransformScaleVector().

Here is the caller graph for this function:

◆ Transform()

StdMeshMatrix StdMeshMatrix::Transform ( const StdMeshTransformation transform)
static

Definition at line 269 of file StdMeshMath.cpp.

270 {
271  StdMeshMatrix m;
272 
273  float tx = 2*transform.rotate.x;
274  float ty = 2*transform.rotate.y;
275  float tz = 2*transform.rotate.z;
276  float twx = tx*transform.rotate.w;
277  float twy = ty*transform.rotate.w;
278  float twz = tz*transform.rotate.w;
279  float txx = tx*transform.rotate.x;
280  float txy = ty*transform.rotate.x;
281  float txz = tz*transform.rotate.x;
282  float tyy = ty*transform.rotate.y;
283  float tyz = tz*transform.rotate.y;
284  float tzz = tz*transform.rotate.z;
285 
286  m.a[0][0] = (1.0f - (tyy + tzz) ) * transform.scale.x;
287  m.a[0][1] = (txy - twz) * transform.scale.y;
288  m.a[0][2] = (txz + twy) * transform.scale.z;
289  m.a[1][0] = (txy + twz) * transform.scale.x;
290  m.a[1][1] = (1.0f - (txx + tzz) ) * transform.scale.y;
291  m.a[1][2] = (tyz - twx) * transform.scale.z;
292  m.a[2][0] = (txz - twy) * transform.scale.x;
293  m.a[2][1] = (tyz + twx) * transform.scale.y;
294  m.a[2][2] = (1.0f - (txx + tyy) ) * transform.scale.z;
295 
296  m.a[0][3] = transform.translate.x;
297  m.a[1][3] = transform.translate.y;
298  m.a[2][3] = transform.translate.z;
299 
300  return m;
301 }

References StdMeshTransformation::rotate, StdMeshTransformation::scale, StdMeshTransformation::translate, StdMeshQuaternion::w, StdMeshVector::x, StdMeshQuaternion::x, StdMeshVector::y, StdMeshQuaternion::y, StdMeshVector::z, and StdMeshQuaternion::z.

Referenced by StdMeshInstance::UpdateBoneTransforms().

Here is the caller graph for this function:

◆ TransformInverse()

StdMeshMatrix StdMeshMatrix::TransformInverse ( const StdMeshTransformation transform)
static

Definition at line 303 of file StdMeshMath.cpp.

304 {
305  StdMeshMatrix m;
306 
307  float tx = 2*transform.rotate.x;
308  float ty = 2*transform.rotate.y;
309  float tz = 2*transform.rotate.z;
310  float twx = -tx*transform.rotate.w;
311  float twy = -ty*transform.rotate.w;
312  float twz = -tz*transform.rotate.w;
313  float txx = tx*transform.rotate.x;
314  float txy = ty*transform.rotate.x;
315  float txz = tz*transform.rotate.x;
316  float tyy = ty*transform.rotate.y;
317  float tyz = tz*transform.rotate.y;
318  float tzz = tz*transform.rotate.z;
319 
320  m.a[0][0] = (1.0f - (tyy + tzz) ) / transform.scale.x;
321  m.a[0][1] = (txy - twz) / transform.scale.x;
322  m.a[0][2] = (txz + twy) / transform.scale.x;
323  m.a[1][0] = (txy + twz) / transform.scale.y;
324  m.a[1][1] = (1.0f - (txx + tzz) ) / transform.scale.y;
325  m.a[1][2] = (tyz - twx) / transform.scale.y;
326  m.a[2][0] = (txz - twy) / transform.scale.z;
327  m.a[2][1] = (tyz + twx) / transform.scale.z;
328  m.a[2][2] = (1.0f - (txx + tyy) ) / transform.scale.z;
329 
330  // Signs do not cancel!
331  StdMeshVector invtranslate = (-transform.rotate) * (-transform.translate/transform.scale);
332 
333  m.a[0][3] = invtranslate.x;
334  m.a[1][3] = invtranslate.y;
335  m.a[2][3] = invtranslate.z;
336 
337  return m;
338 }

References StdMeshTransformation::rotate, StdMeshTransformation::scale, StdMeshTransformation::translate, StdMeshQuaternion::w, StdMeshVector::x, StdMeshQuaternion::x, StdMeshVector::y, StdMeshQuaternion::y, StdMeshVector::z, and StdMeshQuaternion::z.

◆ Translate()

StdMeshMatrix StdMeshMatrix::Translate ( float  dx,
float  dy,
float  dz 
)
static

Definition at line 235 of file StdMeshMath.cpp.

236 {
237  StdMeshMatrix m;
238  m.a[0][0] = 1.0f; m.a[0][1] = 0.0f; m.a[0][2] = 0.0f; m.a[0][3] = dx;
239  m.a[1][0] = 0.0f; m.a[1][1] = 1.0f; m.a[1][2] = 0.0f; m.a[1][3] = dy;
240  m.a[2][0] = 0.0f; m.a[2][1] = 0.0f; m.a[2][2] = 1.0f; m.a[2][3] = dz;
241  return m;
242 }

Referenced by C4Object::DrawFaceImpl().

Here is the caller graph for this function:

◆ Zero()

StdMeshMatrix StdMeshMatrix::Zero ( )
static

Definition at line 174 of file StdMeshMath.cpp.

175 {
176  StdMeshMatrix m;
177  m.a[0][0] = 0.0f; m.a[0][1] = 0.0f; m.a[0][2] = 0.0f; m.a[0][3] = 0.0f;
178  m.a[1][0] = 0.0f; m.a[1][1] = 0.0f; m.a[1][2] = 0.0f; m.a[1][3] = 0.0f;
179  m.a[2][0] = 0.0f; m.a[2][1] = 0.0f; m.a[2][2] = 0.0f; m.a[2][3] = 0.0f;
180  return m;
181 }

Member Data Documentation

◆ NColumns

const int StdMeshMatrix::NColumns = 4
static

Definition at line 92 of file StdMeshMath.h.

◆ NRows

const int StdMeshMatrix::NRows = 3
static

Definition at line 93 of file StdMeshMath.h.


The documentation for this class was generated from the following files: