From ab8bccf16b10dce10e5c8028a37fc5126f3a0ca0 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 30 Jul 2017 11:03:19 +1200 Subject: [PATCH] Implement cloning action --- scripts/vr-edit/modules/selection.js | 35 +++++++++++++++++++++++++- scripts/vr-edit/vr-edit.js | 37 +++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/scripts/vr-edit/modules/selection.js b/scripts/vr-edit/modules/selection.js index 5437e49bf3..dc4d05a374 100644 --- a/scripts/vr-edit/modules/selection.js +++ b/scripts/vr-edit/modules/selection.js @@ -33,7 +33,7 @@ Selection = function (side) { // Recursively traverses tree of entities and their children, gather IDs and properties. var children, properties, - SELECTION_PROPERTIES = ["position", "registrationPoint", "rotation", "dimensions", "localPosition", + SELECTION_PROPERTIES = ["position", "registrationPoint", "rotation", "dimensions", "parentID", "localPosition", "dynamic", "collisionless"], i, length; @@ -42,6 +42,7 @@ Selection = function (side) { result.push({ id: id, position: properties.position, + parentID: properties.parentID, localPosition: properties.localPosition, registrationPoint: properties.registrationPoint, rotation: properties.rotation, @@ -294,6 +295,37 @@ Selection = function (side) { select(selectedEntityID); // Refresh. } + function cloneEntities() { + var parentIDIndexes = [], + parentID, + properties, + i, + j, + length; + + // Map parent IDs. + for (i = 1, length = selection.length; i < length; i += 1) { + parentID = selection[i].parentID; + for (j = 0; j < i; j += 1) { + if (parentID === selection[j].id) { + parentIDIndexes[i] = j; + break; + } + } + } + + // Clone entities. + for (i = 0, length = selection.length; i < length; i += 1) { + properties = Entities.getEntityProperties(selection[i].id); + if (i > 0) { + properties.parentID = selection[parentIDIndexes[i]].id; + } + selection[i].id = Entities.addEntity(properties); + } + + rootEntityID = selection[0].id; + } + function clear() { selection = []; selectedEntityID = null; @@ -327,6 +359,7 @@ Selection = function (side) { handleScale: handleScale, finishHandleScaling: finishHandleScaling, finishEditing: finishEditing, + cloneEntities: cloneEntities, deleteEntities: deleteEntities, clear: clear, destroy: destroy diff --git a/scripts/vr-edit/vr-edit.js b/scripts/vr-edit/vr-edit.js index 06d438a19e..09ad63280f 100644 --- a/scripts/vr-edit/vr-edit.js +++ b/scripts/vr-edit/vr-edit.js @@ -286,8 +286,9 @@ EDITOR_GRABBING = 3, EDITOR_DIRECT_SCALING = 4, // Scaling data are sent to other editor's EDITOR_GRABBING state. EDITOR_HANDLE_SCALING = 5, // "" + EDITOR_CLONING = 6, EDITOR_STATE_STRINGS = ["EDITOR_IDLE", "EDITOR_SEARCHING", "EDITOR_HIGHLIGHTING", "EDITOR_GRABBING", - "EDITOR_DIRECT_SCALING", "EDITOR_HANDLE_SCALING"], + "EDITOR_DIRECT_SCALING", "EDITOR_HANDLE_SCALING", "EDITOR_CLONING"], editorState = EDITOR_IDLE, // State machine. @@ -694,6 +695,16 @@ laser.enable(); } + function enterEditorCloning() { + selection.select(highlightedEntityID); // For when transitioning from EDITOR_SEARCHING. + selection.cloneEntities(); + highlightedEntityID = selection.rootEntityID(); + } + + function exitEditorCloning() { + // Nothing to do. + } + STATE_MACHINE = { EDITOR_IDLE: { enter: enterEditorIdle, @@ -724,6 +735,11 @@ enter: enterEditorHandleScaling, update: updateEditorHandleScaling, exit: exitEditorHandleScaling + }, + EDITOR_CLONING: { + enter: enterEditorCloning, + update: null, + exit: exitEditorCloning } }; @@ -791,6 +807,8 @@ if (!isAppScaleWithHandles) { setState(EDITOR_DIRECT_SCALING); } + } else if (isAppCloneEntities) { + setState(EDITOR_CLONING); } else { setState(EDITOR_GRABBING); } @@ -836,6 +854,8 @@ } else { debug(side, "ERROR: Unexpected condition in EDITOR_HIGHLIGHTING! A"); } + } else if (isAppCloneEntities) { + setState(EDITOR_CLONING); } else { setState(EDITOR_GRABBING); } @@ -921,6 +941,21 @@ setState(EDITOR_GRABBING); } break; + case EDITOR_CLONING: + // Immediate transition out of state after cloning entities during state entry. + if (hand.valid() && hand.triggerClicked()) { + setState(EDITOR_GRABBING); + } else if (!hand.valid()) { + setState(EDITOR_IDLE); + } else if (!hand.triggerClicked()) { + if (intersection.entityID && intersection.editableEntity) { + highlightedEntityID = Entities.rootOf(intersection.entityID); + setState(EDITOR_HIGHLIGHTING); + } else { + setState(EDITOR_SEARCHING); + } + } + break; } if (DEBUG && editorState !== previousState) {