mirror of
https://github.com/overte-org/overte.git
synced 2025-04-11 13:42:38 +02:00
Removed eigen dependency, fixed Debug Draw IK Chains
Also, clarified for special case for secondary shoulder joint look-at constraint.
This commit is contained in:
parent
572213daaf
commit
2a45c6d3dc
6 changed files with 21 additions and 141 deletions
20
cmake/externals/eigen/CMakeLists.txt
vendored
20
cmake/externals/eigen/CMakeLists.txt
vendored
|
@ -1,20 +0,0 @@
|
|||
set(EXTERNAL_NAME eigen)
|
||||
|
||||
include(ExternalProject)
|
||||
ExternalProject_Add(
|
||||
${EXTERNAL_NAME}
|
||||
URL http://bitbucket.org/eigen/eigen/get/3.3.4.zip
|
||||
URL_MD5 e337acc279874bc6a56da4d973a723fb
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
LOG_DOWNLOAD 1
|
||||
)
|
||||
|
||||
# Hide this external target (for ide users)
|
||||
set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals")
|
||||
|
||||
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
|
||||
|
||||
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR} CACHE PATH "List of eigen include directories")
|
|
@ -1,26 +0,0 @@
|
|||
#
|
||||
# FindEigen.cmake
|
||||
#
|
||||
# Try to find Eigen include path.
|
||||
# Once done this will define
|
||||
#
|
||||
# EIGEN_INCLUDE_DIRS
|
||||
#
|
||||
# Created on 7/14/2017 by Anthony Thibault
|
||||
# Copyright 2017 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
|
||||
#
|
||||
|
||||
# setup hints for Eigen search
|
||||
include("${MACRO_DIR}/HifiLibrarySearchHints.cmake")
|
||||
hifi_library_search_hints("eigen")
|
||||
|
||||
# locate dir
|
||||
string(CONCAT EIGEN_INCLUDE_DIRS ${EIGEN_INCLUDE_DIRS} "/src/eigen")
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(EIGEN DEFAULT_MSG EIGEN_INCLUDE_DIRS)
|
||||
|
||||
mark_as_advanced(EIGEN_INCLUDE_DIRS EIGEN_SEARCH_DIRS)
|
|
@ -27,9 +27,9 @@ static const int MAX_TARGET_MARKERS = 30;
|
|||
static const float JOINT_CHAIN_INTERP_TIME = 0.25f;
|
||||
|
||||
static void lookupJointInfo(const AnimInverseKinematics::JointChainInfo& jointChainInfo,
|
||||
int indexA, int indexB,
|
||||
const AnimInverseKinematics::JointInfo** jointInfoA,
|
||||
const AnimInverseKinematics::JointInfo** jointInfoB) {
|
||||
int indexA, int indexB,
|
||||
const AnimInverseKinematics::JointInfo** jointInfoA,
|
||||
const AnimInverseKinematics::JointInfo** jointInfoB) {
|
||||
*jointInfoA = nullptr;
|
||||
*jointInfoB = nullptr;
|
||||
for (size_t i = 0; i < jointChainInfo.jointInfoVec.size(); i++) {
|
||||
|
@ -1640,8 +1640,10 @@ void AnimInverseKinematics::debugDrawIKChain(const JointChainInfo& jointChainInf
|
|||
// copy debug joint rotations into the relative poses
|
||||
for (size_t i = 0; i < jointChainInfo.jointInfoVec.size(); i++) {
|
||||
const JointInfo& info = jointChainInfo.jointInfoVec[i];
|
||||
poses[info.jointIndex].rot() = info.rot;
|
||||
poses[info.jointIndex].trans() = info.trans;
|
||||
if (info.jointIndex != _hipsIndex) {
|
||||
poses[info.jointIndex].rot() = info.rot;
|
||||
poses[info.jointIndex].trans() = info.trans;
|
||||
}
|
||||
}
|
||||
|
||||
// convert relative poses to absolute
|
||||
|
@ -1867,9 +1869,19 @@ void AnimInverseKinematics::setSecondaryTargets(const AnimContext& context) {
|
|||
return;
|
||||
}
|
||||
|
||||
// shoulder joint should look-at position of arm joint.
|
||||
// special case for arm secondary poses.
|
||||
// determine if shoulder joint should look-at position of arm joint.
|
||||
bool shoulderShouldLookAtArm = false;
|
||||
const int leftArmIndex = _skeleton->nameToJointIndex("LeftArm");
|
||||
const int rightArmIndex = _skeleton->nameToJointIndex("RightArm");
|
||||
const int leftShoulderIndex = _skeleton->nameToJointIndex("LeftShoulder");
|
||||
const int rightShoulderIndex = _skeleton->nameToJointIndex("RightShoulder");
|
||||
for (auto& iter : _secondaryTargetsInRigFrame) {
|
||||
if (iter.first == leftShoulderIndex || iter.first == rightShoulderIndex) {
|
||||
shoulderShouldLookAtArm = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AnimPose rigToGeometryPose = AnimPose(glm::inverse(context.getGeometryToRigMatrix()));
|
||||
for (auto& iter : _secondaryTargetsInRigFrame) {
|
||||
|
@ -1883,7 +1895,7 @@ void AnimInverseKinematics::setSecondaryTargets(const AnimContext& context) {
|
|||
}
|
||||
|
||||
// if parent should "look-at" child joint position.
|
||||
if (iter.first == leftArmIndex || iter.first == rightArmIndex) {
|
||||
if (shoulderShouldLookAtArm && (iter.first == leftArmIndex || iter.first == rightArmIndex)) {
|
||||
|
||||
AnimPose grandParentAbsPose;
|
||||
int grandParentIndex = _skeleton->getParentIndex(parentIndex);
|
||||
|
@ -1896,7 +1908,7 @@ void AnimInverseKinematics::setSecondaryTargets(const AnimContext& context) {
|
|||
_relativePoses[parentIndex] = grandParentAbsPose.inverse() * parentAbsPose;
|
||||
}
|
||||
|
||||
// AJT: for now ignore translation on secondary poses.
|
||||
// Ignore translation on secondary poses, to prevent them from distorting the skeleton.
|
||||
glm::vec3 origTrans = _relativePoses[iter.first].trans();
|
||||
_relativePoses[iter.first] = parentAbsPose.inverse() * absPose;
|
||||
_relativePoses[iter.first].trans() = origTrans;
|
||||
|
|
|
@ -18,14 +18,9 @@ if (WIN32)
|
|||
include_hifi_library_headers(octree)
|
||||
|
||||
add_dependency_external_projects(OpenVR)
|
||||
add_dependency_external_projects(eigen)
|
||||
|
||||
find_package(OpenVR REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS})
|
||||
target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES})
|
||||
target_link_libraries(${TARGET_NAME} Winmm.lib)
|
||||
|
||||
# header only library
|
||||
find_package(eigen REQUIRED)
|
||||
target_include_directories(${TARGET_NAME} PRIVATE ${EIGEN_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
|
|
@ -35,8 +35,6 @@
|
|||
#include <Plugins/InputConfiguration.h>
|
||||
#include <controllers/StandardControls.h>
|
||||
|
||||
#include <Eigen/Dense>
|
||||
|
||||
extern PoseData _nextSimPoseData;
|
||||
|
||||
vr::IVRSystem* acquireOpenVrSystem();
|
||||
|
@ -287,9 +285,7 @@ static const size_t CONTROLLER_HISTORY_SIZE = 90 * 3;
|
|||
|
||||
ViveControllerManager::InputDevice::InputDevice(vr::IVRSystem*& system) :
|
||||
controller::InputDevice("Vive"),
|
||||
_system(system),
|
||||
_leftControllerHistory(CONTROLLER_HISTORY_SIZE),
|
||||
_rightControllerHistory(CONTROLLER_HISTORY_SIZE) {
|
||||
_system(system) {
|
||||
|
||||
_configStringMap[Config::None] = QString("None");
|
||||
_configStringMap[Config::Feet] = QString("Feet");
|
||||
|
@ -915,16 +911,6 @@ void ViveControllerManager::InputDevice::handlePoseEvent(float deltaTime, const
|
|||
// transform into avatar frame
|
||||
glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat;
|
||||
_poseStateMap[isLeftHand ? controller::LEFT_HAND : controller::RIGHT_HAND] = pose.transform(controllerToAvatar);
|
||||
|
||||
// AJT: TODO ONLY DO THIS IF CALIBRATING!
|
||||
// record controller history
|
||||
if (isLeftHand) {
|
||||
_leftControllerHistory[_leftControllerHistoryCursor] = pose.translation;
|
||||
_leftControllerHistoryCursor = (_leftControllerHistoryCursor + 1) % CONTROLLER_HISTORY_SIZE;
|
||||
} else {
|
||||
_rightControllerHistory[_rightControllerHistoryCursor] = pose.translation;
|
||||
_rightControllerHistoryCursor = (_rightControllerHistoryCursor + 1) % CONTROLLER_HISTORY_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
bool ViveControllerManager::InputDevice::triggerHapticPulse(float strength, float duration, controller::Hand hand) {
|
||||
|
@ -1088,64 +1074,6 @@ void ViveControllerManager::InputDevice::calibrateChest(const glm::mat4& default
|
|||
_pucksPostOffset[_validTrackedObjects[CHEST].first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultSpine2, _validTrackedObjects[CHEST].second);
|
||||
}
|
||||
|
||||
// assuming the user has kept his arms straight to his sides and has rotated his hand controllers
|
||||
// up and down laterally about his shoulders. This will attempt to locate the users actual shoulders
|
||||
// by calculating a best fit circle around the points, in the plane of the head's forward normal.
|
||||
static glm::vec3 computeUserShoulderPositionFromHistory(const glm::mat4& headMat, const std::vector<glm::vec3>& history) {
|
||||
glm::mat4 invHeadMat = glm::inverse(headMat);
|
||||
|
||||
// AJT: TODO: we could perhaps reject the approximation if the radius is larger or smaller then we expect.
|
||||
// AJT: TODO: abort if history is too small or invalid...
|
||||
|
||||
// Take equation for a circle: (x - h)^2 + (y - k)^2 = r^2
|
||||
// And put it into the linear form: A * x = b
|
||||
//
|
||||
// where A = | (2 * x0) (2 * y0) 1 |
|
||||
// | (2 * x1) (2 * y1) 1 |
|
||||
// | . . . |
|
||||
// | (2 * xn) (2 * yn) 1 |
|
||||
//
|
||||
// and b = | x0^2 + y0^2 |
|
||||
// | x1^2 + y1^2 |
|
||||
// | . |
|
||||
// | xn^2 + yn^2 |
|
||||
//
|
||||
// and x = | h |
|
||||
// | k |
|
||||
// | r^2 - h^2 - k^2 |
|
||||
//
|
||||
|
||||
// Build aMat and bMat
|
||||
Eigen::MatrixXf aMat(CONTROLLER_HISTORY_SIZE, 3);
|
||||
Eigen::MatrixXf bMat(CONTROLLER_HISTORY_SIZE, 1);
|
||||
for (int r = 0; r < CONTROLLER_HISTORY_SIZE; r++) {
|
||||
// transform history[r] into local head coordinates
|
||||
glm::vec3 p = transformPoint(invHeadMat, history[r]);
|
||||
|
||||
// update the aMat with the appropriate 2d history values
|
||||
aMat(r, 0) = 2.0f * p.x;
|
||||
aMat(r, 1) = 2.0f * p.y;
|
||||
aMat(r, 2) = 1.0f;
|
||||
|
||||
// update the bMat with the appropriate 2d history values
|
||||
bMat(r, 0) = p.x * p.x + p.y * p.y;
|
||||
}
|
||||
|
||||
// Then use least squares approximation to solve for the best x.
|
||||
// http://math.mit.edu/~gs/linearalgebra/ila0403.pdf
|
||||
Eigen::MatrixXf aTransMat = aMat.transpose();
|
||||
Eigen::MatrixXf xMat = (aTransMat * aMat).inverse() * aTransMat * bMat;
|
||||
|
||||
// extract the 2d center of the circle from the xMat
|
||||
glm::vec3 center(xMat(0, 0), xMat(1, 0), 0.0f);
|
||||
|
||||
// we don't need the radius, but it's included here for completeness.
|
||||
// float radius = center.x * center.x + center.y * center.y - xMat(2, 0);
|
||||
|
||||
// transform center back into sensor coordinates
|
||||
return transformPoint(headMat, center);
|
||||
}
|
||||
|
||||
// y axis comes out of puck usb port/green light
|
||||
// -z axis comes out of puck center/vive logo
|
||||
static glm::vec3 computeUserShoulderPositionFromMeasurements(float armCirc, float shoulderSpan, const glm::mat4& headMat, const controller::Pose& armPuck, bool isLeftHand) {
|
||||
|
@ -1176,10 +1104,6 @@ void ViveControllerManager::InputDevice::calibrateShoulders(const glm::mat4& def
|
|||
glm::mat4 userRefRightArm = refRightArm;
|
||||
|
||||
glm::mat4 headMat = defaultToReferenceMat * inputCalibration.defaultHeadMat;
|
||||
/* AJT: TODO REMOVE
|
||||
userRefLeftArm[3] = glm::vec4(computeUserShoulderPositionFromHistory(headMat, _leftControllerHistory), 1.0f);
|
||||
userRefRightArm[3] = glm::vec4(computeUserShoulderPositionFromHistory(headMat, _rightControllerHistory), 1.0f);
|
||||
*/
|
||||
|
||||
if (firstShoulderPose.translation.x < secondShoulderPose.translation.x) {
|
||||
_jointToPuckMap[controller::LEFT_ARM] = firstShoulder.first;
|
||||
|
|
|
@ -192,11 +192,6 @@ private:
|
|||
bool _overrideHands { false };
|
||||
mutable std::recursive_mutex _lock;
|
||||
|
||||
std::vector<glm::vec3> _leftControllerHistory;
|
||||
size_t _leftControllerHistoryCursor { 0 };
|
||||
std::vector<glm::vec3> _rightControllerHistory;
|
||||
size_t _rightControllerHistoryCursor { 0 };
|
||||
|
||||
QString configToString(Config config);
|
||||
friend class ViveControllerManager;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue