mirror of
https://github.com/overte-org/overte.git
synced 2025-08-03 23:43:30 +02:00
Skeleton removal checkpoint; compiles, but there are a few bits missing.
This commit is contained in:
parent
7be1d4d8c0
commit
2c7b6b9696
13 changed files with 25 additions and 587 deletions
|
@ -2349,7 +2349,7 @@ void Application::updateTransmitter(float deltaTime) {
|
|||
|
||||
// no transmitter drive implies transmitter pick
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _myTransmitter.isConnected()) {
|
||||
_transmitterPickStart = _myAvatar.getSkeleton().joint[AVATAR_JOINT_CHEST].position;
|
||||
_transmitterPickStart = _myAvatar.getChestJointPosition();
|
||||
glm::vec3 direction = _myAvatar.getOrientation() *
|
||||
glm::quat(glm::radians(_myTransmitter.getEstimatedRotation())) * IDENTITY_FRONT;
|
||||
|
||||
|
|
|
@ -772,4 +772,4 @@ void Audio::renderToolIcon(int screenHeight) {
|
|||
}
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -383,13 +383,6 @@ Menu::Menu() :
|
|||
|
||||
|
||||
QMenu* trackingOptionsMenu = developerMenu->addMenu("Tracking Options");
|
||||
addCheckableActionToQMenuAndActionHash(trackingOptionsMenu,
|
||||
MenuOption::SkeletonTracking,
|
||||
0,
|
||||
false,
|
||||
appInstance->getWebcam(),
|
||||
SLOT(setSkeletonTrackingOn(bool)));
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(trackingOptionsMenu,
|
||||
MenuOption::LEDTracking,
|
||||
0,
|
||||
|
|
|
@ -246,7 +246,6 @@ namespace MenuOption {
|
|||
const QString SimulateLeapHand = "Simulate Leap Hand";
|
||||
const QString VoxelDrumming = "Voxel Drumming";
|
||||
const QString PlaySlaps = "Play Slaps";
|
||||
const QString SkeletonTracking = "Skeleton Tracking";
|
||||
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
||||
const QString LEDTracking = "LED Tracking";
|
||||
const QString Stars = "Stars";
|
||||
|
|
|
@ -97,9 +97,7 @@ Avatar::Avatar(Node* owningNode) :
|
|||
_isCollisionsOn(true),
|
||||
_moving(false),
|
||||
_initialized(false),
|
||||
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
||||
_maxArmLength(0.0f),
|
||||
_pelvisStandingHeight(0.0f)
|
||||
_handHoldingPosition(0.0f, 0.0f, 0.0f)
|
||||
{
|
||||
// we may have been created in the network thread, but we live in the main thread
|
||||
moveToThread(Application::getInstance()->thread());
|
||||
|
@ -108,14 +106,10 @@ Avatar::Avatar(Node* owningNode) :
|
|||
_headData = &_head;
|
||||
_handData = &_hand;
|
||||
|
||||
_skeleton.initialize();
|
||||
|
||||
_height = _skeleton.getHeight();
|
||||
_height = 0.0f; // _skeleton.getHeight();
|
||||
|
||||
_maxArmLength = _skeleton.getArmLength();
|
||||
_pelvisStandingHeight = _skeleton.getPelvisStandingHeight();
|
||||
_pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight();
|
||||
_pelvisToHeadLength = _skeleton.getPelvisToHeadLength();
|
||||
_pelvisFloatingHeight = 0.0f; // _skeleton.getPelvisFloatingHeight();
|
||||
_pelvisToHeadLength = 0.0f; // _skeleton.getPelvisToHeadLength();
|
||||
|
||||
}
|
||||
|
||||
|
@ -153,22 +147,6 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
// copy velocity so we can use it later for acceleration
|
||||
glm::vec3 oldVelocity = getVelocity();
|
||||
|
||||
// update torso rotation based on head lean
|
||||
_skeleton.joint[AVATAR_JOINT_TORSO].rotation = glm::quat(glm::radians(glm::vec3(
|
||||
_head.getLeanForward(), 0.0f, _head.getLeanSideways())));
|
||||
|
||||
// apply joint data (if any) to skeleton
|
||||
bool enableHandMovement = true;
|
||||
for (vector<JointData>::iterator it = _joints.begin(); it != _joints.end(); it++) {
|
||||
_skeleton.joint[it->jointID].rotation = it->rotation;
|
||||
|
||||
// disable hand movement if we have joint info for the right wrist
|
||||
enableHandMovement &= (it->jointID != AVATAR_JOINT_RIGHT_WRIST);
|
||||
}
|
||||
|
||||
// update avatar skeleton
|
||||
_skeleton.update(deltaTime, getOrientation(), _position);
|
||||
|
||||
_hand.simulate(deltaTime, false);
|
||||
_skeletonModel.simulate(deltaTime);
|
||||
_head.setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
|
||||
|
@ -444,13 +422,9 @@ void Avatar::setScale(const float scale) {
|
|||
_scale = _targetScale;
|
||||
}
|
||||
|
||||
_skeleton.setScale(_scale);
|
||||
_height = 0.0f; // _skeleton.getHeight();
|
||||
|
||||
_height = _skeleton.getHeight();
|
||||
|
||||
_maxArmLength = _skeleton.getArmLength();
|
||||
_pelvisStandingHeight = _skeleton.getPelvisStandingHeight();
|
||||
_pelvisFloatingHeight = _skeleton.getPelvisFloatingHeight();
|
||||
_pelvisToHeadLength = _skeleton.getPelvisToHeadLength();
|
||||
_pelvisFloatingHeight = 0.0f; // _skeleton.getPelvisFloatingHeight();
|
||||
_pelvisToHeadLength = 0.0f; // _skeleton.getPelvisToHeadLength();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "Hand.h"
|
||||
#include "Head.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "Skeleton.h"
|
||||
#include "SkeletonModel.h"
|
||||
#include "world.h"
|
||||
#include "devices/Transmitter.h"
|
||||
|
@ -142,11 +141,10 @@ public:
|
|||
|
||||
//getters
|
||||
bool isInitialized() const { return _initialized; }
|
||||
const Skeleton& getSkeleton() const { return _skeleton; }
|
||||
SkeletonModel& getSkeletonModel() { return _skeletonModel; }
|
||||
float getHeadYawRate() const { return _head.yawRate; }
|
||||
const glm::vec3& getHeadJointPosition() const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].position; }
|
||||
const glm::vec3& getChestJointPosition() const { return _skeleton.joint[ AVATAR_JOINT_CHEST ].position; }
|
||||
const glm::vec3& getHeadJointPosition() const { return _position; }
|
||||
const glm::vec3& getChestJointPosition() const { return _position; }
|
||||
float getScale() const { return _scale; }
|
||||
const glm::vec3& getVelocity() const { return _velocity; }
|
||||
Head& getHead() { return _head; }
|
||||
|
@ -182,23 +180,8 @@ public slots:
|
|||
|
||||
|
||||
protected:
|
||||
struct AvatarBall {
|
||||
AvatarJointID parentJoint; /// the skeletal joint that serves as a reference for determining the position
|
||||
glm::vec3 parentOffset; /// a 3D vector in the frame of reference of the parent skeletal joint
|
||||
AvatarBodyBallID parentBall; /// the ball to which this ball is constrained for spring forces
|
||||
glm::vec3 position; /// the actual dynamic position of the ball at any given time
|
||||
glm::quat rotation; /// the rotation of the ball
|
||||
glm::vec3 velocity; /// the velocity of the ball
|
||||
float springLength; /// the ideal length of the spring between this ball and its parentBall
|
||||
float jointTightness; /// how tightly the ball position attempts to stay at its ideal position (determined by parentOffset)
|
||||
float radius; /// the radius of the ball
|
||||
bool isCollidable; /// whether or not the ball responds to collisions
|
||||
float touchForce; /// a scalar determining the amount that the cursor (or hand) is penetrating the ball
|
||||
};
|
||||
|
||||
Head _head;
|
||||
Hand _hand;
|
||||
Skeleton _skeleton;
|
||||
SkeletonModel _skeletonModel;
|
||||
bool _ballSpringsInitialized;
|
||||
float _bodyYawDelta;
|
||||
|
@ -234,8 +217,6 @@ private:
|
|||
|
||||
bool _initialized;
|
||||
glm::vec3 _handHoldingPosition;
|
||||
float _maxArmLength;
|
||||
float _pelvisStandingHeight;
|
||||
|
||||
|
||||
// private methods...
|
||||
|
|
|
@ -24,22 +24,18 @@ void FaceModel::simulate(float deltaTime) {
|
|||
}
|
||||
Avatar* owningAvatar = static_cast<Avatar*>(_owningHead->_owningAvatar);
|
||||
glm::vec3 neckPosition;
|
||||
glm::vec3 modelTranslation;
|
||||
if (!owningAvatar->getSkeletonModel().getNeckPosition(neckPosition)) {
|
||||
neckPosition = owningAvatar->getSkeleton().joint[AVATAR_JOINT_NECK_BASE].position;
|
||||
const glm::vec3 OLD_SKELETON_MODEL_TRANSLATION(0.0f, -60.0f, 40.0f);
|
||||
modelTranslation = OLD_SKELETON_MODEL_TRANSLATION;
|
||||
neckPosition = owningAvatar->getPosition();
|
||||
}
|
||||
setTranslation(neckPosition);
|
||||
glm::quat neckRotation;
|
||||
if (!owningAvatar->getSkeletonModel().getNeckRotation(neckRotation)) {
|
||||
neckRotation = owningAvatar->getSkeleton().joint[AVATAR_JOINT_NECK_BASE].absoluteRotation *
|
||||
glm::angleAxis(180.0f, 0.0f, 1.0f, 0.0f);
|
||||
neckRotation = owningAvatar->getOrientation();
|
||||
}
|
||||
setRotation(neckRotation);
|
||||
const float MODEL_SCALE = 0.0006f;
|
||||
setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningHead->getScale() * MODEL_SCALE);
|
||||
setOffset(modelTranslation - _geometry->getFBXGeometry().neckPivot);
|
||||
setOffset(-_geometry->getFBXGeometry().neckPivot);
|
||||
|
||||
setPupilDilation(_owningHead->getPupilDilation());
|
||||
setBlendshapeCoefficients(_owningHead->getBlendshapeCoefficients());
|
||||
|
|
|
@ -102,21 +102,8 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
// calculate speed
|
||||
_speed = glm::length(_velocity);
|
||||
|
||||
// update torso rotation based on head lean
|
||||
_skeleton.joint[AVATAR_JOINT_TORSO].rotation = glm::quat(glm::radians(glm::vec3(
|
||||
_head.getLeanForward(), 0.0f, _head.getLeanSideways())));
|
||||
|
||||
// apply joint data (if any) to skeleton
|
||||
bool enableHandMovement = true;
|
||||
for (vector<JointData>::iterator it = _joints.begin(); it != _joints.end(); it++) {
|
||||
_skeleton.joint[it->jointID].rotation = it->rotation;
|
||||
|
||||
// disable hand movement if we have joint info for the right wrist
|
||||
enableHandMovement &= (it->jointID != AVATAR_JOINT_RIGHT_WRIST);
|
||||
}
|
||||
|
||||
// update the movement of the hand and process handshaking with other avatars...
|
||||
updateHandMovementAndTouching(deltaTime, enableHandMovement);
|
||||
updateHandMovementAndTouching(deltaTime);
|
||||
|
||||
// apply gravity
|
||||
// For gravity, always move the avatar by the amount driven by gravity, so that the collision
|
||||
|
@ -267,7 +254,6 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
_position += _velocity * deltaTime;
|
||||
|
||||
// update avatar skeleton and simulate hand and head
|
||||
_skeleton.update(deltaTime, getOrientation(), _position);
|
||||
_hand.simulate(deltaTime, true);
|
||||
_skeletonModel.simulate(deltaTime);
|
||||
_head.setBodyRotation(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll));
|
||||
|
@ -331,21 +317,6 @@ void MyAvatar::updateFromGyrosAndOrWebcam(bool turnWithHead) {
|
|||
|
||||
// apply face data
|
||||
_head.getVideoFace().setFrameFromWebcam();
|
||||
|
||||
// compute and store the joint rotations
|
||||
const JointVector& joints = webcam->getEstimatedJoints();
|
||||
_joints.clear();
|
||||
for (int i = 0; i < NUM_AVATAR_JOINTS; i++) {
|
||||
if (joints.size() > i && joints[i].isValid) {
|
||||
JointData data = { i, joints[i].rotation };
|
||||
_joints.push_back(data);
|
||||
|
||||
if (i == AVATAR_JOINT_CHEST) {
|
||||
// if we have a chest rotation, don't apply lean based on head
|
||||
estimatedPosition = glm::vec3();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_head.getVideoFace().clearFrame();
|
||||
}
|
||||
|
@ -547,12 +518,6 @@ glm::vec3 MyAvatar::getUprightHeadPosition() const {
|
|||
return _position + getWorldAlignedOrientation() * glm::vec3(0.0f, _pelvisToHeadLength, 0.0f);
|
||||
}
|
||||
|
||||
glm::vec3 MyAvatar::getEyeLevelPosition() const {
|
||||
const float EYE_UP_OFFSET = 0.36f;
|
||||
return _position + getWorldAlignedOrientation() * _skeleton.joint[AVATAR_JOINT_TORSO].rotation *
|
||||
glm::vec3(0.0f, _pelvisToHeadLength + _scale * BODY_BALL_RADIUS_HEAD_BASE * EYE_UP_OFFSET, 0.0f);
|
||||
}
|
||||
|
||||
void MyAvatar::renderBody(bool forceRenderHead) {
|
||||
|
||||
if (_head.getVideoFace().isFullFrame()) {
|
||||
|
@ -690,7 +655,7 @@ void MyAvatar::updateThrust(float deltaTime, Transmitter * transmitter) {
|
|||
_isThrustOn = (glm::length(_thrust) > EPSILON);
|
||||
}
|
||||
|
||||
void MyAvatar::updateHandMovementAndTouching(float deltaTime, bool enableHandMovement) {
|
||||
void MyAvatar::updateHandMovementAndTouching(float deltaTime) {
|
||||
|
||||
glm::quat orientation = getOrientation();
|
||||
|
||||
|
@ -698,7 +663,7 @@ void MyAvatar::updateHandMovementAndTouching(float deltaTime, bool enableHandMov
|
|||
glm::vec3 up = orientation * IDENTITY_UP;
|
||||
|
||||
bool pointing = false;
|
||||
if (enableHandMovement && glm::length(_mouseRayDirection) > EPSILON && !Application::getInstance()->isMouseHidden()) {
|
||||
if (glm::length(_mouseRayDirection) > EPSILON && !Application::getInstance()->isMouseHidden()) {
|
||||
// confine to the approximate shoulder plane
|
||||
glm::vec3 pointDirection = _mouseRayDirection;
|
||||
if (glm::dot(_mouseRayDirection, up) > 0.0f) {
|
||||
|
|
|
@ -53,7 +53,6 @@ public:
|
|||
const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; }
|
||||
glm::vec3 getGravity() const { return _gravity; }
|
||||
glm::vec3 getUprightHeadPosition() const;
|
||||
glm::vec3 getEyeLevelPosition() const;
|
||||
|
||||
// get/set avatar data
|
||||
void saveData(QSettings* settings);
|
||||
|
@ -92,7 +91,7 @@ private:
|
|||
// private methods
|
||||
void renderBody(bool forceRenderHead);
|
||||
void updateThrust(float deltaTime, Transmitter * transmitter);
|
||||
void updateHandMovementAndTouching(float deltaTime, bool enableHandMovement);
|
||||
void updateHandMovementAndTouching(float deltaTime);
|
||||
void updateAvatarCollisions(float deltaTime);
|
||||
void updateCollisionWithEnvironment(float deltaTime);
|
||||
void updateCollisionWithVoxels(float deltaTime);
|
||||
|
|
|
@ -1,201 +0,0 @@
|
|||
//
|
||||
// Skeleton.cpp
|
||||
// interface
|
||||
//
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
|
||||
#include "Skeleton.h"
|
||||
#include "Util.h"
|
||||
#include "world.h"
|
||||
|
||||
const float BODY_SPRING_DEFAULT_TIGHTNESS = 1000.0f;
|
||||
const float FLOATING_HEIGHT = 0.13f;
|
||||
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_PELVIS = glm::vec3(0.0, 0.0, 0.0 );
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_TORSO = glm::vec3( 0.0, 0.09, -0.01);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_CHEST = glm::vec3( 0.0, 0.09, -0.01);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_NECK_BASE = glm::vec3( 0.0, 0.14, 0.01);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_HEAD_BASE = glm::vec3( 0.0, 0.04, 0.00);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_HEAD_TOP = glm::vec3( 0.0, 0.04, 0.00);
|
||||
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_LEFT_COLLAR = glm::vec3(-0.06, 0.04, 0.01);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_LEFT_SHOULDER = glm::vec3(-0.05, 0.0 , 0.01);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_LEFT_ELBOW = glm::vec3(-0.16, 0.0 , 0.0 );
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_LEFT_WRIST = glm::vec3(-0.12, 0.0 , 0.0 );
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_LEFT_FINGERTIPS = glm::vec3(-0.1, 0.0 , 0.0 );
|
||||
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_RIGHT_COLLAR = glm::vec3( 0.06, 0.04, 0.01);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_RIGHT_SHOULDER = glm::vec3( 0.05, 0.0 , 0.01);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_RIGHT_ELBOW = glm::vec3( 0.16, 0.0 , 0.0 );
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_RIGHT_WRIST = glm::vec3( 0.12, 0.0 , 0.0 );
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_RIGHT_FINGERTIPS = glm::vec3( 0.1, 0.0 , 0.0 );
|
||||
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_LEFT_HIP = glm::vec3(-0.05, 0.0 , 0.02);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_LEFT_KNEE = glm::vec3( 0.00, -0.25, 0.00);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_LEFT_HEEL = glm::vec3( 0.00, -0.23, 0.00);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_LEFT_TOES = glm::vec3( 0.00, 0.00, -0.06);
|
||||
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_RIGHT_HIP = glm::vec3( 0.05, 0.0 , 0.02);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_RIGHT_KNEE = glm::vec3( 0.00, -0.25, 0.00);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_RIGHT_HEEL = glm::vec3( 0.00, -0.23, 0.00);
|
||||
const glm::vec3 AVATAR_JOINT_POSITION_RIGHT_TOES = glm::vec3( 0.00, 0.00, -0.06);
|
||||
|
||||
Skeleton::Skeleton() : _floatingHeight(FLOATING_HEIGHT){
|
||||
}
|
||||
|
||||
void Skeleton::initialize() {
|
||||
|
||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||
joint[b].parent = AVATAR_JOINT_NULL;
|
||||
joint[b].position = glm::vec3(0.0, 0.0, 0.0);
|
||||
joint[b].rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
joint[b].length = 0.0;
|
||||
joint[b].bindRadius = 1.0f / 8;
|
||||
}
|
||||
|
||||
// put the arms at the side
|
||||
joint[AVATAR_JOINT_LEFT_ELBOW].rotation = glm::quat(glm::vec3(0.0f, 0.0f, PIf * 0.5f));
|
||||
joint[AVATAR_JOINT_RIGHT_ELBOW].rotation = glm::quat(glm::vec3(0.0f, 0.0f, -PIf * 0.5f));
|
||||
|
||||
// bend the knees
|
||||
joint[AVATAR_JOINT_LEFT_KNEE].rotation = joint[AVATAR_JOINT_RIGHT_KNEE].rotation =
|
||||
glm::quat(glm::vec3(PIf / 8.0f, 0.0f, 0.0f));
|
||||
joint[AVATAR_JOINT_LEFT_HEEL].rotation = joint[AVATAR_JOINT_RIGHT_HEEL].rotation =
|
||||
glm::quat(glm::vec3(-PIf / 4.0f, 0.0f, 0.0f));
|
||||
|
||||
// specify the parental hierarchy
|
||||
joint[ AVATAR_JOINT_PELVIS ].parent = AVATAR_JOINT_NULL;
|
||||
joint[ AVATAR_JOINT_TORSO ].parent = AVATAR_JOINT_PELVIS;
|
||||
joint[ AVATAR_JOINT_CHEST ].parent = AVATAR_JOINT_TORSO;
|
||||
joint[ AVATAR_JOINT_NECK_BASE ].parent = AVATAR_JOINT_CHEST;
|
||||
joint[ AVATAR_JOINT_HEAD_BASE ].parent = AVATAR_JOINT_NECK_BASE;
|
||||
joint[ AVATAR_JOINT_HEAD_TOP ].parent = AVATAR_JOINT_HEAD_BASE;
|
||||
joint[ AVATAR_JOINT_LEFT_COLLAR ].parent = AVATAR_JOINT_CHEST;
|
||||
joint[ AVATAR_JOINT_LEFT_SHOULDER ].parent = AVATAR_JOINT_LEFT_COLLAR;
|
||||
joint[ AVATAR_JOINT_LEFT_ELBOW ].parent = AVATAR_JOINT_LEFT_SHOULDER;
|
||||
joint[ AVATAR_JOINT_LEFT_WRIST ].parent = AVATAR_JOINT_LEFT_ELBOW;
|
||||
joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].parent = AVATAR_JOINT_LEFT_WRIST;
|
||||
joint[ AVATAR_JOINT_RIGHT_COLLAR ].parent = AVATAR_JOINT_CHEST;
|
||||
joint[ AVATAR_JOINT_RIGHT_SHOULDER ].parent = AVATAR_JOINT_RIGHT_COLLAR;
|
||||
joint[ AVATAR_JOINT_RIGHT_ELBOW ].parent = AVATAR_JOINT_RIGHT_SHOULDER;
|
||||
joint[ AVATAR_JOINT_RIGHT_WRIST ].parent = AVATAR_JOINT_RIGHT_ELBOW;
|
||||
joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].parent = AVATAR_JOINT_RIGHT_WRIST;
|
||||
joint[ AVATAR_JOINT_LEFT_HIP ].parent = AVATAR_JOINT_PELVIS;
|
||||
joint[ AVATAR_JOINT_LEFT_KNEE ].parent = AVATAR_JOINT_LEFT_HIP;
|
||||
joint[ AVATAR_JOINT_LEFT_HEEL ].parent = AVATAR_JOINT_LEFT_KNEE;
|
||||
joint[ AVATAR_JOINT_LEFT_TOES ].parent = AVATAR_JOINT_LEFT_HEEL;
|
||||
joint[ AVATAR_JOINT_RIGHT_HIP ].parent = AVATAR_JOINT_PELVIS;
|
||||
joint[ AVATAR_JOINT_RIGHT_KNEE ].parent = AVATAR_JOINT_RIGHT_HIP;
|
||||
joint[ AVATAR_JOINT_RIGHT_HEEL ].parent = AVATAR_JOINT_RIGHT_KNEE;
|
||||
joint[ AVATAR_JOINT_RIGHT_TOES ].parent = AVATAR_JOINT_RIGHT_HEEL;
|
||||
|
||||
setScale(1.0f);
|
||||
}
|
||||
|
||||
void Skeleton::setScale(float scale) {
|
||||
// specify the bind pose position
|
||||
joint[ AVATAR_JOINT_PELVIS ].bindPosePosition = scale * AVATAR_JOINT_POSITION_PELVIS;
|
||||
joint[ AVATAR_JOINT_TORSO ].bindPosePosition = scale * AVATAR_JOINT_POSITION_TORSO;
|
||||
joint[ AVATAR_JOINT_CHEST ].bindPosePosition = scale * AVATAR_JOINT_POSITION_CHEST;
|
||||
joint[ AVATAR_JOINT_NECK_BASE ].bindPosePosition = scale * AVATAR_JOINT_POSITION_NECK_BASE;
|
||||
joint[ AVATAR_JOINT_HEAD_BASE ].bindPosePosition = scale * AVATAR_JOINT_POSITION_HEAD_BASE;
|
||||
joint[ AVATAR_JOINT_HEAD_TOP ].bindPosePosition = scale * AVATAR_JOINT_POSITION_HEAD_TOP;
|
||||
|
||||
joint[ AVATAR_JOINT_LEFT_COLLAR ].bindPosePosition = scale * AVATAR_JOINT_POSITION_LEFT_COLLAR;
|
||||
joint[ AVATAR_JOINT_LEFT_SHOULDER ].bindPosePosition = scale * AVATAR_JOINT_POSITION_LEFT_SHOULDER;
|
||||
joint[ AVATAR_JOINT_LEFT_ELBOW ].bindPosePosition = scale * AVATAR_JOINT_POSITION_LEFT_ELBOW;
|
||||
joint[ AVATAR_JOINT_LEFT_WRIST ].bindPosePosition = scale * AVATAR_JOINT_POSITION_LEFT_WRIST;
|
||||
joint[ AVATAR_JOINT_LEFT_FINGERTIPS ].bindPosePosition = scale * AVATAR_JOINT_POSITION_LEFT_FINGERTIPS;
|
||||
|
||||
joint[ AVATAR_JOINT_RIGHT_COLLAR ].bindPosePosition = scale * AVATAR_JOINT_POSITION_RIGHT_COLLAR;
|
||||
joint[ AVATAR_JOINT_RIGHT_SHOULDER ].bindPosePosition = scale * AVATAR_JOINT_POSITION_RIGHT_SHOULDER;
|
||||
joint[ AVATAR_JOINT_RIGHT_ELBOW ].bindPosePosition = scale * AVATAR_JOINT_POSITION_RIGHT_ELBOW;
|
||||
joint[ AVATAR_JOINT_RIGHT_WRIST ].bindPosePosition = scale * AVATAR_JOINT_POSITION_RIGHT_WRIST;
|
||||
joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].bindPosePosition = scale * AVATAR_JOINT_POSITION_RIGHT_FINGERTIPS;
|
||||
|
||||
joint[ AVATAR_JOINT_LEFT_HIP ].bindPosePosition = scale * AVATAR_JOINT_POSITION_LEFT_HIP;
|
||||
joint[ AVATAR_JOINT_LEFT_KNEE ].bindPosePosition = scale * AVATAR_JOINT_POSITION_LEFT_KNEE;
|
||||
joint[ AVATAR_JOINT_LEFT_HEEL ].bindPosePosition = scale * AVATAR_JOINT_POSITION_LEFT_HEEL;
|
||||
joint[ AVATAR_JOINT_LEFT_TOES ].bindPosePosition = scale * AVATAR_JOINT_POSITION_LEFT_TOES;
|
||||
|
||||
joint[ AVATAR_JOINT_RIGHT_HIP ].bindPosePosition = scale * AVATAR_JOINT_POSITION_RIGHT_HIP;
|
||||
joint[ AVATAR_JOINT_RIGHT_KNEE ].bindPosePosition = scale * AVATAR_JOINT_POSITION_RIGHT_KNEE;
|
||||
joint[ AVATAR_JOINT_RIGHT_HEEL ].bindPosePosition = scale * AVATAR_JOINT_POSITION_RIGHT_HEEL;
|
||||
joint[ AVATAR_JOINT_RIGHT_TOES ].bindPosePosition = scale * AVATAR_JOINT_POSITION_RIGHT_TOES;
|
||||
|
||||
// calculate bone length, absolute bind positions/rotations
|
||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||
joint[b].length = glm::length(joint[b].bindPosePosition);
|
||||
|
||||
if (joint[b].parent == AVATAR_JOINT_NULL) {
|
||||
joint[b].absoluteBindPosePosition = joint[b].bindPosePosition;
|
||||
joint[b].absoluteBindPoseRotation = glm::quat();
|
||||
} else {
|
||||
joint[b].absoluteBindPosePosition = joint[ joint[b].parent ].absoluteBindPosePosition +
|
||||
joint[b].bindPosePosition;
|
||||
glm::vec3 parentDirection = joint[ joint[b].parent ].absoluteBindPoseRotation * JOINT_DIRECTION;
|
||||
joint[b].absoluteBindPoseRotation = rotationBetween(parentDirection, joint[b].bindPosePosition) *
|
||||
joint[ joint[b].parent ].absoluteBindPoseRotation;
|
||||
}
|
||||
}
|
||||
|
||||
_floatingHeight = scale * FLOATING_HEIGHT;
|
||||
}
|
||||
|
||||
// calculate positions and rotations of all bones by traversing the skeleton tree:
|
||||
void Skeleton::update(float deltaTime, const glm::quat& orientation, glm::vec3 position) {
|
||||
|
||||
for (int b = 0; b < NUM_AVATAR_JOINTS; b++) {
|
||||
if (joint[b].parent == AVATAR_JOINT_NULL) {
|
||||
joint[b].absoluteRotation = orientation * joint[b].rotation;
|
||||
joint[b].position = position;
|
||||
}
|
||||
else {
|
||||
joint[b].absoluteRotation = joint[ joint[b].parent ].absoluteRotation * joint[b].rotation;
|
||||
joint[b].position = joint[ joint[b].parent ].position;
|
||||
}
|
||||
|
||||
glm::vec3 rotatedJointVector = joint[b].absoluteRotation * joint[b].bindPosePosition;
|
||||
joint[b].position += rotatedJointVector;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float Skeleton::getArmLength() {
|
||||
return joint[ AVATAR_JOINT_RIGHT_ELBOW ].length
|
||||
+ joint[ AVATAR_JOINT_RIGHT_WRIST ].length
|
||||
+ joint[ AVATAR_JOINT_RIGHT_FINGERTIPS ].length;
|
||||
}
|
||||
|
||||
float Skeleton::getHeight() {
|
||||
return
|
||||
joint[ AVATAR_JOINT_LEFT_HEEL ].length +
|
||||
joint[ AVATAR_JOINT_LEFT_KNEE ].length +
|
||||
joint[ AVATAR_JOINT_PELVIS ].length +
|
||||
joint[ AVATAR_JOINT_TORSO ].length +
|
||||
joint[ AVATAR_JOINT_CHEST ].length +
|
||||
joint[ AVATAR_JOINT_NECK_BASE ].length +
|
||||
joint[ AVATAR_JOINT_HEAD_BASE ].length;
|
||||
}
|
||||
|
||||
float Skeleton::getPelvisStandingHeight() {
|
||||
return joint[ AVATAR_JOINT_LEFT_HEEL ].length +
|
||||
joint[ AVATAR_JOINT_LEFT_KNEE ].length;
|
||||
}
|
||||
|
||||
float Skeleton::getPelvisFloatingHeight() {
|
||||
return joint[ AVATAR_JOINT_LEFT_HEEL ].length +
|
||||
joint[ AVATAR_JOINT_LEFT_KNEE ].length +
|
||||
_floatingHeight;
|
||||
}
|
||||
|
||||
float Skeleton::getPelvisToHeadLength() {
|
||||
return
|
||||
joint[ AVATAR_JOINT_TORSO ].length +
|
||||
joint[ AVATAR_JOINT_CHEST ].length +
|
||||
joint[ AVATAR_JOINT_NECK_BASE ].length +
|
||||
joint[ AVATAR_JOINT_HEAD_BASE ].length;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
//
|
||||
// Skeleton.h
|
||||
// interface
|
||||
//
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef hifi_Skeleton_h
|
||||
#define hifi_Skeleton_h
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
enum AvatarJointID
|
||||
{
|
||||
AVATAR_JOINT_NULL = -1,
|
||||
AVATAR_JOINT_PELVIS,
|
||||
AVATAR_JOINT_TORSO,
|
||||
AVATAR_JOINT_CHEST,
|
||||
AVATAR_JOINT_NECK_BASE,
|
||||
AVATAR_JOINT_HEAD_BASE,
|
||||
AVATAR_JOINT_HEAD_TOP,
|
||||
AVATAR_JOINT_LEFT_COLLAR,
|
||||
AVATAR_JOINT_LEFT_SHOULDER,
|
||||
AVATAR_JOINT_LEFT_ELBOW,
|
||||
AVATAR_JOINT_LEFT_WRIST,
|
||||
AVATAR_JOINT_LEFT_FINGERTIPS,
|
||||
AVATAR_JOINT_RIGHT_COLLAR,
|
||||
AVATAR_JOINT_RIGHT_SHOULDER,
|
||||
AVATAR_JOINT_RIGHT_ELBOW,
|
||||
AVATAR_JOINT_RIGHT_WRIST,
|
||||
AVATAR_JOINT_RIGHT_FINGERTIPS,
|
||||
AVATAR_JOINT_LEFT_HIP,
|
||||
AVATAR_JOINT_LEFT_KNEE,
|
||||
AVATAR_JOINT_LEFT_HEEL,
|
||||
AVATAR_JOINT_LEFT_TOES,
|
||||
AVATAR_JOINT_RIGHT_HIP,
|
||||
AVATAR_JOINT_RIGHT_KNEE,
|
||||
AVATAR_JOINT_RIGHT_HEEL,
|
||||
AVATAR_JOINT_RIGHT_TOES,
|
||||
|
||||
NUM_AVATAR_JOINTS
|
||||
};
|
||||
|
||||
const glm::vec3 JOINT_DIRECTION = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
|
||||
class Skeleton {
|
||||
public:
|
||||
Skeleton();
|
||||
|
||||
void initialize();
|
||||
void setScale(float scale);
|
||||
void update(float deltaTime, const glm::quat&, glm::vec3 position);
|
||||
void render();
|
||||
|
||||
float getArmLength();
|
||||
float getHeight();
|
||||
float getPelvisStandingHeight();
|
||||
float getPelvisFloatingHeight();
|
||||
float getPelvisToHeadLength();
|
||||
//glm::vec3 getJointVectorFromParent(AvatarJointID jointID) {return joint[jointID].position - joint[joint[jointID].parent].position; }
|
||||
|
||||
struct AvatarJoint
|
||||
{
|
||||
AvatarJointID parent; // which joint is this joint connected to?
|
||||
glm::vec3 position; // the position at the "end" of the joint - in global space
|
||||
glm::vec3 bindPosePosition; // the parent relative position when the avatar is in the "T-pose"
|
||||
glm::vec3 absoluteBindPosePosition; // the absolute position when the avatar is in the "T-pose"
|
||||
glm::quat absoluteBindPoseRotation; // the absolute rotation when the avatar is in the "T-pose"
|
||||
float bindRadius; // the radius of the bone capsule that envelops the vertices to bind
|
||||
glm::quat rotation; // the parent-relative rotation (orientation) of the joint as a quaternion
|
||||
glm::quat absoluteRotation; // the absolute rotation of the joint as a quaternion
|
||||
float length; // the length of vector connecting the joint and its parent
|
||||
};
|
||||
|
||||
AvatarJoint joint[ NUM_AVATAR_JOINTS ];
|
||||
float _floatingHeight;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -29,12 +29,11 @@ using namespace xn;
|
|||
#endif
|
||||
|
||||
// register types with Qt metatype system
|
||||
int jointVectorMetaType = qRegisterMetaType<JointVector>("JointVector");
|
||||
int keyPointVectorMetaType = qRegisterMetaType<KeyPointVector>("KeyPointVector");
|
||||
int matMetaType = qRegisterMetaType<Mat>("cv::Mat");
|
||||
int rotatedRectMetaType = qRegisterMetaType<RotatedRect>("cv::RotatedRect");
|
||||
|
||||
Webcam::Webcam() : _enabled(false), _active(false), _colorTextureID(0), _depthTextureID(0), _skeletonTrackingOn(false) {
|
||||
Webcam::Webcam() : _enabled(false), _active(false), _colorTextureID(0), _depthTextureID(0) {
|
||||
// the grabber simply runs as fast as possible
|
||||
_grabber = new FrameGrabber();
|
||||
_grabber->moveToThread(&_grabberThread);
|
||||
|
@ -111,20 +110,6 @@ void Webcam::renderPreview(int screenWidth, int screenHeight) {
|
|||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
if (!_joints.isEmpty()) {
|
||||
glColor3f(1.0f, 0.0f, 0.0f);
|
||||
glPointSize(4.0f);
|
||||
glBegin(GL_POINTS);
|
||||
float projectedScale = PREVIEW_HEIGHT / _textureSize.height;
|
||||
foreach (const Joint& joint, _joints) {
|
||||
if (joint.isValid) {
|
||||
glVertex2f(left + joint.projected.x * projectedScale,
|
||||
top - PREVIEW_HEIGHT + joint.projected.y * projectedScale);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
glPointSize(1.0f);
|
||||
}
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
@ -238,7 +223,7 @@ static float computeTransformFromKeyPoints(const KeyPointVector& keyPoints, glm:
|
|||
const float METERS_PER_MM = 1.0f / 1000.0f;
|
||||
|
||||
void Webcam::setFrame(const Mat& color, int format, const Mat& depth, float midFaceDepth, float aspectRatio,
|
||||
const RotatedRect& faceRect, bool sending, const JointVector& joints, const KeyPointVector& keyPoints) {
|
||||
const RotatedRect& faceRect, bool sending, const KeyPointVector& keyPoints) {
|
||||
if (!_enabled) {
|
||||
return; // was queued before we shut down; ignore
|
||||
}
|
||||
|
@ -289,7 +274,6 @@ void Webcam::setFrame(const Mat& color, int format, const Mat& depth, float midF
|
|||
_aspectRatio = aspectRatio;
|
||||
_faceRect = faceRect;
|
||||
_sending = sending;
|
||||
_joints = _skeletonTrackingOn ? joints : JointVector();
|
||||
_keyPoints = keyPoints;
|
||||
_frameCount++;
|
||||
|
||||
|
@ -304,32 +288,8 @@ void Webcam::setFrame(const Mat& color, int format, const Mat& depth, float midF
|
|||
}
|
||||
_lastFrameTimestamp = now;
|
||||
|
||||
// see if we have joint data
|
||||
if (!_joints.isEmpty()) {
|
||||
_estimatedJoints.resize(NUM_AVATAR_JOINTS);
|
||||
glm::vec3 origin;
|
||||
if (_joints[AVATAR_JOINT_LEFT_HIP].isValid && _joints[AVATAR_JOINT_RIGHT_HIP].isValid) {
|
||||
origin = glm::mix(_joints[AVATAR_JOINT_LEFT_HIP].position, _joints[AVATAR_JOINT_RIGHT_HIP].position, 0.5f);
|
||||
|
||||
} else if (_joints[AVATAR_JOINT_TORSO].isValid) {
|
||||
const glm::vec3 TORSO_TO_PELVIS = glm::vec3(0.0f, -0.09f, -0.01f);
|
||||
origin = _joints[AVATAR_JOINT_TORSO].position + TORSO_TO_PELVIS;
|
||||
}
|
||||
for (int i = 0; i < NUM_AVATAR_JOINTS; i++) {
|
||||
if (!_joints[i].isValid) {
|
||||
continue;
|
||||
}
|
||||
const float JOINT_SMOOTHING = 0.5f;
|
||||
_estimatedJoints[i].isValid = true;
|
||||
_estimatedJoints[i].position = glm::mix(_joints[i].position - origin,
|
||||
_estimatedJoints[i].position, JOINT_SMOOTHING);
|
||||
_estimatedJoints[i].rotation = safeMix(_joints[i].rotation,
|
||||
_estimatedJoints[i].rotation, JOINT_SMOOTHING);
|
||||
}
|
||||
_estimatedRotation = safeEulerAngles(_estimatedJoints[AVATAR_JOINT_HEAD_BASE].rotation);
|
||||
_estimatedPosition = _estimatedJoints[AVATAR_JOINT_HEAD_BASE].position;
|
||||
|
||||
} else if (!keyPoints.empty()) {
|
||||
// see if we have key points
|
||||
if (!keyPoints.empty()) {
|
||||
glm::quat rotation;
|
||||
glm::vec3 position;
|
||||
float scale = computeTransformFromKeyPoints(keyPoints, rotation, position);
|
||||
|
@ -415,51 +375,6 @@ FrameGrabber::~FrameGrabber() {
|
|||
}
|
||||
|
||||
#ifdef HAVE_OPENNI
|
||||
static AvatarJointID xnToAvatarJoint(XnSkeletonJoint joint) {
|
||||
switch (joint) {
|
||||
case XN_SKEL_HEAD: return AVATAR_JOINT_HEAD_TOP;
|
||||
case XN_SKEL_NECK: return AVATAR_JOINT_HEAD_BASE;
|
||||
case XN_SKEL_TORSO: return AVATAR_JOINT_CHEST;
|
||||
|
||||
case XN_SKEL_LEFT_SHOULDER: return AVATAR_JOINT_RIGHT_ELBOW;
|
||||
case XN_SKEL_LEFT_ELBOW: return AVATAR_JOINT_RIGHT_WRIST;
|
||||
|
||||
case XN_SKEL_RIGHT_SHOULDER: return AVATAR_JOINT_LEFT_ELBOW;
|
||||
case XN_SKEL_RIGHT_ELBOW: return AVATAR_JOINT_LEFT_WRIST;
|
||||
|
||||
case XN_SKEL_LEFT_HIP: return AVATAR_JOINT_RIGHT_KNEE;
|
||||
case XN_SKEL_LEFT_KNEE: return AVATAR_JOINT_RIGHT_HEEL;
|
||||
case XN_SKEL_LEFT_FOOT: return AVATAR_JOINT_RIGHT_TOES;
|
||||
|
||||
case XN_SKEL_RIGHT_HIP: return AVATAR_JOINT_LEFT_KNEE;
|
||||
case XN_SKEL_RIGHT_KNEE: return AVATAR_JOINT_LEFT_HEEL;
|
||||
case XN_SKEL_RIGHT_FOOT: return AVATAR_JOINT_LEFT_TOES;
|
||||
|
||||
default: return AVATAR_JOINT_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int getParentJoint(XnSkeletonJoint joint) {
|
||||
switch (joint) {
|
||||
case XN_SKEL_HEAD: return XN_SKEL_NECK;
|
||||
case XN_SKEL_TORSO: return -1;
|
||||
|
||||
case XN_SKEL_LEFT_ELBOW: return XN_SKEL_LEFT_SHOULDER;
|
||||
case XN_SKEL_LEFT_HAND: return XN_SKEL_LEFT_ELBOW;
|
||||
|
||||
case XN_SKEL_RIGHT_ELBOW: return XN_SKEL_RIGHT_SHOULDER;
|
||||
case XN_SKEL_RIGHT_HAND: return XN_SKEL_RIGHT_ELBOW;
|
||||
|
||||
case XN_SKEL_LEFT_KNEE: return XN_SKEL_LEFT_HIP;
|
||||
case XN_SKEL_LEFT_FOOT: return XN_SKEL_LEFT_KNEE;
|
||||
|
||||
case XN_SKEL_RIGHT_KNEE: return XN_SKEL_RIGHT_HIP;
|
||||
case XN_SKEL_RIGHT_FOOT: return XN_SKEL_RIGHT_KNEE;
|
||||
|
||||
default: return XN_SKEL_TORSO;
|
||||
}
|
||||
}
|
||||
|
||||
static glm::vec3 xnToGLM(const XnVector3D& vector, bool flip = false) {
|
||||
return glm::vec3(vector.X * (flip ? -1 : 1), vector.Y, vector.Z);
|
||||
}
|
||||
|
@ -471,31 +386,6 @@ static glm::quat xnToGLM(const XnMatrix3X3& matrix) {
|
|||
matrix.elements[6], matrix.elements[7], matrix.elements[8]));
|
||||
return glm::quat(rotation.w, -rotation.x, rotation.y, rotation.z);
|
||||
}
|
||||
|
||||
static void XN_CALLBACK_TYPE newUser(UserGenerator& generator, XnUserID id, void* cookie) {
|
||||
qDebug("Found user %d.", id);
|
||||
generator.GetSkeletonCap().RequestCalibration(id, false);
|
||||
}
|
||||
|
||||
static void XN_CALLBACK_TYPE lostUser(UserGenerator& generator, XnUserID id, void* cookie) {
|
||||
qDebug("Lost user %d.", id);
|
||||
}
|
||||
|
||||
static void XN_CALLBACK_TYPE calibrationStarted(SkeletonCapability& capability, XnUserID id, void* cookie) {
|
||||
qDebug("Calibration started for user %d.", id);
|
||||
}
|
||||
|
||||
static void XN_CALLBACK_TYPE calibrationCompleted(SkeletonCapability& capability,
|
||||
XnUserID id, XnCalibrationStatus status, void* cookie) {
|
||||
if (status == XN_CALIBRATION_STATUS_OK) {
|
||||
qDebug("Calibration completed for user %d.", id);
|
||||
capability.StartTracking(id);
|
||||
|
||||
} else {
|
||||
qDebug("Calibration failed to user %d.", id);
|
||||
capability.RequestCalibration(id, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void FrameGrabber::cycleVideoSendMode() {
|
||||
|
@ -517,12 +407,6 @@ void FrameGrabber::setLEDTrackingOn(bool ledTrackingOn) {
|
|||
|
||||
void FrameGrabber::reset() {
|
||||
_searchWindow = cv::Rect(0, 0, 0, 0);
|
||||
|
||||
#ifdef HAVE_OPENNI
|
||||
if (_userGenerator.IsValid() && _userGenerator.GetSkeletonCap().IsTracking(_userID)) {
|
||||
_userGenerator.GetSkeletonCap().RequestCalibration(_userID, true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FrameGrabber::shutdown() {
|
||||
|
@ -551,7 +435,6 @@ void FrameGrabber::grabFrame() {
|
|||
}
|
||||
int format = GL_BGR;
|
||||
Mat color, depth;
|
||||
JointVector joints;
|
||||
|
||||
#ifdef HAVE_OPENNI
|
||||
if (_depthGenerator.IsValid()) {
|
||||
|
@ -560,37 +443,6 @@ void FrameGrabber::grabFrame() {
|
|||
format = GL_RGB;
|
||||
|
||||
depth = Mat(_depthMetaData.YRes(), _depthMetaData.XRes(), CV_16UC1, (void*)_depthGenerator.GetDepthMap());
|
||||
|
||||
_userID = 0;
|
||||
XnUInt16 userCount = 1;
|
||||
_userGenerator.GetUsers(&_userID, userCount);
|
||||
if (userCount > 0 && _userGenerator.GetSkeletonCap().IsTracking(_userID)) {
|
||||
joints.resize(NUM_AVATAR_JOINTS);
|
||||
const int MAX_ACTIVE_JOINTS = 16;
|
||||
XnSkeletonJoint activeJoints[MAX_ACTIVE_JOINTS];
|
||||
XnUInt16 activeJointCount = MAX_ACTIVE_JOINTS;
|
||||
_userGenerator.GetSkeletonCap().EnumerateActiveJoints(activeJoints, activeJointCount);
|
||||
XnSkeletonJointTransformation transform;
|
||||
for (int i = 0; i < activeJointCount; i++) {
|
||||
AvatarJointID avatarJoint = xnToAvatarJoint(activeJoints[i]);
|
||||
if (avatarJoint == AVATAR_JOINT_NULL) {
|
||||
continue;
|
||||
}
|
||||
_userGenerator.GetSkeletonCap().GetSkeletonJoint(_userID, activeJoints[i], transform);
|
||||
XnVector3D projected;
|
||||
_depthGenerator.ConvertRealWorldToProjective(1, &transform.position.position, &projected);
|
||||
glm::quat rotation = xnToGLM(transform.orientation.orientation);
|
||||
int parentJoint = getParentJoint(activeJoints[i]);
|
||||
if (parentJoint != -1) {
|
||||
XnSkeletonJointOrientation parentOrientation;
|
||||
_userGenerator.GetSkeletonCap().GetSkeletonJointOrientation(
|
||||
_userID, (XnSkeletonJoint)parentJoint, parentOrientation);
|
||||
rotation = glm::inverse(xnToGLM(parentOrientation.orientation)) * rotation;
|
||||
}
|
||||
joints[avatarJoint] = Joint(xnToGLM(transform.position.position, true) * METERS_PER_MM,
|
||||
rotation, xnToGLM(projected));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -929,7 +781,7 @@ void FrameGrabber::grabFrame() {
|
|||
QMetaObject::invokeMethod(Application::getInstance()->getWebcam(), "setFrame",
|
||||
Q_ARG(cv::Mat, color), Q_ARG(int, format), Q_ARG(cv::Mat, _grayDepthFrame), Q_ARG(float, _smoothedMidFaceDepth),
|
||||
Q_ARG(float, aspectRatio), Q_ARG(cv::RotatedRect, _smoothedFaceRect), Q_ARG(bool, !payload.isEmpty()),
|
||||
Q_ARG(JointVector, joints), Q_ARG(KeyPointVector, keyPoints));
|
||||
Q_ARG(KeyPointVector, keyPoints));
|
||||
}
|
||||
|
||||
bool FrameGrabber::init() {
|
||||
|
@ -945,20 +797,11 @@ bool FrameGrabber::init() {
|
|||
// first try for a Kinect
|
||||
#ifdef HAVE_OPENNI
|
||||
_xnContext.Init();
|
||||
if (_depthGenerator.Create(_xnContext) == XN_STATUS_OK && _imageGenerator.Create(_xnContext) == XN_STATUS_OK &&
|
||||
_userGenerator.Create(_xnContext) == XN_STATUS_OK &&
|
||||
_userGenerator.IsCapabilitySupported(XN_CAPABILITY_SKELETON)) {
|
||||
if (_depthGenerator.Create(_xnContext) == XN_STATUS_OK && _imageGenerator.Create(_xnContext) == XN_STATUS_OK) {
|
||||
_depthGenerator.GetMetaData(_depthMetaData);
|
||||
_imageGenerator.SetPixelFormat(XN_PIXEL_FORMAT_RGB24);
|
||||
_imageGenerator.GetMetaData(_imageMetaData);
|
||||
|
||||
XnCallbackHandle userCallbacks, calibrationStartCallback, calibrationCompleteCallback;
|
||||
_userGenerator.RegisterUserCallbacks(newUser, lostUser, 0, userCallbacks);
|
||||
_userGenerator.GetSkeletonCap().RegisterToCalibrationStart(calibrationStarted, 0, calibrationStartCallback);
|
||||
_userGenerator.GetSkeletonCap().RegisterToCalibrationComplete(calibrationCompleted, 0, calibrationCompleteCallback);
|
||||
|
||||
_userGenerator.GetSkeletonCap().SetSkeletonProfile(XN_SKEL_PROFILE_UPPER);
|
||||
|
||||
// make the depth viewpoint match that of the video image
|
||||
if (_depthGenerator.IsCapabilitySupported(XN_CAPABILITY_ALTERNATIVE_VIEW_POINT)) {
|
||||
_depthGenerator.GetAlternativeViewPointCap().SetViewPoint(_imageGenerator);
|
||||
|
@ -1018,10 +861,3 @@ void FrameGrabber::destroyCodecs() {
|
|||
_depthCodec.name = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Joint::Joint(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& projected) :
|
||||
isValid(true), position(position), rotation(rotation), projected(projected) {
|
||||
}
|
||||
|
||||
Joint::Joint() : isValid(false) {
|
||||
}
|
||||
|
|
|
@ -31,9 +31,7 @@ class QImage;
|
|||
struct CvCapture;
|
||||
|
||||
class FrameGrabber;
|
||||
class Joint;
|
||||
|
||||
typedef QVector<Joint> JointVector;
|
||||
typedef std::vector<cv::KeyPoint> KeyPointVector;
|
||||
|
||||
/// Handles interaction with the webcam (including depth cameras such as the Kinect).
|
||||
|
@ -61,7 +59,6 @@ public:
|
|||
|
||||
const glm::vec3& getEstimatedPosition() const { return _estimatedPosition; }
|
||||
const glm::vec3& getEstimatedRotation() const { return _estimatedRotation; }
|
||||
const JointVector& getEstimatedJoints() const { return _estimatedJoints; }
|
||||
|
||||
void reset();
|
||||
void renderPreview(int screenWidth, int screenHeight);
|
||||
|
@ -70,8 +67,7 @@ public slots:
|
|||
|
||||
void setEnabled(bool enabled);
|
||||
void setFrame(const cv::Mat& color, int format, const cv::Mat& depth, float midFaceDepth, float aspectRatio,
|
||||
const cv::RotatedRect& faceRect, bool sending, const JointVector& joints, const KeyPointVector& keyPoints);
|
||||
void setSkeletonTrackingOn(bool toggle) { _skeletonTrackingOn = toggle; };
|
||||
const cv::RotatedRect& faceRect, bool sending, const KeyPointVector& keyPoints);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -88,7 +84,6 @@ private:
|
|||
cv::RotatedRect _faceRect;
|
||||
cv::RotatedRect _initialFaceRect;
|
||||
float _initialFaceDepth;
|
||||
JointVector _joints;
|
||||
KeyPointVector _keyPoints;
|
||||
|
||||
glm::quat _initialLEDRotation;
|
||||
|
@ -102,9 +97,6 @@ private:
|
|||
|
||||
glm::vec3 _estimatedPosition;
|
||||
glm::vec3 _estimatedRotation;
|
||||
JointVector _estimatedJoints;
|
||||
|
||||
bool _skeletonTrackingOn;
|
||||
};
|
||||
|
||||
/// Acquires and processes video frames in a dedicated thread.
|
||||
|
@ -164,27 +156,11 @@ private:
|
|||
xn::Context _xnContext;
|
||||
xn::DepthGenerator _depthGenerator;
|
||||
xn::ImageGenerator _imageGenerator;
|
||||
xn::UserGenerator _userGenerator;
|
||||
xn::DepthMetaData _depthMetaData;
|
||||
xn::ImageMetaData _imageMetaData;
|
||||
XnUserID _userID;
|
||||
#endif
|
||||
};
|
||||
|
||||
/// Contains the 3D transform and 2D projected position of a tracked joint.
|
||||
class Joint {
|
||||
public:
|
||||
|
||||
Joint(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& projected);
|
||||
Joint();
|
||||
|
||||
bool isValid;
|
||||
glm::vec3 position;
|
||||
glm::quat rotation;
|
||||
glm::vec3 projected;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(JointVector)
|
||||
Q_DECLARE_METATYPE(KeyPointVector)
|
||||
Q_DECLARE_METATYPE(cv::Mat)
|
||||
Q_DECLARE_METATYPE(cv::RotatedRect)
|
||||
|
|
Loading…
Reference in a new issue