mirror of
https://github.com/overte-org/overte.git
synced 2025-04-11 13:42:38 +02:00
Merge pull request #14246 from sethalves/sync-grab-props
keep userData and new grab properties in sync
This commit is contained in:
commit
fa2fb3a87a
7 changed files with 395 additions and 170 deletions
|
@ -3803,6 +3803,16 @@ bool EntityItemProperties::queryAACubeRelatedPropertyChanged() const {
|
|||
return parentRelatedPropertyChanged() || dimensionsChanged();
|
||||
}
|
||||
|
||||
bool EntityItemProperties::grabbingRelatedPropertyChanged() const {
|
||||
const GrabPropertyGroup& grabProperties = getGrab();
|
||||
return grabProperties.triggerableChanged() || grabProperties.grabbableChanged() ||
|
||||
grabProperties.grabFollowsControllerChanged() || grabProperties.grabKinematicChanged() ||
|
||||
grabProperties.equippableChanged() || grabProperties.equippableLeftPositionChanged() ||
|
||||
grabProperties.equippableRightPositionChanged() || grabProperties.equippableLeftRotationChanged() ||
|
||||
grabProperties.equippableRightRotationChanged() || grabProperties.equippableIndicatorURLChanged() ||
|
||||
grabProperties.equippableIndicatorScaleChanged() || grabProperties.equippableIndicatorOffsetChanged();
|
||||
}
|
||||
|
||||
// Checking Certifiable Properties
|
||||
#define ADD_STRING_PROPERTY(n, N) if (!get##N().isEmpty()) json[#n] = get##N()
|
||||
#define ADD_ENUM_PROPERTY(n, N) json[#n] = get##N##AsString()
|
||||
|
|
|
@ -108,6 +108,7 @@ public:
|
|||
bool getScalesWithParent() const;
|
||||
bool parentRelatedPropertyChanged() const;
|
||||
bool queryAACubeRelatedPropertyChanged() const;
|
||||
bool grabbingRelatedPropertyChanged() const;
|
||||
|
||||
AABox getAABox() const;
|
||||
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
#include <QFutureWatcher>
|
||||
#include <QtConcurrent/QtConcurrentRun>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
|
||||
#include <shared/QtHelpers.h>
|
||||
#include <VariantMapToScriptValue.h>
|
||||
|
@ -37,6 +40,7 @@
|
|||
#include "WebEntityItem.h"
|
||||
#include <EntityScriptClient.h>
|
||||
#include <Profile.h>
|
||||
#include "GrabPropertyGroup.h"
|
||||
|
||||
const QString GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":true}}";
|
||||
const QString NOT_GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":false}}";
|
||||
|
@ -237,6 +241,235 @@ EntityItemProperties convertPropertiesFromScriptSemantics(const EntityItemProper
|
|||
}
|
||||
|
||||
|
||||
void synchronizeSpatialKey(const GrabPropertyGroup& grabProperties, QJsonObject& grabbableKey, bool& userDataChanged) {
|
||||
if (grabProperties.equippableLeftPositionChanged() ||
|
||||
grabProperties.equippableRightPositionChanged() ||
|
||||
grabProperties.equippableRightRotationChanged() ||
|
||||
grabProperties.equippableIndicatorURLChanged() ||
|
||||
grabProperties.equippableIndicatorScaleChanged() ||
|
||||
grabProperties.equippableIndicatorOffsetChanged()) {
|
||||
|
||||
QJsonObject spatialKey = grabbableKey["spatialKey"].toObject();
|
||||
|
||||
if (grabProperties.equippableLeftPositionChanged()) {
|
||||
if (grabProperties.getEquippableLeftPosition() == INITIAL_LEFT_EQUIPPABLE_POSITION) {
|
||||
spatialKey.remove("leftRelativePosition");
|
||||
} else {
|
||||
spatialKey["leftRelativePosition"] =
|
||||
QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableLeftPosition()));
|
||||
}
|
||||
}
|
||||
if (grabProperties.equippableRightPositionChanged()) {
|
||||
if (grabProperties.getEquippableRightPosition() == INITIAL_RIGHT_EQUIPPABLE_POSITION) {
|
||||
spatialKey.remove("rightRelativePosition");
|
||||
} else {
|
||||
spatialKey["rightRelativePosition"] =
|
||||
QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableRightPosition()));
|
||||
}
|
||||
}
|
||||
if (grabProperties.equippableLeftRotationChanged()) {
|
||||
spatialKey["relativeRotation"] =
|
||||
QJsonValue::fromVariant(quatToQMap(grabProperties.getEquippableLeftRotation()));
|
||||
} else if (grabProperties.equippableRightRotationChanged()) {
|
||||
spatialKey["relativeRotation"] =
|
||||
QJsonValue::fromVariant(quatToQMap(grabProperties.getEquippableRightRotation()));
|
||||
}
|
||||
|
||||
grabbableKey["spatialKey"] = spatialKey;
|
||||
userDataChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void synchronizeGrabbableKey(const GrabPropertyGroup& grabProperties, QJsonObject& userData, bool& userDataChanged) {
|
||||
if (grabProperties.triggerableChanged() ||
|
||||
grabProperties.grabbableChanged() ||
|
||||
grabProperties.grabFollowsControllerChanged() ||
|
||||
grabProperties.grabKinematicChanged() ||
|
||||
grabProperties.equippableChanged() ||
|
||||
grabProperties.equippableLeftPositionChanged() ||
|
||||
grabProperties.equippableRightPositionChanged() ||
|
||||
grabProperties.equippableRightRotationChanged()) {
|
||||
|
||||
QJsonObject grabbableKey = userData["grabbableKey"].toObject();
|
||||
|
||||
if (grabProperties.triggerableChanged()) {
|
||||
if (grabProperties.getTriggerable()) {
|
||||
grabbableKey["triggerable"] = true;
|
||||
} else {
|
||||
grabbableKey.remove("triggerable");
|
||||
}
|
||||
}
|
||||
if (grabProperties.grabbableChanged()) {
|
||||
if (grabProperties.getGrabbable()) {
|
||||
grabbableKey.remove("grabbable");
|
||||
} else {
|
||||
grabbableKey["grabbable"] = false;
|
||||
}
|
||||
}
|
||||
if (grabProperties.grabFollowsControllerChanged()) {
|
||||
if (grabProperties.getGrabFollowsController()) {
|
||||
grabbableKey.remove("ignoreIK");
|
||||
} else {
|
||||
grabbableKey["ignoreIK"] = false;
|
||||
}
|
||||
}
|
||||
if (grabProperties.grabKinematicChanged()) {
|
||||
if (grabProperties.getGrabKinematic()) {
|
||||
grabbableKey.remove("kinematic");
|
||||
} else {
|
||||
grabbableKey["kinematic"] = false;
|
||||
}
|
||||
}
|
||||
if (grabProperties.equippableChanged()) {
|
||||
if (grabProperties.getEquippable()) {
|
||||
grabbableKey["equippable"] = true;
|
||||
} else {
|
||||
grabbableKey.remove("equippable");
|
||||
}
|
||||
}
|
||||
|
||||
if (grabbableKey.contains("spatialKey")) {
|
||||
synchronizeSpatialKey(grabProperties, grabbableKey, userDataChanged);
|
||||
}
|
||||
|
||||
userData["grabbableKey"] = grabbableKey;
|
||||
userDataChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void synchronizeGrabJoints(const GrabPropertyGroup& grabProperties, QJsonObject& joints) {
|
||||
QJsonArray rightHand = joints["RightHand"].toArray();
|
||||
QJsonObject rightHandPosition = rightHand.size() > 0 ? rightHand[0].toObject() : QJsonObject();
|
||||
QJsonObject rightHandRotation = rightHand.size() > 1 ? rightHand[1].toObject() : QJsonObject();
|
||||
QJsonArray leftHand = joints["LeftHand"].toArray();
|
||||
QJsonObject leftHandPosition = leftHand.size() > 0 ? leftHand[0].toObject() : QJsonObject();
|
||||
QJsonObject leftHandRotation = leftHand.size() > 1 ? leftHand[1].toObject() : QJsonObject();
|
||||
|
||||
if (grabProperties.equippableLeftPositionChanged()) {
|
||||
leftHandPosition =
|
||||
QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableLeftPosition())).toObject();
|
||||
}
|
||||
if (grabProperties.equippableRightPositionChanged()) {
|
||||
rightHandPosition =
|
||||
QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableRightPosition())).toObject();
|
||||
}
|
||||
if (grabProperties.equippableLeftRotationChanged()) {
|
||||
leftHandRotation =
|
||||
QJsonValue::fromVariant(quatToQMap(grabProperties.getEquippableLeftRotation())).toObject();
|
||||
}
|
||||
if (grabProperties.equippableRightRotationChanged()) {
|
||||
rightHandRotation =
|
||||
QJsonValue::fromVariant(quatToQMap(grabProperties.getEquippableRightRotation())).toObject();
|
||||
}
|
||||
|
||||
rightHand = QJsonArray();
|
||||
rightHand.append(rightHandPosition);
|
||||
rightHand.append(rightHandRotation);
|
||||
joints["RightHand"] = rightHand;
|
||||
leftHand = QJsonArray();
|
||||
leftHand.append(leftHandPosition);
|
||||
leftHand.append(leftHandRotation);
|
||||
joints["LeftHand"] = leftHand;
|
||||
}
|
||||
|
||||
void synchronizeEquipHotspot(const GrabPropertyGroup& grabProperties, QJsonObject& userData, bool& userDataChanged) {
|
||||
if (grabProperties.equippableLeftPositionChanged() ||
|
||||
grabProperties.equippableRightPositionChanged() ||
|
||||
grabProperties.equippableRightRotationChanged() ||
|
||||
grabProperties.equippableIndicatorURLChanged() ||
|
||||
grabProperties.equippableIndicatorScaleChanged() ||
|
||||
grabProperties.equippableIndicatorOffsetChanged()) {
|
||||
|
||||
QJsonArray equipHotspots = userData["equipHotspots"].toArray();
|
||||
QJsonObject equipHotspot = equipHotspots[0].toObject();
|
||||
QJsonObject joints = equipHotspot["joints"].toObject();
|
||||
|
||||
synchronizeGrabJoints(grabProperties, joints);
|
||||
|
||||
if (grabProperties.equippableIndicatorURLChanged()) {
|
||||
equipHotspot["modelURL"] = grabProperties.getEquippableIndicatorURL();
|
||||
}
|
||||
if (grabProperties.equippableIndicatorScaleChanged()) {
|
||||
QJsonObject scale =
|
||||
QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableIndicatorScale())).toObject();
|
||||
equipHotspot["radius"] = scale;
|
||||
equipHotspot["modelScale"] = scale;
|
||||
|
||||
}
|
||||
if (grabProperties.equippableIndicatorOffsetChanged()) {
|
||||
equipHotspot["position"] =
|
||||
QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableIndicatorOffset())).toObject();
|
||||
}
|
||||
|
||||
equipHotspot["joints"] = joints;
|
||||
equipHotspots = QJsonArray();
|
||||
equipHotspots.append(equipHotspot);
|
||||
userData["equipHotspots"] = equipHotspots;
|
||||
userDataChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void synchronizeWearable(const GrabPropertyGroup& grabProperties, QJsonObject& userData, bool& userDataChanged) {
|
||||
if (grabProperties.equippableLeftPositionChanged() ||
|
||||
grabProperties.equippableRightPositionChanged() ||
|
||||
grabProperties.equippableRightRotationChanged() ||
|
||||
grabProperties.equippableIndicatorURLChanged() ||
|
||||
grabProperties.equippableIndicatorScaleChanged() ||
|
||||
grabProperties.equippableIndicatorOffsetChanged()) {
|
||||
|
||||
QJsonObject wearable = userData["wearable"].toObject();
|
||||
QJsonObject joints = wearable["joints"].toObject();
|
||||
|
||||
synchronizeGrabJoints(grabProperties, joints);
|
||||
|
||||
wearable["joints"] = joints;
|
||||
userData["wearable"] = wearable;
|
||||
userDataChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void synchronizeEditedGrabProperties(EntityItemProperties& properties, const QString& previousUserdata) {
|
||||
// After sufficient warning to content creators, we should be able to remove this.
|
||||
|
||||
if (properties.grabbingRelatedPropertyChanged()) {
|
||||
// This edit touches a new-style grab property, so make userData agree...
|
||||
GrabPropertyGroup& grabProperties = properties.getGrab();
|
||||
|
||||
bool userDataChanged { false };
|
||||
|
||||
// if the edit changed userData, use the updated version coming along with the edit. If not, use
|
||||
// what was already in the entity.
|
||||
QByteArray userDataString;
|
||||
if (properties.userDataChanged()) {
|
||||
userDataString = properties.getUserData().toUtf8();
|
||||
} else {
|
||||
userDataString = previousUserdata.toUtf8();;
|
||||
}
|
||||
QJsonObject userData = QJsonDocument::fromJson(userDataString).object();
|
||||
|
||||
if (userData.contains("grabbableKey")) {
|
||||
synchronizeGrabbableKey(grabProperties, userData, userDataChanged);
|
||||
}
|
||||
if (userData.contains("equipHotspots")) {
|
||||
synchronizeEquipHotspot(grabProperties, userData, userDataChanged);
|
||||
}
|
||||
if (userData.contains("wearable")) {
|
||||
synchronizeWearable(grabProperties, userData, userDataChanged);
|
||||
}
|
||||
|
||||
if (userDataChanged) {
|
||||
properties.setUserData(QJsonDocument(userData).toJson());
|
||||
}
|
||||
|
||||
} else if (properties.userDataChanged()) {
|
||||
// This edit touches userData (and doesn't touch a new-style grab property). Check for grabbableKey in the
|
||||
// userdata and make the new-style grab properties agree
|
||||
convertGrabUserDataToProperties(properties);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties, bool clientOnly) {
|
||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||
|
||||
|
@ -257,6 +490,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
|
|||
|
||||
propertiesWithSimID = convertPropertiesFromScriptSemantics(propertiesWithSimID, scalesWithParent);
|
||||
propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged());
|
||||
synchronizeEditedGrabProperties(propertiesWithSimID, QString());
|
||||
|
||||
EntityItemID id;
|
||||
// If we have a local entity tree set, then also update it.
|
||||
|
@ -559,6 +793,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
|||
simulationOwner = entity->getSimulationOwner();
|
||||
});
|
||||
|
||||
QString previousUserdata;
|
||||
if (entity) {
|
||||
if (properties.hasSimulationRestrictedChanges()) {
|
||||
if (_bidOnSimulationOwnership) {
|
||||
|
@ -597,6 +832,8 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
|||
|
||||
// make sure the properties has a type, so that the encode can know which properties to include
|
||||
properties.setType(entity->getType());
|
||||
|
||||
previousUserdata = entity->getUserData();
|
||||
} else if (_bidOnSimulationOwnership) {
|
||||
// bail when simulation participants don't know about entity
|
||||
return QUuid();
|
||||
|
@ -605,6 +842,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
|||
// How to check for this cheaply?
|
||||
|
||||
properties = convertPropertiesFromScriptSemantics(properties, properties.getScalesWithParent());
|
||||
synchronizeEditedGrabProperties(properties, previousUserdata);
|
||||
properties.setLastEditedBy(sessionID);
|
||||
|
||||
// done reading and modifying properties --> start write
|
||||
|
|
|
@ -2493,6 +2493,118 @@ bool EntityTree::writeToMap(QVariantMap& entityDescription, OctreeElementPointer
|
|||
return true;
|
||||
}
|
||||
|
||||
void convertGrabUserDataToProperties(EntityItemProperties& properties) {
|
||||
GrabPropertyGroup& grabProperties = properties.getGrab();
|
||||
QJsonObject userData = QJsonDocument::fromJson(properties.getUserData().toUtf8()).object();
|
||||
|
||||
QJsonValue grabbableKeyValue = userData["grabbableKey"];
|
||||
if (grabbableKeyValue.isObject()) {
|
||||
QJsonObject grabbableKey = grabbableKeyValue.toObject();
|
||||
|
||||
QJsonValue wantsTrigger = grabbableKey["wantsTrigger"];
|
||||
if (wantsTrigger.isBool()) {
|
||||
grabProperties.setTriggerable(wantsTrigger.toBool());
|
||||
}
|
||||
QJsonValue triggerable = grabbableKey["triggerable"];
|
||||
if (triggerable.isBool()) {
|
||||
grabProperties.setTriggerable(triggerable.toBool());
|
||||
}
|
||||
QJsonValue grabbable = grabbableKey["grabbable"];
|
||||
if (grabbable.isBool()) {
|
||||
grabProperties.setGrabbable(grabbable.toBool());
|
||||
}
|
||||
QJsonValue ignoreIK = grabbableKey["ignoreIK"];
|
||||
if (ignoreIK.isBool()) {
|
||||
grabProperties.setGrabFollowsController(ignoreIK.toBool());
|
||||
}
|
||||
QJsonValue kinematic = grabbableKey["kinematic"];
|
||||
if (kinematic.isBool()) {
|
||||
grabProperties.setGrabKinematic(kinematic.toBool());
|
||||
}
|
||||
QJsonValue equippable = grabbableKey["equippable"];
|
||||
if (equippable.isBool()) {
|
||||
grabProperties.setEquippable(equippable.toBool());
|
||||
}
|
||||
|
||||
if (grabbableKey["spatialKey"].isObject()) {
|
||||
QJsonObject spatialKey = grabbableKey["spatialKey"].toObject();
|
||||
grabProperties.setEquippable(true);
|
||||
if (spatialKey["leftRelativePosition"].isObject()) {
|
||||
grabProperties.setEquippableLeftPosition(qMapToVec3(spatialKey["leftRelativePosition"].toVariant()));
|
||||
}
|
||||
if (spatialKey["rightRelativePosition"].isObject()) {
|
||||
grabProperties.setEquippableRightPosition(qMapToVec3(spatialKey["rightRelativePosition"].toVariant()));
|
||||
}
|
||||
if (spatialKey["relativeRotation"].isObject()) {
|
||||
grabProperties.setEquippableLeftRotation(qMapToQuat(spatialKey["relativeRotation"].toVariant()));
|
||||
grabProperties.setEquippableRightRotation(qMapToQuat(spatialKey["relativeRotation"].toVariant()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QJsonValue wearableValue = userData["wearable"];
|
||||
if (wearableValue.isObject()) {
|
||||
QJsonObject wearable = wearableValue.toObject();
|
||||
QJsonObject joints = wearable["joints"].toObject();
|
||||
if (joints["LeftHand"].isArray()) {
|
||||
QJsonArray leftHand = joints["LeftHand"].toArray();
|
||||
if (leftHand.size() == 2) {
|
||||
grabProperties.setEquippable(true);
|
||||
grabProperties.setEquippableLeftPosition(qMapToVec3(leftHand[0].toVariant()));
|
||||
grabProperties.setEquippableLeftRotation(qMapToQuat(leftHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
if (joints["RightHand"].isArray()) {
|
||||
QJsonArray rightHand = joints["RightHand"].toArray();
|
||||
if (rightHand.size() == 2) {
|
||||
grabProperties.setEquippable(true);
|
||||
grabProperties.setEquippableRightPosition(qMapToVec3(rightHand[0].toVariant()));
|
||||
grabProperties.setEquippableRightRotation(qMapToQuat(rightHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QJsonValue equipHotspotsValue = userData["equipHotspots"];
|
||||
if (equipHotspotsValue.isArray()) {
|
||||
QJsonArray equipHotspots = equipHotspotsValue.toArray();
|
||||
if (equipHotspots.size() > 0) {
|
||||
// just take the first one
|
||||
QJsonObject firstHotSpot = equipHotspots[0].toObject();
|
||||
QJsonObject joints = firstHotSpot["joints"].toObject();
|
||||
if (joints["LeftHand"].isArray()) {
|
||||
QJsonArray leftHand = joints["LeftHand"].toArray();
|
||||
if (leftHand.size() == 2) {
|
||||
grabProperties.setEquippableLeftPosition(qMapToVec3(leftHand[0].toVariant()));
|
||||
grabProperties.setEquippableLeftRotation(qMapToQuat(leftHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
if (joints["RightHand"].isArray()) {
|
||||
QJsonArray rightHand = joints["RightHand"].toArray();
|
||||
if (rightHand.size() == 2) {
|
||||
grabProperties.setEquippable(true);
|
||||
grabProperties.setEquippableRightPosition(qMapToVec3(rightHand[0].toVariant()));
|
||||
grabProperties.setEquippableRightRotation(qMapToQuat(rightHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
QJsonValue indicatorURL = firstHotSpot["modelURL"];
|
||||
if (indicatorURL.isString()) {
|
||||
grabProperties.setEquippableIndicatorURL(indicatorURL.toString());
|
||||
}
|
||||
QJsonValue indicatorScale = firstHotSpot["modelScale"];
|
||||
if (indicatorScale.isDouble()) {
|
||||
grabProperties.setEquippableIndicatorScale(glm::vec3((float)indicatorScale.toDouble()));
|
||||
} else if (indicatorScale.isObject()) {
|
||||
grabProperties.setEquippableIndicatorScale(qMapToVec3(indicatorScale.toVariant()));
|
||||
}
|
||||
QJsonValue indicatorOffset = firstHotSpot["position"];
|
||||
if (indicatorOffset.isObject()) {
|
||||
grabProperties.setEquippableIndicatorOffset(qMapToVec3(indicatorOffset.toVariant()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool EntityTree::readFromMap(QVariantMap& map) {
|
||||
// These are needed to deal with older content (before adding inheritance modes)
|
||||
int contentVersion = map["Version"].toInt();
|
||||
|
@ -2639,104 +2751,7 @@ bool EntityTree::readFromMap(QVariantMap& map) {
|
|||
|
||||
// convert old grab-related userData to new grab properties
|
||||
if (contentVersion < (int)EntityVersion::GrabProperties) {
|
||||
QJsonObject userData = QJsonDocument::fromJson(properties.getUserData().toUtf8()).object();
|
||||
QJsonObject grabbableKey = userData["grabbableKey"].toObject();
|
||||
QJsonValue wantsTrigger = grabbableKey["wantsTrigger"];
|
||||
|
||||
GrabPropertyGroup& grabProperties = properties.getGrab();
|
||||
|
||||
if (wantsTrigger.isBool()) {
|
||||
grabProperties.setTriggerable(wantsTrigger.toBool());
|
||||
}
|
||||
QJsonValue triggerable = grabbableKey["triggerable"];
|
||||
if (triggerable.isBool()) {
|
||||
grabProperties.setTriggerable(triggerable.toBool());
|
||||
}
|
||||
QJsonValue grabbable = grabbableKey["grabbable"];
|
||||
if (grabbable.isBool()) {
|
||||
grabProperties.setGrabbable(grabbable.toBool());
|
||||
}
|
||||
QJsonValue ignoreIK = grabbableKey["ignoreIK"];
|
||||
if (ignoreIK.isBool()) {
|
||||
grabProperties.setGrabFollowsController(ignoreIK.toBool());
|
||||
}
|
||||
QJsonValue kinematic = grabbableKey["kinematic"];
|
||||
if (kinematic.isBool()) {
|
||||
grabProperties.setGrabKinematic(kinematic.toBool());
|
||||
}
|
||||
|
||||
if (grabbableKey["spatialKey"].isObject()) {
|
||||
QJsonObject spatialKey = grabbableKey["spatialKey"].toObject();
|
||||
grabProperties.setEquippable(true);
|
||||
if (spatialKey["leftRelativePosition"].isObject()) {
|
||||
grabProperties.setEquippableLeftPosition(qMapToVec3(spatialKey["leftRelativePosition"].toVariant()));
|
||||
}
|
||||
if (spatialKey["rightRelativePosition"].isObject()) {
|
||||
grabProperties.setEquippableRightPosition(qMapToVec3(spatialKey["rightRelativePosition"].toVariant()));
|
||||
}
|
||||
if (spatialKey["relativeRotation"].isObject()) {
|
||||
grabProperties.setEquippableLeftRotation(qMapToQuat(spatialKey["relativeRotation"].toVariant()));
|
||||
grabProperties.setEquippableRightRotation(qMapToQuat(spatialKey["relativeRotation"].toVariant()));
|
||||
}
|
||||
}
|
||||
|
||||
QJsonObject wearable = userData["wearable"].toObject();
|
||||
QJsonObject joints = wearable["joints"].toObject();
|
||||
if (joints["LeftHand"].isArray()) {
|
||||
QJsonArray leftHand = joints["LeftHand"].toArray();
|
||||
if (leftHand.size() == 2) {
|
||||
grabProperties.setEquippable(true);
|
||||
grabProperties.setEquippableLeftPosition(qMapToVec3(leftHand[0].toVariant()));
|
||||
grabProperties.setEquippableLeftRotation(qMapToQuat(leftHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
if (joints["RightHand"].isArray()) {
|
||||
QJsonArray rightHand = joints["RightHand"].toArray();
|
||||
if (rightHand.size() == 2) {
|
||||
grabProperties.setEquippable(true);
|
||||
grabProperties.setEquippableRightPosition(qMapToVec3(rightHand[0].toVariant()));
|
||||
grabProperties.setEquippableRightRotation(qMapToQuat(rightHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
|
||||
if (userData["equipHotspots"].isArray()) {
|
||||
QJsonArray equipHotspots = userData["equipHotspots"].toArray();
|
||||
if (equipHotspots.size() > 0) {
|
||||
// just take the first one
|
||||
QJsonObject firstHotSpot = equipHotspots[0].toObject();
|
||||
QJsonObject joints = firstHotSpot["joints"].toObject();
|
||||
if (joints["LeftHand"].isArray()) {
|
||||
QJsonArray leftHand = joints["LeftHand"].toArray();
|
||||
if (leftHand.size() == 2) {
|
||||
grabProperties.setEquippable(true);
|
||||
grabProperties.setEquippableLeftPosition(qMapToVec3(leftHand[0].toVariant()));
|
||||
grabProperties.setEquippableLeftRotation(qMapToQuat(leftHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
if (joints["RightHand"].isArray()) {
|
||||
QJsonArray rightHand = joints["RightHand"].toArray();
|
||||
if (rightHand.size() == 2) {
|
||||
grabProperties.setEquippable(true);
|
||||
grabProperties.setEquippableRightPosition(qMapToVec3(rightHand[0].toVariant()));
|
||||
grabProperties.setEquippableRightRotation(qMapToQuat(rightHand[1].toVariant()));
|
||||
}
|
||||
}
|
||||
QJsonValue indicatorURL = firstHotSpot["modelURL"];
|
||||
if (indicatorURL.isString()) {
|
||||
grabProperties.setEquippableIndicatorURL(indicatorURL.toString());
|
||||
}
|
||||
QJsonValue indicatorScale = firstHotSpot["modelScale"];
|
||||
if (indicatorScale.isDouble()) {
|
||||
grabProperties.setEquippableIndicatorScale(glm::vec3((float)indicatorScale.toDouble()));
|
||||
} else if (indicatorScale.isObject()) {
|
||||
grabProperties.setEquippableIndicatorScale(qMapToVec3(indicatorScale.toVariant()));
|
||||
}
|
||||
QJsonValue indicatorOffset = firstHotSpot["position"];
|
||||
if (indicatorOffset.isObject()) {
|
||||
grabProperties.setEquippableIndicatorOffset(qMapToVec3(indicatorOffset.toVariant()));
|
||||
}
|
||||
}
|
||||
}
|
||||
convertGrabUserDataToProperties(properties);
|
||||
}
|
||||
|
||||
// Zero out the spread values that were fixed in version ParticleEntityFix so they behave the same as before
|
||||
|
|
|
@ -424,4 +424,6 @@ private:
|
|||
std::map<QString, QString> _namedPaths;
|
||||
};
|
||||
|
||||
void convertGrabUserDataToProperties(EntityItemProperties& properties);
|
||||
|
||||
#endif // hifi_EntityTree_h
|
||||
|
|
|
@ -51,6 +51,9 @@ void GrabPropertyGroup::copyFromScriptValue(const QScriptValue& object, bool& _d
|
|||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableLeftRotation, quat, setEquippableLeftRotation);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableRightPosition, vec3, setEquippableRightPosition);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableRightRotation, quat, setEquippableRightRotation);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableIndicatorURL, QString, setEquippableIndicatorURL);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableIndicatorScale, vec3, setEquippableIndicatorScale);
|
||||
COPY_GROUP_PROPERTY_FROM_QSCRIPTVALUE(grab, equippableIndicatorOffset, vec3, setEquippableIndicatorOffset);
|
||||
}
|
||||
|
||||
void GrabPropertyGroup::merge(const GrabPropertyGroup& other) {
|
||||
|
@ -63,6 +66,9 @@ void GrabPropertyGroup::merge(const GrabPropertyGroup& other) {
|
|||
COPY_PROPERTY_IF_CHANGED(equippableLeftRotation);
|
||||
COPY_PROPERTY_IF_CHANGED(equippableRightPosition);
|
||||
COPY_PROPERTY_IF_CHANGED(equippableRightRotation);
|
||||
COPY_PROPERTY_IF_CHANGED(equippableIndicatorURL);
|
||||
COPY_PROPERTY_IF_CHANGED(equippableIndicatorScale);
|
||||
COPY_PROPERTY_IF_CHANGED(equippableIndicatorOffset);
|
||||
}
|
||||
|
||||
void GrabPropertyGroup::debugDump() const {
|
||||
|
@ -77,6 +83,9 @@ void GrabPropertyGroup::debugDump() const {
|
|||
qCDebug(entities) << " _equippableLeftRotation:" << _equippableLeftRotation;
|
||||
qCDebug(entities) << " _equippableRightPosition:" << _equippableRightPosition;
|
||||
qCDebug(entities) << " _equippableRightRotation:" << _equippableRightRotation;
|
||||
qCDebug(entities) << " _equippableIndicatorURL:" << _equippableIndicatorURL;
|
||||
qCDebug(entities) << " _equippableIndicatorScale:" << _equippableIndicatorScale;
|
||||
qCDebug(entities) << " _equippableIndicatorOffset:" << _equippableIndicatorOffset;
|
||||
}
|
||||
|
||||
void GrabPropertyGroup::listChangedProperties(QList<QString>& out) {
|
||||
|
@ -107,6 +116,15 @@ void GrabPropertyGroup::listChangedProperties(QList<QString>& out) {
|
|||
if (equippableRightRotationChanged()) {
|
||||
out << "grab-equippableRightRotation";
|
||||
}
|
||||
if (equippableIndicatorURLChanged()) {
|
||||
out << "grab-equippableIndicatorURL";
|
||||
}
|
||||
if (equippableIndicatorScaleChanged()) {
|
||||
out << "grab-equippableIndicatorScale";
|
||||
}
|
||||
if (equippableIndicatorOffsetChanged()) {
|
||||
out << "grab-equippableIndicatorOffset";
|
||||
}
|
||||
}
|
||||
|
||||
bool GrabPropertyGroup::appendToEditPacket(OctreePacketData* packetData,
|
||||
|
@ -184,6 +202,9 @@ void GrabPropertyGroup::markAllChanged() {
|
|||
_equippableLeftRotationChanged = true;
|
||||
_equippableRightPositionChanged = true;
|
||||
_equippableRightRotationChanged = true;
|
||||
_equippableIndicatorURLChanged = true;
|
||||
_equippableIndicatorScaleChanged = true;
|
||||
_equippableIndicatorOffsetChanged = true;
|
||||
}
|
||||
|
||||
EntityPropertyFlags GrabPropertyGroup::getChangedProperties() const {
|
||||
|
@ -215,6 +236,9 @@ void GrabPropertyGroup::getProperties(EntityItemProperties& properties) const {
|
|||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableLeftRotation, getEquippableLeftRotation);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableRightPosition, getEquippableRightPosition);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableRightRotation, getEquippableRightRotation);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableIndicatorURL, getEquippableIndicatorURL);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableIndicatorScale, getEquippableIndicatorScale);
|
||||
COPY_ENTITY_GROUP_PROPERTY_TO_PROPERTIES(Grab, EquippableIndicatorOffset, getEquippableIndicatorOffset);
|
||||
}
|
||||
|
||||
bool GrabPropertyGroup::setProperties(const EntityItemProperties& properties) {
|
||||
|
@ -231,6 +255,12 @@ bool GrabPropertyGroup::setProperties(const EntityItemProperties& properties) {
|
|||
setEquippableRightPosition);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableRightRotation, equippableRightRotation,
|
||||
setEquippableRightRotation);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableIndicatorURL, equippableIndicatorURL,
|
||||
setEquippableIndicatorURL);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableIndicatorScale, equippableIndicatorScale,
|
||||
setEquippableIndicatorScale);
|
||||
SET_ENTITY_GROUP_PROPERTY_FROM_PROPERTIES(Grab, EquippableIndicatorOffset, equippableIndicatorOffset,
|
||||
setEquippableIndicatorOffset);
|
||||
|
||||
return somethingChanged;
|
||||
}
|
||||
|
|
|
@ -167,16 +167,6 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa
|
|||
};
|
||||
|
||||
|
||||
var alreadyWarned = {};
|
||||
function warnAboutUserData(props) {
|
||||
if (alreadyWarned[props.id]) {
|
||||
return;
|
||||
}
|
||||
print("Warning -- overriding grab properties with userData for " + props.id + " / " + props.name);
|
||||
alreadyWarned[props.id] = true;
|
||||
}
|
||||
|
||||
|
||||
(function() {
|
||||
|
||||
var ATTACH_POINT_SETTINGS = "io.highfidelity.attachPoints";
|
||||
|
@ -200,7 +190,6 @@ function warnAboutUserData(props) {
|
|||
|
||||
function getWearableData(props) {
|
||||
if (props.grab.equippable) {
|
||||
// if equippable is true, we know this was already converted from the old userData style to properties
|
||||
return {
|
||||
joints: {
|
||||
LeftHand: [ props.grab.equippableLeftPosition, props.grab.equippableLeftRotation ],
|
||||
|
@ -211,67 +200,7 @@ function warnAboutUserData(props) {
|
|||
indicatorOffset: props.grab.equippableIndicatorOffset
|
||||
};
|
||||
} else {
|
||||
// check for old userData equippability. The JSON reader will convert userData to properties
|
||||
// in EntityTree.cpp, but this won't catch things created from scripts or some items in
|
||||
// the market. Eventually we'll remove this section.
|
||||
try {
|
||||
if (!props.userDataParsed) {
|
||||
props.userDataParsed = JSON.parse(props.userData);
|
||||
}
|
||||
var userDataParsed = props.userDataParsed;
|
||||
|
||||
// userData: { wearable: { joints: { LeftHand: {...}, RightHand: {...} } } }
|
||||
if (userDataParsed.wearable && userDataParsed.wearable.joints) {
|
||||
warnAboutUserData(props);
|
||||
userDataParsed.wearable.indicatorURL = "";
|
||||
userDataParsed.wearable.indicatorScale = { x: 1, y: 1, z: 1 };
|
||||
userDataParsed.wearable.indicatorOffset = { x: 0, y: 0, z: 0 };
|
||||
return userDataParsed.wearable;
|
||||
}
|
||||
|
||||
// userData: { equipHotspots: { joints: { LeftHand: {...}, RightHand: {...} } } }
|
||||
// https://highfidelity.atlassian.net/wiki/spaces/HOME/pages/51085337/Authoring+Equippable+Entities
|
||||
if (userDataParsed.equipHotspots &&
|
||||
userDataParsed.equipHotspots.length > 0 &&
|
||||
userDataParsed.equipHotspots[0].joints) {
|
||||
warnAboutUserData(props);
|
||||
var hotSpot = userDataParsed.equipHotspots[0];
|
||||
|
||||
var indicatorScale = { x: hotSpot.radius, y: hotSpot.radius, z: hotSpot.radius };
|
||||
if (hotSpot.modelURL && hotSpot.modelURL !== "") {
|
||||
indicatorScale = hotSpot.modelScale;
|
||||
}
|
||||
|
||||
return {
|
||||
joints: hotSpot.joints,
|
||||
indicatorURL: hotSpot.modelURL,
|
||||
indicatorScale: indicatorScale,
|
||||
indicatorOffset: hotSpot.position,
|
||||
};
|
||||
}
|
||||
|
||||
// userData:{grabbableKey:{spatialKey:{leftRelativePosition:{...},rightRelativePosition:{...}}}}
|
||||
if (userDataParsed.grabbableKey &&
|
||||
userDataParsed.grabbableKey.spatialKey) {
|
||||
warnAboutUserData(props);
|
||||
var joints = {};
|
||||
joints.LeftHand = [ { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0, w: 1 } ];
|
||||
joints.RightHand = [ { x: 0, y: 0, z: 0 }, { x: 0, y: 0, z: 0, w: 1 } ];
|
||||
if (userDataParsed.grabbableKey.spatialKey.leftRelativePosition) {
|
||||
joints.LeftHand = [userDataParsed.grabbableKey.spatialKey.leftRelativePosition,
|
||||
userDataParsed.grabbableKey.spatialKey.relativeRotation];
|
||||
}
|
||||
if (userDataParsed.grabbableKey.spatialKey.rightRelativePosition) {
|
||||
joints.RightHand = [userDataParsed.grabbableKey.spatialKey.rightRelativePosition,
|
||||
userDataParsed.grabbableKey.spatialKey.relativeRotation];
|
||||
}
|
||||
return { joints: joints };
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
// don't spam logs
|
||||
}
|
||||
return null;
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue