Merge pull request from zfox23/fix/getAvatar_Fix

Fix FB3999; Fix crashes caused by getAvatar() design bug
This commit is contained in:
Zach Fox 2017-04-11 11:17:48 -07:00 committed by GitHub
commit 6569de697d
16 changed files with 709 additions and 45 deletions

View file

@ -29,8 +29,8 @@
#include <udt/PacketHeaders.h>
#include <ResourceCache.h>
#include <ScriptCache.h>
#include <SoundCache.h>
#include <ScriptEngines.h>
#include <SoundCache.h>
#include <UUID.h>
#include <recording/Deck.h>

View file

@ -129,6 +129,7 @@
#include "AudioClient.h"
#include "audio/AudioScope.h"
#include "avatar/AvatarManager.h"
#include "avatar/ScriptAvatar.h"
#include "CrashHandler.h"
#include "devices/DdeFaceTracker.h"
#include "devices/EyeTracker.h"

View file

@ -24,6 +24,7 @@
#include "Avatar.h"
#include "AvatarMotionState.h"
#include "ScriptAvatar.h"
class MyAvatar;
class AudioInjector;
@ -41,6 +42,10 @@ public:
void init();
std::shared_ptr<MyAvatar> getMyAvatar() { return _myAvatar; }
// Null/Default-constructed QUuids will return MyAvatar
Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) override { return new ScriptAvatar(getAvatarBySessionID(avatarID)); }
AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const override;
int getNumAvatarsUpdated() const { return _numAvatarsUpdated; }

View file

