mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 17:00:13 +02:00
Merge pull request #6199 from ZappoMan/myAvatarPalmTweaks
thread safety clean up of use of PalmData
This commit is contained in:
commit
45ba0645d0
14 changed files with 202 additions and 392 deletions
|
@ -2741,13 +2741,13 @@ void Application::update(float deltaTime) {
|
||||||
controller::Pose leftHand = userInputMapper->getPoseState(controller::Action::LEFT_HAND);
|
controller::Pose leftHand = userInputMapper->getPoseState(controller::Action::LEFT_HAND);
|
||||||
controller::Pose rightHand = userInputMapper->getPoseState(controller::Action::RIGHT_HAND);
|
controller::Pose rightHand = userInputMapper->getPoseState(controller::Action::RIGHT_HAND);
|
||||||
Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
|
Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
|
||||||
setPalmData(hand, leftHand, deltaTime, LEFT_HAND_INDEX, userInputMapper->getActionState(controller::Action::LEFT_HAND_CLICK));
|
setPalmData(hand, leftHand, deltaTime, HandData::LeftHand, userInputMapper->getActionState(controller::Action::LEFT_HAND_CLICK));
|
||||||
setPalmData(hand, rightHand, deltaTime, RIGHT_HAND_INDEX, userInputMapper->getActionState(controller::Action::RIGHT_HAND_CLICK));
|
setPalmData(hand, rightHand, deltaTime, HandData::RightHand, userInputMapper->getActionState(controller::Action::RIGHT_HAND_CLICK));
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) {
|
||||||
emulateMouse(hand, userInputMapper->getActionState(controller::Action::LEFT_HAND_CLICK),
|
emulateMouse(hand, userInputMapper->getActionState(controller::Action::LEFT_HAND_CLICK),
|
||||||
userInputMapper->getActionState(controller::Action::SHIFT), LEFT_HAND_INDEX);
|
userInputMapper->getActionState(controller::Action::SHIFT), HandData::LeftHand);
|
||||||
emulateMouse(hand, userInputMapper->getActionState(controller::Action::RIGHT_HAND_CLICK),
|
emulateMouse(hand, userInputMapper->getActionState(controller::Action::RIGHT_HAND_CLICK),
|
||||||
userInputMapper->getActionState(controller::Action::SHIFT), RIGHT_HAND_INDEX);
|
userInputMapper->getActionState(controller::Action::SHIFT), HandData::RightHand);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
|
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
|
||||||
|
@ -4805,86 +4805,80 @@ mat4 Application::getHMDSensorPose() const {
|
||||||
return mat4();
|
return mat4();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setPalmData(Hand* hand, const controller::Pose& pose, float deltaTime, int index, float triggerValue) {
|
void Application::setPalmData(Hand* hand, const controller::Pose& pose, float deltaTime, HandData::Hand whichHand, float triggerValue) {
|
||||||
PalmData* palm;
|
|
||||||
bool foundHand = false;
|
// NOTE: the Hand::modifyPalm() will allow the lambda to modify the palm data while ensuring some other user isn't
|
||||||
for (size_t j = 0; j < hand->getNumPalms(); j++) {
|
// reading or writing to the Palms. This is definitely not the best way of handling this, and I'd like to see more
|
||||||
if (hand->getPalms()[j].getSixenseID() == index) {
|
// of this palm manipulation in the Hand class itself. But unfortunately the Hand and Palm don't knbow about
|
||||||
palm = &(hand->getPalms()[j]);
|
// controller::Pose. More work is needed to clean this up.
|
||||||
foundHand = true;
|
hand->modifyPalm(whichHand, [&](PalmData& palm) {
|
||||||
break;
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
|
palm.setActive(pose.isValid());
|
||||||
|
|
||||||
|
// transform from sensor space, to world space, to avatar model space.
|
||||||
|
glm::mat4 poseMat = createMatFromQuatAndPos(pose.getRotation(), pose.getTranslation());
|
||||||
|
glm::mat4 sensorToWorldMat = myAvatar->getSensorToWorldMatrix();
|
||||||
|
glm::mat4 modelMat = createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition());
|
||||||
|
glm::mat4 objectPose = glm::inverse(modelMat) * sensorToWorldMat * poseMat;
|
||||||
|
|
||||||
|
glm::vec3 position = extractTranslation(objectPose);
|
||||||
|
glm::quat rotation = glm::quat_cast(objectPose);
|
||||||
|
|
||||||
|
// Compute current velocity from position change
|
||||||
|
glm::vec3 rawVelocity;
|
||||||
|
if (deltaTime > 0.0f) {
|
||||||
|
rawVelocity = (position - palm.getRawPosition()) / deltaTime;
|
||||||
|
} else {
|
||||||
|
rawVelocity = glm::vec3(0.0f);
|
||||||
}
|
}
|
||||||
}
|
palm.setRawVelocity(rawVelocity); // meters/sec
|
||||||
if (!foundHand) {
|
|
||||||
PalmData newPalm(hand);
|
|
||||||
hand->getPalms().push_back(newPalm);
|
|
||||||
palm = &(hand->getPalms()[hand->getNumPalms() - 1]);
|
|
||||||
palm->setSixenseID(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
palm->setActive(pose.isValid());
|
// Angular Velocity of Palm
|
||||||
|
glm::quat deltaRotation = rotation * glm::inverse(palm.getRawRotation());
|
||||||
|
glm::vec3 angularVelocity(0.0f);
|
||||||
|
float rotationAngle = glm::angle(deltaRotation);
|
||||||
|
if ((rotationAngle > EPSILON) && (deltaTime > 0.0f)) {
|
||||||
|
angularVelocity = glm::normalize(glm::axis(deltaRotation));
|
||||||
|
angularVelocity *= (rotationAngle / deltaTime);
|
||||||
|
palm.setRawAngularVelocity(angularVelocity);
|
||||||
|
} else {
|
||||||
|
palm.setRawAngularVelocity(glm::vec3(0.0f));
|
||||||
|
}
|
||||||
|
|
||||||
// transform from sensor space, to world space, to avatar model space.
|
if (controller::InputDevice::getLowVelocityFilter()) {
|
||||||
glm::mat4 poseMat = createMatFromQuatAndPos(pose.getRotation(), pose.getTranslation());
|
// Use a velocity sensitive filter to damp small motions and preserve large ones with
|
||||||
glm::mat4 sensorToWorldMat = getMyAvatar()->getSensorToWorldMatrix();
|
// no latency.
|
||||||
glm::mat4 modelMat = createMatFromQuatAndPos(getMyAvatar()->getOrientation(), getMyAvatar()->getPosition());
|
float velocityFilter = glm::clamp(1.0f - glm::length(rawVelocity), 0.0f, 1.0f);
|
||||||
glm::mat4 objectPose = glm::inverse(modelMat) * sensorToWorldMat * poseMat;
|
position = palm.getRawPosition() * velocityFilter + position * (1.0f - velocityFilter);
|
||||||
|
rotation = safeMix(palm.getRawRotation(), rotation, 1.0f - velocityFilter);
|
||||||
|
}
|
||||||
|
palm.setRawPosition(position);
|
||||||
|
palm.setRawRotation(rotation);
|
||||||
|
|
||||||
glm::vec3 position = extractTranslation(objectPose);
|
// Store the one fingertip in the palm structure so we can track velocity
|
||||||
glm::quat rotation = glm::quat_cast(objectPose);
|
const float FINGER_LENGTH = 0.3f; // meters
|
||||||
|
const glm::vec3 FINGER_VECTOR(0.0f, FINGER_LENGTH, 0.0f);
|
||||||
// Compute current velocity from position change
|
const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR;
|
||||||
glm::vec3 rawVelocity;
|
glm::vec3 oldTipPosition = palm.getTipRawPosition();
|
||||||
if (deltaTime > 0.0f) {
|
if (deltaTime > 0.0f) {
|
||||||
rawVelocity = (position - palm->getRawPosition()) / deltaTime;
|
palm.setTipVelocity((newTipPosition - oldTipPosition) / deltaTime);
|
||||||
} else {
|
} else {
|
||||||
rawVelocity = glm::vec3(0.0f);
|
palm.setTipVelocity(glm::vec3(0.0f));
|
||||||
}
|
}
|
||||||
palm->setRawVelocity(rawVelocity); // meters/sec
|
palm.setTipPosition(newTipPosition);
|
||||||
|
palm.setTrigger(triggerValue); // FIXME - we want to get rid of this idea of PalmData having a trigger
|
||||||
// Angular Velocity of Palm
|
});
|
||||||
glm::quat deltaRotation = rotation * glm::inverse(palm->getRawRotation());
|
|
||||||
glm::vec3 angularVelocity(0.0f);
|
|
||||||
float rotationAngle = glm::angle(deltaRotation);
|
|
||||||
if ((rotationAngle > EPSILON) && (deltaTime > 0.0f)) {
|
|
||||||
angularVelocity = glm::normalize(glm::axis(deltaRotation));
|
|
||||||
angularVelocity *= (rotationAngle / deltaTime);
|
|
||||||
palm->setRawAngularVelocity(angularVelocity);
|
|
||||||
} else {
|
|
||||||
palm->setRawAngularVelocity(glm::vec3(0.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (controller::InputDevice::getLowVelocityFilter()) {
|
|
||||||
// Use a velocity sensitive filter to damp small motions and preserve large ones with
|
|
||||||
// no latency.
|
|
||||||
float velocityFilter = glm::clamp(1.0f - glm::length(rawVelocity), 0.0f, 1.0f);
|
|
||||||
position = palm->getRawPosition() * velocityFilter + position * (1.0f - velocityFilter);
|
|
||||||
rotation = safeMix(palm->getRawRotation(), rotation, 1.0f - velocityFilter);
|
|
||||||
}
|
|
||||||
palm->setRawPosition(position);
|
|
||||||
palm->setRawRotation(rotation);
|
|
||||||
|
|
||||||
// Store the one fingertip in the palm structure so we can track velocity
|
|
||||||
const float FINGER_LENGTH = 0.3f; // meters
|
|
||||||
const glm::vec3 FINGER_VECTOR(0.0f, FINGER_LENGTH, 0.0f);
|
|
||||||
const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR;
|
|
||||||
glm::vec3 oldTipPosition = palm->getTipRawPosition();
|
|
||||||
if (deltaTime > 0.0f) {
|
|
||||||
palm->setTipVelocity((newTipPosition - oldTipPosition) / deltaTime);
|
|
||||||
} else {
|
|
||||||
palm->setTipVelocity(glm::vec3(0.0f));
|
|
||||||
}
|
|
||||||
palm->setTipPosition(newTipPosition);
|
|
||||||
palm->setTrigger(triggerValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::emulateMouse(Hand* hand, float click, float shift, int index) {
|
void Application::emulateMouse(Hand* hand, float click, float shift, HandData::Hand whichHand) {
|
||||||
|
auto palms = hand->getCopyOfPalms();
|
||||||
|
|
||||||
// Locate the palm, if it exists and is active
|
// Locate the palm, if it exists and is active
|
||||||
PalmData* palm;
|
PalmData* palm;
|
||||||
bool foundHand = false;
|
bool foundHand = false;
|
||||||
for (size_t j = 0; j < hand->getNumPalms(); j++) {
|
for (size_t j = 0; j < palms.size(); j++) {
|
||||||
if (hand->getPalms()[j].getSixenseID() == index) {
|
if (palms[j].whichHand() == whichHand) {
|
||||||
palm = &(hand->getPalms()[j]);
|
palm = &(palms[j]);
|
||||||
foundHand = true;
|
foundHand = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -4896,12 +4890,14 @@ void Application::emulateMouse(Hand* hand, float click, float shift, int index)
|
||||||
// Process the mouse events
|
// Process the mouse events
|
||||||
QPoint pos;
|
QPoint pos;
|
||||||
|
|
||||||
unsigned int deviceID = index == 0 ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT;
|
|
||||||
|
// FIXME - this mouse emulation stuff needs to be reworked for new controller input plugins
|
||||||
|
unsigned int deviceID = whichHand == HandData::LeftHand ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT;
|
||||||
|
int index = (int)whichHand; // FIXME - hack attack
|
||||||
|
|
||||||
if (isHMDMode()) {
|
if (isHMDMode()) {
|
||||||
pos = getApplicationCompositor().getPalmClickLocation(palm);
|
pos = getApplicationCompositor().getPalmClickLocation(palm);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// Get directon relative to avatar orientation
|
// Get directon relative to avatar orientation
|
||||||
glm::vec3 direction = glm::inverse(getMyAvatar()->getOrientation()) * palm->getFingerDirection();
|
glm::vec3 direction = glm::inverse(getMyAvatar()->getOrientation()) * palm->getFingerDirection();
|
||||||
|
|
||||||
|
|
|
@ -352,8 +352,8 @@ private:
|
||||||
|
|
||||||
void update(float deltaTime);
|
void update(float deltaTime);
|
||||||
|
|
||||||
void setPalmData(Hand* hand, const controller::Pose& pose, float deltaTime, int index, float triggerValue);
|
void setPalmData(Hand* hand, const controller::Pose& pose, float deltaTime, HandData::Hand whichHand, float triggerValue);
|
||||||
void emulateMouse(Hand* hand, float click, float shift, int index);
|
void emulateMouse(Hand* hand, float click, float shift, HandData::Hand whichHand);
|
||||||
|
|
||||||
// Various helper functions called during update()
|
// Various helper functions called during update()
|
||||||
void updateLOD();
|
void updateLOD();
|
||||||
|
@ -522,10 +522,13 @@ private:
|
||||||
ApplicationCompositor _compositor;
|
ApplicationCompositor _compositor;
|
||||||
OverlayConductor _overlayConductor;
|
OverlayConductor _overlayConductor;
|
||||||
|
|
||||||
int _oldHandMouseX[2];
|
|
||||||
int _oldHandMouseY[2];
|
// FIXME - Hand Controller to mouse emulation helpers. This is crufty and should be moved
|
||||||
bool _oldHandLeftClick[2];
|
// into the input plugins or something.
|
||||||
bool _oldHandRightClick[2];
|
int _oldHandMouseX[(int)HandData::NUMBER_OF_HANDS];
|
||||||
|
int _oldHandMouseY[(int)HandData::NUMBER_OF_HANDS];
|
||||||
|
bool _oldHandLeftClick[(int)HandData::NUMBER_OF_HANDS];
|
||||||
|
bool _oldHandRightClick[(int)HandData::NUMBER_OF_HANDS];
|
||||||
|
|
||||||
DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface();
|
DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface();
|
||||||
|
|
||||||
|
|
|
@ -1177,22 +1177,6 @@ glm::vec3 Avatar::getLeftPalmPosition() {
|
||||||
return leftHandPosition;
|
return leftHandPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Avatar::getLeftPalmVelocity() {
|
|
||||||
const PalmData* palm = getHand()->getPalm(LEFT_HAND_INDEX);
|
|
||||||
if (palm != NULL) {
|
|
||||||
return palm->getVelocity();
|
|
||||||
}
|
|
||||||
return glm::vec3(0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 Avatar::getLeftPalmAngularVelocity() {
|
|
||||||
const PalmData* palm = getHand()->getPalm(LEFT_HAND_INDEX);
|
|
||||||
if (palm != NULL) {
|
|
||||||
return palm->getRawAngularVelocity();
|
|
||||||
}
|
|
||||||
return glm::vec3(0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::quat Avatar::getLeftPalmRotation() {
|
glm::quat Avatar::getLeftPalmRotation() {
|
||||||
glm::quat leftRotation;
|
glm::quat leftRotation;
|
||||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation);
|
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation);
|
||||||
|
@ -1208,22 +1192,6 @@ glm::vec3 Avatar::getRightPalmPosition() {
|
||||||
return rightHandPosition;
|
return rightHandPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Avatar::getRightPalmVelocity() {
|
|
||||||
const PalmData* palm = getHand()->getPalm(RIGHT_HAND_INDEX);
|
|
||||||
if (palm != NULL) {
|
|
||||||
return palm->getVelocity();
|
|
||||||
}
|
|
||||||
return glm::vec3(0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::vec3 Avatar::getRightPalmAngularVelocity() {
|
|
||||||
const PalmData* palm = getHand()->getPalm(RIGHT_HAND_INDEX);
|
|
||||||
if (palm != NULL) {
|
|
||||||
return palm->getRawAngularVelocity();
|
|
||||||
}
|
|
||||||
return glm::vec3(0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
glm::quat Avatar::getRightPalmRotation() {
|
glm::quat Avatar::getRightPalmRotation() {
|
||||||
glm::quat rightRotation;
|
glm::quat rightRotation;
|
||||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation);
|
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation);
|
||||||
|
|
|
@ -160,13 +160,11 @@ public:
|
||||||
AvatarMotionState* getMotionState() { return _motionState; }
|
AvatarMotionState* getMotionState() { return _motionState; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
// FIXME - these should be migrated to use Pose data instead
|
||||||
glm::vec3 getLeftPalmPosition();
|
glm::vec3 getLeftPalmPosition();
|
||||||
glm::vec3 getLeftPalmVelocity();
|
|
||||||
glm::vec3 getLeftPalmAngularVelocity();
|
|
||||||
glm::quat getLeftPalmRotation();
|
glm::quat getLeftPalmRotation();
|
||||||
glm::vec3 getRightPalmPosition();
|
glm::vec3 getRightPalmPosition();
|
||||||
glm::vec3 getRightPalmVelocity();
|
|
||||||
glm::vec3 getRightPalmAngularVelocity();
|
|
||||||
glm::quat getRightPalmRotation();
|
glm::quat getRightPalmRotation();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -31,13 +31,7 @@ Hand::Hand(Avatar* owningAvatar) :
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hand::simulate(float deltaTime, bool isMine) {
|
void Hand::simulate(float deltaTime, bool isMine) {
|
||||||
if (isMine) {
|
// nothing to do here
|
||||||
// Iterate hand controllers, take actions as needed
|
|
||||||
for (size_t i = 0; i < getNumPalms(); ++i) {
|
|
||||||
PalmData& palm = getPalms()[i];
|
|
||||||
palm.setLastControllerButtons(palm.getControllerButtons());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) {
|
void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) {
|
||||||
|
@ -53,10 +47,11 @@ void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) {
|
||||||
const glm::vec3 grayColor(0.5f);
|
const glm::vec3 grayColor(0.5f);
|
||||||
const float SPHERE_RADIUS = 0.03f * avatarScale;
|
const float SPHERE_RADIUS = 0.03f * avatarScale;
|
||||||
|
|
||||||
|
auto palms = getCopyOfPalms();
|
||||||
|
|
||||||
gpu::Batch& batch = *renderArgs->_batch;
|
gpu::Batch& batch = *renderArgs->_batch;
|
||||||
if (isMine) {
|
if (isMine) {
|
||||||
for (size_t i = 0; i < getNumPalms(); i++) {
|
for (const auto& palm : palms) {
|
||||||
PalmData& palm = getPalms()[i];
|
|
||||||
if (!palm.isActive()) {
|
if (!palm.isActive()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -82,8 +77,7 @@ void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) {
|
||||||
const float AXIS_LENGTH = 10.0f * SPHERE_RADIUS;
|
const float AXIS_LENGTH = 10.0f * SPHERE_RADIUS;
|
||||||
|
|
||||||
// Draw the coordinate frames of the hand targets
|
// Draw the coordinate frames of the hand targets
|
||||||
for (size_t i = 0; i < getNumPalms(); ++i) {
|
for (const auto& palm : palms) {
|
||||||
PalmData& palm = getPalms()[i];
|
|
||||||
if (palm.isActive()) {
|
if (palm.isActive()) {
|
||||||
glm::vec3 root = palm.getPosition();
|
glm::vec3 root = palm.getPosition();
|
||||||
|
|
||||||
|
|
|
@ -548,80 +548,48 @@ void MyAvatar::updateFromTrackers(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FIXME - this is super duper dumb... but this is how master works. When you have
|
|
||||||
// hydras plugged in, you'll get 4 "palms" but only the number of controllers lifted
|
|
||||||
// of the base station are considered active. So when you ask for "left" you get the
|
|
||||||
// first active controller. If you have both controllers held up or just the left, that
|
|
||||||
// will be correct. But if you lift the right controller, then it will be reported
|
|
||||||
// as "left"... you also see this in the avatars hands.
|
|
||||||
const PalmData* MyAvatar::getActivePalm(int palmIndex) const {
|
|
||||||
const HandData* handData = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHandData();
|
|
||||||
int numberOfPalms = handData->getNumPalms();
|
|
||||||
int numberOfActivePalms = 0;
|
|
||||||
for (int i = 0; i < numberOfPalms; i++) {
|
|
||||||
auto palm = handData->getPalms()[i];
|
|
||||||
if (palm.isActive()) {
|
|
||||||
// if we've reached the requested "active" palm, then we will return it
|
|
||||||
if (numberOfActivePalms == palmIndex) {
|
|
||||||
return &handData->getPalms()[i];
|
|
||||||
}
|
|
||||||
numberOfActivePalms++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
glm::vec3 MyAvatar::getLeftHandPosition() const {
|
glm::vec3 MyAvatar::getLeftHandPosition() const {
|
||||||
const int LEFT_HAND = 0;
|
auto palmData = getHandData()->getCopyOfPalmData(HandData::LeftHand);
|
||||||
auto palmData = getActivePalm(LEFT_HAND);
|
return palmData.isValid() ? palmData.getPosition() : glm::vec3(0.0f);
|
||||||
return palmData ? palmData->getPosition() : glm::vec3(0.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 MyAvatar::getRightHandPosition() const {
|
glm::vec3 MyAvatar::getRightHandPosition() const {
|
||||||
const int RIGHT_HAND = 1;
|
auto palmData = getHandData()->getCopyOfPalmData(HandData::RightHand);
|
||||||
auto palmData = getActivePalm(RIGHT_HAND);
|
return palmData.isValid() ? palmData.getPosition() : glm::vec3(0.0f);
|
||||||
return palmData ? palmData->getPosition() : glm::vec3(0.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 MyAvatar::getLeftHandTipPosition() const {
|
glm::vec3 MyAvatar::getLeftHandTipPosition() const {
|
||||||
const int LEFT_HAND = 0;
|
auto palmData = getHandData()->getCopyOfPalmData(HandData::LeftHand);
|
||||||
auto palmData = getActivePalm(LEFT_HAND);
|
return palmData.isValid() ? palmData.getTipPosition() : glm::vec3(0.0f);
|
||||||
return palmData ? palmData->getTipPosition() : glm::vec3(0.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 MyAvatar::getRightHandTipPosition() const {
|
glm::vec3 MyAvatar::getRightHandTipPosition() const {
|
||||||
const int RIGHT_HAND = 1;
|
auto palmData = getHandData()->getCopyOfPalmData(HandData::RightHand);
|
||||||
auto palmData = getActivePalm(RIGHT_HAND);
|
return palmData.isValid() ? palmData.getTipPosition() : glm::vec3(0.0f);
|
||||||
return palmData ? palmData->getTipPosition() : glm::vec3(0.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
controller::Pose MyAvatar::getLeftHandPose() const {
|
controller::Pose MyAvatar::getLeftHandPose() const {
|
||||||
const int LEFT_HAND = 0;
|
auto palmData = getHandData()->getCopyOfPalmData(HandData::LeftHand);
|
||||||
auto palmData = getActivePalm(LEFT_HAND);
|
return palmData.isValid() ? controller::Pose(palmData.getPosition(), palmData.getRotation(),
|
||||||
return palmData ? controller::Pose(palmData->getPosition(), palmData->getRotation(),
|
palmData.getVelocity(), palmData.getRawAngularVelocityAsQuat()) : controller::Pose();
|
||||||
palmData->getVelocity(), palmData->getRawAngularVelocityAsQuat()) : controller::Pose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
controller::Pose MyAvatar::getRightHandPose() const {
|
controller::Pose MyAvatar::getRightHandPose() const {
|
||||||
const int RIGHT_HAND = 1;
|
auto palmData = getHandData()->getCopyOfPalmData(HandData::RightHand);
|
||||||
auto palmData = getActivePalm(RIGHT_HAND);
|
return palmData.isValid() ? controller::Pose(palmData.getPosition(), palmData.getRotation(),
|
||||||
return palmData ? controller::Pose(palmData->getPosition(), palmData->getRotation(),
|
palmData.getVelocity(), palmData.getRawAngularVelocityAsQuat()) : controller::Pose();
|
||||||
palmData->getVelocity(), palmData->getRawAngularVelocityAsQuat()) : controller::Pose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
controller::Pose MyAvatar::getLeftHandTipPose() const {
|
controller::Pose MyAvatar::getLeftHandTipPose() const {
|
||||||
const int LEFT_HAND = 0;
|
auto palmData = getHandData()->getCopyOfPalmData(HandData::LeftHand);
|
||||||
auto palmData = getActivePalm(LEFT_HAND);
|
return palmData.isValid() ? controller::Pose(palmData.getTipPosition(), palmData.getRotation(),
|
||||||
return palmData ? controller::Pose(palmData->getTipPosition(), palmData->getRotation(),
|
palmData.getTipVelocity(), palmData.getRawAngularVelocityAsQuat()) : controller::Pose();
|
||||||
palmData->getTipVelocity(), palmData->getRawAngularVelocityAsQuat()) : controller::Pose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
controller::Pose MyAvatar::getRightHandTipPose() const {
|
controller::Pose MyAvatar::getRightHandTipPose() const {
|
||||||
const int RIGHT_HAND = 1;
|
auto palmData = getHandData()->getCopyOfPalmData(HandData::RightHand);
|
||||||
auto palmData = getActivePalm(RIGHT_HAND);
|
return palmData.isValid() ? controller::Pose(palmData.getTipPosition(), palmData.getRotation(),
|
||||||
return palmData ? controller::Pose(palmData->getTipPosition(), palmData->getRotation(),
|
palmData.getTipVelocity(), palmData.getRawAngularVelocityAsQuat()) : controller::Pose();
|
||||||
palmData->getTipVelocity(), palmData->getRawAngularVelocityAsQuat()) : controller::Pose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
|
@ -1967,28 +1935,6 @@ void MyAvatar::updateMotionBehaviorFromMenu() {
|
||||||
_characterController.setEnabled(menu->isOptionChecked(MenuOption::EnableCharacterController));
|
_characterController.setEnabled(menu->isOptionChecked(MenuOption::EnableCharacterController));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Renders sixense laser pointers for UI selection with controllers
|
|
||||||
void MyAvatar::renderLaserPointers(gpu::Batch& batch) {
|
|
||||||
const float PALM_TIP_ROD_RADIUS = 0.002f;
|
|
||||||
|
|
||||||
//If the Oculus is enabled, we will draw a blue cursor ray
|
|
||||||
|
|
||||||
for (size_t i = 0; i < getHand()->getNumPalms(); ++i) {
|
|
||||||
PalmData& palm = getHand()->getPalms()[i];
|
|
||||||
if (palm.isActive()) {
|
|
||||||
glm::vec3 tip = getLaserPointerTipPosition(&palm);
|
|
||||||
glm::vec3 root = palm.getPosition();
|
|
||||||
|
|
||||||
//Scale the root vector with the avatar scale
|
|
||||||
scaleVectorRelativeToPosition(root);
|
|
||||||
Transform transform = Transform();
|
|
||||||
transform.setTranslation(glm::vec3());
|
|
||||||
batch.setModelTransform(transform);
|
|
||||||
Avatar::renderJointConnectingCone(batch, root, tip, PALM_TIP_ROD_RADIUS, PALM_TIP_ROD_RADIUS, glm::vec4(0, 1, 1, 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Gets the tip position for the laser pointer
|
//Gets the tip position for the laser pointer
|
||||||
glm::vec3 MyAvatar::getLaserPointerTipPosition(const PalmData* palm) {
|
glm::vec3 MyAvatar::getLaserPointerTipPosition(const PalmData* palm) {
|
||||||
glm::vec3 direction = glm::normalize(palm->getTipPosition() - palm->getPosition());
|
glm::vec3 direction = glm::normalize(palm->getTipPosition() - palm->getPosition());
|
||||||
|
|
|
@ -294,7 +294,6 @@ private:
|
||||||
const glm::vec3& translation = glm::vec3(), const glm::quat& rotation = glm::quat(), float scale = 1.0f,
|
const glm::vec3& translation = glm::vec3(), const glm::quat& rotation = glm::quat(), float scale = 1.0f,
|
||||||
bool allowDuplicates = false, bool useSaved = true) override;
|
bool allowDuplicates = false, bool useSaved = true) override;
|
||||||
|
|
||||||
void renderLaserPointers(gpu::Batch& batch);
|
|
||||||
const RecorderPointer getRecorder() const { return _recorder; }
|
const RecorderPointer getRecorder() const { return _recorder; }
|
||||||
const PlayerPointer getPlayer() const { return _player; }
|
const PlayerPointer getPlayer() const { return _player; }
|
||||||
|
|
||||||
|
@ -310,8 +309,7 @@ private:
|
||||||
|
|
||||||
void setVisibleInSceneIfReady(Model* model, render::ScenePointer scene, bool visiblity);
|
void setVisibleInSceneIfReady(Model* model, render::ScenePointer scene, bool visiblity);
|
||||||
|
|
||||||
const PalmData* getActivePalm(int palmIndex) const;
|
PalmData getActivePalmData(int palmIndex) const;
|
||||||
|
|
||||||
|
|
||||||
// derive avatar body position and orientation from the current HMD Sensor location.
|
// derive avatar body position and orientation from the current HMD Sensor location.
|
||||||
// results are in sensor space
|
// results are in sensor space
|
||||||
|
|
|
@ -97,17 +97,6 @@ void SkeletonModel::initJointStates(QVector<JointState> states) {
|
||||||
emit skeletonLoaded();
|
emit skeletonLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const PalmData* getPalmWithIndex(Hand* hand, int index) {
|
|
||||||
const PalmData* palm = nullptr;
|
|
||||||
for (size_t j = 0; j < hand->getNumPalms(); j++) {
|
|
||||||
if (hand->getPalms()[j].getSixenseID() == index) {
|
|
||||||
palm = &(hand->getPalms()[j]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return palm;
|
|
||||||
}
|
|
||||||
|
|
||||||
const float PALM_PRIORITY = DEFAULT_PRIORITY;
|
const float PALM_PRIORITY = DEFAULT_PRIORITY;
|
||||||
// Called within Model::simulate call, below.
|
// Called within Model::simulate call, below.
|
||||||
void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
||||||
|
@ -169,22 +158,22 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) {
|
||||||
|
|
||||||
Rig::HandParameters handParams;
|
Rig::HandParameters handParams;
|
||||||
|
|
||||||
const PalmData* leftPalm = getPalmWithIndex(myAvatar->getHand(), LEFT_HAND_INDEX);
|
auto leftPalm = myAvatar->getHand()->getCopyOfPalmData(HandData::LeftHand);
|
||||||
if (leftPalm && leftPalm->isActive()) {
|
if (leftPalm.isValid() && leftPalm.isActive()) {
|
||||||
handParams.isLeftEnabled = true;
|
handParams.isLeftEnabled = true;
|
||||||
handParams.leftPosition = leftPalm->getRawPosition();
|
handParams.leftPosition = leftPalm.getRawPosition();
|
||||||
handParams.leftOrientation = leftPalm->getRawRotation();
|
handParams.leftOrientation = leftPalm.getRawRotation();
|
||||||
handParams.leftTrigger = leftPalm->getTrigger();
|
handParams.leftTrigger = leftPalm.getTrigger();
|
||||||
} else {
|
} else {
|
||||||
handParams.isLeftEnabled = false;
|
handParams.isLeftEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PalmData* rightPalm = getPalmWithIndex(myAvatar->getHand(), RIGHT_HAND_INDEX);
|
auto rightPalm = myAvatar->getHand()->getCopyOfPalmData(HandData::RightHand);
|
||||||
if (rightPalm && rightPalm->isActive()) {
|
if (rightPalm.isValid() && rightPalm.isActive()) {
|
||||||
handParams.isRightEnabled = true;
|
handParams.isRightEnabled = true;
|
||||||
handParams.rightPosition = rightPalm->getRawPosition();
|
handParams.rightPosition = rightPalm.getRawPosition();
|
||||||
handParams.rightOrientation = rightPalm->getRawRotation();
|
handParams.rightOrientation = rightPalm.getRawRotation();
|
||||||
handParams.rightTrigger = rightPalm->getTrigger();
|
handParams.rightTrigger = rightPalm.getTrigger();
|
||||||
} else {
|
} else {
|
||||||
handParams.isRightEnabled = false;
|
handParams.isRightEnabled = false;
|
||||||
}
|
}
|
||||||
|
@ -247,15 +236,15 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
|
||||||
|
|
||||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
|
|
||||||
// find the left and rightmost active palms
|
|
||||||
int leftPalmIndex, rightPalmIndex;
|
|
||||||
Hand* hand = _owningAvatar->getHand();
|
|
||||||
hand->getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex);
|
|
||||||
|
|
||||||
// Don't Relax toward hand positions when in animGraph mode.
|
// Don't Relax toward hand positions when in animGraph mode.
|
||||||
if (!_rig->getEnableAnimGraph()) {
|
if (!_rig->getEnableAnimGraph()) {
|
||||||
|
|
||||||
|
Hand* hand = _owningAvatar->getHand();
|
||||||
|
auto leftPalm = hand->getCopyOfPalmData(HandData::LeftHand);
|
||||||
|
auto rightPalm = hand->getCopyOfPalmData(HandData::RightHand);
|
||||||
|
|
||||||
const float HAND_RESTORATION_RATE = 0.25f;
|
const float HAND_RESTORATION_RATE = 0.25f;
|
||||||
if (leftPalmIndex == -1 && rightPalmIndex == -1) {
|
if (!leftPalm.isActive() && !rightPalm.isActive()) {
|
||||||
// palms are not yet set, use mouse
|
// palms are not yet set, use mouse
|
||||||
if (_owningAvatar->getHandState() == HAND_STATE_NULL) {
|
if (_owningAvatar->getHandState() == HAND_STATE_NULL) {
|
||||||
restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
|
restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
|
||||||
|
@ -265,20 +254,14 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
|
||||||
applyHandPosition(geometry.rightHandJointIndex, handPosition);
|
applyHandPosition(geometry.rightHandJointIndex, handPosition);
|
||||||
}
|
}
|
||||||
restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
|
restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
|
||||||
|
|
||||||
} else if (leftPalmIndex == rightPalmIndex) {
|
|
||||||
// right hand only
|
|
||||||
applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[leftPalmIndex]);
|
|
||||||
restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (leftPalmIndex != -1) {
|
if (leftPalm.isActive()) {
|
||||||
applyPalmData(geometry.leftHandJointIndex, hand->getPalms()[leftPalmIndex]);
|
applyPalmData(geometry.leftHandJointIndex, leftPalm);
|
||||||
} else {
|
} else {
|
||||||
restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
|
restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
|
||||||
}
|
}
|
||||||
if (rightPalmIndex != -1) {
|
if (rightPalm.isActive()) {
|
||||||
applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[rightPalmIndex]);
|
applyPalmData(geometry.rightHandJointIndex, rightPalm);
|
||||||
} else {
|
} else {
|
||||||
restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
|
restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
|
||||||
}
|
}
|
||||||
|
@ -329,7 +312,7 @@ void SkeletonModel::applyHandPosition(int jointIndex, const glm::vec3& position)
|
||||||
PALM_PRIORITY);
|
PALM_PRIORITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) {
|
void SkeletonModel::applyPalmData(int jointIndex, const PalmData& palm) {
|
||||||
if (jointIndex == -1 || jointIndex >= _rig->getJointStateCount()) {
|
if (jointIndex == -1 || jointIndex >= _rig->getJointStateCount()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ protected:
|
||||||
/// \param position position of joint in model-frame
|
/// \param position position of joint in model-frame
|
||||||
void applyHandPosition(int jointIndex, const glm::vec3& position);
|
void applyHandPosition(int jointIndex, const glm::vec3& position);
|
||||||
|
|
||||||
void applyPalmData(int jointIndex, PalmData& palm);
|
void applyPalmData(int jointIndex, const PalmData& palm);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void renderJointConstraints(gpu::Batch& batch, int jointIndex);
|
void renderJointConstraints(gpu::Batch& batch, int jointIndex);
|
||||||
|
|
|
@ -35,51 +35,6 @@ void ControllerScriptingInterface::handleMetaEvent(HFMetaEvent* event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const PalmData* ControllerScriptingInterface::getPrimaryPalm() const {
|
|
||||||
int leftPalmIndex, rightPalmIndex;
|
|
||||||
|
|
||||||
const HandData* handData = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHandData();
|
|
||||||
handData->getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex);
|
|
||||||
|
|
||||||
if (rightPalmIndex != -1) {
|
|
||||||
return &handData->getPalms()[rightPalmIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ControllerScriptingInterface::getNumberOfActivePalms() const {
|
|
||||||
const HandData* handData = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHandData();
|
|
||||||
int numberOfPalms = handData->getNumPalms();
|
|
||||||
int numberOfActivePalms = 0;
|
|
||||||
for (int i = 0; i < numberOfPalms; i++) {
|
|
||||||
if (getPalm(i)->isActive()) {
|
|
||||||
numberOfActivePalms++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return numberOfActivePalms;
|
|
||||||
}
|
|
||||||
|
|
||||||
const PalmData* ControllerScriptingInterface::getPalm(int palmIndex) const {
|
|
||||||
const HandData* handData = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHandData();
|
|
||||||
return &handData->getPalms()[palmIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
const PalmData* ControllerScriptingInterface::getActivePalm(int palmIndex) const {
|
|
||||||
const HandData* handData = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHandData();
|
|
||||||
int numberOfPalms = handData->getNumPalms();
|
|
||||||
int numberOfActivePalms = 0;
|
|
||||||
for (int i = 0; i < numberOfPalms; i++) {
|
|
||||||
if (getPalm(i)->isActive()) {
|
|
||||||
if (numberOfActivePalms == palmIndex) {
|
|
||||||
return &handData->getPalms()[i];
|
|
||||||
}
|
|
||||||
numberOfActivePalms++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ControllerScriptingInterface::isKeyCaptured(QKeyEvent* event) const {
|
bool ControllerScriptingInterface::isKeyCaptured(QKeyEvent* event) const {
|
||||||
return isKeyCaptured(KeyEvent(*event));
|
return isKeyCaptured(KeyEvent(*event));
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,11 +123,6 @@ signals:
|
||||||
private:
|
private:
|
||||||
QString sanatizeName(const QString& name); /// makes a name clean for inclusing in JavaScript
|
QString sanatizeName(const QString& name); /// makes a name clean for inclusing in JavaScript
|
||||||
|
|
||||||
const PalmData* getPrimaryPalm() const;
|
|
||||||
const PalmData* getPalm(int palmIndex) const;
|
|
||||||
int getNumberOfActivePalms() const;
|
|
||||||
const PalmData* getActivePalm(int palmIndex) const;
|
|
||||||
|
|
||||||
QMultiMap<int,KeyEvent> _capturedKeys;
|
QMultiMap<int,KeyEvent> _capturedKeys;
|
||||||
QSet<int> _capturedJoysticks;
|
QSet<int> _capturedJoysticks;
|
||||||
|
|
||||||
|
|
|
@ -320,8 +320,8 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
|
||||||
// Only render the hand pointers if the EnableHandMouseInput is enabled
|
// Only render the hand pointers if the EnableHandMouseInput is enabled
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) {
|
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) {
|
||||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
|
auto palms = myAvatar->getHand()->getCopyOfPalms();
|
||||||
PalmData& palm = myAvatar->getHand()->getPalms()[i];
|
for (const auto& palm : palms) {
|
||||||
if (palm.isActive()) {
|
if (palm.isActive()) {
|
||||||
glm::vec2 polar = getPolarCoordinates(palm);
|
glm::vec2 polar = getPolarCoordinates(palm);
|
||||||
// Convert to quaternion
|
// Convert to quaternion
|
||||||
|
@ -446,6 +446,7 @@ void ApplicationCompositor::renderPointers(gpu::Batch& batch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME - this is old code that likely needs to be removed and/or reworked to support the new input control model
|
||||||
void ApplicationCompositor::renderControllerPointers(gpu::Batch& batch) {
|
void ApplicationCompositor::renderControllerPointers(gpu::Batch& batch) {
|
||||||
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
|
|
||||||
|
@ -455,23 +456,24 @@ void ApplicationCompositor::renderControllerPointers(gpu::Batch& batch) {
|
||||||
static bool stateWhenPressed[NUMBER_OF_RETICLES] = { false, false, false };
|
static bool stateWhenPressed[NUMBER_OF_RETICLES] = { false, false, false };
|
||||||
|
|
||||||
const HandData* handData = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHandData();
|
const HandData* handData = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHandData();
|
||||||
|
auto palms = handData->getCopyOfPalms();
|
||||||
|
|
||||||
for (unsigned int palmIndex = 2; palmIndex < 4; palmIndex++) {
|
for (unsigned int palmIndex = 2; palmIndex < 4; palmIndex++) {
|
||||||
const int index = palmIndex - 1;
|
const int index = palmIndex - 1;
|
||||||
|
|
||||||
const PalmData* palmData = NULL;
|
const PalmData* palmData = NULL;
|
||||||
|
|
||||||
if (palmIndex >= handData->getPalms().size()) {
|
if (palmIndex >= palms.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handData->getPalms()[palmIndex].isActive()) {
|
if (palms[palmIndex].isActive()) {
|
||||||
palmData = &handData->getPalms()[palmIndex];
|
palmData = &palms[palmIndex];
|
||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int controllerButtons = palmData->getControllerButtons();
|
int controllerButtons = 0;
|
||||||
|
|
||||||
//Check for if we should toggle or drag the magnification window
|
//Check for if we should toggle or drag the magnification window
|
||||||
if (controllerButtons & BUTTON_3) {
|
if (controllerButtons & BUTTON_3) {
|
||||||
|
|
|
@ -21,62 +21,43 @@
|
||||||
HandData::HandData(AvatarData* owningAvatar) :
|
HandData::HandData(AvatarData* owningAvatar) :
|
||||||
_owningAvatarData(owningAvatar)
|
_owningAvatarData(owningAvatar)
|
||||||
{
|
{
|
||||||
// Start with two palms
|
addNewPalm(LeftHand);
|
||||||
addNewPalm();
|
addNewPalm(RightHand);
|
||||||
addNewPalm();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 HandData::worldToLocalVector(const glm::vec3& worldVector) const {
|
glm::vec3 HandData::worldToLocalVector(const glm::vec3& worldVector) const {
|
||||||
return glm::inverse(getBaseOrientation()) * worldVector / getBaseScale();
|
return glm::inverse(getBaseOrientation()) * worldVector / getBaseScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
PalmData& HandData::addNewPalm() {
|
PalmData& HandData::addNewPalm(Hand whichHand) {
|
||||||
_palms.push_back(PalmData(this));
|
QWriteLocker locker(&_palmsLock);
|
||||||
|
_palms.push_back(PalmData(this, whichHand));
|
||||||
return _palms.back();
|
return _palms.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
const PalmData* HandData::getPalm(int sixSenseID) const {
|
PalmData HandData::getCopyOfPalmData(Hand hand) const {
|
||||||
|
QReadLocker locker(&_palmsLock);
|
||||||
|
|
||||||
// the palms are not necessarily added in left-right order,
|
// the palms are not necessarily added in left-right order,
|
||||||
// so we have to search for the right SixSenseID
|
// so we have to search for the correct hand
|
||||||
for (unsigned int i = 0; i < _palms.size(); i++) {
|
for (const auto& palm : _palms) {
|
||||||
const PalmData* palm = &(_palms[i]);
|
if (palm.whichHand() == hand && palm.isActive()) {
|
||||||
if (palm->getSixenseID() == sixSenseID) {
|
return palm;
|
||||||
return palm->isActive() ? palm : NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return PalmData(); // invalid hand
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandData::getLeftRightPalmIndices(int& leftPalmIndex, int& rightPalmIndex) const {
|
PalmData::PalmData(HandData* owningHandData, HandData::Hand hand) :
|
||||||
leftPalmIndex = -1;
|
|
||||||
rightPalmIndex = -1;
|
|
||||||
for (size_t i = 0; i < _palms.size(); i++) {
|
|
||||||
const PalmData& palm = _palms[i];
|
|
||||||
if (palm.isActive()) {
|
|
||||||
if (palm.getSixenseID() == LEFT_HAND_INDEX) {
|
|
||||||
leftPalmIndex = i;
|
|
||||||
}
|
|
||||||
if (palm.getSixenseID() == RIGHT_HAND_INDEX) {
|
|
||||||
rightPalmIndex = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PalmData::PalmData(HandData* owningHandData) :
|
|
||||||
_rawRotation(0.0f, 0.0f, 0.0f, 1.0f),
|
_rawRotation(0.0f, 0.0f, 0.0f, 1.0f),
|
||||||
_rawPosition(0.0f),
|
_rawPosition(0.0f),
|
||||||
_rawVelocity(0.0f),
|
_rawVelocity(0.0f),
|
||||||
_rawAngularVelocity(0.0f),
|
_rawAngularVelocity(0.0f),
|
||||||
_totalPenetration(0.0f),
|
_totalPenetration(0.0f),
|
||||||
_controllerButtons(0),
|
|
||||||
_isActive(false),
|
_isActive(false),
|
||||||
_sixenseID(SIXENSEID_INVALID),
|
|
||||||
_numFramesWithoutData(0),
|
_numFramesWithoutData(0),
|
||||||
_owningHandData(owningHandData),
|
_owningHandData(owningHandData),
|
||||||
_isCollidingWithVoxel(false),
|
_hand(hand) {
|
||||||
_isCollidingWithPalm(false),
|
|
||||||
_collisionlessPaddleExpiry(0) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PalmData::addToPosition(const glm::vec3& delta) {
|
void PalmData::addToPosition(const glm::vec3& delta) {
|
||||||
|
@ -85,9 +66,9 @@ void PalmData::addToPosition(const glm::vec3& delta) {
|
||||||
|
|
||||||
bool HandData::findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration,
|
bool HandData::findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration,
|
||||||
const PalmData*& collidingPalm) const {
|
const PalmData*& collidingPalm) const {
|
||||||
|
QReadLocker locker(&_palmsLock);
|
||||||
for (size_t i = 0; i < _palms.size(); ++i) {
|
|
||||||
const PalmData& palm = _palms[i];
|
for (const auto& palm : _palms) {
|
||||||
if (!palm.isActive()) {
|
if (!palm.isActive()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,26 +12,30 @@
|
||||||
#ifndef hifi_HandData_h
|
#ifndef hifi_HandData_h
|
||||||
#define hifi_HandData_h
|
#define hifi_HandData_h
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/quaternion.hpp>
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
|
#include <QReadWriteLock>
|
||||||
|
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
class AvatarData;
|
class AvatarData;
|
||||||
class PalmData;
|
class PalmData;
|
||||||
|
|
||||||
const int LEFT_HAND_INDEX = 0;
|
|
||||||
const int RIGHT_HAND_INDEX = 1;
|
|
||||||
const int NUM_HANDS = 2;
|
|
||||||
|
|
||||||
const int SIXENSEID_INVALID = -1;
|
|
||||||
|
|
||||||
class HandData {
|
class HandData {
|
||||||
public:
|
public:
|
||||||
|
enum Hand {
|
||||||
|
LeftHand,
|
||||||
|
RightHand,
|
||||||
|
UnknownHand,
|
||||||
|
NUMBER_OF_HANDS
|
||||||
|
};
|
||||||
|
|
||||||
HandData(AvatarData* owningAvatar);
|
HandData(AvatarData* owningAvatar);
|
||||||
virtual ~HandData() {}
|
virtual ~HandData() {}
|
||||||
|
|
||||||
|
@ -46,15 +50,9 @@ public:
|
||||||
|
|
||||||
glm::vec3 worldToLocalVector(const glm::vec3& worldVector) const;
|
glm::vec3 worldToLocalVector(const glm::vec3& worldVector) const;
|
||||||
|
|
||||||
std::vector<PalmData>& getPalms() { return _palms; }
|
PalmData getCopyOfPalmData(Hand hand) const;
|
||||||
const std::vector<PalmData>& getPalms() const { return _palms; }
|
|
||||||
const PalmData* getPalm(int sixSenseID) const;
|
|
||||||
size_t getNumPalms() const { return _palms.size(); }
|
|
||||||
PalmData& addNewPalm();
|
|
||||||
|
|
||||||
/// Finds the indices of the left and right palms according to their locations, or -1 if either or
|
std::vector<PalmData> getCopyOfPalms() const { QReadLocker locker(&_palmsLock); return _palms; }
|
||||||
/// both is not found.
|
|
||||||
void getLeftRightPalmIndices(int& leftPalmIndex, int& rightPalmIndex) const;
|
|
||||||
|
|
||||||
/// Checks for penetration between the described sphere and the hand.
|
/// Checks for penetration between the described sphere and the hand.
|
||||||
/// \param penetratorCenter the center of the penetration test sphere
|
/// \param penetratorCenter the center of the penetration test sphere
|
||||||
|
@ -67,14 +65,22 @@ public:
|
||||||
|
|
||||||
glm::quat getBaseOrientation() const;
|
glm::quat getBaseOrientation() const;
|
||||||
|
|
||||||
|
/// Allows a lamda function write access to the specific palm for this Hand, this might
|
||||||
|
/// modify the _palms vector
|
||||||
|
template<typename PalmModifierFunction> void modifyPalm(Hand whichHand, PalmModifierFunction callback);
|
||||||
|
|
||||||
friend class AvatarData;
|
friend class AvatarData;
|
||||||
protected:
|
protected:
|
||||||
AvatarData* _owningAvatarData;
|
AvatarData* _owningAvatarData;
|
||||||
std::vector<PalmData> _palms;
|
std::vector<PalmData> _palms;
|
||||||
|
mutable QReadWriteLock _palmsLock{ QReadWriteLock::Recursive };
|
||||||
|
|
||||||
glm::vec3 getBasePosition() const;
|
glm::vec3 getBasePosition() const;
|
||||||
float getBaseScale() const;
|
float getBaseScale() const;
|
||||||
|
|
||||||
|
PalmData& addNewPalm(Hand whichHand);
|
||||||
|
PalmData& getPalmData(Hand hand);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// privatize copy ctor and assignment operator so copies of this object cannot be made
|
// privatize copy ctor and assignment operator so copies of this object cannot be made
|
||||||
HandData(const HandData&);
|
HandData(const HandData&);
|
||||||
|
@ -84,18 +90,20 @@ private:
|
||||||
|
|
||||||
class PalmData {
|
class PalmData {
|
||||||
public:
|
public:
|
||||||
PalmData(HandData* owningHandData);
|
PalmData(HandData* owningHandData = nullptr, HandData::Hand hand = HandData::UnknownHand);
|
||||||
glm::vec3 getPosition() const { return _owningHandData->localToWorldPosition(_rawPosition); }
|
glm::vec3 getPosition() const { return _owningHandData->localToWorldPosition(_rawPosition); }
|
||||||
glm::vec3 getVelocity() const { return _owningHandData->localToWorldDirection(_rawVelocity); }
|
glm::vec3 getVelocity() const { return _owningHandData->localToWorldDirection(_rawVelocity); }
|
||||||
|
|
||||||
const glm::vec3& getRawPosition() const { return _rawPosition; }
|
const glm::vec3& getRawPosition() const { return _rawPosition; }
|
||||||
bool isActive() const { return _isActive; }
|
bool isActive() const { return _isActive; }
|
||||||
int getSixenseID() const { return _sixenseID; }
|
bool isValid() const { return _owningHandData; }
|
||||||
|
|
||||||
void setActive(bool active) { _isActive = active; }
|
void setActive(bool active) { _isActive = active; }
|
||||||
void setSixenseID(int id) { _sixenseID = id; }
|
|
||||||
|
|
||||||
void setRawRotation(const glm::quat rawRotation) { _rawRotation = rawRotation; };
|
HandData::Hand whichHand() const { return _hand; }
|
||||||
|
void setHand(HandData::Hand hand) { _hand = hand; }
|
||||||
|
|
||||||
|
void setRawRotation(const glm::quat& rawRotation) { _rawRotation = rawRotation; };
|
||||||
glm::quat getRawRotation() const { return _rawRotation; }
|
glm::quat getRawRotation() const { return _rawRotation; }
|
||||||
glm::quat getRotation() const { return _owningHandData->getBaseOrientation() * _rawRotation; }
|
glm::quat getRotation() const { return _owningHandData->getBaseOrientation() * _rawRotation; }
|
||||||
void setRawPosition(const glm::vec3& pos) { _rawPosition = pos; }
|
void setRawPosition(const glm::vec3& pos) { _rawPosition = pos; }
|
||||||
|
@ -123,31 +131,11 @@ public:
|
||||||
void resetFramesWithoutData() { _numFramesWithoutData = 0; }
|
void resetFramesWithoutData() { _numFramesWithoutData = 0; }
|
||||||
int getFramesWithoutData() const { return _numFramesWithoutData; }
|
int getFramesWithoutData() const { return _numFramesWithoutData; }
|
||||||
|
|
||||||
// Controller buttons
|
// FIXME - these are used in SkeletonModel::updateRig() the skeleton/rig should probably get this information
|
||||||
void setControllerButtons(unsigned int controllerButtons) { _controllerButtons = controllerButtons; }
|
// from an action and/or the UserInputMapper instead of piping it through here.
|
||||||
void setLastControllerButtons(unsigned int controllerButtons) { _lastControllerButtons = controllerButtons; }
|
|
||||||
|
|
||||||
unsigned int getControllerButtons() const { return _controllerButtons; }
|
|
||||||
unsigned int getLastControllerButtons() const { return _lastControllerButtons; }
|
|
||||||
|
|
||||||
void setTrigger(float trigger) { _trigger = trigger; }
|
void setTrigger(float trigger) { _trigger = trigger; }
|
||||||
float getTrigger() const { return _trigger; }
|
float getTrigger() const { return _trigger; }
|
||||||
void setJoystick(float joystickX, float joystickY) { _joystickX = joystickX; _joystickY = joystickY; }
|
|
||||||
float getJoystickX() const { return _joystickX; }
|
|
||||||
float getJoystickY() const { return _joystickY; }
|
|
||||||
|
|
||||||
bool getIsCollidingWithVoxel() const { return _isCollidingWithVoxel; }
|
|
||||||
void setIsCollidingWithVoxel(bool isCollidingWithVoxel) { _isCollidingWithVoxel = isCollidingWithVoxel; }
|
|
||||||
|
|
||||||
bool getIsCollidingWithPalm() const { return _isCollidingWithPalm; }
|
|
||||||
void setIsCollidingWithPalm(bool isCollidingWithPalm) { _isCollidingWithPalm = isCollidingWithPalm; }
|
|
||||||
|
|
||||||
bool hasPaddle() const { return _collisionlessPaddleExpiry < usecTimestampNow(); }
|
|
||||||
void updateCollisionlessPaddleExpiry() { _collisionlessPaddleExpiry = usecTimestampNow() + USECS_PER_SECOND; }
|
|
||||||
|
|
||||||
/// Store position where the palm holds the ball.
|
|
||||||
void getBallHoldPosition(glm::vec3& position) const;
|
|
||||||
|
|
||||||
// return world-frame:
|
// return world-frame:
|
||||||
glm::vec3 getFingerDirection() const;
|
glm::vec3 getFingerDirection() const;
|
||||||
glm::vec3 getNormal() const;
|
glm::vec3 getNormal() const;
|
||||||
|
@ -163,21 +151,24 @@ private:
|
||||||
|
|
||||||
glm::vec3 _tipPosition;
|
glm::vec3 _tipPosition;
|
||||||
glm::vec3 _tipVelocity;
|
glm::vec3 _tipVelocity;
|
||||||
glm::vec3 _totalPenetration; // accumulator for per-frame penetrations
|
glm::vec3 _totalPenetration; /// accumulator for per-frame penetrations
|
||||||
|
|
||||||
unsigned int _controllerButtons;
|
|
||||||
unsigned int _lastControllerButtons;
|
|
||||||
float _trigger;
|
float _trigger;
|
||||||
float _joystickX, _joystickY;
|
|
||||||
|
|
||||||
bool _isActive; // This has current valid data
|
bool _isActive; /// This has current valid data
|
||||||
int _sixenseID; // Sixense controller ID for this palm
|
int _numFramesWithoutData; /// after too many frames without data, this tracked object assumed lost.
|
||||||
int _numFramesWithoutData; // after too many frames without data, this tracked object assumed lost.
|
|
||||||
HandData* _owningHandData;
|
HandData* _owningHandData;
|
||||||
|
HandData::Hand _hand;
|
||||||
bool _isCollidingWithVoxel; /// Whether the finger of this palm is inside a leaf voxel
|
|
||||||
bool _isCollidingWithPalm;
|
|
||||||
quint64 _collisionlessPaddleExpiry; /// Timestamp after which paddle starts colliding
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename PalmModifierFunction> void HandData::modifyPalm(Hand whichHand, PalmModifierFunction callback) {
|
||||||
|
QReadLocker locker(&_palmsLock);
|
||||||
|
for (auto& palm : _palms) {
|
||||||
|
if (palm.whichHand() == whichHand && palm.isValid()) {
|
||||||
|
callback(palm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // hifi_HandData_h
|
#endif // hifi_HandData_h
|
||||||
|
|
Loading…
Reference in a new issue