mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 16:14:35 +02:00
Several UX improvements to Create App voxel creation and editing
This commit is contained in:
parent
412ca8657d
commit
62f37a1cb1
3 changed files with 85 additions and 30 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue