mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-08-08 05:26:57 +02:00
Redesigned voxel edit UI for VR and added VR controller support
This commit is contained in:
parent
51b267a18f
commit
686d84526c
6 changed files with 319 additions and 52 deletions
|
@ -111,6 +111,8 @@ EditTools = function(options) {
|
||||||
if (data.type !== "update-edit-tools") {
|
if (data.type !== "update-edit-tools") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print(JSON.stringify(data));
|
||||||
|
|
||||||
var needsUpdate = false;
|
var needsUpdate = false;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,13 @@
|
||||||
// Created by Seth Alves on 2015-08-25
|
// Created by Seth Alves on 2015-08-25
|
||||||
// Copyright 2015 High Fidelity, Inc.
|
// Copyright 2015 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
|
// Based on entitySelectionTool.js
|
||||||
|
// Created by Brad hefta-Gaub on 10/1/14.
|
||||||
|
// Modified by Daniela Fontes * @DanielaFifo and Tiago Andrade @TagoWill on 4/7/2017
|
||||||
|
// Modified by David Back on 1/9/2018
|
||||||
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
|
// Copyright 2020 Vircadia contributors
|
||||||
|
//
|
||||||
// This script implements voxel edit mode
|
// This script implements voxel edit mode
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
@ -22,6 +29,8 @@ EditVoxels = function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var that = {};
|
var that = {};
|
||||||
|
|
||||||
|
const NO_HAND = -1;
|
||||||
|
|
||||||
var controlHeld = false;
|
var controlHeld = false;
|
||||||
var shiftHeld = false;
|
var shiftHeld = false;
|
||||||
|
|
||||||
|
@ -38,6 +47,11 @@ EditVoxels = function() {
|
||||||
|
|
||||||
var editSphereRadius = 0.15;
|
var editSphereRadius = 0.15;
|
||||||
var brushLength = 0.5;
|
var brushLength = 0.5;
|
||||||
|
|
||||||
|
that.triggerClickMapping = Controller.newMapping(Script.resolvePath('') + '-click-voxels');
|
||||||
|
that.triggerPressMapping = Controller.newMapping(Script.resolvePath('') + '-press-voxels');
|
||||||
|
that.triggeredHand = NO_HAND;
|
||||||
|
that.pressedHand = NO_HAND;
|
||||||
|
|
||||||
that.setActive = function(active) {
|
that.setActive = function(active) {
|
||||||
isActive = (active === true);
|
isActive = (active === true);
|
||||||
|
@ -114,6 +128,10 @@ EditVoxels = function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function attemptVoxelChangeForEntity(entityID, pickRayDir, intersectionLocation) {
|
function attemptVoxelChangeForEntity(entityID, pickRayDir, intersectionLocation) {
|
||||||
|
var wantDebug = false;
|
||||||
|
if (wantDebug) {
|
||||||
|
print("=============== eV::attemptVoxelChangeForEntity BEG =======================");
|
||||||
|
}
|
||||||
|
|
||||||
var properties = Entities.getEntityProperties(entityID);
|
var properties = Entities.getEntityProperties(entityID);
|
||||||
if (properties.type != "PolyVox") {
|
if (properties.type != "PolyVox") {
|
||||||
|
@ -133,6 +151,12 @@ EditVoxels = function() {
|
||||||
var pickRayDirInVoxelSpace = Vec3.subtract(voxelPosition, voxelOrigin);
|
var pickRayDirInVoxelSpace = Vec3.subtract(voxelPosition, voxelOrigin);
|
||||||
pickRayDirInVoxelSpace = Vec3.normalize(pickRayDirInVoxelSpace);
|
pickRayDirInVoxelSpace = Vec3.normalize(pickRayDirInVoxelSpace);
|
||||||
|
|
||||||
|
if (wantDebug) {
|
||||||
|
print("voxelOrigin: " + JSON.stringify(voxelOrigin));
|
||||||
|
print("voxelPosition: " + JSON.stringify(voxelPosition));
|
||||||
|
print("pickRayDirInVoxelSpace: " + JSON.stringify(pickRayDirInVoxelSpace));
|
||||||
|
}
|
||||||
|
|
||||||
var doAdd = addingVoxels;
|
var doAdd = addingVoxels;
|
||||||
var doDelete = deletingVoxels;
|
var doDelete = deletingVoxels;
|
||||||
var doAddSphere = addingSpheres;
|
var doAddSphere = addingSpheres;
|
||||||
|
@ -156,23 +180,49 @@ EditVoxels = function() {
|
||||||
|
|
||||||
if (doDelete) {
|
if (doDelete) {
|
||||||
var toErasePosition = Vec3.sum(voxelPosition, Vec3.multiply(pickRayDirInVoxelSpace, 0.1));
|
var toErasePosition = Vec3.sum(voxelPosition, Vec3.multiply(pickRayDirInVoxelSpace, 0.1));
|
||||||
|
if (wantDebug) {
|
||||||
|
print("Calling setVoxel to delete");
|
||||||
|
print("entityID: " + JSON.stringify(entityID));
|
||||||
|
print("floorVector(toErasePosition): " + JSON.stringify(floorVector(toErasePosition)));
|
||||||
|
}
|
||||||
return Entities.setVoxel(entityID, floorVector(toErasePosition), 0);
|
return Entities.setVoxel(entityID, floorVector(toErasePosition), 0);
|
||||||
}
|
}
|
||||||
if (doAdd) {
|
if (doAdd) {
|
||||||
var toDrawPosition = Vec3.subtract(voxelPosition, Vec3.multiply(pickRayDirInVoxelSpace, 0.1));
|
var toDrawPosition = Vec3.subtract(voxelPosition, Vec3.multiply(pickRayDirInVoxelSpace, 0.1));
|
||||||
|
if (wantDebug) {
|
||||||
|
print("Calling setVoxel to add");
|
||||||
|
print("entityID: " + JSON.stringify(entityID));
|
||||||
|
print("floorVector(toDrawPosition): " + JSON.stringify(floorVector(toDrawPosition)));
|
||||||
|
}
|
||||||
return Entities.setVoxel(entityID, floorVector(toDrawPosition), 255);
|
return Entities.setVoxel(entityID, floorVector(toDrawPosition), 255);
|
||||||
}
|
}
|
||||||
if (doDeleteSphere) {
|
if (doDeleteSphere) {
|
||||||
var toErasePosition = intersectionLocation;
|
var toErasePosition = intersectionLocation;
|
||||||
|
if (wantDebug) {
|
||||||
|
print("Calling setVoxelSphere to delete");
|
||||||
|
print("entityID: " + JSON.stringify(entityID));
|
||||||
|
print("editSphereRadius: " + JSON.stringify(editSphereRadius));
|
||||||
|
print("floorVector(toErasePosition): " + JSON.stringify(floorVector(toErasePosition)));
|
||||||
|
}
|
||||||
return Entities.setVoxelSphere(entityID, floorVector(toErasePosition), editSphereRadius, 0);
|
return Entities.setVoxelSphere(entityID, floorVector(toErasePosition), editSphereRadius, 0);
|
||||||
}
|
}
|
||||||
if (doAddSphere) {
|
if (doAddSphere) {
|
||||||
var toDrawPosition = intersectionLocation;
|
var toDrawPosition = intersectionLocation;
|
||||||
|
if (wantDebug) {
|
||||||
|
print("Calling setVoxelSphere to add");
|
||||||
|
print("entityID: " + JSON.stringify(entityID));
|
||||||
|
print("editSphereRadius: " + JSON.stringify(editSphereRadius));
|
||||||
|
print("floorVector(toDrawPosition): " + JSON.stringify(floorVector(toDrawPosition)));
|
||||||
|
}
|
||||||
return Entities.setVoxelSphere(entityID, floorVector(toDrawPosition), editSphereRadius, 255);
|
return Entities.setVoxelSphere(entityID, floorVector(toDrawPosition), editSphereRadius, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function attemptVoxelChange(pickRayDir, intersection) {
|
function attemptVoxelChange(pickRayDir, intersection) {
|
||||||
|
var wantDebug = false;
|
||||||
|
if (wantDebug) {
|
||||||
|
print("=============== eV::attemptVoxelChange BEG =======================");
|
||||||
|
}
|
||||||
|
|
||||||
var ids;
|
var ids;
|
||||||
|
|
||||||
|
@ -181,6 +231,10 @@ EditVoxels = function() {
|
||||||
ids.push(intersection.entityID);
|
ids.push(intersection.entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wantDebug) {
|
||||||
|
print("Entities: " + JSON.stringify(ids));
|
||||||
|
}
|
||||||
|
|
||||||
var success = false;
|
var success = false;
|
||||||
for (var i = 0; i < ids.length; i++) {
|
for (var i = 0; i < ids.length; i++) {
|
||||||
var entityID = ids[i];
|
var entityID = ids[i];
|
||||||
|
@ -189,14 +243,43 @@ EditVoxels = function() {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function controllerComputePickRay() {
|
||||||
|
var hand = triggered() ? that.triggeredHand : that.pressedHand;
|
||||||
|
var controllerPose = getControllerWorldLocation(hand, true);
|
||||||
|
if (controllerPose.valid) {
|
||||||
|
var controllerPosition = controllerPose.translation;
|
||||||
|
// This gets point direction right, but if you want general quaternion it would be more complicated:
|
||||||
|
var controllerDirection = Quat.getUp(controllerPose.rotation);
|
||||||
|
return {origin: controllerPosition, direction: controllerDirection};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function generalComputePickRay(x, y) {
|
||||||
|
return controllerComputePickRay() || Camera.computePickRay(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
function mousePressEvent(event) {
|
function mousePressEvent(event) {
|
||||||
if (!event.isLeftButton) {
|
var wantDebug = false;
|
||||||
|
if (!editEnabled || !isActive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wantDebug) {
|
||||||
|
print("=============== eV::mousePressEvent BEG =======================");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!event.isLeftButton && !triggered()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pickRay = Camera.computePickRay(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
|
||||||
|
|
||||||
|
if (wantDebug) {
|
||||||
|
print("Pick ray: " + JSON.stringify(pickRay));
|
||||||
|
print("Intersection: " + JSON.stringify(intersection));
|
||||||
|
}
|
||||||
|
|
||||||
if (intersection.intersects) {
|
if (intersection.intersects) {
|
||||||
if (attemptVoxelChange(pickRay.direction, intersection)) {
|
if (attemptVoxelChange(pickRay.direction, intersection)) {
|
||||||
return;
|
return;
|
||||||
|
@ -211,6 +294,10 @@ EditVoxels = function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mouseReleaseEvent(event) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
function keyPressEvent(event) {
|
function keyPressEvent(event) {
|
||||||
if (event.text == "CONTROL") {
|
if (event.text == "CONTROL") {
|
||||||
controlHeld = true;
|
controlHeld = true;
|
||||||
|
@ -229,16 +316,78 @@ EditVoxels = function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function triggered() {
|
||||||
|
return that.triggeredHand !== NO_HAND;
|
||||||
|
};
|
||||||
|
|
||||||
|
function pointingAtDesktopWindowOrTablet(hand) {
|
||||||
|
var pointingAtDesktopWindow = (hand === Controller.Standard.RightHand &&
|
||||||
|
SelectionManager.pointingAtDesktopWindowRight) ||
|
||||||
|
(hand === Controller.Standard.LeftHand &&
|
||||||
|
SelectionManager.pointingAtDesktopWindowLeft);
|
||||||
|
var pointingAtTablet = (hand === Controller.Standard.RightHand && SelectionManager.pointingAtTabletRight) ||
|
||||||
|
(hand === Controller.Standard.LeftHand && SelectionManager.pointingAtTabletLeft);
|
||||||
|
return pointingAtDesktopWindow || pointingAtTablet;
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeClickHandler(hand) {
|
||||||
|
return function (clicked) {
|
||||||
|
if (!editEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Don't allow both hands to trigger at the same time
|
||||||
|
if (triggered() && hand !== that.triggeredHand) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!triggered() && clicked && !pointingAtDesktopWindowOrTablet(hand)) {
|
||||||
|
that.triggeredHand = hand;
|
||||||
|
mousePressEvent({});
|
||||||
|
} else if (triggered() && !clicked) {
|
||||||
|
that.triggeredHand = NO_HAND;
|
||||||
|
mouseReleaseEvent({});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function makePressHandler(hand) {
|
||||||
|
return function (value) {
|
||||||
|
if (!editEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (value >= TRIGGER_ON_VALUE && !triggered() && !pointingAtDesktopWindowOrTablet(hand)) {
|
||||||
|
that.pressedHand = hand;
|
||||||
|
} else {
|
||||||
|
that.pressedHand = NO_HAND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function cleanup() {
|
function cleanup() {
|
||||||
Controller.mousePressEvent.disconnect(self.mousePressEvent);
|
Controller.mousePressEvent.disconnect(self.mousePressEvent);
|
||||||
|
Controller.mouseReleaseEvent.disconnect(self.mouseReleaseEvent);
|
||||||
Controller.keyPressEvent.disconnect(self.keyPressEvent);
|
Controller.keyPressEvent.disconnect(self.keyPressEvent);
|
||||||
Controller.keyReleaseEvent.disconnect(self.keyReleaseEvent);
|
Controller.keyReleaseEvent.disconnect(self.keyReleaseEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.mousePressEvent.connect(mousePressEvent);
|
Controller.mousePressEvent.connect(mousePressEvent);
|
||||||
|
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
|
||||||
Controller.keyPressEvent.connect(keyPressEvent);
|
Controller.keyPressEvent.connect(keyPressEvent);
|
||||||
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
Controller.keyReleaseEvent.connect(keyReleaseEvent);
|
||||||
|
that.triggerClickMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Controller.Standard.RightHand));
|
||||||
|
that.triggerClickMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand));
|
||||||
|
that.triggerPressMapping.from(Controller.Standard.RT).peek().to(makePressHandler(Controller.Standard.RightHand));
|
||||||
|
that.triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand));
|
||||||
|
that.enableTriggerMapping = function() {
|
||||||
|
that.triggerClickMapping.enable();
|
||||||
|
that.triggerPressMapping.enable();
|
||||||
|
};
|
||||||
|
that.disableTriggerMapping = function() {
|
||||||
|
that.triggerClickMapping.disable();
|
||||||
|
that.triggerPressMapping.disable();
|
||||||
|
};
|
||||||
|
that.enableTriggerMapping();
|
||||||
Script.scriptEnding.connect(cleanup);
|
Script.scriptEnding.connect(cleanup);
|
||||||
|
Script.scriptEnding.connect(that.disableTriggerMapping);
|
||||||
|
|
||||||
return that;
|
return that;
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,9 @@ SelectionManager = (function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (messageParsed.method === "selectEntity") {
|
if (messageParsed.method === "selectEntity") {
|
||||||
|
if (!that.editEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!SelectionDisplay.triggered() || SelectionDisplay.triggeredHand === messageParsed.hand) {
|
if (!SelectionDisplay.triggered() || SelectionDisplay.triggeredHand === messageParsed.hand) {
|
||||||
if (wantDebug) {
|
if (wantDebug) {
|
||||||
print("setting selection to " + messageParsed.entityID);
|
print("setting selection to " + messageParsed.entityID);
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
// Created by Ryan Huffman on 13 Nov 2014
|
// Created by Ryan Huffman on 13 Nov 2014
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
// Copyright 2020 Vircadia contributors.
|
// Copyright 2020 Vircadia contributors.
|
||||||
|
// Copyright 2022 Overte e.V.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
@ -2062,6 +2063,23 @@ div.entity-list-menu {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.tools-select-menu {
|
||||||
|
position: relative;
|
||||||
|
display: none;
|
||||||
|
width: 370px;
|
||||||
|
height: 0px;
|
||||||
|
top: 0px;
|
||||||
|
left: 8px;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #505050;
|
||||||
|
border-width: 1px;
|
||||||
|
background-color: #c0c0c0;
|
||||||
|
z-index: 2;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
div.menu-separator{
|
div.menu-separator{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 2px;
|
height: 2px;
|
||||||
|
|
|
@ -24,49 +24,73 @@
|
||||||
<div id="mode-section" class="section">
|
<div id="mode-section" class="section">
|
||||||
<div class="property container">
|
<div class="property container">
|
||||||
<label for="create-app-mode">Create app mode </label>
|
<label for="create-app-mode">Create app mode </label>
|
||||||
<select name="create-app-mode" id="create-app-mode">
|
<!-- <select name="create-app-mode" id="create-app-mode">
|
||||||
<option value="object">Object mode</option>
|
<option value="object">Object mode</option>
|
||||||
<option value="voxel">Voxel edit mode</option>
|
<option value="voxel">Voxel edit mode</option>
|
||||||
</select>
|
</select> -->
|
||||||
|
<div class="property container">
|
||||||
|
<input name="create-app-mode" type="button" class="entity-list-menutitle" id="create-app-mode" value="Create app mode▾" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="tools-select-menu" id="edit-mode-menu" >
|
||||||
|
<button class="menu-button" id="edit-mode-object" >
|
||||||
|
<div class = "menu-item">
|
||||||
|
<div class = "menu-item-caption">Object mode</div>
|
||||||
|
<div class = "menu-item-shortcut"></div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
<button class="menu-button" id="edit-mode-voxel" >
|
||||||
|
<div class = "menu-item">
|
||||||
|
<div class = "menu-item-caption">Voxel edit mode</div>
|
||||||
|
<div class = "menu-item-shortcut"></div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="voxels-section" class="section">
|
<div id="voxels-section" class="section">
|
||||||
<h2>Voxel edit settings</h2>
|
<h2>Voxel edit settings</h2>
|
||||||
<div class="property container">
|
<div class="property container">
|
||||||
<label for="voxel-edit-mode">Voxel edit mode </label>
|
<label for="voxel-edit-mode">Voxel edit mode </label>
|
||||||
<select name="voxel-edit-mode" id="voxel-edit-mode">
|
<!-- <select name="voxel-edit-mode" id="voxel-edit-mode">
|
||||||
<option value="single">Single voxels</option>
|
<option value="single">Single voxels</option>
|
||||||
<option value="sphere">Spheres</option>
|
<option value="sphere">Spheres</option>
|
||||||
<option value="cube">Cubes</option>
|
<option value="cube">Cubes</option>
|
||||||
</select>
|
</select> -->
|
||||||
|
<div class="property container">
|
||||||
|
<input name="voxel-edit-mode" type="button" class="entity-list-menutitle" id="voxel-edit-mode" value="Voxel edit mode▾" />
|
||||||
|
</div>
|
||||||
<label for="voxel-sphere-size"> Sphere/cube size <span class="unit">m</span></label>
|
<label for="voxel-sphere-size"> Sphere/cube size <span class="unit">m</span></label>
|
||||||
<div class="number">
|
<div class="number">
|
||||||
<input type="number" id="voxel-sphere-size" min="0.01" step="0.2" />
|
<input type="number" id="voxel-sphere-size" min="0.01" step="0.2" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="tools-select-menu" id="voxel-edit-mode-menu" >
|
||||||
|
<button class="menu-button" id="voxel-edit-mode-single" >
|
||||||
|
<div class = "menu-item">
|
||||||
|
<div class = "menu-item-caption">Single voxels</div>
|
||||||
|
<div class = "menu-item-shortcut"></div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
<button class="menu-button" id="voxel-edit-mode-sphere" >
|
||||||
|
<div class = "menu-item">
|
||||||
|
<div class = "menu-item-caption">Spheres</div>
|
||||||
|
<div class = "menu-item-shortcut"></div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
<button class="menu-button" id="voxel-edit-mode-cube" >
|
||||||
|
<div class = "menu-item">
|
||||||
|
<div class = "menu-item-caption">Cubes</div>
|
||||||
|
<div class = "menu-item-shortcut"></div>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div class="property container">
|
<div class="property container">
|
||||||
<label for="voxel-edit-dynamics">Voxel edit dynamics </label>
|
|
||||||
<select name="voxel-edit-dynamics" id="voxel-edit-dynamics">
|
|
||||||
<option value="click">Modify on click</option>
|
|
||||||
<option value="continuous">Continuous</option>
|
|
||||||
</select>
|
|
||||||
<label for="voxel-remove"> Remove voxels</label>
|
<label for="voxel-remove"> Remove voxels</label>
|
||||||
<div style="width: 100%">
|
<div style="width: 100%">
|
||||||
<input type='checkbox' id="voxel-remove" style="width: 100%">
|
<input type='checkbox' id="voxel-remove" style="width: 100%">
|
||||||
<label for="voxel-remove"> </label>
|
<label for="voxel-remove"> </label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="property container">
|
|
||||||
<label for="voxel-pointer-mode">VR pointer mode </label>
|
|
||||||
<select name="voxel-pointer-mode" id="voxel-pointer-mode">
|
|
||||||
<option value="laser">Laser pointer</option>
|
|
||||||
<option value="brush">Brush</option>
|
|
||||||
</select>
|
|
||||||
<label for="voxel-brush-length"> Brush length <span class="unit">m</span></label>
|
|
||||||
<div class="number">
|
|
||||||
<input type="number" id="voxel-brush-length" min="0.2" step="0.2" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="grid-section" class="section">
|
<div id="grid-section" class="section">
|
||||||
<h2>Grid settings</h2>
|
<h2>Grid settings</h2>
|
||||||
|
@ -116,5 +140,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="menuBackgroundOverlay" ></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -7,15 +7,25 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
var createAppModeValue = "";
|
||||||
|
var voxelEditModeValue = "";
|
||||||
|
|
||||||
function loaded() {
|
function loaded() {
|
||||||
openEventBridge(function() {
|
openEventBridge(function() {
|
||||||
elCreateAppMode = document.getElementById("create-app-mode");
|
elCreateAppModeMenu = document.getElementById("create-app-mode");
|
||||||
elVoxelEditMode = document.getElementById("voxel-edit-mode");
|
elEditModeObject = document.getElementById("edit-mode-object");
|
||||||
|
elEditModeVoxel = document.getElementById("edit-mode-voxel");
|
||||||
|
elVoxelEditModeMenu = document.getElementById("voxel-edit-mode");
|
||||||
|
elVoxelEditModeSingle = document.getElementById("voxel-edit-mode-single");
|
||||||
|
elVoxelEditModeSphere = document.getElementById("voxel-edit-mode-sphere");
|
||||||
|
elVoxelEditModeCube = document.getElementById("voxel-edit-mode-cube");
|
||||||
|
elMenuBackgroundOverlay = document.getElementById("menuBackgroundOverlay");
|
||||||
|
|
||||||
elVoxelSphereSize = document.getElementById("voxel-sphere-size");
|
elVoxelSphereSize = document.getElementById("voxel-sphere-size");
|
||||||
elVoxelEditDynamics = document.getElementById("voxel-edit-dynamics");
|
//elVoxelEditDynamics = document.getElementById("voxel-edit-dynamics");
|
||||||
elVoxelRemove = document.getElementById("voxel-remove");
|
elVoxelRemove = document.getElementById("voxel-remove");
|
||||||
elVoxelPointerMode = document.getElementById("voxel-pointer-mode");
|
//elVoxelPointerMode = document.getElementById("voxel-pointer-mode");
|
||||||
elVoxelBrushLength = document.getElementById("voxel-brush-length");
|
//elVoxelBrushLength = document.getElementById("voxel-brush-length");
|
||||||
|
|
||||||
elPosY = document.getElementById("horiz-y");
|
elPosY = document.getElementById("horiz-y");
|
||||||
elMinorSpacing = document.getElementById("minor-spacing");
|
elMinorSpacing = document.getElementById("minor-spacing");
|
||||||
|
@ -25,38 +35,93 @@ function loaded() {
|
||||||
elMoveToSelection = document.getElementById("move-to-selection");
|
elMoveToSelection = document.getElementById("move-to-selection");
|
||||||
elMoveToAvatar = document.getElementById("move-to-avatar");
|
elMoveToAvatar = document.getElementById("move-to-avatar");
|
||||||
|
|
||||||
|
elCreateAppModeMenu.onclick = function() {
|
||||||
|
document.getElementById("menuBackgroundOverlay").style.display = "block";
|
||||||
|
document.getElementById("edit-mode-menu").style.display = "block";
|
||||||
|
};
|
||||||
|
|
||||||
|
elVoxelEditModeMenu.onclick = function() {
|
||||||
|
document.getElementById("menuBackgroundOverlay").style.display = "block";
|
||||||
|
document.getElementById("voxel-edit-mode-menu").style.display = "block";
|
||||||
|
};
|
||||||
|
|
||||||
|
elMenuBackgroundOverlay.onclick = function() {
|
||||||
|
closeAllEntityListMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
elEditModeObject.onclick = function() {
|
||||||
|
createAppModeValue = "object";
|
||||||
|
elCreateAppModeMenu.value = "Object mode\u25BE";
|
||||||
|
emitUpdateEditTools();
|
||||||
|
closeAllEntityListMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
elEditModeVoxel.onclick = function() {
|
||||||
|
createAppModeValue = "voxel";
|
||||||
|
elCreateAppModeMenu.value = "Voxel edit mode\u25BE";
|
||||||
|
emitUpdateEditTools();
|
||||||
|
closeAllEntityListMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
elVoxelEditModeSingle.onclick = function() {
|
||||||
|
voxelEditModeValue = "single";
|
||||||
|
elVoxelEditModeMenu.value = "Single voxels\u25BE";
|
||||||
|
emitUpdateEditTools();
|
||||||
|
closeAllEntityListMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
elVoxelEditModeSphere.onclick = function() {
|
||||||
|
voxelEditModeValue = "sphere";
|
||||||
|
elVoxelEditModeMenu.value = "Spheres\u25BE";
|
||||||
|
emitUpdateEditTools();
|
||||||
|
closeAllEntityListMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
elVoxelEditModeCube.onclick = function() {
|
||||||
|
voxelEditModeValue = "cube";
|
||||||
|
elVoxelEditModeMenu.value = "Cubes\u25BE";
|
||||||
|
emitUpdateEditTools();
|
||||||
|
closeAllEntityListMenu();
|
||||||
|
};
|
||||||
|
|
||||||
if (window.EventBridge !== undefined) {
|
if (window.EventBridge !== undefined) {
|
||||||
EventBridge.scriptEventReceived.connect(function(data) {
|
EventBridge.scriptEventReceived.connect(function(data) {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
|
|
||||||
if (data.createAppMode !== undefined) {
|
if (data.createAppMode !== undefined) {
|
||||||
elCreateAppMode.value = data.createAppMode;
|
if (data.createAppMode === "object") {
|
||||||
|
createAppModeValue = data.createAppMode;
|
||||||
|
elCreateAppModeMenu.value = "Object mode\u25BE";
|
||||||
|
}
|
||||||
|
if (data.createAppMode === "voxel") {
|
||||||
|
createAppModeValue = data.createAppMode;
|
||||||
|
elCreateAppModeMenu.value = "Voxel edit mode\u25BE";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.voxelEditMode !== undefined) {
|
if (data.voxelEditMode !== undefined) {
|
||||||
elVoxelEditMode.value = data.voxelEditMode;
|
if (data.voxelEditMode === "single") {
|
||||||
|
voxelEditModeValue = data.voxelEditMode;
|
||||||
|
elVoxelEditModeMenu.value = "Single voxels\u25BE";
|
||||||
|
}
|
||||||
|
if (data.voxelEditMode === "sphere") {
|
||||||
|
voxelEditModeValue = data.voxelEditMode;
|
||||||
|
elVoxelEditModeMenu.value = "Spheres\u25BE";
|
||||||
|
}
|
||||||
|
if (data.voxelEditMode === "cube") {
|
||||||
|
voxelEditModeValue = data.voxelEditMode;
|
||||||
|
elVoxelEditModeMenu.value = "Cubes\u25BE";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.voxelSphereSize !== undefined) {
|
if (data.voxelSphereSize !== undefined) {
|
||||||
elVoxelSphereSize.value = data.voxelSphereSize;
|
elVoxelSphereSize.value = data.voxelSphereSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.voxelEditDynamics !== undefined) {
|
|
||||||
elVoxelEditDynamics.value = data.voxelEditDynamics;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.voxelRemove !== undefined) {
|
if (data.voxelRemove !== undefined) {
|
||||||
elVoxelRemove.checked = data.voxelRemove == true;
|
elVoxelRemove.checked = data.voxelRemove == true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.voxelPointerMode !== undefined) {
|
|
||||||
elVoxelPointerMode.value = data.voxelPointerMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.voxelBrushLength !== undefined) {
|
|
||||||
elVoxelBrushLength.value = data.voxelBrushLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.origin) {
|
if (data.origin) {
|
||||||
var origin = data.origin;
|
var origin = data.origin;
|
||||||
elPosY.value = origin.y;
|
elPosY.value = origin.y;
|
||||||
|
@ -100,24 +165,22 @@ function loaded() {
|
||||||
function emitUpdateEditTools() {
|
function emitUpdateEditTools() {
|
||||||
EventBridge.emitWebEvent(JSON.stringify({
|
EventBridge.emitWebEvent(JSON.stringify({
|
||||||
type: "update-edit-tools",
|
type: "update-edit-tools",
|
||||||
createAppMode: elCreateAppMode.value,
|
createAppMode: createAppModeValue,
|
||||||
voxelEditMode: elVoxelEditMode.value,
|
voxelEditMode: voxelEditModeValue,
|
||||||
voxelSphereSize: elVoxelSphereSize.value,
|
voxelSphereSize: elVoxelSphereSize.value,
|
||||||
voxelEditDynamics: elVoxelEditDynamics.value,
|
//voxelEditDynamics: elVoxelEditDynamics.value,
|
||||||
voxelRemove: elVoxelRemove.checked,
|
voxelRemove: elVoxelRemove.checked,
|
||||||
voxelPointerMode: elVoxelPointerMode.value,
|
//voxelPointerMode: elVoxelPointerMode.value,
|
||||||
voxelBrushLength: elVoxelBrushLength.value,
|
//voxelBrushLength: elVoxelBrushLength.value,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elCreateAppMode.addEventListener("change", emitUpdateEditTools);
|
|
||||||
elVoxelEditMode.addEventListener("change", emitUpdateEditTools);
|
|
||||||
elVoxelSphereSize.addEventListener("change", emitUpdateEditTools);
|
elVoxelSphereSize.addEventListener("change", emitUpdateEditTools);
|
||||||
elVoxelEditDynamics.addEventListener("change", emitUpdateEditTools);
|
//elVoxelEditDynamics.addEventListener("change", emitUpdateEditTools);
|
||||||
elVoxelRemove.addEventListener("change", emitUpdateEditTools);
|
elVoxelRemove.addEventListener("change", emitUpdateEditTools);
|
||||||
elVoxelPointerMode.addEventListener("change", emitUpdateEditTools);
|
//elVoxelPointerMode.addEventListener("change", emitUpdateEditTools);
|
||||||
elVoxelBrushLength.addEventListener("change", emitUpdateEditTools);
|
//elVoxelBrushLength.addEventListener("change", emitUpdateEditTools);
|
||||||
|
|
||||||
elPosY.addEventListener("change", emitUpdate);
|
elPosY.addEventListener("change", emitUpdate);
|
||||||
elMinorSpacing.addEventListener("change", emitUpdate);
|
elMinorSpacing.addEventListener("change", emitUpdate);
|
||||||
|
@ -211,8 +274,15 @@ function loaded() {
|
||||||
}));
|
}));
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
|
function closeAllEntityListMenu() {
|
||||||
|
document.getElementById("menuBackgroundOverlay").style.display = "none";
|
||||||
|
document.getElementById("edit-mode-menu").style.display = "none";
|
||||||
|
document.getElementById("voxel-edit-mode-menu").style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
// Disable right-click context menu which is not visible in the HMD and makes it seem like the app has locked
|
// Disable right-click context menu which is not visible in the HMD and makes it seem like the app has locked
|
||||||
document.addEventListener("contextmenu", function (event) {
|
document.addEventListener("contextmenu", function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue