mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01: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);
|
measureMotionDerivatives(deltaTime);
|
||||||
|
|
||||||
simulateAttachments(deltaTime);
|
simulateAttachments(deltaTime);
|
||||||
|
updatePalms();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) const {
|
bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) const {
|
||||||
|
@ -1155,34 +1156,24 @@ void Avatar::rebuildCollisionShape() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// thread-safe
|
||||||
glm::vec3 Avatar::getLeftPalmPosition() {
|
glm::vec3 Avatar::getLeftPalmPosition() {
|
||||||
glm::vec3 leftHandPosition;
|
return _leftPalmPositionCache.get();
|
||||||
getSkeletonModel().getLeftHandPosition(leftHandPosition);
|
|
||||||
glm::quat leftRotation;
|
|
||||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation);
|
|
||||||
leftHandPosition += HAND_TO_PALM_OFFSET * glm::inverse(leftRotation);
|
|
||||||
return leftHandPosition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// thread-safe
|
||||||
glm::quat Avatar::getLeftPalmRotation() {
|
glm::quat Avatar::getLeftPalmRotation() {
|
||||||
glm::quat leftRotation;
|
return _leftPalmRotationCache.get();
|
||||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getLeftHandJointIndex(), leftRotation);
|
|
||||||
return leftRotation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// thread-safe
|
||||||
glm::vec3 Avatar::getRightPalmPosition() {
|
glm::vec3 Avatar::getRightPalmPosition() {
|
||||||
glm::vec3 rightHandPosition;
|
return _rightPalmPositionCache.get();
|
||||||
getSkeletonModel().getRightHandPosition(rightHandPosition);
|
|
||||||
glm::quat rightRotation;
|
|
||||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation);
|
|
||||||
rightHandPosition += HAND_TO_PALM_OFFSET * glm::inverse(rightRotation);
|
|
||||||
return rightHandPosition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// thread-safe
|
||||||
glm::quat Avatar::getRightPalmRotation() {
|
glm::quat Avatar::getRightPalmRotation() {
|
||||||
glm::quat rightRotation;
|
return _rightPalmRotationCache.get();
|
||||||
getSkeletonModel().getJointRotationInWorldFrame(getSkeletonModel().getRightHandJointIndex(), rightRotation);
|
|
||||||
return rightRotation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::setPosition(const glm::vec3& position) {
|
void Avatar::setPosition(const glm::vec3& position) {
|
||||||
|
@ -1194,3 +1185,24 @@ void Avatar::setOrientation(const glm::quat& orientation) {
|
||||||
AvatarData::setOrientation(orientation);
|
AvatarData::setOrientation(orientation);
|
||||||
updateAttitude();
|
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 "SkeletonModel.h"
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "Rig.h"
|
#include "Rig.h"
|
||||||
|
#include <ThreadSafeValueCache.h>
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar);
|
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar);
|
||||||
|
@ -227,8 +228,15 @@ protected:
|
||||||
|
|
||||||
virtual void updateJointMappings() override;
|
virtual void updateJointMappings() override;
|
||||||
|
|
||||||
|
virtual void updatePalms();
|
||||||
|
|
||||||
render::ItemID _renderItemID;
|
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:
|
private:
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
NetworkTexturePointer _billboardTexture;
|
NetworkTexturePointer _billboardTexture;
|
||||||
|
|
|
@ -417,6 +417,8 @@ void MyAvatar::updateSensorToWorldMatrix() {
|
||||||
// position when driven from the head.
|
// position when driven from the head.
|
||||||
glm::mat4 desiredMat = createMatFromQuatAndPos(getOrientation(), getPosition());
|
glm::mat4 desiredMat = createMatFromQuatAndPos(getOrientation(), getPosition());
|
||||||
_sensorToWorldMatrix = desiredMat * glm::inverse(_bodySensorMatrix);
|
_sensorToWorldMatrix = desiredMat * glm::inverse(_bodySensorMatrix);
|
||||||
|
|
||||||
|
lateUpdatePalms();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update avatar head rotation with sensor data
|
// Update avatar head rotation with sensor data
|
||||||
|
@ -1839,3 +1841,8 @@ QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioList
|
||||||
void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode) {
|
void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMode& audioListenerMode) {
|
||||||
audioListenerMode = (AudioListenerMode)object.toUInt16();
|
audioListenerMode = (AudioListenerMode)object.toUInt16();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MyAvatar::lateUpdatePalms() {
|
||||||
|
Avatar::updatePalms();
|
||||||
|
}
|
||||||
|
|
|
@ -311,12 +311,14 @@ private:
|
||||||
|
|
||||||
void setVisibleInSceneIfReady(Model* model, render::ScenePointer scene, bool visiblity);
|
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.
|
// derive avatar body position and orientation from the current HMD Sensor location.
|
||||||
// results are in HMD frame
|
// results are in HMD frame
|
||||||
glm::mat4 deriveBodyFromHMDSensor() const;
|
glm::mat4 deriveBodyFromHMDSensor() const;
|
||||||
|
|
||||||
|
virtual void updatePalms() override {}
|
||||||
|
void lateUpdatePalms();
|
||||||
|
|
||||||
|
|
||||||
float _driveKeys[MAX_DRIVE_KEYS];
|
float _driveKeys[MAX_DRIVE_KEYS];
|
||||||
bool _wasPushing;
|
bool _wasPushing;
|
||||||
bool _isPushing;
|
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