Renamed imag component to dual, using the correct nomenclature

Also removed incomplete test from unit tests.
This commit is contained in:
Anthony J. Thibault 2018-01-08 18:21:23 -08:00
parent d08f94a74d
commit fbea22e0f0
5 changed files with 40 additions and 73 deletions

View file

@ -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));

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -20,7 +20,6 @@ private slots:
void mult();
void xform();
void trans();
void dlb();
};
#endif // hifi_DualQuaternionTests_h