More work on editVoxel.js

This commit is contained in:
Clement 2014-03-11 16:01:21 -07:00
parent ca0cd2d9d0
commit dcaef45f2e
9 changed files with 273 additions and 138 deletions

View file

@ -15,16 +15,16 @@ function mousePressEvent(event) {
var pickRay = Camera.computePickRay(event.x, event.y); var pickRay = Camera.computePickRay(event.x, event.y);
var intersection = Voxels.findRayIntersection(pickRay); var intersection = Voxels.findRayIntersection(pickRay);
if (intersection.intersects) { if (intersection.intersects) {
// Note: due to the current C++ "click on voxel" behavior, these values may be the animated color for the voxel // Note: due to the current C++ "click on voxel" behavior, these values may be the animated color for the voxel
print("clicked on voxel.red/green/blue=" + intersection.voxel.red + ", " print("clicked on voxel.red/green/blue=" + intersection.voxel.red + ", "
+ intersection.voxel.green + ", " + intersection.voxel.blue); + intersection.voxel.green + ", " + intersection.voxel.blue);
print("clicked on voxel.x/y/z/s=" + intersection.voxel.x + ", " print("clicked on voxel.x/y/z/s=" + intersection.voxel.x + ", "
+ intersection.voxel.y + ", " + intersection.voxel.z+ ": " + intersection.voxel.s); + intersection.voxel.y + ", " + intersection.voxel.z+ ": " + intersection.voxel.s);
print("clicked on face=" + intersection.face); print("clicked on face=" + intersection.face);
print("clicked on distance=" + intersection.distance); print("clicked on distance=" + intersection.distance);
var newVoxel = { var newVoxel = {
x: intersection.voxel.x, x: intersection.voxel.x,
y: intersection.voxel.y, y: intersection.voxel.y,
z: intersection.voxel.z, z: intersection.voxel.z,
@ -32,7 +32,7 @@ function mousePressEvent(event) {
red: 255, red: 255,
green: 0, green: 0,
blue: 255 }; blue: 255 };
if (intersection.face == "MIN_X_FACE") { if (intersection.face == "MIN_X_FACE") {
newVoxel.x -= newVoxel.s; newVoxel.x -= newVoxel.s;
} else if (intersection.face == "MAX_X_FACE") { } else if (intersection.face == "MAX_X_FACE") {
@ -46,11 +46,11 @@ function mousePressEvent(event) {
} else if (intersection.face == "MAX_Z_FACE") { } else if (intersection.face == "MAX_Z_FACE") {
newVoxel.z += newVoxel.s; newVoxel.z += newVoxel.s;
} }
print("Voxels.setVoxel("+newVoxel.x + ", " print("Voxels.setVoxel("+newVoxel.x + ", "
+ newVoxel.y + ", " + newVoxel.z + ", " + newVoxel.s + ", " + newVoxel.y + ", " + newVoxel.z + ", " + newVoxel.s + ", "
+ newVoxel.red + ", " + newVoxel.green + ", " + newVoxel.blue + ")" ); + newVoxel.red + ", " + newVoxel.green + ", " + newVoxel.blue + ")" );
Voxels.setVoxel(newVoxel.x, newVoxel.y, newVoxel.z, newVoxel.s, newVoxel.red, newVoxel.green, newVoxel.blue); Voxels.setVoxel(newVoxel.x, newVoxel.y, newVoxel.z, newVoxel.s, newVoxel.red, newVoxel.green, newVoxel.blue);
} }
} }

View file

@ -8,10 +8,10 @@
// Captures mouse clicks and edits voxels accordingly. // Captures mouse clicks and edits voxels accordingly.
// //
// click = create a new voxel on this face, same color as old (default color picker state) // click = create a new voxel on this face, same color as old (default color picker state)
// right click or control + click = delete this voxel // right click or control + click = delete this voxel
// shift + click = recolor this voxel // shift + click = recolor this voxel
// 1 - 8 = pick new color from palette // 1 - 8 = pick new color from palette
// 9 = create a new voxel in front of the camera // 9 = create a new voxel in front of the camera
// //
// Click and drag to create more new voxels in the same direction // Click and drag to create more new voxels in the same direction
// //
@ -36,19 +36,19 @@ var previewLineWidth = 1.5;
var oldMode = Camera.getMode(); var oldMode = Camera.getMode();
var isAdding = false; var isAdding = false;
var isExtruding = false; var isExtruding = false;
var isOrbiting = false; var isOrbiting = false;
var isOrbitingFromTouch = false; var isOrbitingFromTouch = false;
var isPanning = false; var isPanning = false;
var isPanningFromTouch = false; var isPanningFromTouch = false;
var touchPointsToOrbit = 2; // you can change these, but be mindful that on some track pads 2 touch points = right click+drag var touchPointsToOrbit = 2; // you can change these, but be mindful that on some track pads 2 touch points = right click+drag
var touchPointsToPan = 3; var touchPointsToPan = 3;
var orbitAzimuth = 0.0; var orbitAzimuth = 0.0;
var orbitAltitude = 0.0; var orbitAltitude = 0.0;
var orbitCenter = { x: 0, y: 0, z: 0 }; var orbitCenter = { x: 0, y: 0, z: 0 };
var orbitPosition = { x: 0, y: 0, z: 0 }; var orbitPosition = { x: 0, y: 0, z: 0 };
var torsoToEyeVector = { x: 0, y: 0, z: 0 }; var torsoToEyeVector = { x: 0, y: 0, z: 0 };
var orbitRadius = 0.0; var orbitRadius = 0.0;
var extrudeDirection = { x: 0, y: 0, z: 0 }; var extrudeDirection = { x: 0, y: 0, z: 0 };
var extrudeScale = 0.0; var extrudeScale = 0.0;
@ -60,7 +60,7 @@ var wheelPixelsMoved = 0;
var mouseX = 0; var mouseX = 0;
var mouseY = 0; var mouseY = 0;
// Create a table of the different colors you can choose // Create a table of the different colors you can choose
var colors = new Array(); var colors = new Array();
@ -76,7 +76,7 @@ colors[8] = { red: 31, green: 64, blue: 64 };
var numColors = 9; var numColors = 9;
var whichColor = -1; // Starting color is 'Copy' mode var whichColor = -1; // Starting color is 'Copy' mode
// Create sounds for adding, deleting, recoloring voxels // Create sounds for adding, deleting, recoloring voxels
var addSound1 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+create+2.raw"); var addSound1 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+create+2.raw");
var addSound2 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+create+3.raw"); var addSound2 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+create+3.raw");
var addSound3 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+create+4.raw"); var addSound3 = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-public/sounds/Voxels/voxel+create+4.raw");
@ -93,7 +93,7 @@ var editToolsOn = true; // starts out off
// previewAsVoxel - by default, we will preview adds/deletes/recolors as just 4 lines on the intersecting face. But if you // previewAsVoxel - by default, we will preview adds/deletes/recolors as just 4 lines on the intersecting face. But if you
// the preview to show a full voxel then set this to true and the voxel will be displayed for voxel editing // the preview to show a full voxel then set this to true and the voxel will be displayed for voxel editing
var previewAsVoxel = false; var previewAsVoxel = true;
var voxelPreview = Overlays.addOverlay("cube", { var voxelPreview = Overlays.addOverlay("cube", {
position: { x: 0, y: 0, z: 0}, position: { x: 0, y: 0, z: 0},
@ -104,7 +104,7 @@ var voxelPreview = Overlays.addOverlay("cube", {
visible: false, visible: false,
lineWidth: 4 lineWidth: 4
}); });
var linePreviewTop = Overlays.addOverlay("line3d", { var linePreviewTop = Overlays.addOverlay("line3d", {
position: { x: 0, y: 0, z: 0}, position: { x: 0, y: 0, z: 0},
end: { x: 0, y: 0, z: 0}, end: { x: 0, y: 0, z: 0},
@ -228,7 +228,7 @@ var eyedropperTool = Overlays.addOverlay("image", {
visible: false, visible: false,
alpha: 0.9 alpha: 0.9
}); });
// This will create a couple of image overlays that make a "slider", we will demonstrate how to trap mouse messages to // This will create a couple of image overlays that make a "slider", we will demonstrate how to trap mouse messages to
// move the slider // move the slider
@ -277,6 +277,88 @@ var pointerVoxelScaleMin = Math.pow(2, (1-pointerVoxelScaleOriginStep));
var pointerVoxelScaleMax = Math.pow(2, (pointerVoxelScaleSteps-pointerVoxelScaleOriginStep)); var pointerVoxelScaleMax = Math.pow(2, (pointerVoxelScaleSteps-pointerVoxelScaleOriginStep));
var thumbDeltaPerStep = thumbExtents / (pointerVoxelScaleSteps - 1); var thumbDeltaPerStep = thumbExtents / (pointerVoxelScaleSteps - 1);
///////////////////////////////////// IMPORT MODULE ///////////////////////////////
// Move the following code to a separate file when include will be available.
var importTree;
var importPreview;
var isImporting;
var importPosition;
var importScale;
function initImport() {
importPreview = Overlays.addOverlay("localvoxels", {
name: "import",
position: { x: 0, y: 0, z: 0},
scale: 0,
visible: false
});
isImporting = false;
importPosition = { x: 0, y: 0, z: 0 };
importScale = 0;
}
function importVoxels() {
if (Clipboard.importVoxels() == 0) {
isImporting = true;
if (importScale <= 0) {
importScale = 1;
}
} else {
isImporting = false;
}
return isImporting;
}
function moveImport(position) {
if (0 < position.x && 0 < position.y && 0 < position.z) {
importPosition = position;
Overlays.editOverlay(importPreview, {
position: { x: importPosition.x, y: importPosition.y, z: importPosition.z }
});
}
}
function rescaleImport(scale) {
if (0 < scale) {
importScale = scale;
Overlays.editOverlay(importPreview, {
scale: importScale
});
}
}
function showImport(doShow) {
Overlays.editOverlay(importPreview, {
visible: doShow
});
}
function placeImport() {
if (isImporting) {
Clipboard.pasteVoxel(importPosition.x, importPosition.y, importPosition.z, importScale);
isImporting = false;
}
}
function cancelImport() {
if (isImporting) {
isImporting = false;
showImport(false);
}
}
function cleanupImport() {
Overlays.deleteOverlay(importPreview);
isImporting = false;
importPostion = { x: 0, y: 0, z: 0 };
importScale = 0;
}
/////////////////////////////////// END IMPORT MODULE /////////////////////////////
initImport();
if (editToolsOn) { if (editToolsOn) {
moveTools(); moveTools();
} }
@ -301,9 +383,16 @@ function calcScaleFromThumb(newThumbX) {
thumbAt = newThumbX - minThumbX; thumbAt = newThumbX - minThumbX;
thumbStep = Math.floor((thumbAt/ thumbExtents) * (pointerVoxelScaleSteps-1)) + 1; thumbStep = Math.floor((thumbAt/ thumbExtents) * (pointerVoxelScaleSteps-1)) + 1;
pointerVoxelScale = Math.pow(2, (thumbStep-pointerVoxelScaleOriginStep)); pointerVoxelScale = Math.pow(2, (thumbStep-pointerVoxelScaleOriginStep));
// if importing, rescale import ...
if (isImporting) {
var importScale = (pointerVoxelScale / MAX_VOXEL_SCALE) * MAX_PASTE_VOXEL_SCALE;
rescaleImport(importScale);
}
// now reset the display accordingly... // now reset the display accordingly...
calcThumbFromScale(pointerVoxelScale); calcThumbFromScale(pointerVoxelScale);
// if the user moved the thumb, then they are fixing the voxel scale // if the user moved the thumb, then they are fixing the voxel scale
pointerVoxelScaleSet = true; pointerVoxelScaleSet = true;
} }
@ -322,7 +411,7 @@ function getNewPasteVoxel(pickRay) {
origin.x += pickRay.origin.x; origin.x += pickRay.origin.x;
origin.y += pickRay.origin.y; origin.y += pickRay.origin.y;
origin.z += pickRay.origin.z; origin.z += pickRay.origin.z;
origin.x -= voxelSize / 2; origin.x -= voxelSize / 2;
origin.y -= voxelSize / 2; origin.y -= voxelSize / 2;
origin.z += voxelSize / 2; origin.z += voxelSize / 2;
@ -330,7 +419,7 @@ function getNewPasteVoxel(pickRay) {
return {origin: origin, voxelSize: voxelSize}; return {origin: origin, voxelSize: voxelSize};
} }
function getNewVoxelPosition() { function getNewVoxelPosition() {
var camera = Camera.getPosition(); var camera = Camera.getPosition();
var forwardVector = Quat.getFront(MyAvatar.orientation); var forwardVector = Quat.getFront(MyAvatar.orientation);
var newPosition = Vec3.sum(camera, Vec3.multiply(forwardVector, NEW_VOXEL_DISTANCE_FROM_CAMERA)); var newPosition = Vec3.sum(camera, Vec3.multiply(forwardVector, NEW_VOXEL_DISTANCE_FROM_CAMERA));
@ -377,27 +466,27 @@ function calculateVoxelFromIntersection(intersection, operation) {
var wantDebug = false; var wantDebug = false;
if (wantDebug) { if (wantDebug) {
print(">>>>> calculateVoxelFromIntersection().... intersection voxel.red/green/blue=" + intersection.voxel.red + ", " print(">>>>> calculateVoxelFromIntersection().... intersection voxel.red/green/blue=" + intersection.voxel.red + ", "
+ intersection.voxel.green + ", " + intersection.voxel.blue); + intersection.voxel.green + ", " + intersection.voxel.blue);
print(" intersection voxel.x/y/z/s=" + intersection.voxel.x + ", " print(" intersection voxel.x/y/z/s=" + intersection.voxel.x + ", "
+ intersection.voxel.y + ", " + intersection.voxel.z+ ": " + intersection.voxel.s); + intersection.voxel.y + ", " + intersection.voxel.z+ ": " + intersection.voxel.s);
print(" intersection face=" + intersection.face); print(" intersection face=" + intersection.face);
print(" intersection distance=" + intersection.distance); print(" intersection distance=" + intersection.distance);
print(" intersection intersection.x/y/z=" + intersection.intersection.x + ", " print(" intersection intersection.x/y/z=" + intersection.intersection.x + ", "
+ intersection.intersection.y + ", " + intersection.intersection.z); + intersection.intersection.y + ", " + intersection.intersection.z);
} }
var voxelSize; var voxelSize;
if (pointerVoxelScaleSet) { if (pointerVoxelScaleSet) {
voxelSize = pointerVoxelScale; voxelSize = pointerVoxelScale;
} else { } else {
voxelSize = intersection.voxel.s; voxelSize = intersection.voxel.s;
} }
var x; var x;
var y; var y;
var z; var z;
// if our "target voxel size" is larger than the voxel we intersected with, then we need to find the closest // if our "target voxel size" is larger than the voxel we intersected with, then we need to find the closest
// ancestor voxel of our target size that contains our intersected voxel. // ancestor voxel of our target size that contains our intersected voxel.
if (voxelSize > intersection.voxel.s) { if (voxelSize > intersection.voxel.s) {
@ -438,7 +527,7 @@ function calculateVoxelFromIntersection(intersection, operation) {
if (wantAddAdjust) { if (wantAddAdjust) {
resultVoxel.x -= voxelSize; resultVoxel.x -= voxelSize;
} }
resultVoxel.bottomLeft = {x: highlightAt.x, y: highlightAt.y + zFightingSizeAdjust, z: highlightAt.z + zFightingSizeAdjust }; resultVoxel.bottomLeft = {x: highlightAt.x, y: highlightAt.y + zFightingSizeAdjust, z: highlightAt.z + zFightingSizeAdjust };
resultVoxel.bottomRight = {x: highlightAt.x, y: highlightAt.y + zFightingSizeAdjust, z: highlightAt.z + voxelSize - zFightingSizeAdjust }; resultVoxel.bottomRight = {x: highlightAt.x, y: highlightAt.y + zFightingSizeAdjust, z: highlightAt.z + voxelSize - zFightingSizeAdjust };
resultVoxel.topLeft = {x: highlightAt.x, y: highlightAt.y + voxelSize - zFightingSizeAdjust, z: highlightAt.z + zFightingSizeAdjust }; resultVoxel.topLeft = {x: highlightAt.x, y: highlightAt.y + voxelSize - zFightingSizeAdjust, z: highlightAt.z + zFightingSizeAdjust };
@ -462,7 +551,7 @@ function calculateVoxelFromIntersection(intersection, operation) {
if (wantAddAdjust) { if (wantAddAdjust) {
resultVoxel.y -= voxelSize; resultVoxel.y -= voxelSize;
} }
resultVoxel.topRight = {x: highlightAt.x + zFightingSizeAdjust , y: highlightAt.y, z: highlightAt.z + zFightingSizeAdjust }; resultVoxel.topRight = {x: highlightAt.x + zFightingSizeAdjust , y: highlightAt.y, z: highlightAt.z + zFightingSizeAdjust };
resultVoxel.topLeft = {x: highlightAt.x + voxelSize - zFightingSizeAdjust, y: highlightAt.y, z: highlightAt.z + zFightingSizeAdjust }; resultVoxel.topLeft = {x: highlightAt.x + voxelSize - zFightingSizeAdjust, y: highlightAt.y, z: highlightAt.z + zFightingSizeAdjust };
resultVoxel.bottomRight = {x: highlightAt.x + zFightingSizeAdjust , y: highlightAt.y, z: highlightAt.z + voxelSize - zFightingSizeAdjust }; resultVoxel.bottomRight = {x: highlightAt.x + zFightingSizeAdjust , y: highlightAt.y, z: highlightAt.z + voxelSize - zFightingSizeAdjust };
@ -474,7 +563,7 @@ function calculateVoxelFromIntersection(intersection, operation) {
if (wantAddAdjust) { if (wantAddAdjust) {
resultVoxel.y += voxelSize; resultVoxel.y += voxelSize;
} }
resultVoxel.bottomRight = {x: highlightAt.x + zFightingSizeAdjust, y: highlightAt.y, z: highlightAt.z + zFightingSizeAdjust }; resultVoxel.bottomRight = {x: highlightAt.x + zFightingSizeAdjust, y: highlightAt.y, z: highlightAt.z + zFightingSizeAdjust };
resultVoxel.bottomLeft = {x: highlightAt.x + voxelSize - zFightingSizeAdjust, y: highlightAt.y, z: highlightAt.z + zFightingSizeAdjust}; resultVoxel.bottomLeft = {x: highlightAt.x + voxelSize - zFightingSizeAdjust, y: highlightAt.y, z: highlightAt.z + zFightingSizeAdjust};
resultVoxel.topRight = {x: highlightAt.x + zFightingSizeAdjust, y: highlightAt.y, z: highlightAt.z + voxelSize - zFightingSizeAdjust}; resultVoxel.topRight = {x: highlightAt.x + zFightingSizeAdjust, y: highlightAt.y, z: highlightAt.z + voxelSize - zFightingSizeAdjust};
@ -486,7 +575,7 @@ function calculateVoxelFromIntersection(intersection, operation) {
if (wantAddAdjust) { if (wantAddAdjust) {
resultVoxel.z -= voxelSize; resultVoxel.z -= voxelSize;
} }
resultVoxel.bottomRight = {x: highlightAt.x + zFightingSizeAdjust, y: highlightAt.y + zFightingSizeAdjust, z: highlightAt.z }; resultVoxel.bottomRight = {x: highlightAt.x + zFightingSizeAdjust, y: highlightAt.y + zFightingSizeAdjust, z: highlightAt.z };
resultVoxel.bottomLeft = {x: highlightAt.x + voxelSize - zFightingSizeAdjust, y: highlightAt.y + zFightingSizeAdjust, z: highlightAt.z}; resultVoxel.bottomLeft = {x: highlightAt.x + voxelSize - zFightingSizeAdjust, y: highlightAt.y + zFightingSizeAdjust, z: highlightAt.z};
resultVoxel.topRight = {x: highlightAt.x + zFightingSizeAdjust, y: highlightAt.y + voxelSize - zFightingSizeAdjust, z: highlightAt.z }; resultVoxel.topRight = {x: highlightAt.x + zFightingSizeAdjust, y: highlightAt.y + voxelSize - zFightingSizeAdjust, z: highlightAt.z };
@ -505,7 +594,7 @@ function calculateVoxelFromIntersection(intersection, operation) {
resultVoxel.topRight = {x: highlightAt.x + voxelSize - zFightingSizeAdjust, y: highlightAt.y + voxelSize - zFightingSizeAdjust, z: highlightAt.z}; resultVoxel.topRight = {x: highlightAt.x + voxelSize - zFightingSizeAdjust, y: highlightAt.y + voxelSize - zFightingSizeAdjust, z: highlightAt.z};
} }
return resultVoxel; return resultVoxel;
} }
@ -515,7 +604,7 @@ function showPreviewVoxel() {
var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY); var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY);
var intersection = Voxels.findRayIntersection(pickRay); var intersection = Voxels.findRayIntersection(pickRay);
// if the user hasn't updated the // if the user hasn't updated the
if (!pointerVoxelScaleSet) { if (!pointerVoxelScaleSet) {
calcThumbFromScale(intersection.voxel.s); calcThumbFromScale(intersection.voxel.s);
} }
@ -548,41 +637,41 @@ function showPreviewLines() {
var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY); var pickRay = Camera.computePickRay(trackLastMouseX, trackLastMouseY);
if (pasteMode) { // free voxel pasting if (pasteMode) { // free voxel pasting
Overlays.editOverlay(voxelPreview, { visible: false }); Overlays.editOverlay(voxelPreview, { visible: false });
Overlays.editOverlay(linePreviewLeft, { visible: false }); Overlays.editOverlay(linePreviewLeft, { visible: false });
var pasteVoxel = getNewPasteVoxel(pickRay); var pasteVoxel = getNewPasteVoxel(pickRay);
// X axis // X axis
Overlays.editOverlay(linePreviewBottom, { Overlays.editOverlay(linePreviewBottom, {
position: pasteVoxel.origin, position: pasteVoxel.origin,
end: {x: pasteVoxel.origin.x + pasteVoxel.voxelSize, y: pasteVoxel.origin.y, z: pasteVoxel.origin.z }, end: {x: pasteVoxel.origin.x + pasteVoxel.voxelSize, y: pasteVoxel.origin.y, z: pasteVoxel.origin.z },
visible: true visible: true
}); });
// Y axis // Y axis
Overlays.editOverlay(linePreviewRight, { Overlays.editOverlay(linePreviewRight, {
position: pasteVoxel.origin, position: pasteVoxel.origin,
end: {x: pasteVoxel.origin.x, y: pasteVoxel.origin.y + pasteVoxel.voxelSize, z: pasteVoxel.origin.z }, end: {x: pasteVoxel.origin.x, y: pasteVoxel.origin.y + pasteVoxel.voxelSize, z: pasteVoxel.origin.z },
visible: true visible: true
}); });
// Z axis // Z axis
Overlays.editOverlay(linePreviewTop, { Overlays.editOverlay(linePreviewTop, {
position: pasteVoxel.origin, position: pasteVoxel.origin,
end: {x: pasteVoxel.origin.x, y: pasteVoxel.origin.y, z: pasteVoxel.origin.z - pasteVoxel.voxelSize }, end: {x: pasteVoxel.origin.x, y: pasteVoxel.origin.y, z: pasteVoxel.origin.z - pasteVoxel.voxelSize },
visible: true visible: true
}); });
return; return;
} }
var intersection = Voxels.findRayIntersection(pickRay); var intersection = Voxels.findRayIntersection(pickRay);
if (intersection.intersects) { if (intersection.intersects) {
// if the user hasn't updated the // if the user hasn't updated the
if (!pointerVoxelScaleSet) { if (!pointerVoxelScaleSet) {
calcThumbFromScale(intersection.voxel.s); calcThumbFromScale(intersection.voxel.s);
} }
@ -699,14 +788,14 @@ function trackKeyReleaseEvent(event) {
trackAsOrbitOrPan = false; trackAsOrbitOrPan = false;
moveTools(); moveTools();
} }
// on F1 toggle the preview mode between cubes and lines // on F1 toggle the preview mode between cubes and lines
if (event.text == "F1") { if (event.text == "F1") {
previewAsVoxel = !previewAsVoxel; previewAsVoxel = !previewAsVoxel;
} }
showPreviewGuides(); showPreviewGuides();
} }
} }
function startOrbitMode(event) { function startOrbitMode(event) {
@ -715,7 +804,7 @@ function startOrbitMode(event) {
var pickRay = Camera.computePickRay(event.x, event.y); var pickRay = Camera.computePickRay(event.x, event.y);
var intersection = Voxels.findRayIntersection(pickRay); var intersection = Voxels.findRayIntersection(pickRay);
// start orbit camera! // start orbit camera!
var cameraPosition = Camera.getPosition(); var cameraPosition = Camera.getPosition();
torsoToEyeVector = Vec3.subtract(cameraPosition, MyAvatar.position); torsoToEyeVector = Vec3.subtract(cameraPosition, MyAvatar.position);
torsoToEyeVector.x = 0.0; torsoToEyeVector.x = 0.0;
@ -724,12 +813,12 @@ function startOrbitMode(event) {
Camera.setMode("independent"); Camera.setMode("independent");
Camera.keepLookingAt(intersection.intersection); Camera.keepLookingAt(intersection.intersection);
// get position for initial azimuth, elevation // get position for initial azimuth, elevation
orbitCenter = intersection.intersection; orbitCenter = intersection.intersection;
var orbitVector = Vec3.subtract(cameraPosition, orbitCenter); var orbitVector = Vec3.subtract(cameraPosition, orbitCenter);
orbitRadius = Vec3.length(orbitVector); orbitRadius = Vec3.length(orbitVector);
orbitAzimuth = Math.atan2(orbitVector.z, orbitVector.x); orbitAzimuth = Math.atan2(orbitVector.z, orbitVector.x);
orbitAltitude = Math.asin(orbitVector.y / Vec3.length(orbitVector)); orbitAltitude = Math.asin(orbitVector.y / Vec3.length(orbitVector));
//print("startOrbitMode..."); //print("startOrbitMode...");
} }
@ -737,17 +826,17 @@ function handleOrbitingMove(event) {
var cameraOrientation = Camera.getOrientation(); var cameraOrientation = Camera.getOrientation();
var origEulers = Quat.safeEulerAngles(cameraOrientation); var origEulers = Quat.safeEulerAngles(cameraOrientation);
var newEulers = fixEulerAngles(Quat.safeEulerAngles(cameraOrientation)); var newEulers = fixEulerAngles(Quat.safeEulerAngles(cameraOrientation));
var dx = event.x - mouseX; var dx = event.x - mouseX;
var dy = event.y - mouseY; var dy = event.y - mouseY;
orbitAzimuth += dx / ORBIT_RATE_AZIMUTH; orbitAzimuth += dx / ORBIT_RATE_AZIMUTH;
orbitAltitude += dy / ORBIT_RATE_ALTITUDE; orbitAltitude += dy / ORBIT_RATE_ALTITUDE;
var orbitVector = { x:(Math.cos(orbitAltitude) * Math.cos(orbitAzimuth)) * orbitRadius, var orbitVector = { x:(Math.cos(orbitAltitude) * Math.cos(orbitAzimuth)) * orbitRadius,
y:Math.sin(orbitAltitude) * orbitRadius, y:Math.sin(orbitAltitude) * orbitRadius,
z:(Math.cos(orbitAltitude) * Math.sin(orbitAzimuth)) * orbitRadius }; z:(Math.cos(orbitAltitude) * Math.sin(orbitAzimuth)) * orbitRadius };
orbitPosition = Vec3.sum(orbitCenter, orbitVector); orbitPosition = Vec3.sum(orbitCenter, orbitVector);
Camera.setPosition(orbitPosition); Camera.setPosition(orbitPosition);
mouseX = event.x; mouseX = event.x;
mouseY = event.y; mouseY = event.y;
//print("handleOrbitingMove..."); //print("handleOrbitingMove...");
} }
@ -763,7 +852,7 @@ function endOrbitMode(event) {
} }
function startPanMode(event, intersection) { function startPanMode(event, intersection) {
// start pan camera! // start pan camera!
print("handle PAN mode!!!"); print("handle PAN mode!!!");
} }
@ -781,14 +870,14 @@ function mousePressEvent(event) {
// if our tools are off, then don't do anything // if our tools are off, then don't do anything
if (!editToolsOn) { if (!editToolsOn) {
return; return;
} }
// Normally, if we're panning or orbiting from touch, ignore these... because our touch takes precedence. // Normally, if we're panning or orbiting from touch, ignore these... because our touch takes precedence.
// but In the case of a button="RIGHT" click, we may get some touch messages first, and we actually want to // but In the case of a button="RIGHT" click, we may get some touch messages first, and we actually want to
// cancel any touch mode, and then let the right-click through // cancel any touch mode, and then let the right-click through
if (isOrbitingFromTouch || isPanningFromTouch) { if (isOrbitingFromTouch || isPanningFromTouch) {
// if the user is holding the ALT key AND they are clicking the RIGHT button (or on multi-touch doing a two // if the user is holding the ALT key AND they are clicking the RIGHT button (or on multi-touch doing a two
// finger touch, then we want to let the new panning behavior take over. // finger touch, then we want to let the new panning behavior take over.
// if it's any other case we still want to bail // if it's any other case we still want to bail
@ -805,15 +894,15 @@ function mousePressEvent(event) {
} }
// let things fall through // let things fall through
} else { } else {
return; return;
} }
} }
// no clicking on overlays while in panning mode // no clicking on overlays while in panning mode
if (!trackAsOrbitOrPan) { if (!trackAsOrbitOrPan) {
var clickedOnSomething = false; var clickedOnSomething = false;
var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y});
// If the user clicked on the thumb, handle the slider logic // If the user clicked on the thumb, handle the slider logic
if (clickedOverlay == thumb) { if (clickedOverlay == thumb) {
@ -870,7 +959,7 @@ function mousePressEvent(event) {
return; // no further processing return; // no further processing
} }
} }
// TODO: does any of this stuff need to execute if we're panning or orbiting? // TODO: does any of this stuff need to execute if we're panning or orbiting?
trackMouseEvent(event); // used by preview support trackMouseEvent(event); // used by preview support
mouseX = event.x; mouseX = event.x;
@ -879,6 +968,15 @@ function mousePressEvent(event) {
var intersection = Voxels.findRayIntersection(pickRay); var intersection = Voxels.findRayIntersection(pickRay);
audioOptions.position = Vec3.sum(pickRay.origin, pickRay.direction); audioOptions.position = Vec3.sum(pickRay.origin, pickRay.direction);
if (isImporting) {
print("placing import...");
placeImport();
showImport(false);
pasteMode = false;
moveTools();
return;
}
if (pasteMode) { if (pasteMode) {
var pasteVoxel = getNewPasteVoxel(pickRay); var pasteVoxel = getNewPasteVoxel(pickRay);
Clipboard.pasteVoxel(pasteVoxel.origin.x, pasteVoxel.origin.y, pasteVoxel.origin.z, pasteVoxel.voxelSize); Clipboard.pasteVoxel(pasteVoxel.origin.x, pasteVoxel.origin.y, pasteVoxel.origin.z, pasteVoxel.voxelSize);
@ -888,11 +986,11 @@ function mousePressEvent(event) {
} }
if (intersection.intersects) { if (intersection.intersects) {
// if the user hasn't updated the // if the user hasn't updated the
if (!pointerVoxelScaleSet) { if (!pointerVoxelScaleSet) {
calcThumbFromScale(intersection.voxel.s); calcThumbFromScale(intersection.voxel.s);
} }
// Note: touch and mouse events can cross paths, so we want to ignore any mouse events that would // Note: touch and mouse events can cross paths, so we want to ignore any mouse events that would
// start a pan or orbit if we're already doing a pan or orbit via touch... // start a pan or orbit if we're already doing a pan or orbit via touch...
if ((event.isAlt || trackAsOrbitOrPan) && !(isOrbitingFromTouch || isPanningFromTouch)) { if ((event.isAlt || trackAsOrbitOrPan) && !(isOrbitingFromTouch || isPanningFromTouch)) {
@ -916,14 +1014,14 @@ function mousePressEvent(event) {
colors[whichColor].blue = intersection.voxel.blue; colors[whichColor].blue = intersection.voxel.blue;
moveTools(); moveTools();
} }
} else if (recolorToolSelected || trackAsRecolor) { } else if (recolorToolSelected || trackAsRecolor) {
// Recolor Voxel // Recolor Voxel
voxelDetails = calculateVoxelFromIntersection(intersection,"recolor"); voxelDetails = calculateVoxelFromIntersection(intersection,"recolor");
// doing this erase then set will make sure we only recolor just the target voxel // doing this erase then set will make sure we only recolor just the target voxel
Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s); Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s);
Voxels.setVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s, Voxels.setVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s,
colors[whichColor].red, colors[whichColor].green, colors[whichColor].blue); colors[whichColor].red, colors[whichColor].green, colors[whichColor].blue);
Audio.playSound(changeColorSound, audioOptions); Audio.playSound(changeColorSound, audioOptions);
Overlays.editOverlay(voxelPreview, { visible: false }); Overlays.editOverlay(voxelPreview, { visible: false });
@ -931,17 +1029,17 @@ function mousePressEvent(event) {
// Add voxel on face // Add voxel on face
if (whichColor == -1) { if (whichColor == -1) {
// Copy mode - use clicked voxel color // Copy mode - use clicked voxel color
newColor = { newColor = {
red: intersection.voxel.red, red: intersection.voxel.red,
green: intersection.voxel.green, green: intersection.voxel.green,
blue: intersection.voxel.blue }; blue: intersection.voxel.blue };
} else { } else {
newColor = { newColor = {
red: colors[whichColor].red, red: colors[whichColor].red,
green: colors[whichColor].green, green: colors[whichColor].green,
blue: colors[whichColor].blue }; blue: colors[whichColor].blue };
} }
voxelDetails = calculateVoxelFromIntersection(intersection,"add"); voxelDetails = calculateVoxelFromIntersection(intersection,"add");
Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s); Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s);
Voxels.setVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s, Voxels.setVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s,
@ -951,11 +1049,11 @@ function mousePressEvent(event) {
lastVoxelScale = voxelDetails.s; lastVoxelScale = voxelDetails.s;
playRandomAddSound(audioOptions); playRandomAddSound(audioOptions);
Overlays.editOverlay(voxelPreview, { visible: false }); Overlays.editOverlay(voxelPreview, { visible: false });
dragStart = { x: event.x, y: event.y }; dragStart = { x: event.x, y: event.y };
isAdding = true; isAdding = true;
} }
} }
} }
@ -974,14 +1072,14 @@ function keyPressEvent(event) {
Audio.playSound(clickSound, audioOptions); Audio.playSound(clickSound, audioOptions);
moveTools(); moveTools();
} else if (event.text == "0") { } else if (event.text == "0") {
// Create a brand new 1 meter voxel in front of your avatar // Create a brand new 1 meter voxel in front of your avatar
var color = whichColor; var color = whichColor;
if (color == -1) color = 0; if (color == -1) color = 0;
var newPosition = getNewVoxelPosition(); var newPosition = getNewVoxelPosition();
var newVoxel = { var newVoxel = {
x: newPosition.x, x: newPosition.x,
y: newPosition.y , y: newPosition.y ,
z: newPosition.z, z: newPosition.z,
s: NEW_VOXEL_SIZE, s: NEW_VOXEL_SIZE,
red: colors[color].red, red: colors[color].red,
green: colors[color].green, green: colors[color].green,
@ -992,7 +1090,7 @@ function keyPressEvent(event) {
playRandomAddSound(audioOptions); playRandomAddSound(audioOptions);
} }
} }
trackKeyPressEvent(event); // used by preview support trackKeyPressEvent(event); // used by preview support
} }
@ -1051,24 +1149,36 @@ function menuItemEvent(menuItem) {
moveTools(); moveTools();
} }
if (menuItem == "Paste") { if (menuItem == "Paste") {
print("pasting..."); if (isImporting) {
Clipboard.pasteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s); print("placing import...");
placeImport();
showImport(false);
} else {
print("pasting...");
Clipboard.pasteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
pasteMode = false; pasteMode = false;
moveTools(); moveTools();
} }
if (menuItem == "Delete") { if (menuItem == "Delete") {
print("deleting..."); print("deleting...");
Clipboard.deleteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s); if (isImporting) {
cancelImport();
} else {
Clipboard.deleteVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
}
} }
if (menuItem == "Export Voxels") { if (menuItem == "Export Voxels") {
print("export"); print("export");
Clipboard.exportVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s); Clipboard.exportVoxel(selectedVoxel.x, selectedVoxel.y, selectedVoxel.z, selectedVoxel.s);
} }
if (menuItem == "Import Voxels") { if (menuItem == "Import Voxels") {
print("import"); print("importing...");
Clipboard.importVoxels(); if (importVoxels()) {
pasteMode = true; showImport(true);
pasteMode = true;
}
moveTools(); moveTools();
} }
if (menuItem == "Nudge") { if (menuItem == "Nudge") {
@ -1083,11 +1193,11 @@ function mouseMoveEvent(event) {
return; return;
} }
// if we're panning or orbiting from touch, ignore these... because our touch takes precedence. // if we're panning or orbiting from touch, ignore these... because our touch takes precedence.
if (isOrbitingFromTouch || isPanningFromTouch) { if (isOrbitingFromTouch || isPanningFromTouch) {
return; return;
} }
// double check that we didn't accidentally miss a pan or orbit click request // double check that we didn't accidentally miss a pan or orbit click request
if (trackAsOrbitOrPan && !isPanning && !isOrbiting) { if (trackAsOrbitOrPan && !isPanning && !isOrbiting) {
if (event.isLeftButton && !event.isRightButton) { if (event.isLeftButton && !event.isRightButton) {
@ -1109,7 +1219,7 @@ function mouseMoveEvent(event) {
thumbX = maxThumbX; thumbX = maxThumbX;
} }
calcScaleFromThumb(thumbX); calcScaleFromThumb(thumbX);
} else if (isOrbiting) { } else if (isOrbiting) {
handleOrbitingMove(event); handleOrbitingMove(event);
} else if (isPanning) { } else if (isPanning) {
@ -1118,8 +1228,8 @@ function mouseMoveEvent(event) {
// Watch the drag direction to tell which way to 'extrude' this voxel // Watch the drag direction to tell which way to 'extrude' this voxel
if (!isExtruding) { if (!isExtruding) {
var pickRay = Camera.computePickRay(event.x, event.y); var pickRay = Camera.computePickRay(event.x, event.y);
var lastVoxelDistance = { x: pickRay.origin.x - lastVoxelPosition.x, var lastVoxelDistance = { x: pickRay.origin.x - lastVoxelPosition.x,
y: pickRay.origin.y - lastVoxelPosition.y, y: pickRay.origin.y - lastVoxelPosition.y,
z: pickRay.origin.z - lastVoxelPosition.z }; z: pickRay.origin.z - lastVoxelPosition.z };
var distance = Vec3.length(lastVoxelDistance); var distance = Vec3.length(lastVoxelDistance);
var mouseSpot = { x: pickRay.direction.x * distance, y: pickRay.direction.y * distance, z: pickRay.direction.z * distance }; var mouseSpot = { x: pickRay.direction.x * distance, y: pickRay.direction.y * distance, z: pickRay.direction.z * distance };
@ -1138,22 +1248,22 @@ function mouseMoveEvent(event) {
else if (dy < -lastVoxelScale) extrudeDirection.y = -extrudeScale; else if (dy < -lastVoxelScale) extrudeDirection.y = -extrudeScale;
else if (dz > lastVoxelScale) extrudeDirection.z = extrudeScale; else if (dz > lastVoxelScale) extrudeDirection.z = extrudeScale;
else if (dz < -lastVoxelScale) extrudeDirection.z = -extrudeScale; else if (dz < -lastVoxelScale) extrudeDirection.z = -extrudeScale;
else isExtruding = false; else isExtruding = false;
} else { } else {
// We have got an extrusion direction, now look for mouse move beyond threshold to add new voxel // We have got an extrusion direction, now look for mouse move beyond threshold to add new voxel
var dx = event.x - mouseX; var dx = event.x - mouseX;
var dy = event.y - mouseY; var dy = event.y - mouseY;
if (Math.sqrt(dx*dx + dy*dy) > PIXELS_PER_EXTRUDE_VOXEL) { if (Math.sqrt(dx*dx + dy*dy) > PIXELS_PER_EXTRUDE_VOXEL) {
lastVoxelPosition = Vec3.sum(lastVoxelPosition, extrudeDirection); lastVoxelPosition = Vec3.sum(lastVoxelPosition, extrudeDirection);
Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s); Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s);
Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z, Voxels.setVoxel(lastVoxelPosition.x, lastVoxelPosition.y, lastVoxelPosition.z,
extrudeScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue); extrudeScale, lastVoxelColor.red, lastVoxelColor.green, lastVoxelColor.blue);
mouseX = event.x; mouseX = event.x;
mouseY = event.y; mouseY = event.y;
} }
} }
} }
// update the add voxel/delete voxel overlay preview // update the add voxel/delete voxel overlay preview
trackMouseEvent(event); trackMouseEvent(event);
} }
@ -1161,13 +1271,13 @@ function mouseMoveEvent(event) {
function mouseReleaseEvent(event) { function mouseReleaseEvent(event) {
// if our tools are off, then don't do anything // if our tools are off, then don't do anything
if (!editToolsOn) { if (!editToolsOn) {
return; return;
} }
if (isMovingSlider) { if (isMovingSlider) {
isMovingSlider = false; isMovingSlider = false;
} }
if (isOrbiting) { if (isOrbiting) {
endOrbitMode(event); endOrbitMode(event);
isOrbiting = false; isOrbiting = false;
@ -1178,7 +1288,7 @@ function mouseReleaseEvent(event) {
isPanning = false; isPanning = false;
} }
isAdding = false; isAdding = false;
isExtruding = false; isExtruding = false;
} }
function moveTools() { function moveTools() {
@ -1206,7 +1316,7 @@ function moveTools() {
if (s == (numColors - 1)) { if (s == (numColors - 1)) {
extraWidth = swatchExtraPadding; extraWidth = swatchExtraPadding;
} }
Overlays.editOverlay(swatches[s], { Overlays.editOverlay(swatches[s], {
x: swatchX, x: swatchX,
y: swatchesY, y: swatchesY,
@ -1270,16 +1380,16 @@ function touchBeginEvent(event) {
if (!editToolsOn) { if (!editToolsOn) {
return; return;
} }
// if we're already in the middle of orbiting or panning, then ignore these multi-touch events... // if we're already in the middle of orbiting or panning, then ignore these multi-touch events...
if (isOrbiting || isPanning) { if (isOrbiting || isPanning) {
return; return;
} }
if (event.isAlt || trackAsOrbitOrPan) { if (event.isAlt || trackAsOrbitOrPan) {
if (event.touchPoints == touchPointsToOrbit) { if (event.touchPoints == touchPointsToOrbit) {
// we need to double check that we didn't start an orbit, because the touch events will sometimes // we need to double check that we didn't start an orbit, because the touch events will sometimes
// come in as 2 then 3 touches... // come in as 2 then 3 touches...
if (isPanningFromTouch) { if (isPanningFromTouch) {
print("touchBeginEvent... calling endPanMode()"); print("touchBeginEvent... calling endPanMode()");
endPanMode(event); endPanMode(event);
@ -1289,7 +1399,7 @@ function touchBeginEvent(event) {
isOrbitingFromTouch = true; isOrbitingFromTouch = true;
} else if (event.touchPoints == touchPointsToPan) { } else if (event.touchPoints == touchPointsToPan) {
// we need to double check that we didn't start an orbit, because the touch events will sometimes // we need to double check that we didn't start an orbit, because the touch events will sometimes
// come in as 2 then 3 touches... // come in as 2 then 3 touches...
if (isOrbitingFromTouch) { if (isOrbitingFromTouch) {
endOrbitMode(event); endOrbitMode(event);
isOrbitingFromTouch = false; isOrbitingFromTouch = false;
@ -1308,11 +1418,11 @@ function touchUpdateEvent(event) {
// if we're already in the middle of orbiting or panning, then ignore these multi-touch events... // if we're already in the middle of orbiting or panning, then ignore these multi-touch events...
if (isOrbiting || isPanning) { if (isOrbiting || isPanning) {
return; return;
} }
if (isOrbitingFromTouch) { if (isOrbitingFromTouch) {
// we need to double check that we didn't start an orbit, because the touch events will sometimes // we need to double check that we didn't start an orbit, because the touch events will sometimes
// come in as 2 then 3 touches... // come in as 2 then 3 touches...
if (event.touchPoints == touchPointsToPan) { if (event.touchPoints == touchPointsToPan) {
//print("we now have touchPointsToPan touches... switch to pan..."); //print("we now have touchPointsToPan touches... switch to pan...");
endOrbitMode(event); endOrbitMode(event);
@ -1326,7 +1436,7 @@ function touchUpdateEvent(event) {
if (isPanningFromTouch) { if (isPanningFromTouch) {
//print("touchUpdateEvent... isPanningFromTouch... event.touchPoints=" + event.touchPoints); //print("touchUpdateEvent... isPanningFromTouch... event.touchPoints=" + event.touchPoints);
// we need to double check that we didn't start an orbit, because the touch events will sometimes // we need to double check that we didn't start an orbit, because the touch events will sometimes
// come in as 2 then 3 touches... // come in as 2 then 3 touches...
if (event.touchPoints == touchPointsToOrbit) { if (event.touchPoints == touchPointsToOrbit) {
//print("we now have touchPointsToOrbit touches... switch to orbit..."); //print("we now have touchPointsToOrbit touches... switch to orbit...");
//print("touchUpdateEvent... calling endPanMode()"); //print("touchUpdateEvent... calling endPanMode()");
@ -1349,8 +1459,8 @@ function touchEndEvent(event) {
// if we're already in the middle of orbiting or panning, then ignore these multi-touch events... // if we're already in the middle of orbiting or panning, then ignore these multi-touch events...
if (isOrbiting || isPanning) { if (isOrbiting || isPanning) {
return; return;
} }
if (isOrbitingFromTouch) { if (isOrbitingFromTouch) {
endOrbitMode(event); endOrbitMode(event);
isOrbitingFromTouch = false; isOrbitingFromTouch = false;
@ -1368,10 +1478,10 @@ var lastFingerDeleteVoxel = { x: -1, y: -1, z: -1}; // off of the build-able are
function checkControllers() { function checkControllers() {
var controllersPerPalm = 2; // palm and finger var controllersPerPalm = 2; // palm and finger
for (var palm = 0; palm < 2; palm++) { for (var palm = 0; palm < 2; palm++) {
var palmController = palm * controllersPerPalm; var palmController = palm * controllersPerPalm;
var fingerTipController = palmController + 1; var fingerTipController = palmController + 1;
var fingerTipPosition = Controller.getSpatialControlPosition(fingerTipController); var fingerTipPosition = Controller.getSpatialControlPosition(fingerTipController);
var BUTTON_COUNT = 6; var BUTTON_COUNT = 6;
var BUTTON_BASE = palm * BUTTON_COUNT; var BUTTON_BASE = palm * BUTTON_COUNT;
var BUTTON_1 = BUTTON_BASE + 1; var BUTTON_1 = BUTTON_BASE + 1;
@ -1389,7 +1499,7 @@ function checkControllers() {
Voxels.eraseVoxel(fingerTipPosition.x, fingerTipPosition.y, fingerTipPosition.z, FINGERTIP_VOXEL_SIZE); Voxels.eraseVoxel(fingerTipPosition.x, fingerTipPosition.y, fingerTipPosition.z, FINGERTIP_VOXEL_SIZE);
Voxels.setVoxel(fingerTipPosition.x, fingerTipPosition.y, fingerTipPosition.z, FINGERTIP_VOXEL_SIZE, Voxels.setVoxel(fingerTipPosition.x, fingerTipPosition.y, fingerTipPosition.z, FINGERTIP_VOXEL_SIZE,
newColor.red, newColor.green, newColor.blue); newColor.red, newColor.green, newColor.blue);
lastFingerAddVoxel = fingerTipPosition; lastFingerAddVoxel = fingerTipPosition;
} }
} else if (Controller.isButtonPressed(BUTTON_2)) { } else if (Controller.isButtonPressed(BUTTON_2)) {
@ -1407,7 +1517,7 @@ function update(deltaTime) {
windowDimensions = newWindowDimensions; windowDimensions = newWindowDimensions;
moveTools(); moveTools();
} }
if (editToolsOn) { if (editToolsOn) {
checkControllers(); checkControllers();
} }
@ -1425,7 +1535,7 @@ function wheelEvent(event) {
pointerVoxelScale /= 2.0; pointerVoxelScale /= 2.0;
if (pointerVoxelScale < MIN_VOXEL_SCALE) { if (pointerVoxelScale < MIN_VOXEL_SCALE) {
pointerVoxelScale = MIN_VOXEL_SCALE; pointerVoxelScale = MIN_VOXEL_SCALE;
} }
} else { } else {
pointerVoxelScale *= 2.0; pointerVoxelScale *= 2.0;
if (pointerVoxelScale > MAX_VOXEL_SCALE) { if (pointerVoxelScale > MAX_VOXEL_SCALE) {
@ -1435,6 +1545,11 @@ function wheelEvent(event) {
calcThumbFromScale(pointerVoxelScale); calcThumbFromScale(pointerVoxelScale);
trackMouseEvent(event); trackMouseEvent(event);
wheelPixelsMoved = 0; wheelPixelsMoved = 0;
if (isImporting) {
var importScale = (pointerVoxelScale / MAX_VOXEL_SCALE) * MAX_PASTE_VOXEL_SCALE;
rescaleImport(importScale);
}
} }
} }
@ -1467,6 +1582,7 @@ function scriptEnding() {
Overlays.deleteOverlay(thumb); Overlays.deleteOverlay(thumb);
Controller.releaseKeyEvents({ text: "+" }); Controller.releaseKeyEvents({ text: "+" });
Controller.releaseKeyEvents({ text: "-" }); Controller.releaseKeyEvents({ text: "-" });
cleanupImport();
cleanupMenus(); cleanupMenus();
} }
Script.scriptEnding.connect(scriptEnding); Script.scriptEnding.connect(scriptEnding);

View file

@ -140,9 +140,9 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_fps(120.0f), _fps(120.0f),
_justStarted(true), _justStarted(true),
_voxelImporter(NULL), _voxelImporter(NULL),
_sharedVoxelSystem(TREE_SCALE, DEFAULT_MAX_VOXELS_PER_SYSTEM, &_clipboard),
_wantToKillLocalVoxels(false), _wantToKillLocalVoxels(false),
_audioScope(256, 200, true), _audioScope(256, 200, true),
_myAvatar(),
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)), _mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
_mouseX(0), _mouseX(0),
_mouseY(0), _mouseY(0),
@ -1387,6 +1387,8 @@ void Application::exportVoxels(const VoxelDetail& sourceVoxel) {
} }
void Application::importVoxels() { void Application::importVoxels() {
int result = 1;
if (!_voxelImporter) { if (!_voxelImporter) {
_voxelImporter = new VoxelImporter(_window); _voxelImporter = new VoxelImporter(_window);
_voxelImporter->loadSettings(_settings); _voxelImporter->loadSettings(_settings);
@ -1394,6 +1396,7 @@ void Application::importVoxels() {
if (!_voxelImporter->exec()) { if (!_voxelImporter->exec()) {
qDebug() << "[DEBUG] Import succeeded." << endl; qDebug() << "[DEBUG] Import succeeded." << endl;
result = 0;
} else { } else {
qDebug() << "[DEBUG] Import failed." << endl; qDebug() << "[DEBUG] Import failed." << endl;
if (_sharedVoxelSystem.getTree() == _voxelImporter->getVoxelTree()) { if (_sharedVoxelSystem.getTree() == _voxelImporter->getVoxelTree()) {
@ -1404,6 +1407,8 @@ void Application::importVoxels() {
// restore the main window's active state // restore the main window's active state
_window->activateWindow(); _window->activateWindow();
emit importDone(result);
} }
void Application::cutVoxels(const VoxelDetail& sourceVoxel) { void Application::cutVoxels(const VoxelDetail& sourceVoxel) {
@ -1495,10 +1500,9 @@ void Application::init() {
// Cleanup of the original shared tree // Cleanup of the original shared tree
_sharedVoxelSystem.init(); _sharedVoxelSystem.init();
VoxelTree* tmpTree = _sharedVoxelSystem.getTree();
_sharedVoxelSystem.changeTree(&_clipboard); _voxelImporter = new VoxelImporter(_window);
delete tmpTree;
_environment.init(); _environment.init();
_glowEffect.init(); _glowEffect.init();

View file

@ -225,6 +225,9 @@ signals:
/// Fired when we're rendering in-world interface elements; allows external parties to hook in. /// Fired when we're rendering in-world interface elements; allows external parties to hook in.
void renderingInWorldInterface(); void renderingInWorldInterface();
/// Fired when the import window is closed with a return code.
void importDone(int);
public slots: public slots:
void domainChanged(const QString& domainHostname); void domainChanged(const QString& domainHostname);
void updateWindowTitle(); void updateWindowTitle();
@ -351,13 +354,13 @@ private:
glm::vec3 _gravity; glm::vec3 _gravity;
// Frame Rate Measurement // Frame Rate Measurement
int _frameCount; int _frameCount;
float _fps; float _fps;
timeval _applicationStartupTime; timeval _applicationStartupTime;
timeval _timerStart, _timerEnd; timeval _timerStart, _timerEnd;
timeval _lastTimeUpdated; timeval _lastTimeUpdated;
bool _justStarted; bool _justStarted;
Stars _stars; Stars _stars;
BuckyBalls _buckyBalls; BuckyBalls _buckyBalls;

View file

@ -9,6 +9,7 @@
#include "ClipboardScriptingInterface.h" #include "ClipboardScriptingInterface.h"
ClipboardScriptingInterface::ClipboardScriptingInterface() { ClipboardScriptingInterface::ClipboardScriptingInterface() {
connect(this, SIGNAL(readyToImport()), Application::getInstance(), SLOT(importVoxels()));
} }
void ClipboardScriptingInterface::cutVoxel(const VoxelDetail& sourceVoxel) { void ClipboardScriptingInterface::cutVoxel(const VoxelDetail& sourceVoxel) {
@ -70,12 +71,17 @@ void ClipboardScriptingInterface::exportVoxel(float x, float y, float z, float s
z / (float)TREE_SCALE, z / (float)TREE_SCALE,
s / (float)TREE_SCALE }; s / (float)TREE_SCALE };
QMetaObject::invokeMethod(Application::getInstance(), "exportVoxels", Application::getInstance()->exportVoxels(sourceVoxel);
Q_ARG(const VoxelDetail&, sourceVoxel));
} }
void ClipboardScriptingInterface::importVoxels() { bool ClipboardScriptingInterface::importVoxels() {
QMetaObject::invokeMethod(Application::getInstance(), "importVoxels"); qDebug() << "[DEBUG] Importing ... ";
QEventLoop loop;
connect(Application::getInstance(), SIGNAL(importDone(int)), &loop, SLOT(quit()));
emit readyToImport();
int returnCode = loop.exec();
return returnCode;
} }
void ClipboardScriptingInterface::nudgeVoxel(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec) { void ClipboardScriptingInterface::nudgeVoxel(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec) {

View file

@ -18,6 +18,9 @@ class ClipboardScriptingInterface : public QObject {
public: public:
ClipboardScriptingInterface(); ClipboardScriptingInterface();
signals:
void readyToImport();
public slots: public slots:
void cutVoxel(const VoxelDetail& sourceVoxel); void cutVoxel(const VoxelDetail& sourceVoxel);
void cutVoxel(float x, float y, float z, float s); void cutVoxel(float x, float y, float z, float s);
@ -34,7 +37,7 @@ public slots:
void exportVoxel(const VoxelDetail& sourceVoxel); void exportVoxel(const VoxelDetail& sourceVoxel);
void exportVoxel(float x, float y, float z, float s); void exportVoxel(float x, float y, float z, float s);
void importVoxels(); bool importVoxels();
void nudgeVoxel(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec); void nudgeVoxel(const VoxelDetail& sourceVoxel, const glm::vec3& nudgeVec);
void nudgeVoxel(float x, float y, float z, float s, const glm::vec3& nudgeVec); void nudgeVoxel(float x, float y, float z, float s, const glm::vec3& nudgeVec);

View file

@ -1177,8 +1177,6 @@ void VoxelSystem::init() {
} }
void VoxelSystem::changeTree(VoxelTree* newTree) { void VoxelSystem::changeTree(VoxelTree* newTree) {
disconnect(_tree, 0, this, 0);
_tree = newTree; _tree = newTree;
_tree->setDirtyBit(); _tree->setDirtyBit();

View file

@ -40,9 +40,11 @@ void LocalVoxelsOverlay::update(float deltatime) {
_voxelSystem->init(); _voxelSystem->init();
} }
if (_voxelCount != _tree->getOctreeElementsCount()) { if (_visible && _voxelCount != _tree->getOctreeElementsCount()) {
_voxelCount = _tree->getOctreeElementsCount(); _voxelCount = _tree->getOctreeElementsCount();
_tree->lockForWrite();
_voxelSystem->forceRedrawEntireTree(); _voxelSystem->forceRedrawEntireTree();
_tree->unlock();
} }
} }

View file

@ -31,6 +31,9 @@ void Volume3DOverlay::setProperties(const QScriptValue& properties) {
if (properties.property("size").isValid()) { if (properties.property("size").isValid()) {
setSize(properties.property("size").toVariant().toFloat()); setSize(properties.property("size").toVariant().toFloat());
} }
if (properties.property("scale").isValid()) {
setSize(properties.property("scale").toVariant().toFloat());
}
if (properties.property("isSolid").isValid()) { if (properties.property("isSolid").isValid()) {
setIsSolid(properties.property("isSolid").toVariant().toBool()); setIsSolid(properties.property("isSolid").toVariant().toBool());