@ -73,10 +73,17 @@ void Head::reset() {
void Head::simulate(float deltaTime, bool isMine) {
const float NORMAL_HZ = 60.0f; // the update rate the constant values were tuned for
// grab the audio loudness from the owning avatar, if we have one
float audioLoudness = 0.0f;
if (_owningAvatar) {
_owningAvatar->getAudioLoudness();
}
// Update audio trailing average for rendering facial animations
const float AUDIO_AVERAGING_SECS = 0.05f;
const float AUDIO_LONG_TERM_AVERAGING_SECS = 30.0f;
_averageLoudness = glm::mix(_averageLoudness, _audioLoudness, glm::min(deltaTime / AUDIO_AVERAGING_SECS, 1.0f));
_averageLoudness = glm::mix(_averageLoudness, audioLoudness, glm::min(deltaTime / AUDIO_AVERAGING_SECS, 1.0f));
if (_longTermAverageLoudness == -1.0f) {
_longTermAverageLoudness = _averageLoudness;
@ -154,8 +161,8 @@ void Head::simulate(float deltaTime, bool isMine) {
// Update audio attack data for facial animation (eyebrows and mouth)
float audioAttackAveragingRate = (10.0f - deltaTime * NORMAL_HZ) / 10.0f; // --> 0.9 at 60 Hz
_audioAttack = audioAttackAveragingRate * _audioAttack +
(1.0f - audioAttackAveragingRate) * fabs((_audioLoudness - _longTermAverageLoudness) - _lastLoudness);
_lastLoudness = (_audioLoudness - _longTermAverageLoudness);
(1.0f - audioAttackAveragingRate) * fabs((audioLoudness - _longTermAverageLoudness) - _lastLoudness);
_lastLoudness = (audioLoudness - _longTermAverageLoudness);
const float BROW_LIFT_THRESHOLD = 100.0f;
if (_audioAttack > BROW_LIFT_THRESHOLD) {

View file

@ -404,8 +404,8 @@ void MyAvatar::update(float deltaTime) {
// Also get the AudioClient so we can update the avatar bounding box data
// on the AudioClient side.
auto audio = DependencyManager::get<AudioClient>();
head->setAudioLoudness(audio->getLastInputLoudness());
head->setAudioAverageLoudness(audio->getAudioAverageInputLoudness());
setAudioLoudness(audio->getLastInputLoudness());
setAudioAverageLoudness(audio->getAudioAverageInputLoudness());
glm::vec3 halfBoundingBoxDimensions(_characterController.getCapsuleRadius(), _characterController.getCapsuleHalfHeight(), _characterController.getCapsuleRadius());
halfBoundingBoxDimensions += _characterController.getCapsuleLocalOffset();

View file

@ -0,0 +1,146 @@
//
// ScriptAvatar.cpp
// interface/src/avatars
//
// Created by Stephen Birarda on 4/10/17.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ScriptAvatar.h"
ScriptAvatar::ScriptAvatar(AvatarSharedPointer avatarData) :
ScriptAvatarData(avatarData)
{
}
std::shared_ptr<Avatar> ScriptAvatar::lockAvatar() const {
if (auto lockedAvatarData = _avatarData.lock()) {
return std::dynamic_pointer_cast<Avatar>(lockedAvatarData);
} else {
return std::shared_ptr<Avatar>();
}
}
glm::quat ScriptAvatar::getDefaultJointRotation(int index) const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getDefaultJointRotation(index);
} else {
return glm::quat();
}
}
glm::vec3 ScriptAvatar::getDefaultJointTranslation(int index) const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getDefaultJointTranslation(index);
} else {
return glm::vec3();
}
}
glm::vec3 ScriptAvatar::getSkeletonOffset() const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getSkeletonOffset();
} else {
return glm::vec3();
}
}
glm::vec3 ScriptAvatar::getJointPosition(int index) const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getJointPosition(index);
} else {
return glm::vec3();
}
}
glm::vec3 ScriptAvatar::getJointPosition(const QString& name) const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getJointPosition(name);
} else {
return glm::vec3();
}
}
glm::vec3 ScriptAvatar::getNeckPosition() const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getNeckPosition();
} else {
return glm::vec3();
}
}
glm::vec3 ScriptAvatar::getAcceleration() const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getAcceleration();
} else {
return glm::vec3();
}
}
QUuid ScriptAvatar::getParentID() const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getParentID();
} else {
return QUuid();
}
}
quint16 ScriptAvatar::getParentJointIndex() const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getParentJointIndex();
} else {
return INVALID_JOINT_INDEX;
}
}
QVariantList ScriptAvatar::getSkeleton() const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getSkeleton();
} else {
return QVariantList();
}
}
float ScriptAvatar::getSimulationRate(const QString& rateName) const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getSimulationRate(rateName);
} else {
return 0.0f;;
}
}
glm::vec3 ScriptAvatar::getLeftPalmPosition() const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getLeftPalmPosition();
} else {
return glm::vec3();
}
}
glm::quat ScriptAvatar::getLeftPalmRotation() const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getLeftPalmRotation();
} else {
return glm::quat();
}
}
glm::vec3 ScriptAvatar::getRightPalmPosition() const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getRightPalmPosition();
} else {
return glm::vec3();
}
}
glm::quat ScriptAvatar::getRightPalmRotation() const {
if (auto lockedAvatar = lockAvatar()) {
return lockedAvatar->getRightPalmRotation();
} else {
return glm::quat();
}
}

View file

@ -0,0 +1,56 @@
//
// ScriptAvatar.h
// interface/src/avatars
//
// Created by Stephen Birarda on 4/10/17.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_ScriptAvatar_h
#define hifi_ScriptAvatar_h
#include <ScriptAvatarData.h>
#include "Avatar.h"
class ScriptAvatar : public ScriptAvatarData {
Q_OBJECT
Q_PROPERTY(glm::vec3 skeletonOffset READ getSkeletonOffset)
public:
ScriptAvatar(AvatarSharedPointer avatarData);
public slots:
glm::quat getDefaultJointRotation(int index) const;
glm::vec3 getDefaultJointTranslation(int index) const;
glm::vec3 getSkeletonOffset() const;
glm::vec3 getJointPosition(int index) const;
glm::vec3 getJointPosition(const QString& name) const;
glm::vec3 getNeckPosition() const;
glm::vec3 getAcceleration() const;
QUuid getParentID() const;
quint16 getParentJointIndex() const;
QVariantList getSkeleton() const;
float getSimulationRate(const QString& rateName = QString("")) const;
glm::vec3 getLeftPalmPosition() const;
glm::quat getLeftPalmRotation() const;
glm::vec3 getRightPalmPosition() const;
glm::quat getRightPalmRotation() const;
private:
std::shared_ptr<Avatar> lockAvatar() const;
};
#endif // hifi_ScriptAvatar_h

