Implement cloning action

This commit is contained in:
David Rowe 2017-07-30 11:03:19 +12:00
parent 48ee7a3b1a
commit ab8bccf16b
2 changed files with 70 additions and 2 deletions

View file

@ -33,7 +33,7 @@ Selection = function (side) {
// Recursively traverses tree of entities and their children, gather IDs and properties. // Recursively traverses tree of entities and their children, gather IDs and properties.
var children, var children,
properties, properties,
SELECTION_PROPERTIES = ["position", "registrationPoint", "rotation", "dimensions", "localPosition", SELECTION_PROPERTIES = ["position", "registrationPoint", "rotation", "dimensions", "parentID", "localPosition",
"dynamic", "collisionless"], "dynamic", "collisionless"],
i, i,
length; length;
@ -42,6 +42,7 @@ Selection = function (side) {
result.push({ result.push({
id: id, id: id,
position: properties.position, position: properties.position,
parentID: properties.parentID,
localPosition: properties.localPosition, localPosition: properties.localPosition,
registrationPoint: properties.registrationPoint, registrationPoint: properties.registrationPoint,
rotation: properties.rotation, rotation: properties.rotation,
@ -294,6 +295,37 @@ Selection = function (side) {
select(selectedEntityID); // Refresh. 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() { function clear() {
selection = []; selection = [];
selectedEntityID = null; selectedEntityID = null;
@ -327,6 +359,7 @@ Selection = function (side) {
handleScale: handleScale, handleScale: handleScale,
finishHandleScaling: finishHandleScaling, finishHandleScaling: finishHandleScaling,
finishEditing: finishEditing, finishEditing: finishEditing,
cloneEntities: cloneEntities,
deleteEntities: deleteEntities, deleteEntities: deleteEntities,
clear: clear, clear: clear,
destroy: destroy destroy: destroy

View file

@ -286,8 +286,9 @@
EDITOR_GRABBING = 3, EDITOR_GRABBING = 3,
EDITOR_DIRECT_SCALING = 4, // Scaling data are sent to other editor's EDITOR_GRABBING state. EDITOR_DIRECT_SCALING = 4, // Scaling data are sent to other editor's EDITOR_GRABBING state.
EDITOR_HANDLE_SCALING = 5, // "" EDITOR_HANDLE_SCALING = 5, // ""
EDITOR_CLONING = 6,
EDITOR_STATE_STRINGS = ["EDITOR_IDLE", "EDITOR_SEARCHING", "EDITOR_HIGHLIGHTING", "EDITOR_GRABBING", 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, editorState = EDITOR_IDLE,
// State machine. // State machine.
@ -694,6 +695,16 @@
laser.enable(); 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 = { STATE_MACHINE = {
EDITOR_IDLE: { EDITOR_IDLE: {
enter: enterEditorIdle, enter: enterEditorIdle,
@ -724,6 +735,11 @@
enter: enterEditorHandleScaling, enter: enterEditorHandleScaling,
update: updateEditorHandleScaling, update: updateEditorHandleScaling,
exit: exitEditorHandleScaling exit: exitEditorHandleScaling
},
EDITOR_CLONING: {
enter: enterEditorCloning,
update: null,
exit: exitEditorCloning
} }
}; };
@ -791,6 +807,8 @@
if (!isAppScaleWithHandles) { if (!isAppScaleWithHandles) {
setState(EDITOR_DIRECT_SCALING); setState(EDITOR_DIRECT_SCALING);
} }
} else if (isAppCloneEntities) {
setState(EDITOR_CLONING);
} else { } else {
setState(EDITOR_GRABBING); setState(EDITOR_GRABBING);
} }
@ -836,6 +854,8 @@
} else { } else {
debug(side, "ERROR: Unexpected condition in EDITOR_HIGHLIGHTING! A"); debug(side, "ERROR: Unexpected condition in EDITOR_HIGHLIGHTING! A");
} }
} else if (isAppCloneEntities) {
setState(EDITOR_CLONING);
} else { } else {
setState(EDITOR_GRABBING); setState(EDITOR_GRABBING);
} }
@ -921,6 +941,21 @@
setState(EDITOR_GRABBING); setState(EDITOR_GRABBING);
} }
break; 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) { if (DEBUG && editorState !== previousState) {