From f1992af38e3d682719a3eaf10c1048848794d737 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 12 Mar 2016 10:13:13 -0800 Subject: [PATCH 1/5] started to add grabbable psuedo properties to edit.js --- examples/attachedEntitiesManager.js | 1 - examples/controllers/handControllerGrab.js | 8 +-- examples/html/entityProperties.html | 60 +++++++++++++++++++--- 3 files changed, 56 insertions(+), 13 deletions(-) diff --git a/examples/attachedEntitiesManager.js b/examples/attachedEntitiesManager.js index 4dda76f4df..ef85f8cb98 100644 --- a/examples/attachedEntitiesManager.js +++ b/examples/attachedEntitiesManager.js @@ -213,7 +213,6 @@ function AttachedEntitiesManager() { var props = Entities.getEntityProperties(entityID); if (props.parentID == MyAvatar.sessionUUID) { grabData = getEntityCustomData('grabKey', entityID, {}); - grabbableData = getEntityCustomData('grabbableKey', entityID, {}); var wearableData = getEntityCustomData('wearable', entityID, DEFAULT_WEARABLE_DATA); var currentJointName = MyAvatar.getJointNames()[props.parentJointIndex]; wearableData.joints[currentJointName] = [props.localPosition, props.localRotation]; diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 964fca4136..43c18da72d 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -1006,7 +1006,7 @@ function MyController(hand) { // else this thing isn't physical. grab it by reparenting it (but not if we've already // grabbed it). - if (grabbableData.refCount < 1) { + if (refCount < 1) { this.setState(this.state == STATE_SEARCHING ? STATE_NEAR_GRABBING : STATE_EQUIP); return; } else { @@ -1120,7 +1120,6 @@ function MyController(hand) { var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES); - var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA); if (this.state == STATE_CONTINUE_DISTANCE_HOLDING && this.bumperSqueezed() && this.hasPresetOffsets()) { @@ -1307,7 +1306,6 @@ function MyController(hand) { this.nearGrabbing = function() { var now = Date.now(); - var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA); if (this.state == STATE_NEAR_GRABBING && this.triggerSmoothedReleased()) { this.setState(STATE_RELEASE); @@ -1330,10 +1328,9 @@ function MyController(hand) { var handRotation = (this.hand === RIGHT_HAND) ? MyAvatar.getRightPalmRotation() : MyAvatar.getLeftPalmRotation(); var handPosition = this.getHandPosition(); - var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA); - var hasPresetPosition = false; if (this.state != STATE_NEAR_GRABBING && this.hasPresetOffsets()) { + var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA); // if an object is "equipped" and has a predefined offset, use it. this.ignoreIK = grabbableData.ignoreIK ? grabbableData.ignoreIK : false; this.offsetPosition = this.getPresetPosition(); @@ -1676,7 +1673,6 @@ function MyController(hand) { }; this.activateEntity = function(entityID, grabbedProperties, wasLoaded) { - var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, entityID, DEFAULT_GRABBABLE_DATA); var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {}); var now = Date.now(); diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 1101a08acb..92df997ac2 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -243,6 +243,21 @@ } + function createUserDataChanger(groupName, keyName, propertyElement, userData) { + return function() { + var properties = {}; + // // this.checked + // properties['userData'] = ... JSON.stringify (...) + // EventBridge.emitWebEvent( + // JSON.stringify({ + // type: "update", + // properties: properties, + // }) + // ); + } + }; + + function loaded() { openEventBridge(function() { var allSections = []; @@ -305,6 +320,11 @@ var elCollideMyAvatar = document.getElementById("property-collide-myAvatar"); var elCollideOtherAvatar = document.getElementById("property-collide-otherAvatar"); var elCollisionSoundURL = document.getElementById("property-collision-sound-url"); + + var elGrabbable = document.getElementById("property-grabbable" ); + var elWantsTrigger = document.getElementById("property-wants-trigger" ); + var elIgnoreIK = document.getElementById("property-ignore-ik" ); + var elLifetime = document.getElementById("property-lifetime"); var elScriptURL = document.getElementById("property-script-url"); var elScriptTimestamp = document.getElementById("property-script-timestamp"); @@ -408,7 +428,7 @@ var elXTextureURL = document.getElementById("property-x-texture-url"); var elYTextureURL = document.getElementById("property-y-texture-url"); var elZTextureURL = document.getElementById("property-z-texture-url"); - + var elPreviewCameraButton = document.getElementById("preview-camera-button"); if (window.EventBridge !== undefined) { @@ -518,13 +538,15 @@ elCollisionless.checked = properties.collisionless; elDynamic.checked = properties.dynamic; - elCollideStatic.checked = properties.collidesWith.indexOf("static") > -1; elCollideKinematic.checked = properties.collidesWith.indexOf("kinematic") > -1; elCollideDynamic.checked = properties.collidesWith.indexOf("dynamic") > -1; elCollideMyAvatar.checked = properties.collidesWith.indexOf("myAvatar") > -1; elCollideOtherAvatar.checked = properties.collidesWith.indexOf("otherAvatar") > -1; + elGrabbable.checked = properties.collidesWith.indexOf("grabbable") > -1; + elWantsTrigger.checked = properties.collidesWith.indexOf("wantsTrigger") > -1; + elIgnoreIK.checked = properties.collidesWith.indexOf("ignoreIK") > -1; elCollisionSoundURL.value = properties.collisionSoundURL; elLifetime.value = properties.lifetime; @@ -737,9 +759,6 @@ elCollisionless.addEventListener('change', createEmitCheckedPropertyUpdateFunction('collisionless')); elDynamic.addEventListener('change', createEmitCheckedPropertyUpdateFunction('dynamic')); - - - elCollideDynamic.addEventListener('change', function() { updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideDynamic, 'dynamic'); }); @@ -758,6 +777,12 @@ updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideOtherAvatar, 'otherAvatar'); }); + elGrabbable.addEventListener('change', createUserDataChanger("grabbableKey", "grabbable", + elGrabbable, properties.userData)); + elWantsTrigger.addEventListener('change', createUserDataChanger("grabbableKey", "wantsTrigger", + elWantsTrigger, properties.userData)); + elIgnoreIK.addEventListener('change', createUserDataChanger("grabbableKey", "ignoreIK", + elIgnoreIK, properties.userData)); elCollisionSoundURL.addEventListener('change', createEmitTextPropertyUpdateFunction('collisionSoundURL')); @@ -954,7 +979,7 @@ action: "previewCamera" })); }); - + window.onblur = function() { // Fake a change event var ev = document.createEvent("HTMLEvents"); @@ -1476,6 +1501,29 @@ +
Grabbable:
+
+
+ grabbable + + + +
+ +
+ triggerable + + + +
+ +
+ ignore inverse-kinematics + + + +
+
From be51040420e363394bb1c3aa1cc5da8874a2ae54 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 12 Mar 2016 13:17:42 -0800 Subject: [PATCH 2/5] grabbable controlls are working --- examples/html/entityProperties.html | 73 ++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 23 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 92df997ac2..cdba00d245 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -243,18 +243,26 @@ } - function createUserDataChanger(groupName, keyName, propertyElement, userData) { - return function() { - var properties = {}; - // // this.checked - // properties['userData'] = ... JSON.stringify (...) - // EventBridge.emitWebEvent( - // JSON.stringify({ - // type: "update", - // properties: properties, - // }) - // ); + function userDataChanger(groupName, keyName, checkBoxElement, userDataElement) { + var properties = {}; + var parsedData = {}; + try { + parsedData = JSON.parse(userDataElement.value); + } catch(e) {} + + if (!(groupName in parsedData)) { + parsedData[groupName] = {} } + parsedData[groupName][keyName] = checkBoxElement.checked; + properties['userData'] = JSON.stringify(parsedData); + userDataElement.value = properties['userData']; + + EventBridge.emitWebEvent( + JSON.stringify({ + type: "update", + properties: properties, + }) + ); }; @@ -321,9 +329,9 @@ var elCollideOtherAvatar = document.getElementById("property-collide-otherAvatar"); var elCollisionSoundURL = document.getElementById("property-collision-sound-url"); - var elGrabbable = document.getElementById("property-grabbable" ); - var elWantsTrigger = document.getElementById("property-wants-trigger" ); - var elIgnoreIK = document.getElementById("property-ignore-ik" ); + var elGrabbable = document.getElementById("property-grabbable"); + var elWantsTrigger = document.getElementById("property-wants-trigger"); + var elIgnoreIK = document.getElementById("property-ignore-ik"); var elLifetime = document.getElementById("property-lifetime"); var elScriptURL = document.getElementById("property-script-url"); @@ -544,9 +552,25 @@ elCollideMyAvatar.checked = properties.collidesWith.indexOf("myAvatar") > -1; elCollideOtherAvatar.checked = properties.collidesWith.indexOf("otherAvatar") > -1; - elGrabbable.checked = properties.collidesWith.indexOf("grabbable") > -1; - elWantsTrigger.checked = properties.collidesWith.indexOf("wantsTrigger") > -1; - elIgnoreIK.checked = properties.collidesWith.indexOf("ignoreIK") > -1; + elGrabbable.checked = false; + elWantsTrigger.checked = false; + elIgnoreIK.checked = false; + var parsedUserData = {} + try { + debugPrint("OKOKOK:" + properties.userData); + parsedUserData = JSON.parse(properties.userData); + } catch(e) {} + if ("grabbableKey" in parsedUserData) { + if (parsedUserData["grabbableKey"].grabbable) { + elGrabbable.checked = true; + } + if (parsedUserData["grabbableKey"].wantsTrigger) { + elWantsTrigger.checked = true; + } + if (parsedUserData["grabbableKey"].ignoreIK) { + elIgnoreIK.checked = true; + } + } elCollisionSoundURL.value = properties.collisionSoundURL; elLifetime.value = properties.lifetime; @@ -777,12 +801,15 @@ updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideOtherAvatar, 'otherAvatar'); }); - elGrabbable.addEventListener('change', createUserDataChanger("grabbableKey", "grabbable", - elGrabbable, properties.userData)); - elWantsTrigger.addEventListener('change', createUserDataChanger("grabbableKey", "wantsTrigger", - elWantsTrigger, properties.userData)); - elIgnoreIK.addEventListener('change', createUserDataChanger("grabbableKey", "ignoreIK", - elIgnoreIK, properties.userData)); + elGrabbable.addEventListener('change', function() { + userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData); + }); + elWantsTrigger.addEventListener('change', function() { + userDataChanger("grabbableKey", "wantsTrigger", elWantsTrigger, elUserData); + }); + elIgnoreIK.addEventListener('change', function() { + userDataChanger("grabbableKey", "ignoreIK", elIgnoreIK, elUserData); + }); elCollisionSoundURL.addEventListener('change', createEmitTextPropertyUpdateFunction('collisionSoundURL')); From cca4a93b2b604b036588e32135d8062f251e5057 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 12 Mar 2016 14:09:52 -0800 Subject: [PATCH 3/5] don't full up userData with default grabbable data --- examples/html/entityProperties.html | 46 ++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index cdba00d245..ae42ea7caf 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -243,7 +243,13 @@ } - function userDataChanger(groupName, keyName, checkBoxElement, userDataElement) { + function isGrabbableByDefault(properties) { + return properties.type == "Box" || + properties.type == "Sphere" || + properties.dynamic + } + + function userDataChanger(groupName, keyName, checkBoxElement, userDataElement, defaultValue) { var properties = {}; var parsedData = {}; try { @@ -253,8 +259,20 @@ if (!(groupName in parsedData)) { parsedData[groupName] = {} } - parsedData[groupName][keyName] = checkBoxElement.checked; - properties['userData'] = JSON.stringify(parsedData); + delete parsedData[groupName][keyName]; + if (checkBoxElement.checked !== defaultValue) { + parsedData[groupName][keyName] = checkBoxElement.checked; + } + + if (Object.keys(parsedData[groupName]).length == 0) { + delete parsedData[groupName]; + } + if (Object.keys(parsedData).length > 0) { + properties['userData'] = JSON.stringify(parsedData); + } else { + properties['userData'] = ''; + } + userDataElement.value = properties['userData']; EventBridge.emitWebEvent( @@ -552,23 +570,23 @@ elCollideMyAvatar.checked = properties.collidesWith.indexOf("myAvatar") > -1; elCollideOtherAvatar.checked = properties.collidesWith.indexOf("otherAvatar") > -1; - elGrabbable.checked = false; + // boxes and sphere are grabbable by default + elGrabbable.checked = isGrabbableByDefault(properties); elWantsTrigger.checked = false; elIgnoreIK.checked = false; var parsedUserData = {} try { - debugPrint("OKOKOK:" + properties.userData); parsedUserData = JSON.parse(properties.userData); } catch(e) {} if ("grabbableKey" in parsedUserData) { - if (parsedUserData["grabbableKey"].grabbable) { - elGrabbable.checked = true; + if ("grabbable" in parsedUserData["grabbableKey"]) { + elGrabbable.checked = parsedUserData["grabbableKey"].grabbable; } - if (parsedUserData["grabbableKey"].wantsTrigger) { - elWantsTrigger.checked = true; + if ("wantsTrigger" in parsedUserData["grabbableKey"]) { + elWantsTrigger.checked = parsedUserData["grabbableKey"].wantsTrigger; } - if (parsedUserData["grabbableKey"].ignoreIK) { - elIgnoreIK.checked = true; + if ("ignoreIK" in parsedUserData["grabbableKey"]) { + elIgnoreIK.checked = parsedUserData["grabbableKey"].ignoreIK; } } @@ -802,13 +820,13 @@ }); elGrabbable.addEventListener('change', function() { - userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData); + userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData, isGrabbableByDefault(properties)); }); elWantsTrigger.addEventListener('change', function() { - userDataChanger("grabbableKey", "wantsTrigger", elWantsTrigger, elUserData); + userDataChanger("grabbableKey", "wantsTrigger", elWantsTrigger, elUserData, false); }); elIgnoreIK.addEventListener('change', function() { - userDataChanger("grabbableKey", "ignoreIK", elIgnoreIK, elUserData); + userDataChanger("grabbableKey", "ignoreIK", elIgnoreIK, elUserData, false); }); elCollisionSoundURL.addEventListener('change', createEmitTextPropertyUpdateFunction('collisionSoundURL')); From 1f8a55da3abbaec197ab407dc949e396596b1405 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 14 Mar 2016 11:36:44 -0700 Subject: [PATCH 4/5] dynamic is the same as grabbable-by-default --- examples/html/entityProperties.html | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index ae42ea7caf..139d5cef67 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -243,12 +243,6 @@ } - function isGrabbableByDefault(properties) { - return properties.type == "Box" || - properties.type == "Sphere" || - properties.dynamic - } - function userDataChanger(groupName, keyName, checkBoxElement, userDataElement, defaultValue) { var properties = {}; var parsedData = {}; @@ -571,7 +565,7 @@ elCollideOtherAvatar.checked = properties.collidesWith.indexOf("otherAvatar") > -1; // boxes and sphere are grabbable by default - elGrabbable.checked = isGrabbableByDefault(properties); + elGrabbable.checked = properties.dynamic; elWantsTrigger.checked = false; elIgnoreIK.checked = false; var parsedUserData = {} @@ -820,7 +814,7 @@ }); elGrabbable.addEventListener('change', function() { - userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData, isGrabbableByDefault(properties)); + userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData, properties.dynamic); }); elWantsTrigger.addEventListener('change', function() { userDataChanger("grabbableKey", "wantsTrigger", elWantsTrigger, elUserData, false); From d811c4f6b53ff7abf18fc7539b658aaff0947067 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 14 Mar 2016 11:39:56 -0700 Subject: [PATCH 5/5] dynamic is the same as grabbable-by-default --- examples/html/entityProperties.html | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 139d5cef67..e3a64da5d4 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -564,7 +564,6 @@ elCollideMyAvatar.checked = properties.collidesWith.indexOf("myAvatar") > -1; elCollideOtherAvatar.checked = properties.collidesWith.indexOf("otherAvatar") > -1; - // boxes and sphere are grabbable by default elGrabbable.checked = properties.dynamic; elWantsTrigger.checked = false; elIgnoreIK.checked = false;