View file

@ -352,7 +352,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
if (hasAudioLoudness) {
auto startSection = destinationBuffer;
auto data = reinterpret_cast<AvatarDataPacket::AudioLoudness*>(destinationBuffer);
data->audioLoudness = packFloatGainToByte(_headData->getAudioLoudness() / AUDIO_LOUDNESS_SCALE);
data->audioLoudness = packFloatGainToByte(getAudioLoudness() / AUDIO_LOUDNESS_SCALE);
destinationBuffer += sizeof(AvatarDataPacket::AudioLoudness);
int numBytes = destinationBuffer - startSection;
@ -836,7 +836,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
}
return buffer.size();
}
_headData->setAudioLoudness(audioLoudness);
setAudioLoudness(audioLoudness);
int numBytesRead = sourceBuffer - startSection;
_audioLoudnessRate.increment(numBytesRead);
_audioLoudnessUpdateRate.increment();

View file

@ -448,10 +448,18 @@ public:
void setHeadRoll(float value) { _headData->setBaseRoll(value); }
// access to Head().set/getAverageLoudness
float getAudioLoudness() const { return _headData->getAudioLoudness(); }
void setAudioLoudness(float value) { _headData->setAudioLoudness(value); }
float getAudioAverageLoudness() const { return _headData->getAudioAverageLoudness(); }
void setAudioAverageLoudness(float value) { _headData->setAudioAverageLoudness(value); }
float getAudioLoudness() const { return _audioLoudness; }
void setAudioLoudness(float audioLoudness) {
if (audioLoudness != _audioLoudness) {
_audioLoudnessChanged = usecTimestampNow();
}
_audioLoudness = audioLoudness;
}
bool audioLoudnessChangedSince(quint64 time) const { return _audioLoudnessChanged >= time; }
float getAudioAverageLoudness() const { return _audioAverageLoudness; }
void setAudioAverageLoudness(float audioAverageLoudness) { _audioAverageLoudness = audioAverageLoudness; }
// Scale
virtual void setTargetScale(float targetScale);
@ -642,7 +650,6 @@ protected:
bool avatarBoundingBoxChangedSince(quint64 time) const { return _avatarBoundingBoxChanged >= time; }
bool avatarScaleChangedSince(quint64 time) const { return _avatarScaleChanged >= time; }
bool lookAtPositionChangedSince(quint64 time) const { return _headData->lookAtPositionChangedSince(time); }
bool audioLoudnessChangedSince(quint64 time) const { return _headData->audioLoudnessChangedSince(time); }
bool sensorToWorldMatrixChangedSince(quint64 time) const { return _sensorToWorldMatrixChanged >= time; }
bool additionalFlagsChangedSince(quint64 time) const { return _additionalFlagsChanged >= time; }
bool parentInfoChangedSince(quint64 time) const { return _parentChanged >= time; }
@ -768,6 +775,10 @@ protected:
int getFauxJointIndex(const QString& name) const;
float _audioLoudness { 0.0f };
quint64 _audioLoudnessChanged { 0 };
float _audioAverageLoudness { 0.0f };
private:
friend void avatarStateFromFrame(const QByteArray& frameData, AvatarData* _avatar);
static QUrl _defaultFullAvatarModelUrl;

View file

