From 62f37a1cb177ca1ef8a3b1e6c5f9698a5aa49bab Mon Sep 17 00:00:00 2001 From: ksuprynowicz Date: Sat, 9 Jul 2022 16:28:10 +0200 Subject: [PATCH] Several UX improvements to Create App voxel creation and editing --- scripts/system/create/edit.js | 55 +++++++++++++------ scripts/system/create/editModes/editVoxels.js | 54 +++++++++++++----- .../system/create/qml/NewPolyVoxDialog.qml | 6 +- 3 files changed, 85 insertions(+), 30 deletions(-) diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js index cc6f5d84e7..89689825b7 100644 --- a/scripts/system/create/edit.js +++ b/scripts/system/create/edit.js @@ -770,10 +770,16 @@ var toolBar = (function () { var volumeSizeY = parseInt(result.volumeSizeY); var volumeSizeZ = parseInt(result.volumeSizeZ); var voxelSurfaceStyle = parseInt(result.surfaceStyleIndex); + var voxelPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: volumeSizeZ * -1.6 })); var polyVoxID = createNewEntity({ type: "PolyVox", name: "terrain", + dimensions: { + x: volumeSizeX, + y: volumeSizeY, + z: volumeSizeZ + }, voxelVolumeSize: { x: volumeSizeX, y: volumeSizeY, @@ -788,28 +794,25 @@ var toolBar = (function () { grabbable: result.grabbable }, }); + + Entities.editEntity(polyVoxID, { + position: voxelPosition + }); + if (polyVoxID){ - // var properties = Entities.getEntityProperties(polyVoxID, ["position", "localDimensions"]); - // var position = properties.position; - // var localDimensions = properties.localDimensions; switch (initialShape) { - // Sphere - // case 0: - // Entities.setVoxelSphere(polyVoxID, position, localDimensions/4, 255); - // break; - // Box case 0: Entities.setVoxelsInCuboid(polyVoxID, { - x: Math.round(volumeSizeX/4), - y: Math.round(volumeSizeY/4), - z: Math.round(volumeSizeZ/4) + x: Math.round(volumeSizeX / 4), + y: Math.round(volumeSizeY / 4), + z: Math.round(volumeSizeZ / 4) }, { - x: Math.round(volumeSizeX/2.0), - y: Math.round(volumeSizeY/2.0), - z: Math.round(volumeSizeZ/2.0) + x: Math.round(volumeSizeX / 2.0), + y: Math.round(volumeSizeY / 2.0), + z: Math.round(volumeSizeZ / 2.0) }, 255); break; - // Plane + // Plane 1/4 case 1: Entities.setVoxelsInCuboid(polyVoxID, { x: 0, @@ -817,10 +820,30 @@ var toolBar = (function () { z: 0 }, { x: volumeSizeX, - y: Math.round(volumeSizeY/4), + y: Math.round(volumeSizeY / 4), z: volumeSizeZ }, 255); break; + // Plane 3/4 + case 2: + Entities.setVoxelsInCuboid(polyVoxID, { + x: 0, + y: 0, + z: 0 + }, { + x: volumeSizeX, + y: Math.round(3 * volumeSizeY / 4), + z: volumeSizeZ + }, 255); + break; + // Single voxel at center + case 3: + Entities.setVoxel(polyVoxID, { + x: Math.round(volumeSizeX / 2), + y: Math.round(volumeSizeY / 2), + z: Math.round(volumeSizeZ / 2) + }, 255); + break; } } } diff --git a/scripts/system/create/editModes/editVoxels.js b/scripts/system/create/editModes/editVoxels.js index 29b47d3145..528443d33c 100644 --- a/scripts/system/create/editModes/editVoxels.js +++ b/scripts/system/create/editModes/editVoxels.js @@ -1,7 +1,7 @@ // // editModes.js // -// Created by Karol Suprynowicz on 2022.05.17. +// Created by dr Karol Suprynowicz on 2022.05.17. // Copyright 2022 Overte e.V. // // Based on voxels.js @@ -23,8 +23,11 @@ Script.include([ "./libraries/utils.js", + "entitySelectionTool/entitySelectionTool.js", ]); +var selectionManager = SelectionManager; + EditVoxels = function() { var self = this; var that = {}; @@ -67,6 +70,12 @@ EditVoxels = function() { var soundAdd = SoundCache.getSound(Script.resourcesPath() + "sounds/Button05.wav"); var soundDelete = SoundCache.getSound(Script.resourcesPath() + "sounds/Tab03.wav"); + // Continuous start timer prevents activating continuous mode on short button presses + // and adding multiple voxels when only one was intended + + var continuousStartTimerMax = 0.200; + var continuousStartTimer = 0.0; + that.setActive = function(active) { isActive = (active === true); } @@ -260,6 +269,10 @@ EditVoxels = function() { return; } + if (triggered() && selectionManager.pointingAtDesktopWindowOrTablet(that.triggeredHand)) { + return; + } + if (event.isLeftButton || event.isMiddleButton){ if (event.isMiddleButton){ inverseOperation = true; @@ -274,7 +287,9 @@ EditVoxels = function() { if(that.triggeredHand === Controller.Standard.LeftHand && Controller.getValue(Controller.Standard.LeftGrip) > 0.5){ inverseOperation = true; } - } + } + + continuousStartTimer = 0; var pickRay = generalComputePickRay(event.x, event.y); var intersection = Entities.findRayIntersection(pickRay, true); // accurate picking @@ -401,27 +416,34 @@ EditVoxels = function() { //} - if(isEditing === false || editedVoxelEntity === null){ + if (isEditing === false || editedVoxelEntity === null){ + return; + } + + continuousStartTimer += delta; + + if (continuousStartTimer < continuousStartTimerMax) { return; } // Get pick ray origin and direction - + var pickRay = null; var hand = triggered() ? that.triggeredHand : that.pressedHand; - if (hand === NO_HAND){ + if (hand === NO_HAND) { pickRay = Camera.computePickRay(Controller.getValue(Controller.Hardware.Keyboard.MouseX), Controller.getValue(Controller.Hardware.Keyboard.MouseY)); }else{ pickRay = controllerComputePickRay(); } - - if (pickRay === null){ + + if (pickRay === null) { return; } - + + // Compute intersection of pick ray with given plane in local coordinates - + var globalOriginInVoxelSpace = Entities.worldCoordsToVoxelCoords(editedVoxelEntity, { x: 0, y: 0, z: 0 }); var pickRayDirInVoxelSpace = Vec3.subtract(Entities.worldCoordsToVoxelCoords(editedVoxelEntity, pickRay.direction), globalOriginInVoxelSpace); var voxelPickRayOrigin = Entities.worldCoordsToVoxelCoords(editedVoxelEntity, pickRay.origin); @@ -429,23 +451,29 @@ EditVoxels = function() { pickRayDirInVoxelSpace = Vec3.normalize(pickRayDirInVoxelSpace); var directionMultiplier = 1.0; var offsetVector = { x: 0, y: 0, z: 0 }; - switch (editPlane){ + switch (editPlane) { // 0 - plane parallel to YZ plane case 0: //var dirSign = (pickRayDirInVoxelSpace.x > 0) ? 1 : -1; offsetVector.x = 0.5; + offsetVector.y = (offsetVector.x / pickRayDirInVoxelSpace.x) * pickRayDirInVoxelSpace.y; + offsetVector.z = (offsetVector.x / pickRayDirInVoxelSpace.x) * pickRayDirInVoxelSpace.z; directionMultiplier = (oldEditPosition.x - voxelPickRayOrigin.x) / pickRayDirInVoxelSpace.x; break; // 1 - plane parallel to XZ plane case 1: //var dirSign = (pickRayDirInVoxelSpace.x > 0) ? 1 : -1; offsetVector.y = 0.5; + offsetVector.x = (offsetVector.y / pickRayDirInVoxelSpace.y) * pickRayDirInVoxelSpace.x; + offsetVector.z = (offsetVector.y / pickRayDirInVoxelSpace.y) * pickRayDirInVoxelSpace.z; directionMultiplier = (oldEditPosition.y - voxelPickRayOrigin.y) / pickRayDirInVoxelSpace.y; break; // 2 - plane parallel to XY plane case 2: //var dirSign = (pickRayDirInVoxelSpace.x > 0) ? 1 : -1; offsetVector.z = 0.5; + offsetVector.x = (offsetVector.z / pickRayDirInVoxelSpace.z) * pickRayDirInVoxelSpace.x; + offsetVector.y = (offsetVector.z / pickRayDirInVoxelSpace.z) * pickRayDirInVoxelSpace.y; directionMultiplier = (oldEditPosition.z - voxelPickRayOrigin.z) / pickRayDirInVoxelSpace.z; break; default: @@ -455,11 +483,11 @@ EditVoxels = function() { intersectionPoint = Vec3.sum(Vec3.multiply(pickRayDirInVoxelSpace, directionMultiplier), voxelPickRayOrigin); newEditPosition = floorVector(Vec3.sum(intersectionPoint, offsetVector)); - if (newEditPosition === oldEditPosition){ + if (newEditPosition === oldEditPosition) { return; } - if (wantDebug){ + if (wantDebug) { print("Old edit position: " + JSON.stringify(oldEditPosition)); print("New edit position: " + JSON.stringify(newEditPosition)); print("directionMultiplier: " + JSON.stringify(directionMultiplier) + " pickRay.direction: " + JSON.stringify(pickRay.direction) + " pickRayDirInVoxelSpace: " + JSON.stringify(pickRayDirInVoxelSpace) + " voxelPickRayOrigin: " + JSON.stringify(voxelPickRayOrigin) + " editPlane: " + JSON.stringify(editPlane)); @@ -470,7 +498,7 @@ EditVoxels = function() { oldEditPosition = newEditPosition; Audio.playSystemSound((lastEditValue === 255) ? soundAdd : soundDelete); } - }else if (editSpheres){ + } else if (editSpheres) { if (Entities.setVoxel(editedVoxelEntity, newEditPosition, lastEditValue)){ oldEditPosition = newEditPosition; Audio.playSystemSound((lastEditValue === 255) ? soundAdd : soundDelete); diff --git a/scripts/system/create/qml/NewPolyVoxDialog.qml b/scripts/system/create/qml/NewPolyVoxDialog.qml index fde7d075e0..8a8b77818b 100644 --- a/scripts/system/create/qml/NewPolyVoxDialog.qml +++ b/scripts/system/create/qml/NewPolyVoxDialog.qml @@ -1,5 +1,6 @@ // // NewPolyVoxDialog.qml +// Created by dr Karol Suprynowicz on 2022.05.17. // based on NewModelDialog.qml // qml/hifi // @@ -488,7 +489,10 @@ Rectangle { currentIndex: 0 property var initialShapeArray: ["Box", - "Plane"] + "Plane, 1/4 full", + "Plane, 3/4 full", + "Single voxel", + ] width: 200 z: 100