Changeset View
Changeset View
Standalone View
Standalone View
source/maths/Matrix3D.h
/* Copyright (C) 2019 Wildfire Games. | /* Copyright (C) 2021 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
Show All 11 Lines | |||||
*/ | */ | ||||
#ifndef INCLUDED_MATRIX3D | #ifndef INCLUDED_MATRIX3D | ||||
#define INCLUDED_MATRIX3D | #define INCLUDED_MATRIX3D | ||||
#include "maths/Vector3D.h" | #include "maths/Vector3D.h" | ||||
#include "maths/Vector4D.h" | #include "maths/Vector4D.h" | ||||
class CQuaternion; | class CQuaternion; | ||||
Stan: Might make more sense to include sse.h which would pull those headers. | |||||
///////////////////////////////////////////////////////////////////////// | ///////////////////////////////////////////////////////////////////////// | ||||
// CMatrix3D: a 4x4 matrix class for common operations in 3D | // CMatrix3D: a 4x4 matrix class for common operations in 3D | ||||
class CMatrix3D | class CMatrix3D | ||||
{ | { | ||||
public: | public: | ||||
// the matrix data itself - accessible as either longhand names | // the matrix data itself - accessible as either longhand names | ||||
// or via a flat or 2d array | // or via a flat or 2d array | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | public: | ||||
{ | { | ||||
return _data[idx]; | return _data[idx]; | ||||
} | } | ||||
const float& operator[](int idx) const | const float& operator[](int idx) const | ||||
{ | { | ||||
return _data[idx]; | return _data[idx]; | ||||
} | } | ||||
static CMatrix3D(*Multiply)(const CMatrix3D& source, const CMatrix3D& matrix); | |||||
static void(*BlendMat)(CMatrix3D* s, const CMatrix3D& m, float f); | |||||
static void(*AddBlendMat)(CMatrix3D* s, const CMatrix3D& m, float f); | |||||
// matrix multiplication | // matrix multiplication | ||||
CMatrix3D operator*(const CMatrix3D &matrix) const | CMatrix3D operator* (const CMatrix3D& matrix) const | ||||
{ | { | ||||
return CMatrix3D( | return Multiply(*this, matrix); | ||||
_11*matrix._11 + _12*matrix._21 + _13*matrix._31 + _14*matrix._41, | |||||
_11*matrix._12 + _12*matrix._22 + _13*matrix._32 + _14*matrix._42, | |||||
_11*matrix._13 + _12*matrix._23 + _13*matrix._33 + _14*matrix._43, | |||||
_11*matrix._14 + _12*matrix._24 + _13*matrix._34 + _14*matrix._44, | |||||
_21*matrix._11 + _22*matrix._21 + _23*matrix._31 + _24*matrix._41, | |||||
_21*matrix._12 + _22*matrix._22 + _23*matrix._32 + _24*matrix._42, | |||||
_21*matrix._13 + _22*matrix._23 + _23*matrix._33 + _24*matrix._43, | |||||
_21*matrix._14 + _22*matrix._24 + _23*matrix._34 + _24*matrix._44, | |||||
_31*matrix._11 + _32*matrix._21 + _33*matrix._31 + _34*matrix._41, | |||||
_31*matrix._12 + _32*matrix._22 + _33*matrix._32 + _34*matrix._42, | |||||
_31*matrix._13 + _32*matrix._23 + _33*matrix._33 + _34*matrix._43, | |||||
_31*matrix._14 + _32*matrix._24 + _33*matrix._34 + _34*matrix._44, | |||||
_41*matrix._11 + _42*matrix._21 + _43*matrix._31 + _44*matrix._41, | |||||
_41*matrix._12 + _42*matrix._22 + _43*matrix._32 + _44*matrix._42, | |||||
_41*matrix._13 + _42*matrix._23 + _43*matrix._33 + _44*matrix._43, | |||||
_41*matrix._14 + _42*matrix._24 + _43*matrix._34 + _44*matrix._44 | |||||
); | |||||
} | } | ||||
// matrix multiplication/assignment | // matrix multiplication/assignment | ||||
CMatrix3D& operator*=(const CMatrix3D &matrix) | CMatrix3D& operator*=(const CMatrix3D &matrix) | ||||
{ | { | ||||
Concatenate(matrix); | Concatenate(matrix); | ||||
return *this; | return *this; | ||||
} | } | ||||
Show All 26 Lines | CMatrix3D& operator+=(const CMatrix3D &m) | ||||
_11 += m._11; _21 += m._21; _31 += m._31; _41 += m._41; | _11 += m._11; _21 += m._21; _31 += m._31; _41 += m._41; | ||||
_12 += m._12; _22 += m._22; _32 += m._32; _42 += m._42; | _12 += m._12; _22 += m._22; _32 += m._32; _42 += m._42; | ||||
_13 += m._13; _23 += m._23; _33 += m._33; _43 += m._43; | _13 += m._13; _23 += m._23; _33 += m._33; _43 += m._43; | ||||
_14 += m._14; _24 += m._24; _34 += m._34; _44 += m._44; | _14 += m._14; _24 += m._24; _34 += m._34; _44 += m._44; | ||||
return *this; | return *this; | ||||
} | } | ||||
// equality | // equality | ||||
bool operator==(const CMatrix3D &m) const | bool operator==(const CMatrix3D &m) const | ||||
Not Done Inline ActionsFor what it's worth, here's what Clang generates for me on SSE3 (NB -> assembly): rdx -> this rsi -> argument Matrix rdi -> return Matrix movss xmm3, dword [rdx] movss xmm4, dword [rdx+4] movss xmm7, dword [rdx+8] movss xmm0, dword [rdx+0xc] movss xmm5, dword [rdx+0x10] movss xmm6, dword [rdx+0x14] movups xmm2, xmmword [rsi] movups xmm1, xmmword [rsi+0x10] shufps xmm3, xmm3, 0x0 mulps xmm3, xmm2 shufps xmm4, xmm4, 0x0 mulps xmm4, xmm1 addps xmm4, xmm3 movups xmm3, xmmword [rsi+0x20] shufps xmm7, xmm7, 0x0 mulps xmm7, xmm3 addps xmm7, xmm4 movups xmm4, xmmword [rsi+0x30] shufps xmm0, xmm0, 0x0 mulps xmm0, xmm4 addps xmm0, xmm7 movss xmm7, dword [rdx+0x18] shufps xmm5, xmm5, 0x0 mulps xmm5, xmm2 shufps xmm6, xmm6, 0x0 mulps xmm6, xmm1 addps xmm6, xmm5 movss xmm5, dword [rdx+0x1c] shufps xmm7, xmm7, 0x0 mulps xmm7, xmm3 addps xmm7, xmm6 movss xmm6, dword [rdx+0x20] shufps xmm5, xmm5, 0x0 mulps xmm5, xmm4 addps xmm5, xmm7 movss xmm7, dword [rdx+0x24] shufps xmm6, xmm6, 0x0 mulps xmm6, xmm2 shufps xmm7, xmm7, 0x0 mulps xmm7, xmm1 addps xmm7, xmm6 movss xmm6, dword [rdx+0x28] shufps xmm6, xmm6, 0x0 mulps xmm6, xmm3 addps xmm6, xmm7 movss xmm7, dword [rdx+0x2c] shufps xmm7, xmm7, 0x0 mulps xmm7, xmm4 addps xmm7, xmm6 movss xmm6, dword [rdx+0x30] shufps xmm6, xmm6, 0x0 mulps xmm6, xmm2 movss xmm2, dword [rdx+0x34] shufps xmm2, xmm2, 0x0 mulps xmm2, xmm1 addps xmm2, xmm6 movss xmm1, dword [rdx+0x38] shufps xmm1, xmm1, 0x0 mulps xmm1, xmm3 addps xmm1, xmm2 movss xmm2, dword [rdx+0x3c] shufps xmm2, xmm2, 0x0 mulps xmm2, xmm4 addps xmm2, xmm1 movups xmmword [rdi], xmm0 movups xmmword [rdi+0x10], xmm5 movups xmmword [rdi+0x20], xmm7 movups xmmword [rdi+0x20], xmm7 movups xmmword [rdi+0x30], xmm2 wraitii: For what it's worth, here's what Clang generates for me on SSE3 (NB -> assembly):
```
rdx ->… | |||||
Not Done Inline ActionsSo this is the generated assembly for the non-SSE function? It looks nearly the same, as the code that was created by MSVC2017 for the SSE function. The code, which is generated by MSVC2017 for the non-SSE function, is round about 3 times longer. OptimusShepard: So this is the generated assembly for the non-SSE function? It looks nearly the same, as the… | |||||
{ | { | ||||
return _11 == m._11 && _21 == m._21 && _31 == m._31 && _41 == m._41 && | return _11 == m._11 && _21 == m._21 && _31 == m._31 && _41 == m._41 && | ||||
_12 == m._12 && _22 == m._22 && _32 == m._32 && _42 == m._42 && | _12 == m._12 && _22 == m._22 && _32 == m._32 && _42 == m._42 && | ||||
_13 == m._13 && _23 == m._23 && _33 == m._33 && _43 == m._43 && | _13 == m._13 && _23 == m._23 && _33 == m._33 && _43 == m._43 && | ||||
_14 == m._14 && _24 == m._24 && _34 == m._34 && _44 == m._44; | _14 == m._14 && _24 == m._24 && _34 == m._34 && _44 == m._44; | ||||
} | } | ||||
// inequality | // inequality | ||||
Show All 16 Lines | public: | ||||
void Concatenate(const CMatrix3D& m) | void Concatenate(const CMatrix3D& m) | ||||
{ | { | ||||
(*this) = m * (*this); | (*this) = m * (*this); | ||||
} | } | ||||
// blend matrix using only 4x3 subset | // blend matrix using only 4x3 subset | ||||
void Blend(const CMatrix3D& m, float f) | void Blend(const CMatrix3D& m, float f) | ||||
{ | { | ||||
_11 = m._11*f; _21 = m._21*f; _31 = m._31*f; | BlendMat(this, m, f); | ||||
_12 = m._12*f; _22 = m._22*f; _32 = m._32*f; | |||||
_13 = m._13*f; _23 = m._23*f; _33 = m._33*f; | |||||
_14 = m._14*f; _24 = m._24*f; _34 = m._34*f; | |||||
} | } | ||||
// blend matrix using only 4x3 and add onto existing blend | // blend matrix using only 4x3 and add onto existing blend | ||||
void AddBlend(const CMatrix3D& m, float f) | void AddBlend(const CMatrix3D& m, float f) | ||||
{ | { | ||||
_11 += m._11*f; _21 += m._21*f; _31 += m._31*f; | AddBlendMat(this, m, f); | ||||
_12 += m._12*f; _22 += m._22*f; _32 += m._32*f; | |||||
_13 += m._13*f; _23 += m._23*f; _33 += m._33*f; | |||||
_14 += m._14*f; _24 += m._24*f; _34 += m._34*f; | |||||
} | } | ||||
Done Inline Actions0.f here and above :) Stan: 0.f here and above :)
| |||||
// set this matrix to a rotation matrix for a rotation about X axis of given angle | // set this matrix to a rotation matrix for a rotation about X axis of given angle | ||||
void SetXRotation(float angle); | void SetXRotation(float angle); | ||||
// set this matrix to a rotation matrix for a rotation about Y axis of given angle | // set this matrix to a rotation matrix for a rotation about Y axis of given angle | ||||
void SetYRotation(float angle); | void SetYRotation(float angle); | ||||
// set this matrix to a rotation matrix for a rotation about Z axis of given angle | // set this matrix to a rotation matrix for a rotation about Z axis of given angle | ||||
void SetZRotation(float angle); | void SetZRotation(float angle); | ||||
// set this matrix to a rotation described by given quaternion | // set this matrix to a rotation described by given quaternion | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | void Rotate(const CVector3D& vector, CVector3D& result) const | ||||
result.Z = _31*vector.X + _32*vector.Y + _33*vector.Z; | result.Z = _31*vector.X + _32*vector.Y + _33*vector.Z; | ||||
} | } | ||||
// rotate a vector by the transpose of this matrix | // rotate a vector by the transpose of this matrix | ||||
void RotateTransposed(const CVector3D& vector,CVector3D& result) const; | void RotateTransposed(const CVector3D& vector,CVector3D& result) const; | ||||
CVector3D RotateTransposed(const CVector3D& vector) const; | CVector3D RotateTransposed(const CVector3D& vector) const; | ||||
}; | }; | ||||
extern void Matrix3DActivateFastImpl(); | |||||
#endif // INCLUDED_MATRIX3D | #endif // INCLUDED_MATRIX3D |
Wildfire Games · Phabricator
Might make more sense to include sse.h which would pull those headers.