@ -30,11 +30,6 @@ QVector<QUuid> AvatarHashMap::getAvatarIdentifiers() {
return _avatarHash.keys().toVector();
}
AvatarData* AvatarHashMap::getAvatar(QUuid avatarID) {
// Null/Default-constructed QUuids will return MyAvatar
return getAvatarBySessionID(avatarID).get();
}
bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range) {
auto hashCopy = getHashCopy();
foreach(const AvatarSharedPointer& sharedAvatar, hashCopy) {

View file

@ -25,6 +25,8 @@
#include <NLPacket.h>
#include <Node.h>
#include "ScriptAvatarData.h"
#include "AvatarData.h"
class AvatarHashMap : public QObject, public Dependency {
@ -37,7 +39,9 @@ public:
// Currently, your own avatar will be included as the null avatar id.
Q_INVOKABLE QVector<QUuid> getAvatarIdentifiers();
Q_INVOKABLE AvatarData* getAvatar(QUuid avatarID);
// Null/Default-constructed QUuids will return MyAvatar
virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); }
virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const { return findAvatar(sessionID); }
int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters);

View file

@ -32,14 +32,12 @@ HeadData::HeadData(AvatarData* owningAvatar) :
_basePitch(0.0f),
_baseRoll(0.0f),
_lookAtPosition(0.0f, 0.0f, 0.0f),
_audioLoudness(0.0f),
_isFaceTrackerConnected(false),
_isEyeTrackerConnected(false),
_leftEyeBlink(0.0f),
_rightEyeBlink(0.0f),
_averageLoudness(0.0f),
_browAudioLift(0.0f),
_audioAverageLoudness(0.0f),
_owningAvatar(owningAvatar)
{

View file

@ -57,18 +57,6 @@ public:
glm::quat getOrientation() const;
void setOrientation(const glm::quat& orientation);
float getAudioLoudness() const { return _audioLoudness; }
void setAudioLoudness(float audioLoudness) {
if (audioLoudness != _audioLoudness) {
_audioLoudnessChanged = usecTimestampNow();
}
_audioLoudness = audioLoudness;
}
bool audioLoudnessChangedSince(quint64 time) { return _audioLoudnessChanged >= time; }
float getAudioAverageLoudness() const { return _audioAverageLoudness; }
void setAudioAverageLoudness(float audioAverageLoudness) { _audioAverageLoudness = audioAverageLoudness; }
void setBlendshape(QString name, float val);
const QVector<float>& getBlendshapeCoefficients() const { return _blendshapeCoefficients; }
void setBlendshapeCoefficients(const QVector<float>& blendshapeCoefficients) { _blendshapeCoefficients = blendshapeCoefficients; }
@ -96,16 +84,13 @@ protected:
glm::vec3 _lookAtPosition;
quint64 _lookAtPositionChanged { 0 };
float _audioLoudness;
quint64 _audioLoudnessChanged { 0 };
bool _isFaceTrackerConnected;
bool _isEyeTrackerConnected;
float _leftEyeBlink;
float _rightEyeBlink;
float _averageLoudness;
float _browAudioLift;
float _audioAverageLoudness;
QVector<float> _blendshapeCoefficients;
AvatarData* _owningAvatar;

View file

@ -0,0 +1,314 @@
//
// ScriptAvatarData.cpp
// libraries/script-engine/src
//
// Created by Zach Fox on 2017-04-10.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "ScriptAvatarData.h"
ScriptAvatarData::ScriptAvatarData(AvatarSharedPointer avatarData) :
_avatarData(avatarData)
{
QObject::connect(avatarData.get(), &AvatarData::displayNameChanged, this, &ScriptAvatarData::displayNameChanged);
}
//
// PHYSICAL PROPERTIES: POSITION AND ORIENTATION
// START
//
glm::vec3 ScriptAvatarData::getPosition() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getPosition();
} else {
return glm::vec3();
}
}
float ScriptAvatarData::getTargetScale() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getTargetScale();
} else {
return 0.0f;
}
}
glm::vec3 ScriptAvatarData::getHandPosition() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getHandPosition();
} else {
return glm::vec3();
}
}
float ScriptAvatarData::getBodyPitch() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getBodyPitch();
} else {
return 0.0f;
}
}
float ScriptAvatarData::getBodyYaw() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getBodyYaw();
} else {
return 0.0f;
}
}
float ScriptAvatarData::getBodyRoll() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getBodyRoll();
} else {
return 0.0f;
}
}
glm::quat ScriptAvatarData::getOrientation() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getOrientation();
} else {
return glm::quat();
}
}
glm::quat ScriptAvatarData::getHeadOrientation() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getHeadOrientation();
} else {
return glm::quat();
}
}
float ScriptAvatarData::getHeadPitch() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getHeadPitch();
} else {
return 0.0f;
}
}
float ScriptAvatarData::getHeadYaw() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getHeadYaw();
} else {
return 0.0f;
}
}
float ScriptAvatarData::getHeadRoll() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getHeadRoll();
} else {
return 0.0f;
}
}
//
// PHYSICAL PROPERTIES: POSITION AND ORIENTATION
// END
//
//
// PHYSICAL PROPERTIES: VELOCITY
// START
//
glm::vec3 ScriptAvatarData::getVelocity() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getVelocity();
} else {
return glm::vec3();
}
}
glm::vec3 ScriptAvatarData::getAngularVelocity() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getAngularVelocity();
} else {
return glm::vec3();
}
}
//
// PHYSICAL PROPERTIES: VELOCITY
// END
//
//
// IDENTIFIER PROPERTIES
// START
//
QUuid ScriptAvatarData::getSessionUUID() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getSessionUUID();
} else {
return QUuid();
}
}
QString ScriptAvatarData::getDisplayName() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getDisplayName();
} else {
return QString();
}
}
QString ScriptAvatarData::getSessionDisplayName() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getSessionDisplayName();
} else {
return QString();
}
}
//
// IDENTIFIER PROPERTIES
// END
//
//
// ATTACHMENT AND JOINT PROPERTIES
// START
//
QString ScriptAvatarData::getSkeletonModelURLFromScript() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getSkeletonModelURLFromScript();
} else {
return QString();
}
}
char ScriptAvatarData::getHandState() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getHandState();
} else {
return -1;
}
}
glm::quat ScriptAvatarData::getJointRotation(int index) const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getJointRotation(index);
} else {
return glm::quat();
}
}
glm::vec3 ScriptAvatarData::getJointTranslation(int index) const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getJointTranslation(index);
} else {
return glm::vec3();
}
}
glm::quat ScriptAvatarData::getJointRotation(const QString& name) const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getJointRotation(name);
} else {
return glm::quat();
}
}
glm::vec3 ScriptAvatarData::getJointTranslation(const QString& name) const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getJointTranslation(name);
} else {
return glm::vec3();
}
}
QVector<glm::quat> ScriptAvatarData::getJointRotations() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getJointRotations();
} else {
return QVector<glm::quat>();
}
}
bool ScriptAvatarData::isJointDataValid(const QString& name) const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->isJointDataValid(name);
} else {
return false;
}
}
int ScriptAvatarData::getJointIndex(const QString& name) const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getJointIndex(name);
} else {
return -1;
}
}
QStringList ScriptAvatarData::getJointNames() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getJointNames();
} else {
return QStringList();
}
}
QVector<AttachmentData> ScriptAvatarData::getAttachmentData() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getAttachmentData();
} else {
return QVector<AttachmentData>();
}
}
//
// ATTACHMENT AND JOINT PROPERTIES
// END
//
//
// AUDIO PROPERTIES
// START
//
float ScriptAvatarData::getAudioLoudness() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getAudioLoudness();
} else {
return 0.0f;
}
}
float ScriptAvatarData::getAudioAverageLoudness() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getAudioAverageLoudness();
} else {
return 0.0f;
}
}
//
// AUDIO PROPERTIES
// END
//
//
// MATRIX PROPERTIES
// START
//
glm::mat4 ScriptAvatarData::getSensorToWorldMatrix() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getSensorToWorldMatrix();
} else {
return glm::mat4();
}
}
glm::mat4 ScriptAvatarData::getControllerLeftHandMatrix() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getControllerLeftHandMatrix();
} else {
return glm::mat4();
}
}
glm::mat4 ScriptAvatarData::getControllerRightHandMatrix() const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getControllerRightHandMatrix();
} else {
return glm::mat4();
}
}
//
// MATRIX PROPERTIES
// END
//
glm::quat ScriptAvatarData::getAbsoluteJointRotationInObjectFrame(int index) const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getAbsoluteJointRotationInObjectFrame(index);
} else {
return glm::quat();
}
}
glm::vec3 ScriptAvatarData::getAbsoluteJointTranslationInObjectFrame(int index) const {
if (AvatarSharedPointer sharedAvatarData = _avatarData.lock()) {
return sharedAvatarData->getAbsoluteJointTranslationInObjectFrame(index);
} else {
return glm::vec3();
}
}

