diff --git a/libraries/render-utils/src/Skinning.slh b/libraries/render-utils/src/Skinning.slh index ddcdd2c71f..49d0df3d2c 100644 --- a/libraries/render-utils/src/Skinning.slh +++ b/libraries/render-utils/src/Skinning.slh @@ -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)); diff --git a/libraries/shared/src/DualQuaternion.cpp b/libraries/shared/src/DualQuaternion.cpp index 03628f8aba..2accbed2a9 100644 --- a/libraries/shared/src/DualQuaternion.cpp +++ b/libraries/shared/src/DualQuaternion.cpp @@ -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); } diff --git a/libraries/shared/src/DualQuaternion.h b/libraries/shared/src/DualQuaternion.h index 508570a930..709c089fdc 100644 --- a/libraries/shared/src/DualQuaternion.h +++ b/libraries/shared/src/DualQuaternion.h @@ -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; } diff --git a/tests/shared/src/DualQuaternionTests.cpp b/tests/shared/src/DualQuaternionTests.cpp index 1c34bfbee7..fe14d9d166 100644 --- a/tests/shared/src/DualQuaternionTests.cpp +++ b/tests/shared/src/DualQuaternionTests.cpp @@ -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; -} diff --git a/tests/shared/src/DualQuaternionTests.h b/tests/shared/src/DualQuaternionTests.h index 988973b689..aa4b40cfd6 100644 --- a/tests/shared/src/DualQuaternionTests.h +++ b/tests/shared/src/DualQuaternionTests.h @@ -20,7 +20,6 @@ private slots: void mult(); void xform(); void trans(); - void dlb(); }; #endif // hifi_DualQuaternionTests_h