mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Renamed imag component to dual, using the correct nomenclature
Also removed incomplete test from unit tests.
This commit is contained in:
parent
d08f94a74d
commit
fbea22e0f0
5 changed files with 40 additions and 73 deletions
|
@ -24,7 +24,7 @@ layout(std140) uniform skinClusterBuffer {
|
|||
|
||||
<@if SKIN_DQ@>
|
||||
|
||||
mat4 dualQuatToMat4(vec4 real, vec4 imag) {
|
||||
mat4 dualQuatToMat4(vec4 real, vec4 dual) {
|
||||
float twoRealXSq = 2.0 * real.x * real.x;
|
||||
float twoRealYSq = 2.0 * real.y * real.y;
|
||||
float twoRealZSq = 2.0 * real.z * real.z;
|
||||
|
@ -46,9 +46,9 @@ mat4 dualQuatToMat4(vec4 real, vec4 imag) {
|
|||
twoRealYZ - twoRealXW,
|
||||
1 - twoRealXSq - twoRealYSq,
|
||||
0.0);
|
||||
vec4 col3 = vec4(2.0 * (-imag.w * real.x + imag.x * real.w - imag.y * real.z + imag.z * real.y),
|
||||
2.0 * (-imag.w * real.y + imag.x * real.z + imag.y * real.w - imag.z * real.x),
|
||||
2.0 * (-imag.w * real.z - imag.x * real.y + imag.y * real.x + imag.z * real.w),
|
||||
vec4 col3 = vec4(2.0 * (-dual.w * real.x + dual.x * real.w - dual.y * real.z + dual.z * real.y),
|
||||
2.0 * (-dual.w * real.y + dual.x * real.z + dual.y * real.w - dual.z * real.x),
|
||||
2.0 * (-dual.w * real.z - dual.x * real.y + dual.y * real.x + dual.z * real.w),
|
||||
1.0);
|
||||
|
||||
return mat4(col0, col1, col2, col3);
|
||||
|
@ -60,7 +60,7 @@ void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPositio
|
|||
// linearly blend scale and dual quaternion components
|
||||
vec3 sAccum = vec3(0.0, 0.0, 0.0);
|
||||
vec4 rAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 iAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 dAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 polarityReference = clusterMatrices[skinClusterIndex[0]][1];
|
||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||
mat4 clusterMatrix = clusterMatrices[(skinClusterIndex[i])];
|
||||
|
@ -68,7 +68,7 @@ void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPositio
|
|||
|
||||
vec3 scale = vec3(clusterMatrix[0]);
|
||||
vec4 real = clusterMatrix[1];
|
||||
vec4 imag = clusterMatrix[2];
|
||||
vec4 dual = clusterMatrix[2];
|
||||
|
||||
// to ensure that we rotate along the shortest arc, reverse dual quaternions with negative polarity.
|
||||
float dqClusterWeight = clusterWeight;
|
||||
|
@ -78,16 +78,16 @@ void skinPosition(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inPositio
|
|||
|
||||
sAccum += scale * clusterWeight;
|
||||
rAccum += real * dqClusterWeight;
|
||||
iAccum += imag * dqClusterWeight;
|
||||
dAccum += dual * dqClusterWeight;
|
||||
}
|
||||
|
||||
// normalize dual quaternion
|
||||
float norm = length(rAccum);
|
||||
rAccum /= norm;
|
||||
iAccum /= norm;
|
||||
dAccum /= norm;
|
||||
|
||||
// conversion from dual quaternion to 4x4 matrix.
|
||||
mat4 m = dualQuatToMat4(rAccum, iAccum);
|
||||
mat4 m = dualQuatToMat4(rAccum, dAccum);
|
||||
skinnedPosition = m * (vec4(sAccum, 1) * inPosition);
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inP
|
|||
// linearly blend scale and dual quaternion components
|
||||
vec3 sAccum = vec3(0.0, 0.0, 0.0);
|
||||
vec4 rAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 iAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 dAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 polarityReference = clusterMatrices[skinClusterIndex[0]][1];
|
||||
|
||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||
|
@ -106,7 +106,7 @@ void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inP
|
|||
|
||||
vec3 scale = vec3(clusterMatrix[0]);
|
||||
vec4 real = clusterMatrix[1];
|
||||
vec4 imag = clusterMatrix[2];
|
||||
vec4 dual = clusterMatrix[2];
|
||||
|
||||
// to ensure that we rotate along the shortest arc, reverse dual quaternions with negative polarity.
|
||||
float dqClusterWeight = clusterWeight;
|
||||
|
@ -116,16 +116,16 @@ void skinPositionNormal(ivec4 skinClusterIndex, vec4 skinClusterWeight, vec4 inP
|
|||
|
||||
sAccum += scale * clusterWeight;
|
||||
rAccum += real * dqClusterWeight;
|
||||
iAccum += imag * dqClusterWeight;
|
||||
dAccum += dual * dqClusterWeight;
|
||||
}
|
||||
|
||||
// normalize dual quaternion
|
||||
float norm = length(rAccum);
|
||||
rAccum /= norm;
|
||||
iAccum /= norm;
|
||||
dAccum /= norm;
|
||||
|
||||
// conversion from dual quaternion to 4x4 matrix.
|
||||
mat4 m = dualQuatToMat4(rAccum, iAccum);
|
||||
mat4 m = dualQuatToMat4(rAccum, dAccum);
|
||||
skinnedPosition = m * (vec4(sAccum, 1) * inPosition);
|
||||
skinnedNormal = vec3(m * vec4(inNormal, 0));
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, v
|
|||
// linearly blend scale and dual quaternion components
|
||||
vec3 sAccum = vec3(0.0, 0.0, 0.0);
|
||||
vec4 rAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 iAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 dAccum = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
vec4 polarityReference = clusterMatrices[skinClusterIndex[0]][1];
|
||||
|
||||
for (int i = 0; i < INDICES_PER_VERTEX; i++) {
|
||||
|
@ -145,7 +145,7 @@ void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, v
|
|||
|
||||
vec3 scale = vec3(clusterMatrix[0]);
|
||||
vec4 real = clusterMatrix[1];
|
||||
vec4 imag = clusterMatrix[2];
|
||||
vec4 dual = clusterMatrix[2];
|
||||
|
||||
// to ensure that we rotate along the shortest arc, reverse dual quaternions with negative polarity.
|
||||
float dqClusterWeight = clusterWeight;
|
||||
|
@ -155,16 +155,16 @@ void skinPositionNormalTangent(ivec4 skinClusterIndex, vec4 skinClusterWeight, v
|
|||
|
||||
sAccum += scale * clusterWeight;
|
||||
rAccum += real * dqClusterWeight;
|
||||
iAccum += imag * dqClusterWeight;
|
||||
dAccum += dual * dqClusterWeight;
|
||||
}
|
||||
|
||||
// normalize dual quaternion
|
||||
float norm = length(rAccum);
|
||||
rAccum /= norm;
|
||||
iAccum /= norm;
|
||||
dAccum /= norm;
|
||||
|
||||
// conversion from dual quaternion to 4x4 matrix.
|
||||
mat4 m = dualQuatToMat4(rAccum, iAccum);
|
||||
mat4 m = dualQuatToMat4(rAccum, dAccum);
|
||||
skinnedPosition = m * (vec4(sAccum, 1) * inPosition);
|
||||
skinnedNormal = vec3(m * vec4(inNormal, 0));
|
||||
skinnedTangent = vec3(m * vec4(inTangent, 0));
|
||||
|
|
|
@ -12,42 +12,42 @@
|
|||
#include "GLMHelpers.h"
|
||||
|
||||
// delegating constructor
|
||||
DualQuaternion::DualQuaternion() : _real(1.0f, 0.0f, 0.0f, 0.0), _imag(0.0f, 0.0f, 0.0f, 0.0f) {
|
||||
DualQuaternion::DualQuaternion() : _real(1.0f, 0.0f, 0.0f, 0.0), _dual(0.0f, 0.0f, 0.0f, 0.0f) {
|
||||
}
|
||||
|
||||
DualQuaternion::DualQuaternion(const glm::mat4& m) : DualQuaternion(glmExtractRotation(m), extractTranslation(m)) {
|
||||
}
|
||||
|
||||
DualQuaternion::DualQuaternion(const glm::quat& real, const glm::quat& imag) : _real(real), _imag(imag) {
|
||||
DualQuaternion::DualQuaternion(const glm::quat& real, const glm::quat& dual) : _real(real), _dual(dual) {
|
||||
}
|
||||
|
||||
DualQuaternion::DualQuaternion(const glm::vec4& real, const glm::vec4& imag) :
|
||||
DualQuaternion::DualQuaternion(const glm::vec4& real, const glm::vec4& dual) :
|
||||
_real(real.w, real.x, real.y, real.z),
|
||||
_imag(imag.w, imag.x, imag.y, imag.z) {
|
||||
_dual(dual.w, dual.x, dual.y, dual.z) {
|
||||
}
|
||||
|
||||
DualQuaternion::DualQuaternion(const glm::quat& rotation, const glm::vec3& translation) {
|
||||
_real = rotation;
|
||||
_imag = glm::quat(0.0f, 0.5f * translation.x, 0.5f * translation.y, 0.5f * translation.z) * rotation;
|
||||
_dual = glm::quat(0.0f, 0.5f * translation.x, 0.5f * translation.y, 0.5f * translation.z) * rotation;
|
||||
}
|
||||
|
||||
DualQuaternion DualQuaternion::operator*(const DualQuaternion& rhs) const {
|
||||
return DualQuaternion(_real * rhs._real, _real * rhs._imag + _imag * rhs._real);
|
||||
return DualQuaternion(_real * rhs._real, _real * rhs._dual + _dual * rhs._real);
|
||||
}
|
||||
|
||||
DualQuaternion DualQuaternion::operator*(float scalar) const {
|
||||
return DualQuaternion(_real * scalar, _imag * scalar);
|
||||
return DualQuaternion(_real * scalar, _dual * scalar);
|
||||
}
|
||||
|
||||
DualQuaternion DualQuaternion::operator+(const DualQuaternion& rhs) const {
|
||||
return DualQuaternion(_real + rhs._real, _imag + rhs._imag);
|
||||
return DualQuaternion(_real + rhs._real, _dual + rhs._dual);
|
||||
}
|
||||
|
||||
glm::vec3 DualQuaternion::xformPoint(const glm::vec3& rhs) const {
|
||||
DualQuaternion v(glm::quat(), glm::quat(0.0f, rhs.x, rhs.y, rhs.z));
|
||||
DualQuaternion dualConj(glm::conjugate(_real), -glm::conjugate(_imag));
|
||||
DualQuaternion dualConj(glm::conjugate(_real), -glm::conjugate(_dual));
|
||||
DualQuaternion result = *this * v * dualConj;
|
||||
return vec3(result._imag.x, result._imag.y, result._imag.z);
|
||||
return vec3(result._dual.x, result._dual.y, result._dual.z);
|
||||
}
|
||||
|
||||
glm::quat DualQuaternion::getRotation() const {
|
||||
|
@ -55,7 +55,7 @@ glm::quat DualQuaternion::getRotation() const {
|
|||
}
|
||||
|
||||
glm::vec3 DualQuaternion::getTranslation() const {
|
||||
glm::quat result = 2.0f * (_imag * glm::inverse(_real));
|
||||
glm::quat result = 2.0f * (_dual * glm::inverse(_real));
|
||||
return glm::vec3(result.x, result.y, result.z);
|
||||
}
|
||||
|
||||
|
@ -65,11 +65,11 @@ glm::vec3 DualQuaternion::xformVector(const glm::vec3& rhs) const {
|
|||
|
||||
DualQuaternion DualQuaternion::inverse() const {
|
||||
glm::quat invReal = glm::inverse(_real);
|
||||
return DualQuaternion(invReal, - invReal * _imag * invReal);
|
||||
return DualQuaternion(invReal, - invReal * _dual * invReal);
|
||||
}
|
||||
|
||||
DualQuaternion DualQuaternion::conjugate() const {
|
||||
return DualQuaternion(glm::conjugate(_real), glm::conjugate(_imag));
|
||||
return DualQuaternion(glm::conjugate(_real), glm::conjugate(_dual));
|
||||
}
|
||||
|
||||
float DualQuaternion::length() const {
|
||||
|
@ -88,5 +88,5 @@ float DualQuaternion::dot(const DualQuaternion& rhs) const {
|
|||
}
|
||||
|
||||
DualQuaternion DualQuaternion::operator-() const {
|
||||
return DualQuaternion(-_real, -_imag);
|
||||
return DualQuaternion(-_real, -_dual);
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ public:
|
|||
const glm::quat& real() const { return _real; }
|
||||
glm::quat& real() { return _real; }
|
||||
|
||||
const glm::quat& imag() const { return _imag; }
|
||||
glm::quat& imag() { return _imag; }
|
||||
const glm::quat& dual() const { return _dual; }
|
||||
glm::quat& dual() { return _dual; }
|
||||
|
||||
glm::quat getRotation() const;
|
||||
glm::vec3 getTranslation() const;
|
||||
|
@ -50,12 +50,12 @@ public:
|
|||
protected:
|
||||
friend QDebug operator<<(QDebug debug, const DualQuaternion& pose);
|
||||
glm::quat _real;
|
||||
glm::quat _imag;
|
||||
glm::quat _dual;
|
||||
};
|
||||
|
||||
|
||||
inline QDebug operator<<(QDebug debug, const DualQuaternion& dq) {
|
||||
debug << "AnimPose, real = (" << dq._real.x << dq._real.y << dq._real.z << dq._real.w << "), imag = (" << dq._imag.x << dq._imag.y << dq._imag.z << dq._imag.w << ")";
|
||||
debug << "AnimPose, real = (" << dq._real.x << dq._real.y << dq._real.z << dq._real.w << "), dual = (" << dq._dual.x << dq._dual.y << dq._dual.z << dq._dual.w << ")";
|
||||
return debug;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,11 @@ static void quatComp(const glm::quat& q1, const glm::quat& q2) {
|
|||
|
||||
void DualQuaternionTests::ctor() {
|
||||
glm::quat real = angleAxis(PI / 2.0f, Vectors::UNIT_Y);
|
||||
glm::quat imag(0.0f, 1.0f, 2.0f, 3.0f);
|
||||
glm::quat dual(0.0f, 1.0f, 2.0f, 3.0f);
|
||||
|
||||
DualQuaternion dq(real, imag);
|
||||
DualQuaternion dq(real, dual);
|
||||
quatComp(real, dq.real());
|
||||
quatComp(imag, dq.imag());
|
||||
quatComp(dual, dq.dual());
|
||||
|
||||
glm::quat rotation = angleAxis(PI / 3.0f, Vectors::UNIT_X);
|
||||
glm::vec3 translation(1.0, 2.0f, 3.0f);
|
||||
|
@ -113,35 +113,3 @@ void DualQuaternionTests::trans() {
|
|||
QCOMPARE_WITH_ABS_ERROR(t2, dq2.getTranslation(), 0.001f);
|
||||
QCOMPARE_WITH_ABS_ERROR(t3, dq3.getTranslation(), 0.001f);
|
||||
}
|
||||
|
||||
// Dual Quaternion Linear Blending test
|
||||
void DualQuaternionTests::dlb() {
|
||||
DualQuaternion dq1(Quaternions::IDENTITY, glm::vec3());
|
||||
DualQuaternion dq2(angleAxis(PI / 2.0f, Vectors::UNIT_X), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
DualQuaternion dq2Alt(-angleAxis(PI / 2.0f, Vectors::UNIT_X), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
qDebug() << "dq1 =" << dq1;
|
||||
qDebug() << "dq2 =" << dq2;
|
||||
|
||||
// linear blend between dq1 and dq2
|
||||
DualQuaternion dq3 = dq1 * 0.5f + dq2 * 0.5f;
|
||||
|
||||
// alternate linear blend between dq1 and dq2
|
||||
DualQuaternion dq4 = dq1 * 0.5 + dq2Alt * 0.5f;
|
||||
|
||||
qDebug() << "dq3 =" << dq3;
|
||||
qDebug() << "dq4 =" << dq4;
|
||||
|
||||
glm::vec3 p1(0.0f, 0.5f, -0.5f);
|
||||
glm::vec3 p2(0.0f, 0.5f, 0.5f);
|
||||
|
||||
glm::vec3 p3 = dq3.xformPoint(p1);
|
||||
glm::vec3 p4 = dq3.xformPoint(p2);
|
||||
glm::vec3 p5 = dq4.xformPoint(p1);
|
||||
glm::vec3 p6 = dq4.xformPoint(p2);
|
||||
|
||||
qDebug() << "p3 =" << p3;
|
||||
qDebug() << "p4 =" << p4;
|
||||
qDebug() << "p5 =" << p5;
|
||||
qDebug() << "p6 =" << p6;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ private slots:
|
|||
void mult();
|
||||
void xform();
|
||||
void trans();
|
||||
void dlb();
|
||||
};
|
||||
|
||||
#endif // hifi_DualQuaternionTests_h
|
||||
|
|
Loading…
Reference in a new issue