View file

@ -0,0 +1,138 @@
//
// ScriptAvatarData.h
// libraries/script-engine/src
//
// Created by Zach Fox on 2017-04-10.
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_ScriptAvatarData_h
#define hifi_ScriptAvatarData_h
#include <QtCore/QObject>
#include "AvatarData.h"
class ScriptAvatarData : public QObject {
Q_OBJECT
//
// PHYSICAL PROPERTIES: POSITION AND ORIENTATION
//
Q_PROPERTY(glm::vec3 position READ getPosition)
Q_PROPERTY(float scale READ getTargetScale)
Q_PROPERTY(glm::vec3 handPosition READ getHandPosition)
Q_PROPERTY(float bodyPitch READ getBodyPitch)
Q_PROPERTY(float bodyYaw READ getBodyYaw)
Q_PROPERTY(float bodyRoll READ getBodyRoll)
Q_PROPERTY(glm::quat orientation READ getOrientation)
Q_PROPERTY(glm::quat headOrientation READ getHeadOrientation)
Q_PROPERTY(float headPitch READ getHeadPitch)
Q_PROPERTY(float headYaw READ getHeadYaw)
Q_PROPERTY(float headRoll READ getHeadRoll)
//
// PHYSICAL PROPERTIES: VELOCITY
//
Q_PROPERTY(glm::vec3 velocity READ getVelocity)
Q_PROPERTY(glm::vec3 angularVelocity READ getAngularVelocity)
//
// IDENTIFIER PROPERTIES
//
Q_PROPERTY(QUuid sessionUUID READ getSessionUUID)
Q_PROPERTY(QString displayName READ getDisplayName NOTIFY displayNameChanged)
Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName)
//
// ATTACHMENT AND JOINT PROPERTIES
//
Q_PROPERTY(QString skeletonModelURL READ getSkeletonModelURLFromScript)
Q_PROPERTY(QVector<AttachmentData> attachmentData READ getAttachmentData)
Q_PROPERTY(QStringList jointNames READ getJointNames)
//
// AUDIO PROPERTIES
//
Q_PROPERTY(float audioLoudness READ getAudioLoudness)
Q_PROPERTY(float audioAverageLoudness READ getAudioAverageLoudness)
//
// MATRIX PROPERTIES
//
Q_PROPERTY(glm::mat4 sensorToWorldMatrix READ getSensorToWorldMatrix)
Q_PROPERTY(glm::mat4 controllerLeftHandMatrix READ getControllerLeftHandMatrix)
Q_PROPERTY(glm::mat4 controllerRightHandMatrix READ getControllerRightHandMatrix)
public:
ScriptAvatarData(AvatarSharedPointer avatarData);
//
// PHYSICAL PROPERTIES: POSITION AND ORIENTATION
//
glm::vec3 getPosition() const;
float getTargetScale() const;
glm::vec3 getHandPosition() const;
float getBodyPitch() const;
float getBodyYaw() const;
float getBodyRoll() const;
glm::quat getOrientation() const;
glm::quat getHeadOrientation() const;
float getHeadPitch() const;
float getHeadYaw() const;
float getHeadRoll() const;
//
// PHYSICAL PROPERTIES: VELOCITY
//
glm::vec3 getVelocity() const;
glm::vec3 getAngularVelocity() const;
//
// IDENTIFIER PROPERTIES
//
QUuid getSessionUUID() const;
QString getDisplayName() const;
QString getSessionDisplayName() const;
//
// ATTACHMENT AND JOINT PROPERTIES
//
QString getSkeletonModelURLFromScript() const;
Q_INVOKABLE char getHandState() const;
Q_INVOKABLE glm::quat getJointRotation(int index) const;
Q_INVOKABLE glm::vec3 getJointTranslation(int index) const;
Q_INVOKABLE glm::quat getJointRotation(const QString& name) const;
Q_INVOKABLE glm::vec3 getJointTranslation(const QString& name) const;
Q_INVOKABLE QVector<glm::quat> getJointRotations() const;
Q_INVOKABLE bool isJointDataValid(const QString& name) const;
Q_INVOKABLE int getJointIndex(const QString& name) const;
Q_INVOKABLE QStringList getJointNames() const;
Q_INVOKABLE QVector<AttachmentData> getAttachmentData() const;
//
// AUDIO PROPERTIES
//
float getAudioLoudness() const;
float getAudioAverageLoudness() const;
//
// MATRIX PROPERTIES
//
glm::mat4 getSensorToWorldMatrix() const;
glm::mat4 getControllerLeftHandMatrix() const;
glm::mat4 getControllerRightHandMatrix() const;
signals:
void displayNameChanged();
public slots:
glm::quat getAbsoluteJointRotationInObjectFrame(int index) const;
glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const;
protected:
std::weak_ptr<AvatarData> _avatarData;
};
#endif // hifi_ScriptAvatarData_h

