mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 08:33:12 +02:00
Merge pull request #6673 from hyperlogic/tony/get-palm-thread-safe
Make Avatar palm position/rotation accessors thread safe
This commit is contained in:
commit
c2f2f950fb
5 changed files with 98 additions and 20 deletions
|
@ -237,6 +237,7 @@ void Avatar::simulate(float deltaTime) {
|
|||
measureMotionDerivatives(deltaTime);
|
||||
|
||||
simulateAttachments(deltaTime);
|
||||
updatePalms();
|
||||
}
|
||||
|
||||
bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) const {
|
||||
|
@ -1155,34 +1156,24 @@ void Avatar::rebuildCollisionShape() {
|
|||
}
|
||||
}
|
||||
|
||||
// thread-safe
|
||||
glm::vec3 Avatar::getLeftPalmPosition() {
|
||||
glm::vec3 leftHandPosition;
|
||||
getSkeletonModel().getLeftHandPosition(leftHandPosition);
|
||||
glm::quat leftRotation;
|
||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation);
|
||||
leftHandPosition += HAND_TO_PALM_OFFSET * glm::inverse(leftRotation);
|
||||
return leftHandPosition;
|
||||
return _leftPalmPositionCache.get();
|
||||
}
|
||||
|
||||
// thread-safe
|
||||
glm::quat Avatar::getLeftPalmRotation() {
|
||||
glm::quat leftRotation;
|
||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation);
|
||||
return leftRotation;
|
||||
return _leftPalmRotationCache.get();
|
||||
}
|
||||
|
||||
// thread-safe
|
||||
glm::vec3 Avatar::getRightPalmPosition() {
|
||||
glm::vec3 rightHandPosition;
|
||||
getSkeletonModel().getRightHandPosition(rightHandPosition);
|
||||
glm::quat rightRotation;
|
||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation);
|
||||
rightHandPosition += HAND_TO_PALM_OFFSET * glm::inverse(rightRotation);
|
||||
return rightHandPosition;
|
||||
return _rightPalmPositionCache.get();
|
||||
}
|
||||
|
||||
// thread-safe
|
||||
glm::quat Avatar::getRightPalmRotation() {
|
||||
glm::quat rightRotation;
|
||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation);
|
||||
return rightRotation;
|
||||
return _rightPalmRotationCache.get();
|
||||
}
|
||||
|
||||
void Avatar::setPosition(const glm::vec3& position) {
|
||||
|
@ -1194,3 +1185,24 @@ void Avatar::setOrientation(const glm::quat& orientation) {
|
|||
AvatarData::setOrientation(orientation);
|
||||
updateAttitude();
|
||||
}
|
||||
|
||||
void Avatar::updatePalms() {
|
||||
|
||||
// get palm rotations
|
||||
glm::quat leftPalmRotation, rightPalmRotation;
|
||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftPalmRotation);
|
||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightPalmRotation);
|
||||
|
||||
// get palm positions
|
||||
glm::vec3 leftPalmPosition, rightPalmPosition;
|
||||
getSkeletonModel().getLeftHandPosition(leftPalmPosition);
|
||||
getSkeletonModel().getRightHandPosition(rightPalmPosition);
|
||||
leftPalmPosition += HAND_TO_PALM_OFFSET * glm::inverse(leftPalmRotation);
|
||||
rightPalmPosition += HAND_TO_PALM_OFFSET * glm::inverse(rightPalmRotation);
|
||||
|
||||
// update thread-safe caches
|
||||
_leftPalmRotationCache.set(leftPalmRotation);
|
||||
_rightPalmRotationCache.set(rightPalmRotation);
|
||||
_leftPalmPositionCache.set(leftPalmPosition);
|
||||
_rightPalmPositionCache.set(rightPalmPosition);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "SkeletonModel.h"
|
||||
#include "world.h"
|
||||
#include "Rig.h"
|
||||
#include <ThreadSafeValueCache.h>
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar);
|
||||
|
@ -227,8 +228,15 @@ protected:
|
|||
|
||||
virtual void updateJointMappings() override;
|
||||
|
||||
virtual void updatePalms();
|
||||
|
||||
render::ItemID _renderItemID;
|
||||
|
||||
ThreadSafeValueCache<glm::vec3> _leftPalmPositionCache { glm::vec3() };
|
||||
ThreadSafeValueCache<glm::quat> _leftPalmRotationCache { glm::quat() };
|
||||
ThreadSafeValueCache<glm::vec3> _rightPalmPositionCache { glm::vec3() };
|
||||
ThreadSafeValueCache<glm::quat> _rightPalmRotationCache { glm::quat() };
|
||||
|
||||
private:
|
||||
bool _initialized;
|
||||
NetworkTexturePointer _billboardTexture;
|
||||
|
|
|
@ -417,6 +417,8 @@ void MyAvatar::updateSensorToWorldMatrix() {
|
|||
// position when driven from the head.
|
||||
glm::mat4 desiredMat = createMatFromQuatAndPos(getOrientation(), getPosition());
|
||||
_sensorToWorldMatrix = desiredMat * glm::inverse(_bodySensorMatrix);
|
||||
|
||||
lateUpdatePalms();
|
||||
}
|
||||
|
||||
// Update avatar head rotation with sensor data
|
||||
|
@ -1839,3 +1841,8 @@ QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioList
|
|||
void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode) {
|
||||
audioListenerMode = (AudioListenerMode)object.toUInt16();
|
||||
}
|
||||
|
||||
|
||||
void MyAvatar::lateUpdatePalms() {
|
||||
Avatar::updatePalms();
|
||||
}
|
||||
|
|
|
@ -311,12 +311,14 @@ private:
|
|||
|
||||
void setVisibleInSceneIfReady(Model* model, render::ScenePointer scene, bool visiblity);
|
||||
|
||||
PalmData getActivePalmData(int palmIndex) const;
|
||||
|
||||
// derive avatar body position and orientation from the current HMD Sensor location.
|
||||
// results are in HMD frame
|
||||
glm::mat4 deriveBodyFromHMDSensor() const;
|
||||
|
||||
virtual void updatePalms() override {}
|
||||
void lateUpdatePalms();
|
||||
|
||||
|
||||
float _driveKeys[MAX_DRIVE_KEYS];
|
||||
bool _wasPushing;
|
||||
bool _isPushing;
|
||||
|
|
49
libraries/shared/src/ThreadSafeValueCache.h
Normal file
49
libraries/shared/src/ThreadSafeValueCache.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// ThreadSafeValueCache.h
|
||||
// interface/src/avatar
|
||||
//
|
||||
// Copyright 2012 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ThreadSafeValueCache_h
|
||||
#define hifi_ThreadSafeValueCache_h
|
||||
|
||||
#include <mutex>
|
||||
|
||||
// Helper class for for sharing a value type between threads.
|
||||
// It allows many threads to get or set a value atomically.
|
||||
// This provides cache semantics, any get will return the last set value.
|
||||
//
|
||||
// For example: This can be used to copy values between C++ code running on the application thread
|
||||
// and JavaScript which is running on a different thread.
|
||||
|
||||
template <typename T>
|
||||
class ThreadSafeValueCache {
|
||||
public:
|
||||
ThreadSafeValueCache(const T& v) : _value { v } {}
|
||||
|
||||
// returns atomic copy of the cached value.
|
||||
T get() const {
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
return _value;
|
||||
}
|
||||
|
||||
// will reflect copy of value into the cache.
|
||||
void set(const T& v) {
|
||||
std::lock_guard<std::mutex> guard(_mutex);
|
||||
_value = v;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::mutex _mutex;
|
||||
T _value;
|
||||
|
||||
// no copies
|
||||
ThreadSafeValueCache(const ThreadSafeValueCache&) = delete;
|
||||
ThreadSafeValueCache& operator=(const ThreadSafeValueCache&) = delete;
|
||||
};
|
||||
|
||||
#endif // #define hifi_ThreadSafeValueCache_h
|
Loading…
Reference in a new issue