Several UX improvements to Create App voxel creation and editing

This commit is contained in:
ksuprynowicz 2022-07-09 16:28:10 +02:00
parent 412ca8657d
commit 62f37a1cb1
3 changed files with 85 additions and 30 deletions

View file

@ -770,10 +770,16 @@ var toolBar = (function () {
var volumeSizeY = parseInt(result.volumeSizeY); var volumeSizeY = parseInt(result.volumeSizeY);
var volumeSizeZ = parseInt(result.volumeSizeZ); var volumeSizeZ = parseInt(result.volumeSizeZ);
var voxelSurfaceStyle = parseInt(result.surfaceStyleIndex); 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({ var polyVoxID = createNewEntity({
type: "PolyVox", type: "PolyVox",
name: "terrain", name: "terrain",
dimensions: {
x: volumeSizeX,
y: volumeSizeY,
z: volumeSizeZ
},
voxelVolumeSize: { voxelVolumeSize: {
x: volumeSizeX, x: volumeSizeX,
y: volumeSizeY, y: volumeSizeY,
@ -788,28 +794,25 @@ var toolBar = (function () {
grabbable: result.grabbable grabbable: result.grabbable
}, },
}); });
Entities.editEntity(polyVoxID, {
position: voxelPosition
});
if (polyVoxID){ if (polyVoxID){
// var properties = Entities.getEntityProperties(polyVoxID, ["position", "localDimensions"]);
// var position = properties.position;
// var localDimensions = properties.localDimensions;
switch (initialShape) { switch (initialShape) {
// Sphere
// case 0:
// Entities.setVoxelSphere(polyVoxID, position, localDimensions/4, 255);
// break;
// Box
case 0: case 0:
Entities.setVoxelsInCuboid(polyVoxID, { Entities.setVoxelsInCuboid(polyVoxID, {
x: Math.round(volumeSizeX/4), x: Math.round(volumeSizeX / 4),
y: Math.round(volumeSizeY/4), y: Math.round(volumeSizeY / 4),
z: Math.round(volumeSizeZ/4) z: Math.round(volumeSizeZ / 4)
}, { }, {
x: Math.round(volumeSizeX/2.0), x: Math.round(volumeSizeX / 2.0),
y: Math.round(volumeSizeY/2.0), y: Math.round(volumeSizeY / 2.0),
z: Math.round(volumeSizeZ/2.0) z: Math.round(volumeSizeZ / 2.0)
}, 255); }, 255);
break; break;
// Plane // Plane 1/4
case 1: case 1:
Entities.setVoxelsInCuboid(polyVoxID, { Entities.setVoxelsInCuboid(polyVoxID, {
x: 0, x: 0,
@ -817,10 +820,30 @@ var toolBar = (function () {
z: 0 z: 0
}, { }, {
x: volumeSizeX, x: volumeSizeX,
y: Math.round(volumeSizeY/4), y: Math.round(volumeSizeY / 4),
z: volumeSizeZ z: volumeSizeZ
}, 255); }, 255);
break; 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;
} }
} }
} }

View file

@ -1,7 +1,7 @@
// //
// editModes.js // editModes.js
// //
// Created by Karol Suprynowicz on 2022.05.17. // Created by dr Karol Suprynowicz on 2022.05.17.
// Copyright 2022 Overte e.V. // Copyright 2022 Overte e.V.
// //
// Based on voxels.js // Based on voxels.js
@ -23,8 +23,11 @@
Script.include([ Script.include([
"./libraries/utils.js", "./libraries/utils.js",
"entitySelectionTool/entitySelectionTool.js",
]); ]);
var selectionManager = SelectionManager;
EditVoxels = function() { EditVoxels = function() {
var self = this; var self = this;
var that = {}; var that = {};
@ -67,6 +70,12 @@ EditVoxels = function() {
var soundAdd = SoundCache.getSound(Script.resourcesPath() + "sounds/Button05.wav"); var soundAdd = SoundCache.getSound(Script.resourcesPath() + "sounds/Button05.wav");
var soundDelete = SoundCache.getSound(Script.resourcesPath() + "sounds/Tab03.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) { that.setActive = function(active) {
isActive = (active === true); isActive = (active === true);
} }
@ -260,6 +269,10 @@ EditVoxels = function() {
return; return;
} }
if (triggered() && selectionManager.pointingAtDesktopWindowOrTablet(that.triggeredHand)) {
return;
}
if (event.isLeftButton || event.isMiddleButton){ if (event.isLeftButton || event.isMiddleButton){
if (event.isMiddleButton){ if (event.isMiddleButton){
inverseOperation = true; inverseOperation = true;
@ -274,7 +287,9 @@ EditVoxels = function() {
if(that.triggeredHand === Controller.Standard.LeftHand && Controller.getValue(Controller.Standard.LeftGrip) > 0.5){ if(that.triggeredHand === Controller.Standard.LeftHand && Controller.getValue(Controller.Standard.LeftGrip) > 0.5){
inverseOperation = true; inverseOperation = true;
} }
} }
continuousStartTimer = 0;
var pickRay = generalComputePickRay(event.x, event.y); var pickRay = generalComputePickRay(event.x, event.y);
var intersection = Entities.findRayIntersection(pickRay, true); // accurate picking 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; return;
} }
// Get pick ray origin and direction // Get pick ray origin and direction
var pickRay = null; var pickRay = null;
var hand = triggered() ? that.triggeredHand : that.pressedHand; 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)); pickRay = Camera.computePickRay(Controller.getValue(Controller.Hardware.Keyboard.MouseX), Controller.getValue(Controller.Hardware.Keyboard.MouseY));
}else{ }else{
pickRay = controllerComputePickRay(); pickRay = controllerComputePickRay();
} }
if (pickRay === null){ if (pickRay === null) {
return; return;
} }
// Compute intersection of pick ray with given plane in local coordinates // Compute intersection of pick ray with given plane in local coordinates
var globalOriginInVoxelSpace = Entities.worldCoordsToVoxelCoords(editedVoxelEntity, { x: 0, y: 0, z: 0 }); var globalOriginInVoxelSpace = Entities.worldCoordsToVoxelCoords(editedVoxelEntity, { x: 0, y: 0, z: 0 });
var pickRayDirInVoxelSpace = Vec3.subtract(Entities.worldCoordsToVoxelCoords(editedVoxelEntity, pickRay.direction), globalOriginInVoxelSpace); var pickRayDirInVoxelSpace = Vec3.subtract(Entities.worldCoordsToVoxelCoords(editedVoxelEntity, pickRay.direction), globalOriginInVoxelSpace);
var voxelPickRayOrigin = Entities.worldCoordsToVoxelCoords(editedVoxelEntity, pickRay.origin); var voxelPickRayOrigin = Entities.worldCoordsToVoxelCoords(editedVoxelEntity, pickRay.origin);
@ -429,23 +451,29 @@ EditVoxels = function() {
pickRayDirInVoxelSpace = Vec3.normalize(pickRayDirInVoxelSpace); pickRayDirInVoxelSpace = Vec3.normalize(pickRayDirInVoxelSpace);
var directionMultiplier = 1.0; var directionMultiplier = 1.0;
var offsetVector = { x: 0, y: 0, z: 0 }; var offsetVector = { x: 0, y: 0, z: 0 };
switch (editPlane){ switch (editPlane) {
// 0 - plane parallel to YZ plane // 0 - plane parallel to YZ plane
case 0: case 0:
//var dirSign = (pickRayDirInVoxelSpace.x > 0) ? 1 : -1; //var dirSign = (pickRayDirInVoxelSpace.x > 0) ? 1 : -1;
offsetVector.x = 0.5; 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; directionMultiplier = (oldEditPosition.x - voxelPickRayOrigin.x) / pickRayDirInVoxelSpace.x;
break; break;
// 1 - plane parallel to XZ plane // 1 - plane parallel to XZ plane
case 1: case 1:
//var dirSign = (pickRayDirInVoxelSpace.x > 0) ? 1 : -1; //var dirSign = (pickRayDirInVoxelSpace.x > 0) ? 1 : -1;
offsetVector.y = 0.5; 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; directionMultiplier = (oldEditPosition.y - voxelPickRayOrigin.y) / pickRayDirInVoxelSpace.y;
break; break;
// 2 - plane parallel to XY plane // 2 - plane parallel to XY plane
case 2: case 2:
//var dirSign = (pickRayDirInVoxelSpace.x > 0) ? 1 : -1; //var dirSign = (pickRayDirInVoxelSpace.x > 0) ? 1 : -1;
offsetVector.z = 0.5; 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; directionMultiplier = (oldEditPosition.z - voxelPickRayOrigin.z) / pickRayDirInVoxelSpace.z;
break; break;
default: default:
@ -455,11 +483,11 @@ EditVoxels = function() {
intersectionPoint = Vec3.sum(Vec3.multiply(pickRayDirInVoxelSpace, directionMultiplier), voxelPickRayOrigin); intersectionPoint = Vec3.sum(Vec3.multiply(pickRayDirInVoxelSpace, directionMultiplier), voxelPickRayOrigin);
newEditPosition = floorVector(Vec3.sum(intersectionPoint, offsetVector)); newEditPosition = floorVector(Vec3.sum(intersectionPoint, offsetVector));
if (newEditPosition === oldEditPosition){ if (newEditPosition === oldEditPosition) {
return; return;
} }
if (wantDebug){ if (wantDebug) {
print("Old edit position: " + JSON.stringify(oldEditPosition)); print("Old edit position: " + JSON.stringify(oldEditPosition));
print("New edit position: " + JSON.stringify(newEditPosition)); 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)); 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; oldEditPosition = newEditPosition;
Audio.playSystemSound((lastEditValue === 255) ? soundAdd : soundDelete); Audio.playSystemSound((lastEditValue === 255) ? soundAdd : soundDelete);
} }
}else if (editSpheres){ } else if (editSpheres) {
if (Entities.setVoxel(editedVoxelEntity, newEditPosition, lastEditValue)){ if (Entities.setVoxel(editedVoxelEntity, newEditPosition, lastEditValue)){
oldEditPosition = newEditPosition; oldEditPosition = newEditPosition;
Audio.playSystemSound((lastEditValue === 255) ? soundAdd : soundDelete); Audio.playSystemSound((lastEditValue === 255) ? soundAdd : soundDelete);

View file

@ -1,5 +1,6 @@
// //
// NewPolyVoxDialog.qml // NewPolyVoxDialog.qml
// Created by dr Karol Suprynowicz on 2022.05.17.
// based on NewModelDialog.qml // based on NewModelDialog.qml
// qml/hifi // qml/hifi
// //
@ -488,7 +489,10 @@ Rectangle {
currentIndex: 0 currentIndex: 0
property var initialShapeArray: ["Box", property var initialShapeArray: ["Box",
"Plane"] "Plane, 1/4 full",
"Plane, 3/4 full",
"Single voxel",
]
width: 200 width: 200
z: 100 z: 100