mirror of
https://github.com/overte-org/overte.git
synced 2025-06-18 07:40:09 +02:00
186 lines
5.3 KiB
C++
186 lines
5.3 KiB
C++
//
|
|
// Created by Sam Cake on 6/20/14.
|
|
// Copyright 2014 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#include "MotionTracker.h"
|
|
|
|
// glm::mult(mat43, mat43) just the composition of the 2 matrices assuming they are in fact mat44 with the last raw = { 0, 0, 0, 1 }
|
|
namespace glm {
|
|
mat4x3 mult(const mat4& lhs, const mat4x3& rhs) {
|
|
vec3 lrx(lhs[0].x, lhs[1].x, lhs[2].x);
|
|
vec3 lry(lhs[0].y, lhs[1].y, lhs[2].y);
|
|
vec3 lrz(lhs[0].z, lhs[1].z, lhs[2].z);
|
|
return mat4x3(
|
|
dot(lrx, rhs[0]),
|
|
dot(lry, rhs[0]),
|
|
dot(lrz, rhs[0]),
|
|
|
|
dot(lrx, rhs[1]),
|
|
dot(lry, rhs[1]),
|
|
dot(lrz, rhs[1]),
|
|
|
|
dot(lrx, rhs[2]),
|
|
dot(lry, rhs[2]),
|
|
dot(lrz, rhs[2]),
|
|
|
|
dot(lrx, rhs[3]) + lhs[3].x,
|
|
dot(lry, rhs[3]) + lhs[3].y,
|
|
dot(lrz, rhs[3]) + lhs[3].z
|
|
);
|
|
}
|
|
mat4x3 mult(const mat4x3& lhs, const mat4x3& rhs) {
|
|
vec3 lrx(lhs[0].x, lhs[1].x, lhs[2].x);
|
|
vec3 lry(lhs[0].y, lhs[1].y, lhs[2].y);
|
|
vec3 lrz(lhs[0].z, lhs[1].z, lhs[2].z);
|
|
return mat4x3(
|
|
dot(lrx, rhs[0]),
|
|
dot(lry, rhs[0]),
|
|
dot(lrz, rhs[0]),
|
|
|
|
dot(lrx, rhs[1]),
|
|
dot(lry, rhs[1]),
|
|
dot(lrz, rhs[1]),
|
|
|
|
dot(lrx, rhs[2]),
|
|
dot(lry, rhs[2]),
|
|
dot(lrz, rhs[2]),
|
|
|
|
dot(lrx, rhs[3]) + lhs[3].x,
|
|
dot(lry, rhs[3]) + lhs[3].y,
|
|
dot(lrz, rhs[3]) + lhs[3].z
|
|
);
|
|
}
|
|
}
|
|
|
|
// MotionTracker
|
|
MotionTracker::MotionTracker() :
|
|
DeviceTracker()
|
|
{
|
|
_jointsArray.resize(1);
|
|
_jointsMap.insert(JointTracker::Map::value_type(Semantic("Root"), 0));
|
|
}
|
|
|
|
MotionTracker::~MotionTracker()
|
|
{
|
|
}
|
|
|
|
bool MotionTracker::isConnected() const {
|
|
return false;
|
|
}
|
|
|
|
MotionTracker::Index MotionTracker::addJoint(const Semantic& semantic, Index parent) {
|
|
// Check the parent
|
|
if (int(parent) < 0)
|
|
return INVALID_PARENT;
|
|
|
|
// Check that the semantic is not already in use
|
|
Index foundIndex = findJointIndex(semantic);
|
|
if (foundIndex >= 0) {
|
|
return INVALID_SEMANTIC;
|
|
}
|
|
|
|
|
|
// All good then allocate the joint
|
|
Index newIndex = (Index)_jointsArray.size();
|
|
_jointsArray.push_back(JointTracker(semantic, parent));
|
|
_jointsMap.insert(JointTracker::Map::value_type(semantic, newIndex));
|
|
|
|
return newIndex;
|
|
}
|
|
|
|
MotionTracker::Index MotionTracker::findJointIndex(const Semantic& semantic) const {
|
|
// TODO C++11 auto jointIt = _jointsMap.find(semantic);
|
|
JointTracker::Map::const_iterator jointIt = _jointsMap.find(semantic);
|
|
if (jointIt != _jointsMap.end()) {
|
|
return (*jointIt).second;
|
|
}
|
|
|
|
return INVALID_SEMANTIC;
|
|
}
|
|
|
|
void MotionTracker::updateAllAbsTransform() {
|
|
_jointsArray[0].updateAbsFromLocTransform(0);
|
|
|
|
// Because we know the hierarchy is stored from root down the branches let's just traverse and update
|
|
for (Index i = 1; i < (Index)(_jointsArray.size()); i++) {
|
|
JointTracker* joint = _jointsArray.data() + i;
|
|
joint->updateAbsFromLocTransform(_jointsArray.data() + joint->getParent());
|
|
}
|
|
}
|
|
|
|
|
|
// MotionTracker::JointTracker
|
|
MotionTracker::JointTracker::JointTracker() :
|
|
_locFrame(),
|
|
_absFrame(),
|
|
_semantic(""),
|
|
_parent(INVALID_PARENT),
|
|
_lastUpdate(1) // Joint inactive
|
|
{
|
|
}
|
|
|
|
MotionTracker::JointTracker::JointTracker(const Semantic& semantic, Index parent) :
|
|
_semantic(semantic),
|
|
_parent(parent),
|
|
_lastUpdate(1) // Joint inactive
|
|
{
|
|
}
|
|
|
|
MotionTracker::JointTracker::JointTracker(const JointTracker& tracker) :
|
|
_locFrame(tracker._locFrame),
|
|
_absFrame(tracker._absFrame),
|
|
_semantic(tracker._semantic),
|
|
_parent(tracker._parent),
|
|
_lastUpdate(tracker._lastUpdate)
|
|
{
|
|
}
|
|
|
|
void MotionTracker::JointTracker::updateAbsFromLocTransform(const JointTracker* parentJoint) {
|
|
if (parentJoint) {
|
|
editAbsFrame()._transform = (parentJoint->getAbsFrame()._transform * getLocFrame()._transform);
|
|
} else {
|
|
editAbsFrame()._transform = getLocFrame()._transform;
|
|
}
|
|
}
|
|
|
|
void MotionTracker::JointTracker::updateLocFromAbsTransform(const JointTracker* parentJoint) {
|
|
if (parentJoint) {
|
|
glm::mat4 ip = glm::inverse(parentJoint->getAbsFrame()._transform);
|
|
editLocFrame()._transform = (ip * getAbsFrame()._transform);
|
|
} else {
|
|
editLocFrame()._transform = getAbsFrame()._transform;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------
|
|
// MotionTracker::Frame
|
|
//--------------------------------------------------------------------------------------
|
|
|
|
MotionTracker::Frame::Frame() :
|
|
_transform()
|
|
{
|
|
}
|
|
|
|
void MotionTracker::Frame::setRotation(const glm::quat& rotation) {
|
|
glm::mat3x3 rot = glm::mat3_cast(rotation);
|
|
_transform[0] = glm::vec4(rot[0], 0.0f);
|
|
_transform[1] = glm::vec4(rot[1], 0.0f);
|
|
_transform[2] = glm::vec4(rot[2], 0.0f);
|
|
}
|
|
|
|
void MotionTracker::Frame::getRotation(glm::quat& rotation) const {
|
|
rotation = glm::quat_cast(_transform);
|
|
}
|
|
|
|
void MotionTracker::Frame::setTranslation(const glm::vec3& translation) {
|
|
_transform[3] = glm::vec4(translation, 1.0f);
|
|
}
|
|
|
|
void MotionTracker::Frame::getTranslation(glm::vec3& translation) const {
|
|
translation = extractTranslation(_transform);
|
|
}
|
|
|