History

attempt to keep userData and new grab properties in sync

Seth Alves committed 8 years ago

Commit 252e5041 parent b9f8c596 files · +388 −98Browse files

Showing the changes to libraries/entities/src/EntityScriptingInterface.cpp (1 of 6 files). Show all

Unified · Split

libraries/entities/src/EntityScriptingInterface.cpp+232−0
@@ -16,6 +16,9 @@ · 15 unmodified lines
1616
1717 #include <QFutureWatcher>
1818 #include <QtConcurrent/QtConcurrentRun>
19+#include <QJsonObject>
20+#include <QJsonDocument>
21+#include <QJsonArray>
1922
2023 #include <shared/QtHelpers.h>
2124 #include <VariantMapToScriptValue.h>
@@ -37,6 +40,7 @@ · 15 unmodified lines
3740 #include "WebEntityItem.h"
3841 #include <EntityScriptClient.h>
3942 #include <Profile.h>
43+#include "GrabPropertyGroup.h"
4044
4145 const QString GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":true}}";
4246 const QString NOT_GRABBABLE_USER_DATA = "{\"grabbableKey\":{\"grabbable\":false}}";
@@ -237,6 +241,229 @@ EntityItemProperties convertPropertiesFromScriptSemantics(const EntityItemProper · 194 unmodified lines
237241 }
238242
239243
244+void synchronizeSpatialKey(const GrabPropertyGroup& grabProperties, QJsonObject& grabbableKey, bool& userDataChanged) {
245+ if (grabProperties.equippableLeftPositionChanged() ||
246+ grabProperties.equippableRightPositionChanged() ||
247+ grabProperties.equippableRightRotationChanged() ||
248+ grabProperties.equippableIndicatorURLChanged() ||
249+ grabProperties.equippableIndicatorScaleChanged() ||
250+ grabProperties.equippableIndicatorOffsetChanged()) {
251+
252+ QJsonObject spatialKey = grabbableKey["spatialKey"].toObject();
253+
254+ if (grabProperties.equippableLeftPositionChanged()) {
255+ if (grabProperties.getEquippableLeftPosition() == INITIAL_LEFT_EQUIPPABLE_POSITION) {
256+ spatialKey.remove("leftRelativePosition");
257+ } else {
258+ spatialKey["leftRelativePosition"] =
259+ QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableLeftPosition()));
260+ }
261+ }
262+ if (grabProperties.equippableRightPositionChanged()) {
263+ if (grabProperties.getEquippableRightPosition() == INITIAL_RIGHT_EQUIPPABLE_POSITION) {
264+ spatialKey.remove("rightRelativePosition");
265+ } else {
266+ spatialKey["rightRelativePosition"] =
267+ QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableRightPosition()));
268+ }
269+ }
270+ if (grabProperties.equippableLeftRotationChanged()) {
271+ spatialKey["relativeRotation"] =
272+ QJsonValue::fromVariant(quatToQMap(grabProperties.getEquippableLeftRotation()));
273+ } else if (grabProperties.equippableRightRotationChanged()) {
274+ spatialKey["relativeRotation"] =
275+ QJsonValue::fromVariant(quatToQMap(grabProperties.getEquippableRightRotation()));
276+ }
277+
278+ grabbableKey["spatialKey"] = spatialKey;
279+ userDataChanged = true;
280+ }
281+}
282+
283+
284+void synchronizeGrabbableKey(const GrabPropertyGroup& grabProperties, QJsonObject& userData, bool& userDataChanged) {
285+ if (grabProperties.triggerableChanged() ||
286+ grabProperties.grabbableChanged() ||
287+ grabProperties.grabFollowsControllerChanged() ||
288+ grabProperties.grabKinematicChanged() ||
289+ grabProperties.equippableChanged()) {
290+
291+ QJsonObject grabbableKey = userData["grabbableKey"].toObject();
292+
293+ if (grabProperties.triggerableChanged()) {
294+ if (grabProperties.getTriggerable()) {
295+ grabbableKey["triggerable"] = true;
296+ } else {
297+ grabbableKey.remove("triggerable");
298+ }
299+ }
300+ if (grabProperties.grabbableChanged()) {
301+ if (grabProperties.getGrabbable()) {
302+ grabbableKey.remove("grabbable");
303+ } else {
304+ grabbableKey["grabbable"] = false;
305+ }
306+ }
307+ if (grabProperties.grabFollowsControllerChanged()) {
308+ if (grabProperties.getGrabFollowsController()) {
309+ grabbableKey.remove("ignoreIK");
310+ } else {
311+ grabbableKey["ignoreIK"] = false;
312+ }
313+ }
314+ if (grabProperties.grabKinematicChanged()) {
315+ if (grabProperties.getGrabKinematic()) {
316+ grabbableKey.remove("kinematic");
317+ } else {
318+ grabbableKey["kinematic"] = false;
319+ }
320+ }
321+ if (grabProperties.equippableChanged()) {
322+ if (grabProperties.getEquippable()) {
323+ grabbableKey["equippable"] = true;
324+ } else {
325+ grabbableKey.remove("equippable");
326+ }
327+ }
328+
329+ if (grabbableKey.contains("spatialKey")) {
330+ synchronizeSpatialKey(grabProperties, grabbableKey, userDataChanged);
331+ }
332+
333+ userData["grabbableKey"] = grabbableKey;
334+ userDataChanged = true;
335+ }
336+}
337+
338+void synchronizeGrabJoints(const GrabPropertyGroup& grabProperties, QJsonObject& joints) {
339+ QJsonArray rightHand = joints["RightHand"].toArray();
340+ QJsonObject rightHandPosition = rightHand.size() > 0 ? rightHand[0].toObject() : QJsonObject();
341+ QJsonObject rightHandRotation = rightHand.size() > 1 ? rightHand[1].toObject() : QJsonObject();
342+ QJsonArray leftHand = joints["LeftHand"].toArray();
343+ QJsonObject leftHandPosition = leftHand.size() > 0 ? leftHand[0].toObject() : QJsonObject();
344+ QJsonObject leftHandRotation = leftHand.size() > 1 ? leftHand[1].toObject() : QJsonObject();
345+
346+ if (grabProperties.equippableLeftPositionChanged()) {
347+ leftHandPosition =
348+ QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableLeftPosition())).toObject();
349+ }
350+ if (grabProperties.equippableRightPositionChanged()) {
351+ rightHandPosition =
352+ QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableRightPosition())).toObject();
353+ }
354+ if (grabProperties.equippableLeftRotationChanged()) {
355+ leftHandRotation =
356+ QJsonValue::fromVariant(quatToQMap(grabProperties.getEquippableLeftRotation())).toObject();
357+ }
358+ if (grabProperties.equippableRightRotationChanged()) {
359+ rightHandRotation =
360+ QJsonValue::fromVariant(quatToQMap(grabProperties.getEquippableRightRotation())).toObject();
361+ }
362+
363+ rightHand[0] = rightHandPosition;
364+ rightHand[1] = rightHandRotation;
365+ joints["RightHand"] = rightHand;
366+ leftHand[0] = leftHandPosition;
367+ leftHand[1] = leftHandRotation;
368+ joints["LeftHand"] = leftHand;
369+}
370+
371+void synchronizeEquipHotspot(const GrabPropertyGroup& grabProperties, QJsonObject& userData, bool& userDataChanged) {
372+ if (grabProperties.equippableLeftPositionChanged() ||
373+ grabProperties.equippableRightPositionChanged() ||
374+ grabProperties.equippableRightRotationChanged() ||
375+ grabProperties.equippableIndicatorURLChanged() ||
376+ grabProperties.equippableIndicatorScaleChanged() ||
377+ grabProperties.equippableIndicatorOffsetChanged()) {
378+
379+ QJsonArray equipHotspots = userData["equipHotspots"].toArray();
380+ QJsonObject equipHotspot = equipHotspots[0].toObject();
381+ QJsonObject joints = equipHotspot["joints"].toObject();
382+
383+ synchronizeGrabJoints(grabProperties, joints);
384+
385+ if (grabProperties.equippableIndicatorURLChanged()) {
386+ equipHotspot["modelURL"] = grabProperties.getEquippableIndicatorURL();
387+ }
388+ if (grabProperties.equippableIndicatorScaleChanged()) {
389+ QJsonObject scale =
390+ QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableIndicatorScale())).toObject();
391+ equipHotspot["radius"] = scale;
392+ equipHotspot["modelScale"] = scale;
393+
394+ }
395+ if (grabProperties.equippableIndicatorOffsetChanged()) {
396+ equipHotspot["position"] =
397+ QJsonValue::fromVariant(vec3ToQMap(grabProperties.getEquippableIndicatorOffset())).toObject();
398+ }
399+
400+ equipHotspot["joints"] = joints;
401+ equipHotspots[0] = equipHotspot;
402+ userData["equipHotspots"] = equipHotspots;
403+ userDataChanged = true;
404+ }
405+}
406+
407+void synchronizeWearable(const GrabPropertyGroup& grabProperties, QJsonObject& userData, bool& userDataChanged) {
408+ if (grabProperties.equippableLeftPositionChanged() ||
409+ grabProperties.equippableRightPositionChanged() ||
410+ grabProperties.equippableRightRotationChanged() ||
411+ grabProperties.equippableIndicatorURLChanged() ||
412+ grabProperties.equippableIndicatorScaleChanged() ||
413+ grabProperties.equippableIndicatorOffsetChanged()) {
414+
415+ QJsonObject wearable = userData["wearable"].toObject();
416+ QJsonObject joints = wearable["joints"].toObject();
417+
418+ synchronizeGrabJoints(grabProperties, joints);
419+
420+ wearable["joints"] = joints;
421+ userData["wearable"] = wearable;
422+ userDataChanged = true;
423+ }
424+}
425+
426+void synchronizeEditedGrabProperties(EntityItemProperties& properties, const QString& previousUserdata) {
427+ // After sufficient warning to content creators, we should be able to remove this.
428+
429+ if (properties.grabbingRelatedPropertyChanged()) {
430+ // This edit touches a new-style grab property, so make userData agree...
431+ GrabPropertyGroup& grabProperties = properties.getGrab();
432+
433+ bool userDataChanged { false };
434+
435+ // if the edit changed userData, use the updated version coming along with the edit. If not, use
436+ // what was already in the entity.
437+ QByteArray userDataString;
438+ if (properties.userDataChanged()) {
439+ userDataString = properties.getUserData().toUtf8();
440+ } else {
441+ userDataString = previousUserdata.toUtf8();;
442+ }
443+ QJsonObject userData = QJsonDocument::fromJson(userDataString).object();
444+
445+ if (userData.contains("grabbableKey")) {
446+ synchronizeGrabbableKey(grabProperties, userData, userDataChanged);
447+ }
448+ if (userData.contains("equipHotspots")) {
449+ synchronizeEquipHotspot(grabProperties, userData, userDataChanged);
450+ }
451+ if (userData.contains("wearable")) {
452+ synchronizeWearable(grabProperties, userData, userDataChanged);
453+ }
454+
455+ if (userDataChanged) {
456+ properties.setUserData(QJsonDocument(userData).toJson());
457+ }
458+
459+ } else if (properties.userDataChanged()) {
460+ // This edit touches userData (and doesn't touch a new-style grab property). Check for grabbableKey in the
461+ // userdata and make the new-style grab properties agree
462+ convertGrabUserDataToProperties(properties);
463+ }
464+}
465+
466+
240467 QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties, bool clientOnly) {
241468 PROFILE_RANGE(script_entities, __FUNCTION__);
242469
@@ -257,6 +484,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties · 14 unmodified lines
257484
258485 propertiesWithSimID = convertPropertiesFromScriptSemantics(propertiesWithSimID, scalesWithParent);
259486 propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged());
487+ synchronizeEditedGrabProperties(propertiesWithSimID, QString());
260488
261489 EntityItemID id;
262490 // If we have a local entity tree set, then also update it.
@@ -559,6 +787,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& · 296 unmodified lines
559787 simulationOwner = entity->getSimulationOwner();
560788 });
561789
790+ QString previousUserdata;
562791 if (entity) {
563792 if (properties.hasSimulationRestrictedChanges()) {
564793 if (_bidOnSimulationOwnership) {
@@ -597,6 +826,8 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& · 32 unmodified lines
597826
598827 // make sure the properties has a type, so that the encode can know which properties to include
599828 properties.setType(entity->getType());
829+
830+ previousUserdata = entity->getUserData();
600831 } else if (_bidOnSimulationOwnership) {
601832 // bail when simulation participants don't know about entity
602833 return QUuid();
@@ -605,6 +836,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& · 2 unmodified lines
605836 // How to check for this cheaply?
606837
607838 properties = convertPropertiesFromScriptSemantics(properties, properties.getScalesWithParent());
839+ synchronizeEditedGrabProperties(properties, previousUserdata);
608840 properties.setLastEditedBy(sessionID);
609841
610842 // done reading and modifying properties --> start write