Add version number to avatar recording frame

New recordings will have a version number of 1.
A missing version field indicates the initial version of 0.
Warn when playing back version 0 files which are no longer fully supported and fall back to default pose.
Playback of version 1 files should work as expected.
This commit is contained in:
Anthony J. Thibault 2016-06-03 11:08:05 -07:00
parent 35b80ba066
commit 8f9fc08226

View file

@ -1270,6 +1270,10 @@ static const QString JSON_AVATAR_DISPLAY_NAME = QStringLiteral("displayName");
static const QString JSON_AVATAR_ATTACHEMENTS = QStringLiteral("attachments"); static const QString JSON_AVATAR_ATTACHEMENTS = QStringLiteral("attachments");
static const QString JSON_AVATAR_ENTITIES = QStringLiteral("attachedEntities"); static const QString JSON_AVATAR_ENTITIES = QStringLiteral("attachedEntities");
static const QString JSON_AVATAR_SCALE = QStringLiteral("scale"); static const QString JSON_AVATAR_SCALE = QStringLiteral("scale");
static const QString JSON_AVATAR_VERSION = QStringLiteral("version");
static const int JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION = 0;
static const int JSON_AVATAR_JOINT_ROTATIONS_IN_ABSOLUTE_FRAME_VERSION = 1;
QJsonValue toJsonValue(const JointData& joint) { QJsonValue toJsonValue(const JointData& joint) {
QJsonArray result; QJsonArray result;
@ -1293,6 +1297,8 @@ JointData jointDataFromJsonValue(const QJsonValue& json) {
QJsonObject AvatarData::toJson() const { QJsonObject AvatarData::toJson() const {
QJsonObject root; QJsonObject root;
root[JSON_AVATAR_VERSION] = JSON_AVATAR_JOINT_ROTATIONS_IN_ABSOLUTE_FRAME_VERSION;
if (!getSkeletonModelURL().isEmpty()) { if (!getSkeletonModelURL().isEmpty()) {
root[JSON_AVATAR_BODY_MODEL] = getSkeletonModelURL().toString(); root[JSON_AVATAR_BODY_MODEL] = getSkeletonModelURL().toString();
} }
@ -1359,6 +1365,15 @@ QJsonObject AvatarData::toJson() const {
} }
void AvatarData::fromJson(const QJsonObject& json) { void AvatarData::fromJson(const QJsonObject& json) {
int version;
if (json.contains(JSON_AVATAR_VERSION)) {
version = json[JSON_AVATAR_VERSION].toInt();
} else {
// initial data did not have a version field.
version = JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION;
}
// The head setOrientation likes to overwrite the avatar orientation, // The head setOrientation likes to overwrite the avatar orientation,
// so lets do the head first // so lets do the head first
// Most head data is relative to the avatar, and needs no basis correction, // Most head data is relative to the avatar, and needs no basis correction,
@ -1424,20 +1439,28 @@ void AvatarData::fromJson(const QJsonObject& json) {
// } // }
// } // }
// Joint rotations are relative to the avatar, so they require no basis correction
if (json.contains(JSON_AVATAR_JOINT_ARRAY)) { if (json.contains(JSON_AVATAR_JOINT_ARRAY)) {
QVector<JointData> jointArray; if (version == JSON_AVATAR_JOINT_ROTATIONS_IN_RELATIVE_FRAME_VERSION) {
QJsonArray jointArrayJson = json[JSON_AVATAR_JOINT_ARRAY].toArray(); // because we don't have the full joint hierarchy skeleton of the model,
jointArray.reserve(jointArrayJson.size()); // we can't properly convert from relative rotations into absolute rotations.
int i = 0; quint64 now = usecTimestampNow();
for (const auto& jointJson : jointArrayJson) { if (shouldLogError(now)) {
auto joint = jointDataFromJsonValue(jointJson); qCWarning(avatars) << "Version 0 avatar recordings not supported. using default rotations";
jointArray.push_back(joint); }
setJointData(i, joint.rotation, joint.translation); } else {
_jointData[i].rotationSet = true; // Have to do that to broadcast the avatar new pose QVector<JointData> jointArray;
i++; QJsonArray jointArrayJson = json[JSON_AVATAR_JOINT_ARRAY].toArray();
jointArray.reserve(jointArrayJson.size());
int i = 0;
for (const auto& jointJson : jointArrayJson) {
auto joint = jointDataFromJsonValue(jointJson);
jointArray.push_back(joint);
setJointData(i, joint.rotation, joint.translation);
_jointData[i].rotationSet = true; // Have to do that to broadcast the avatar new pose
i++;
}
setRawJointData(jointArray);
} }
setRawJointData(jointArray);
} }
} }