mirror of
https://github.com/overte-org/overte.git
synced 2025-05-13 16:09:28 +02:00
92 lines
2.9 KiB
C++
92 lines
2.9 KiB
C++
//
|
|
// DualQuaternion.cpp
|
|
//
|
|
// Created by Anthony J. Thibault on Dec 13th 2017.
|
|
// Copyright (c) 2017 High Fidelity, Inc. All rights reserved.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include "DualQuaternion.h"
|
|
#include "GLMHelpers.h"
|
|
|
|
// delegating constructor
|
|
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& dual) : _real(real), _dual(dual) {
|
|
}
|
|
|
|
DualQuaternion::DualQuaternion(const glm::vec4& real, const glm::vec4& dual) :
|
|
_real(real.w, real.x, real.y, real.z),
|
|
_dual(dual.w, dual.x, dual.y, dual.z) {
|
|
}
|
|
|
|
DualQuaternion::DualQuaternion(const glm::quat& rotation, const glm::vec3& translation) {
|
|
_real = 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._dual + _dual * rhs._real);
|
|
}
|
|
|
|
DualQuaternion DualQuaternion::operator*(float scalar) const {
|
|
return DualQuaternion(_real * scalar, _dual * scalar);
|
|
}
|
|
|
|
DualQuaternion DualQuaternion::operator+(const DualQuaternion& rhs) const {
|
|
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(_dual));
|
|
DualQuaternion result = *this * v * dualConj;
|
|
return vec3(result._dual.x, result._dual.y, result._dual.z);
|
|
}
|
|
|
|
glm::quat DualQuaternion::getRotation() const {
|
|
return _real;
|
|
}
|
|
|
|
glm::vec3 DualQuaternion::getTranslation() const {
|
|
glm::quat result = 2.0f * (_dual * glm::inverse(_real));
|
|
return glm::vec3(result.x, result.y, result.z);
|
|
}
|
|
|
|
glm::vec3 DualQuaternion::xformVector(const glm::vec3& rhs) const {
|
|
return _real * rhs;
|
|
}
|
|
|
|
DualQuaternion DualQuaternion::inverse() const {
|
|
glm::quat invReal = glm::inverse(_real);
|
|
return DualQuaternion(invReal, - invReal * _dual * invReal);
|
|
}
|
|
|
|
DualQuaternion DualQuaternion::conjugate() const {
|
|
return DualQuaternion(glm::conjugate(_real), glm::conjugate(_dual));
|
|
}
|
|
|
|
float DualQuaternion::length() const {
|
|
float dot = this->dot(*this);
|
|
return sqrtf(dot);
|
|
}
|
|
|
|
DualQuaternion DualQuaternion::normalize() const {
|
|
float invLen = 1.0f / length();
|
|
return *this * invLen;
|
|
}
|
|
|
|
float DualQuaternion::dot(const DualQuaternion& rhs) const {
|
|
DualQuaternion result = *this * conjugate();
|
|
return result._real.w;
|
|
}
|
|
|
|
DualQuaternion DualQuaternion::operator-() const {
|
|
return DualQuaternion(-_real, -_dual);
|
|
}
|