overte/interface/src/devices/MotionTracker.cpp
2017-04-28 16:34:54 -07:00

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