View file

@ -44,6 +44,7 @@
#include <PathUtils.h>
#include <ResourceScriptingInterface.h>
#include <NodeList.h>
#include <ScriptAvatarData.h>
#include <udt/PacketHeaders.h>
#include <UUID.h>
#include <ui/Menu.h>
@ -59,6 +60,7 @@
#include "FileScriptingInterface.h" // unzip project
#include "MenuItemProperties.h"
#include "ScriptAudioInjector.h"
#include "ScriptAvatarData.h"
#include "ScriptCache.h"
#include "ScriptEngineLogging.h"
#include "ScriptEngine.h"
@ -111,14 +113,6 @@ static QScriptValue debugPrint(QScriptContext* context, QScriptEngine* engine) {
return QScriptValue();
}
QScriptValue avatarDataToScriptValue(QScriptEngine* engine, AvatarData* const &in) {
return engine->newQObject(in, QScriptEngine::QtOwnership, DEFAULT_QOBJECT_WRAP_OPTIONS);
}
void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) {
out = qobject_cast<AvatarData*>(object.toQObject());
}
Q_DECLARE_METATYPE(controller::InputController*)
//static int inputControllerPointerId = qRegisterMetaType<controller::InputController*>();
@ -542,6 +536,16 @@ static QScriptValue createScriptableResourcePrototype(QScriptEngine* engine) {
return prototype;
}
QScriptValue avatarDataToScriptValue(QScriptEngine* engine, ScriptAvatarData* const& in) {
return engine->newQObject(in, QScriptEngine::ScriptOwnership, DEFAULT_QOBJECT_WRAP_OPTIONS);
}
void avatarDataFromScriptValue(const QScriptValue& object, ScriptAvatarData*& out) {
// This is not implemented because there are no slots/properties that take an AvatarSharedPointer from a script
assert(false);
out = nullptr;
}
void ScriptEngine::resetModuleCache(bool deleteScriptCache) {
if (QThread::currentThread() != thread()) {
executeOnScriptThread([=]() { resetModuleCache(deleteScriptCache); });