From 1fd37b51a2bced38a435128d327e0aa4269388b7 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 12 Nov 2015 17:54:35 -0800 Subject: [PATCH] trying to get somewhere.... --- examples/utilities/record/recorder.js | 2 + interface/src/avatar/MyAvatar.cpp | 2 +- libraries/avatars/src/AvatarData.cpp | 67 +++++++++++++++++++-------- libraries/avatars/src/AvatarData.h | 3 ++ 4 files changed, 54 insertions(+), 20 deletions(-) diff --git a/examples/utilities/record/recorder.js b/examples/utilities/record/recorder.js index 6d49030a28..13ea1e0c72 100644 --- a/examples/utilities/record/recorder.js +++ b/examples/utilities/record/recorder.js @@ -176,6 +176,8 @@ function formatTime(time) { var SEC_PER_MIN = 60; var MSEC_PER_SEC = 1000; + time = time * (MSEC_PER_SEC * SEC_PER_MIN * MIN_PER_HOUR); + var hours = Math.floor(time / (MSEC_PER_SEC * SEC_PER_MIN * MIN_PER_HOUR)); time -= hours * (MSEC_PER_SEC * SEC_PER_MIN * MIN_PER_HOUR); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5e14c66ff1..4d62946a5f 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -608,7 +608,7 @@ float MyAvatar::recorderElapsed() { if (!_recorder) { return 0; } - return (float)_recorder->position() / MSECS_PER_SECOND; + return (float)_recorder->position(); } QMetaObject::Connection _audioClientRecorderConnection; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index adf471c50e..e2d2c05ef6 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -804,12 +804,12 @@ float AvatarData::playerElapsed() { return 0; } if (QThread::currentThread() != thread()) { - qint64 result; + float result; QMetaObject::invokeMethod(this, "playerElapsed", Qt::BlockingQueuedConnection, - Q_RETURN_ARG(qint64, result)); + Q_RETURN_ARG(float, result)); return result; } - return (float)_player->position() / MSECS_PER_SECOND; + return (float)_player->position(); } float AvatarData::playerLength() { @@ -817,12 +817,12 @@ float AvatarData::playerLength() { return 0; } if (QThread::currentThread() != thread()) { - qint64 result; + float result; QMetaObject::invokeMethod(this, "playerLength", Qt::BlockingQueuedConnection, - Q_RETURN_ARG(qint64, result)); + Q_RETURN_ARG(float, result)); return result; } - return _player->length() / MSECS_PER_SECOND; + return _player->length(); } void AvatarData::loadRecording(const QString& filename) { @@ -870,7 +870,7 @@ void AvatarData::setPlayerTime(float time) { return; } - _player->seek(time * MSECS_PER_SECOND); + _player->seek(time); } void AvatarData::setPlayFromCurrentLocation(bool playFromCurrentLocation) { @@ -1532,7 +1532,7 @@ Transform AvatarData::getTransform() const { static const QString JSON_AVATAR_BASIS = QStringLiteral("basisTransform"); static const QString JSON_AVATAR_RELATIVE = QStringLiteral("relativeTransform"); -static const QString JSON_AVATAR_JOINT_ROTATIONS = QStringLiteral("jointRotations"); +static const QString JSON_AVATAR_JOINT_ARRAY = QStringLiteral("jointArray"); static const QString JSON_AVATAR_HEAD = QStringLiteral("head"); static const QString JSON_AVATAR_HEAD_ROTATION = QStringLiteral("rotation"); static const QString JSON_AVATAR_HEAD_BLENDSHAPE_COEFFICIENTS = QStringLiteral("blendShapes"); @@ -1544,6 +1544,24 @@ static const QString JSON_AVATAR_BODY_MODEL = QStringLiteral("bodyModel"); static const QString JSON_AVATAR_DISPLAY_NAME = QStringLiteral("displayName"); static const QString JSON_AVATAR_ATTACHEMENTS = QStringLiteral("attachments"); +QJsonValue toJsonValue(const JointData& joint) { + QJsonArray result; + result.push_back(toJsonValue(joint.rotation)); + result.push_back(toJsonValue(joint.translation)); + return result; +} + +JointData jointDataFromJsonValue(const QJsonValue& json) { + JointData result; + if (json.isArray()) { + QJsonArray array = json.toArray(); + result.rotation = quatFromJsonValue(array[0]); + result.rotationSet = true; + result.translation = vec3FromJsonValue(array[1]); + result.translationSet = false; + } + return result; +} // Every frame will store both a basis for the recording and a relative transform // This allows the application to decide whether playback should be relative to an avatar's @@ -1575,13 +1593,16 @@ QByteArray avatarStateToFrame(const AvatarData* _avatar) { root[JSON_AVATAR_RELATIVE] = Transform::toJson(relativeTransform); root[JSON_AVATAR_BASIS] = Transform::toJson(*recordingBasis); } + } else { + root[JSON_AVATAR_RELATIVE] = Transform::toJson(_avatar->getTransform()); } - QJsonArray jointRotations; - for (const auto& jointRotation : _avatar->getJointRotations()) { - jointRotations.push_back(toJsonValue(jointRotation)); + // Skeleton pose + QJsonArray jointArray; + for (const auto& joint : _avatar->getRawJointData()) { + jointArray.push_back(toJsonValue(joint)); } - root[JSON_AVATAR_JOINT_ROTATIONS] = jointRotations; + root[JSON_AVATAR_JOINT_ARRAY] = jointArray; const HeadData* head = _avatar->getHeadData(); if (head) { @@ -1646,21 +1667,29 @@ void avatarStateFromFrame(const QByteArray& frameData, AvatarData* _avatar) { _avatar->setTargetScale(worldTransform.getScale().x); } -#if 0 + if (root.contains(JSON_AVATAR_ATTACHEMENTS)) { // FIXME de-serialize attachment data } // Joint rotations are relative to the avatar, so they require no basis correction - if (root.contains(JSON_AVATAR_JOINT_ROTATIONS)) { - QVector jointRotations; - QJsonArray jointRotationsJson = root[JSON_AVATAR_JOINT_ROTATIONS].toArray(); - jointRotations.reserve(jointRotationsJson.size()); - for (const auto& jointRotationJson : jointRotationsJson) { - jointRotations.push_back(quatFromJsonValue(jointRotationJson)); + if (root.contains(JSON_AVATAR_JOINT_ARRAY)) { + QVector jointArray; + QJsonArray jointArrayJson = root[JSON_AVATAR_JOINT_ARRAY].toArray(); + jointArray.reserve(jointArrayJson.size()); + for (const auto& jointJson : jointArrayJson) { + jointArray.push_back(jointDataFromJsonValue(jointJson)); } + + QVector jointRotations; + jointRotations.reserve(jointArray.size()); + for (const auto& joint : jointArray) { + jointRotations.push_back(joint.rotation); + } + _avatar->setJointRotations(jointRotations); } +#if 0 // Most head data is relative to the avatar, and needs no basis correction, // but the lookat vector does need correction HeadData* head = _avatar->_headData; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 7716a16a1c..26bc9d83ff 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -457,6 +457,9 @@ public: bool translationSet = false; }; +QJsonValue toJsonValue(const JointData& joint); +JointData jointDataFromJsonValue(const QJsonValue& q); + class AttachmentData { public: QUrl modelURL;