From cd78be7d2500a2a4a00bd19f1c147302969aab50 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 8 May 2014 16:47:18 -0700 Subject: [PATCH 1/7] Some work on mouse tools for editModels.js --- examples/editModels.js | 34 +++++++++++++++++++++++++++++++++- examples/testScript.js | 0 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 examples/testScript.js diff --git a/examples/editModels.js b/examples/editModels.js index ecf398edfa..737b6a85a5 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -33,6 +33,7 @@ var modelURLs = [ "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/slimer.fbx", ]; +var tools = []; var toolIconUrl = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/"; var numberOfTools = 1; var toolHeight = 50; @@ -44,13 +45,44 @@ var toolsY = (windowDimensions.y - toolsHeight) / 2; var firstModel = Overlays.addOverlay("image", { - x: 0, y: 0, width: toolWidth, height: toolHeight, subImage: { x: 0, y: toolHeight, width: toolWidth, height: toolHeight }, imageURL: toolIconUrl + "voxel-tool.svg", x: toolsX, y: toolsY + ((toolHeight + toolVerticalSpacing) * 0), width: toolWidth, height: toolHeight, visible: true, alpha: 0.9 }); +function Tool(iconURL) { + this.overlay = Overlays.addOverlay("image", { + subImage: { x: 0, y: toolHeight, width: toolWidth, height: toolHeight }, + imageURL: iconURL, + x: toolsX, + y: toolsY + ((toolHeight + toolVerticalSpacing) * tools.length), + width: toolWidth, + height: toolHeight, + visible: true, + alpha: 0.9 + }); + + + this.cleanup = function() { + Ovelays.deleteOverlay(this.overlay); + } + tools[tools.length] = this; + return tools.length - 1; +} +Tool.ICON_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/"; +Tool.HEIGHT = 50; +Tool.WIDTH = 50; + +function ToolBar(direction, x, y) { + this.tools = []; + + this.numberOfTools = function() { + return this.tools.length; + } +} +ToolBar.SPACING = 4; + function controller(wichSide) { this.side = wichSide; diff --git a/examples/testScript.js b/examples/testScript.js new file mode 100644 index 0000000000..e69de29bb2 From 37700c6ad3a331aac0bd3b8b4c2896512ba0b3e7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 12 May 2014 17:10:19 -0700 Subject: [PATCH 2/7] Fixed prompt size --- examples/editModels.js | 167 ++++++++------- examples/testScript.js | 0 examples/toolBars.js | 200 ++++++++++++++++++ .../scripting/WindowScriptingInterface.cpp | 1 + 4 files changed, 291 insertions(+), 77 deletions(-) delete mode 100644 examples/testScript.js create mode 100644 examples/toolBars.js diff --git a/examples/editModels.js b/examples/editModels.js index 9acbff4aa6..90ce87d259 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -9,7 +9,12 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("toolBars.js"); + var windowDimensions = Controller.getViewportDimensions(); +var toolIconUrl = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/"; +var toolHeight = 50; +var toolWidth = 50; var LASER_WIDTH = 4; var LASER_COLOR = { red: 255, green: 0, blue: 0 }; @@ -33,56 +38,7 @@ var modelURLs = [ "http://highfidelity-public.s3-us-west-1.amazonaws.com/meshes/slimer.fbx", ]; -var tools = []; -var toolIconUrl = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/"; -var numberOfTools = 1; -var toolHeight = 50; -var toolWidth = 50; -var toolVerticalSpacing = 4; -var toolsHeight = toolHeight * numberOfTools + toolVerticalSpacing * (numberOfTools - 1); -var toolsX = windowDimensions.x - 8 - toolWidth; -var toolsY = (windowDimensions.y - toolsHeight) / 2; - - -var firstModel = Overlays.addOverlay("image", { - subImage: { x: 0, y: toolHeight, width: toolWidth, height: toolHeight }, - imageURL: toolIconUrl + "voxel-tool.svg", - x: toolsX, y: toolsY + ((toolHeight + toolVerticalSpacing) * 0), width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }); -function Tool(iconURL) { - this.overlay = Overlays.addOverlay("image", { - subImage: { x: 0, y: toolHeight, width: toolWidth, height: toolHeight }, - imageURL: iconURL, - x: toolsX, - y: toolsY + ((toolHeight + toolVerticalSpacing) * tools.length), - width: toolWidth, - height: toolHeight, - visible: true, - alpha: 0.9 - }); - - - this.cleanup = function() { - Ovelays.deleteOverlay(this.overlay); - } - tools[tools.length] = this; - return tools.length - 1; -} -Tool.ICON_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/tools/"; -Tool.HEIGHT = 50; -Tool.WIDTH = 50; - -function ToolBar(direction, x, y) { - this.tools = []; - - this.numberOfTools = function() { - return this.tools.length; - } -} -ToolBar.SPACING = 4; - +var toolBar; function controller(wichSide) { this.side = wichSide; @@ -238,6 +194,13 @@ function controller(wichSide) { }); } + this.hideLaser = function() { + Overlays.editOverlay(this.laser, { visible: false }); + Overlays.editOverlay(this.ball, { visible: false }); + Overlays.editOverlay(this.leftRight, { visible: false }); + Overlays.editOverlay(this.topDown, { visible: false }); + } + this.moveModel = function () { if (this.grabbing) { var newPosition = Vec3.sum(this.palmPosition, @@ -377,67 +340,117 @@ function moveModels() { rightController.moveModel(); } +var hydraConnected = false; function checkController(deltaTime) { var numberOfButtons = Controller.getNumberOfButtons(); var numberOfTriggers = Controller.getNumberOfTriggers(); var numberOfSpatialControls = Controller.getNumberOfSpatialControls(); var controllersPerTrigger = numberOfSpatialControls / numberOfTriggers; - - moveOverlays(); // this is expected for hydras - if (!(numberOfButtons==12 && numberOfTriggers == 2 && controllersPerTrigger == 2)) { - //print("no hydra connected?"); - return; // bail if no hydra + if (numberOfButtons==12 && numberOfTriggers == 2 && controllersPerTrigger == 2) { + if (!hydraConnected) { + hydraConnected = true; + } + + leftController.update(); + rightController.update(); + moveModels(); + } else { + if (hydraConnected) { + hydraConnected = false; + + leftController.hideLaser(); + rightController.hideLaser(); + } } - leftController.update(); - rightController.update(); - moveModels(); + moveOverlays(); } function moveOverlays() { - windowDimensions = Controller.getViewportDimensions(); - - toolsX = windowDimensions.x - 8 - toolWidth; - toolsY = (windowDimensions.y - toolsHeight) / 2; - - Overlays.editOverlay(firstModel, { - x: toolsX, y: toolsY + ((toolHeight + toolVerticalSpacing) * 0), width: toolWidth, height: toolHeight, + if (typeof(toolBar) === 'undefined') { + toolBar = new ToolBar(0, 0, ToolBar.VERTICAL); + // New Model + toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 }); + // Move YZ + toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 + }, true); + // Move XZ + toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 + }, true); + // Move XY + toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 + }, true); + } else if (windowDimensions.x == Controller.getViewportDimensions().x && + windowDimensions.y == Controller.getViewportDimensions().y) { + return; + } + + + windowDimensions = Controller.getViewportDimensions(); + var toolsX = windowDimensions.x - 8 - toolBar.width; + var toolsY = (windowDimensions.y - toolBar.height) / 2; + + toolBar.move(toolsX, toolsY); } function mousePressEvent(event) { var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); var url; - - if (clickedOverlay == firstModel) { + var index = toolBar.clicked(clickedOverlay); + if (index == 0) { url = Window.prompt("Model url", modelURLs[Math.floor(Math.random() * modelURLs.length)]); if (url == null) { - return; } - } else { + return; + } + + var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); + Models.addModel({ position: position, + radius: radiusDefault, + modelURL: url + }); + } else if (index == -1) { print("Didn't click on anything"); - return; } +} + +function mouseMoveEvent(event) { - var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); - Models.addModel({ position: position, - radius: radiusDefault, - modelURL: url - }); } function scriptEnding() { leftController.cleanup(); rightController.cleanup(); - - Overlays.deleteOverlay(firstModel); + toolBar.cleanup(); } Script.scriptEnding.connect(scriptEnding); // register the call back so it fires before each data send Script.update.connect(checkController); Controller.mousePressEvent.connect(mousePressEvent); +Controller.mousePressEvent.connect(mouseMoveEvent); diff --git a/examples/testScript.js b/examples/testScript.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/toolBars.js b/examples/toolBars.js new file mode 100644 index 0000000000..62a01a9a15 --- /dev/null +++ b/examples/toolBars.js @@ -0,0 +1,200 @@ +// +// testScript.js +// examples +// +// Created by Clément Brisset on 5/7/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +Overlay2D = function(properties, overlay) { // overlay is an optionnal variable + if (!(typeof(properties) === 'undefined')) { + if(typeof(overlay) === 'undefined') { + overlay = Overlays.addOverlay("image", properties); + print("New overlay: " + overlay); + } else { + Overlays.editOverlay(overlay, properties); + } + } + + this.overlay = function() { + return overlay; + } + this.x = function() { + return properties.x; + } + this.y = function() { + return properties.y; + } + this.width = function() { + return properties.width; + } + this.height = function() { + return properties.height; + } + this.alpha = function() { + return properties.alpha; + } + this.visible = function() { + return properties.visible; + } + + + this.move = function(x, y) { + properties.x = x; + properties.y = y; + Overlays.editOverlay(overlay, { x: x, y: y }); + } + this.resize = function(width, height) { + properties.width = width; + properties.height = height; + Overlays.editOverlay(overlay, { width: width, height: height }); + } + this.setAlpha = function(alpha) { + properties.alpha = alpha; + Overlays.editOverlay(overlay, { alpha: alpha }); + } + this.show = function(doShow) { + properties.visible = doShow; + Overlays.editOverlay(overlay, { visible: doShow }); + } + + this.clicked = function(clickedOverlay) { + return (overlay == clickedOverlay ? true : false); + } + + this.cleanup = function() { + print("Cleanup"); + Overlays.deleteOverlay(overlay); + } +} + + +Tool = function(properties, selectable, selected) { // selectable and selected are optional variables. + Overlay2D.call(this, properties); + + if(typeof(selectable)==='undefined') { + selectable = false; + if(typeof(selected)==='undefined') { + selected = false; + + } + } + + this.selectable = function() { + return selectable; + } + + if (this.selectable()) { + this.selected = function() { + return selected; + } + this.select = function(doSelect) { + selected = doSelect; + properties.subImage.y = (selected ? 2 : 1) * properties.subImage.height; + Overlays.editOverlay(this.overlay(), { subImage: properties.subImage }); + } + this.toggle = function() { + selected = !selected; + properties.subImage.y = (selected ? 2 : 1) * properties.subImage.height; + Overlays.editOverlay(this.overlay(), { subImage: properties.subImage }); + + return selected; + } + + this.select(selected); + } + + this.baseClicked = this.clicked; + this.clicked = function(clickedOverlay) { + if (this.baseClicked(clickedOverlay)) { + if (selectable) { + this.toggle(); + } + return true; + } + return false; + } +} +Tool.prototype = new Overlay2D; +Tool.IMAGE_HEIGHT = 50; +Tool.IMAGE_WIDTH = 50; + +ToolBar = function(x, y, direction) { + this.tools = []; + this.x = x; + this.y = y; + this.width = 0; + this.height = 0; + + + this.addTool = function(properties, selectable, selected) { + if (direction == ToolBar.HORIZONTAL) { + properties.x = this.x + this.width; + properties.y = this.y; + this.width += properties.width + ToolBar.SPACING; + this.height += Math.max(properties.height, this.height); + } else { + properties.x = this.x; + properties.y = this.y + this.height; + this.width = Math.max(properties.width, this.width); + this.height += properties.height + ToolBar.SPACING; + } + + this.tools[this.tools.length] = new Tool(properties, selectable, selected); + return this.tools.length - 1; + } + + this.move = function(x, y) { + var dx = x - this.x; + var dy = y - this.y; + this.x = x; + this.y = y; + for(var tool in this.tools) { + this.tools[tool].move(this.tools[tool].x() + dx, this.tools[tool].y() + dy); + } + } + + this.setAlpha = function(alpha) { + for(var tool in this.tools) { + this.tools[tool].setAlpha(alpha); + } + } + + this.show = function(doShow) { + for(var tool in this.tools) { + this.tools[tool].show(doShow); + } + } + + this.clicked = function(clickedOverlay) { + for(var tool in this.tools) { + if (this.tools[tool].visible() && this.tools[tool].clicked(clickedOverlay)) { + return tool; + } + } + return -1; + } + + this.numberOfTools = function() { + return this.tools.length; + } + + this.cleanup = function() { + for(var tool in this.tools) { + this.tools[tool].cleanup(); + delete this.tools[tool]; + } + + this.tools = []; + this.x = x; + this.y = y; + this.width = 0; + this.height = 0; + } +} +ToolBar.SPACING = 4; +ToolBar.VERTICAL = 0; +ToolBar.HORIZONTAL = 1; \ No newline at end of file diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index 144415d6ee..e10197d488 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -78,6 +78,7 @@ QScriptValue WindowScriptingInterface::showPrompt(const QString& message, const promptDialog.setWindowTitle(""); promptDialog.setLabelText(message); promptDialog.setTextValue(defaultText); + promptDialog.setFixedSize(600, 200); if (promptDialog.exec() == QDialog::Accepted) { return QScriptValue(promptDialog.textValue()); From c59358ac96446c6a5e8947f4688db93afe51c64b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 13 May 2014 14:10:01 -0700 Subject: [PATCH 3/7] First cut at editModels with the mouse --- examples/editModels.js | 273 ++++++++++++++++++++++++++++++++++------- examples/toolBars.js | 39 +++--- 2 files changed, 244 insertions(+), 68 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index 90ce87d259..46e8248681 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -368,41 +368,100 @@ function checkController(deltaTime) { moveOverlays(); } +var clickEvent = false; +var newModel; +var modifierType = -1; +var moveYZ; +var moveXZ; +var moveXY; +var yaw; +var pitch; +var roll; +var scale; + +var modelSelected = false; +var selectedModelID; +var selectedModelProperties; + + +function initToolBar() { + toolBar = new ToolBar(0, 0, ToolBar.VERTICAL); + // New Model + newModel = toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 + }); + print("New Model: " + newModel) + + // Move YZ + moveYZ = toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 + }, true); + // Move XZ + moveXZ = toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 + }, true); + // Move XY + moveXY = toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 + }, true); + + + // Yaw + yaw = toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 + }, true); + // Pitch + pitch = toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 + }, true); + // Roll + roll = toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 + }, true); + + + // Scale + scale = toolBar.addTool({ + imageURL: toolIconUrl + "voxel-tool.svg", + subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, + width: toolWidth, height: toolHeight, + visible: true, + alpha: 0.9 + }, true); +} + function moveOverlays() { if (typeof(toolBar) === 'undefined') { - toolBar = new ToolBar(0, 0, ToolBar.VERTICAL); - // New Model - toolBar.addTool({ - imageURL: toolIconUrl + "voxel-tool.svg", - subImage: { x: 0, y: Tool.IMAGE_WIDTH, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }); - // Move YZ - toolBar.addTool({ - imageURL: toolIconUrl + "voxel-tool.svg", - subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }, true); - // Move XZ - toolBar.addTool({ - imageURL: toolIconUrl + "voxel-tool.svg", - subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }, true); - // Move XY - toolBar.addTool({ - imageURL: toolIconUrl + "voxel-tool.svg", - subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }, true); + initToolBar(); + } else if (windowDimensions.x == Controller.getViewportDimensions().x && windowDimensions.y == Controller.getViewportDimensions().y) { return; @@ -417,27 +476,147 @@ function moveOverlays() { } function mousePressEvent(event) { + modelSelected = false; var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); - var url; - var index = toolBar.clicked(clickedOverlay); - if (index == 0) { - url = Window.prompt("Model url", modelURLs[Math.floor(Math.random() * modelURLs.length)]); - if (url == null) { - return; - } + + if (clickedOverlay != 0) { + var index = toolBar.clicked(clickedOverlay); - var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); - Models.addModel({ position: position, - radius: radiusDefault, - modelURL: url - }); - } else if (index == -1) { - print("Didn't click on anything"); + switch(index) { + case newModel: + var url = Window.prompt("Model url", modelURLs[Math.floor(Math.random() * modelURLs.length)]); + if (url == null) { + return; + } + + var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); + Models.addModel({ position: position, + radius: radiusDefault, + modelURL: url + }); + break; + case moveYZ: + print("Selected moveYZ"); + + break; + case moveXZ: + print("Selected moveXZ"); + + break; + case moveXY: + print("Selected moveXY"); + + break; + case yaw: + print("Selected yaw"); + + break; + case pitch: + print("Selected pitch"); + + break; + case roll: + print("Selected roll"); + + break; + case scale: + print("Selected scale"); + + break; + default: + clickEvent = false; + return; + } + clickEvent = true; + + if (modifierType != -1) { + toolBar.tools[modifierType].select(false); + } + modifierType = index; + } else { + var pickRay = Camera.computePickRay(event.x, event.y); + Vec3.print("Looking at: ", pickRay.origin); + var foundModels = Models.findModels(pickray.origin, LASER_LENGTH_FACTOR); + for (var i = 0; i < foundModels.length; i++) { + if (!foundModels[i].isKnownID) { + var identify = Models.identifyModel(foundModels[i]); + if (!identify.isKnownID) { + print("Unknown ID " + identify.id + "(update loop)"); + return; + } + foundModels[i] = identify; + } + + var properties = Models.getModelProperties(foundModels[i]); + print("Checking properties: " + properties.id + " " + properties.isKnownID); + + // P P - Model + // /| A - Palm + // / | d B - unit vector toward tip + // / | X - base of the perpendicular line + // A---X----->B d - distance fom axis + // x x - distance from A + // + // |X-A| = (P-A).B + // X == A + ((P-A).B)B + // d = |P-X| + + var A = pickRay.origin; + var B = Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, LASER_LENGTH_FACTOR)); + var P = properties.position; + + var x = Vec3.dot(Vec3.subtract(P, A), B); + var X = Vec3.sum(A, Vec3.multiply(B, x)); + var d = Vec3.length(Vec3.subtract(P, X)); + + if (d < properties.radius && 0 < x && x < LASER_LENGTH_FACTOR) { + modelSelected = true; + selectedModelID = foundModels[i]; + selectedModelProperties = properties; + return; + } + } } } function mouseMoveEvent(event) { + if (clickEvent && !modelSelected) { + return; + } + print("Dragging"); + + switch(modifierType) { + case moveYZ: + print("Move " + moveYZ); + break; + case moveXZ: + print("Move " + moveXZ); + + break; + case moveXY: + print("Move " + moveXY); + + break; + case yaw: + print("Move " + yaw); + + break; + case pitch: + print("Move " + pitch); + + break; + case roll: + print("Move " + roll); + + break; + case scale: + print("Move " + scale); + + break; + } + + Model.editModel(selectedModelID, selectedModelProperties); } function scriptEnding() { diff --git a/examples/toolBars.js b/examples/toolBars.js index 62a01a9a15..7f8f09575b 100644 --- a/examples/toolBars.js +++ b/examples/toolBars.js @@ -13,7 +13,6 @@ Overlay2D = function(properties, overlay) { // overlay is an optionnal variable if (!(typeof(properties) === 'undefined')) { if(typeof(overlay) === 'undefined') { overlay = Overlays.addOverlay("image", properties); - print("New overlay: " + overlay); } else { Overlays.editOverlay(overlay, properties); } @@ -87,25 +86,23 @@ Tool = function(properties, selectable, selected) { // selectable and selected a return selectable; } - if (this.selectable()) { - this.selected = function() { - return selected; - } - this.select = function(doSelect) { - selected = doSelect; - properties.subImage.y = (selected ? 2 : 1) * properties.subImage.height; - Overlays.editOverlay(this.overlay(), { subImage: properties.subImage }); - } - this.toggle = function() { - selected = !selected; - properties.subImage.y = (selected ? 2 : 1) * properties.subImage.height; - Overlays.editOverlay(this.overlay(), { subImage: properties.subImage }); - - return selected; - } - - this.select(selected); + this.selected = function() { + return selected; } + this.select = function(doSelect) { + selected = doSelect; + properties.subImage.y = (selected ? 2 : 1) * properties.subImage.height; + Overlays.editOverlay(this.overlay(), { subImage: properties.subImage }); + } + this.toggle = function() { + selected = !selected; + properties.subImage.y = (selected ? 2 : 1) * properties.subImage.height; + Overlays.editOverlay(this.overlay(), { subImage: properties.subImage }); + + return selected; + } + + this.select(selected); this.baseClicked = this.clicked; this.clicked = function(clickedOverlay) { @@ -144,7 +141,7 @@ ToolBar = function(x, y, direction) { } this.tools[this.tools.length] = new Tool(properties, selectable, selected); - return this.tools.length - 1; + return ((this.tools.length) - 1); } this.move = function(x, y) { @@ -172,7 +169,7 @@ ToolBar = function(x, y, direction) { this.clicked = function(clickedOverlay) { for(var tool in this.tools) { if (this.tools[tool].visible() && this.tools[tool].clicked(clickedOverlay)) { - return tool; + return parseInt(tool); } } return -1; From 701bc63bd19b37907ad7272898f6b044ec42948e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 13 May 2014 14:34:08 -0700 Subject: [PATCH 4/7] Removed old toolbar --- examples/editModels.js | 185 +++++------------------------------------ 1 file changed, 22 insertions(+), 163 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index 46e8248681..07b31e77d2 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -18,7 +18,7 @@ var toolWidth = 50; var LASER_WIDTH = 4; var LASER_COLOR = { red: 255, green: 0, blue: 0 }; -var LASER_LENGTH_FACTOR = 1.5; +var LASER_LENGTH_FACTOR = 5; var LEFT = 0; var RIGHT = 1; @@ -368,20 +368,6 @@ function checkController(deltaTime) { moveOverlays(); } -var clickEvent = false; -var newModel; -var modifierType = -1; -var moveYZ; -var moveXZ; -var moveXY; -var yaw; -var pitch; -var roll; -var scale; - -var modelSelected = false; -var selectedModelID; -var selectedModelProperties; function initToolBar() { @@ -394,68 +380,6 @@ function initToolBar() { visible: true, alpha: 0.9 }); - print("New Model: " + newModel) - - // Move YZ - moveYZ = toolBar.addTool({ - imageURL: toolIconUrl + "voxel-tool.svg", - subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }, true); - // Move XZ - moveXZ = toolBar.addTool({ - imageURL: toolIconUrl + "voxel-tool.svg", - subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }, true); - // Move XY - moveXY = toolBar.addTool({ - imageURL: toolIconUrl + "voxel-tool.svg", - subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }, true); - - - // Yaw - yaw = toolBar.addTool({ - imageURL: toolIconUrl + "voxel-tool.svg", - subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }, true); - // Pitch - pitch = toolBar.addTool({ - imageURL: toolIconUrl + "voxel-tool.svg", - subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }, true); - // Roll - roll = toolBar.addTool({ - imageURL: toolIconUrl + "voxel-tool.svg", - subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }, true); - - - // Scale - scale = toolBar.addTool({ - imageURL: toolIconUrl + "voxel-tool.svg", - subImage: { x: 0, y: 0, width: Tool.IMAGE_WIDTH, height: Tool.IMAGE_HEIGHT }, - width: toolWidth, height: toolHeight, - visible: true, - alpha: 0.9 - }, true); } function moveOverlays() { @@ -475,74 +399,39 @@ function moveOverlays() { toolBar.move(toolsX, toolsY); } + + +var modelSelected = false; +var selectedModelID; +var selectedModelProperties; + function mousePressEvent(event) { - modelSelected = false; + var modelSelected = false; var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); - if (clickedOverlay != 0) { - var index = toolBar.clicked(clickedOverlay); - - switch(index) { - case newModel: - var url = Window.prompt("Model url", modelURLs[Math.floor(Math.random() * modelURLs.length)]); - if (url == null) { - return; - } - - var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); - Models.addModel({ position: position, - radius: radiusDefault, - modelURL: url - }); - break; - case moveYZ: - print("Selected moveYZ"); - - break; - case moveXZ: - print("Selected moveXZ"); - - break; - case moveXY: - print("Selected moveXY"); - - break; - case yaw: - print("Selected yaw"); - - break; - case pitch: - print("Selected pitch"); - - break; - case roll: - print("Selected roll"); - - break; - case scale: - print("Selected scale"); - - break; - default: - clickEvent = false; - return; + if (newModel == toolBar.clicked(clickedOverlay)) { + var url = Window.prompt("Model url", modelURLs[Math.floor(Math.random() * modelURLs.length)]); + if (url == null) { + return; } - clickEvent = true; - if (modifierType != -1) { - toolBar.tools[modifierType].select(false); - } - modifierType = index; + var position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), SPAWN_DISTANCE)); + Models.addModel({ position: position, + radius: radiusDefault, + modelURL: url + }); + } else { var pickRay = Camera.computePickRay(event.x, event.y); - Vec3.print("Looking at: ", pickRay.origin); + Vec3.print("[Mouse] Looking at: ", pickRay.origin); var foundModels = Models.findModels(pickray.origin, LASER_LENGTH_FACTOR); + print("Num: " + foundModels.length.toString()); for (var i = 0; i < foundModels.length; i++) { if (!foundModels[i].isKnownID) { var identify = Models.identifyModel(foundModels[i]); if (!identify.isKnownID) { print("Unknown ID " + identify.id + "(update loop)"); - return; + continue; } foundModels[i] = identify; } @@ -580,41 +469,11 @@ function mousePressEvent(event) { } function mouseMoveEvent(event) { - if (clickEvent && !modelSelected) { + if (!modelSelected) { return; } - print("Dragging"); - switch(modifierType) { - case moveYZ: - print("Move " + moveYZ); - break; - case moveXZ: - print("Move " + moveXZ); - - break; - case moveXY: - print("Move " + moveXY); - - break; - case yaw: - print("Move " + yaw); - - break; - case pitch: - print("Move " + pitch); - - break; - case roll: - print("Move " + roll); - - break; - case scale: - print("Move " + scale); - - break; - } Model.editModel(selectedModelID, selectedModelProperties); } From 624ae4732f8a11af7aabc9c1abab9282fb751acb Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 13 May 2014 14:58:34 -0700 Subject: [PATCH 5/7] Fixes to PickRay check --- examples/editModels.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index 07b31e77d2..017e4ba740 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -406,7 +406,7 @@ var selectedModelID; var selectedModelProperties; function mousePressEvent(event) { - var modelSelected = false; + modelSelected = false; var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); if (newModel == toolBar.clicked(clickedOverlay)) { @@ -424,8 +424,7 @@ function mousePressEvent(event) { } else { var pickRay = Camera.computePickRay(event.x, event.y); Vec3.print("[Mouse] Looking at: ", pickRay.origin); - var foundModels = Models.findModels(pickray.origin, LASER_LENGTH_FACTOR); - print("Num: " + foundModels.length.toString()); + var foundModels = Models.findModels(pickRay.origin, LASER_LENGTH_FACTOR); for (var i = 0; i < foundModels.length; i++) { if (!foundModels[i].isKnownID) { var identify = Models.identifyModel(foundModels[i]); @@ -451,7 +450,7 @@ function mousePressEvent(event) { // d = |P-X| var A = pickRay.origin; - var B = Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, LASER_LENGTH_FACTOR)); + var B = Vec3.normalize(pickRay.direction); var P = properties.position; var x = Vec3.dot(Vec3.subtract(P, A), B); @@ -462,6 +461,7 @@ function mousePressEvent(event) { modelSelected = true; selectedModelID = foundModels[i]; selectedModelProperties = properties; + print("Clicked on " + selectedModelID.id + " " + modelSelected); return; } } @@ -475,7 +475,7 @@ function mouseMoveEvent(event) { print("Dragging"); - Model.editModel(selectedModelID, selectedModelProperties); + //Model.editModel(selectedModelID, selectedModelProperties); } function scriptEnding() { @@ -488,7 +488,7 @@ Script.scriptEnding.connect(scriptEnding); // register the call back so it fires before each data send Script.update.connect(checkController); Controller.mousePressEvent.connect(mousePressEvent); -Controller.mousePressEvent.connect(mouseMoveEvent); +Controller.mouseMoveEvent.connect(mouseMoveEvent); From 5ef71d6a3557715773d2dde964aedb08bb33a158 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 14 May 2014 10:40:50 -0700 Subject: [PATCH 6/7] Full mouse handling --- examples/editModels.js | 121 +++++++++++++++++- .../models/src/ModelsScriptingInterface.cpp | 1 - 2 files changed, 119 insertions(+), 3 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index 017e4ba740..70a2e178ae 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -404,8 +404,24 @@ function moveOverlays() { var modelSelected = false; var selectedModelID; var selectedModelProperties; +var mouseLastPosition; +var orientation; +var intersection; + + +var SCALE_FACTOR = 200.0; +var TRANSLATION_FACTOR = 100.0; +var ROTATION_FACTOR = 100.0; + +function rayPlaneIntersection(pickRay, point, normal) { + var d = -Vec3.dot(point, normal); + var t = -(Vec3.dot(pickRay.origin, normal) + d) / Vec3.dot(pickRay.direction, normal); + + return Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, t)); +} function mousePressEvent(event) { + mouseLastPosition = { x: event.x, y: event.y }; modelSelected = false; var clickedOverlay = Overlays.getOverlayAtPoint({x: event.x, y: event.y}); @@ -461,21 +477,122 @@ function mousePressEvent(event) { modelSelected = true; selectedModelID = foundModels[i]; selectedModelProperties = properties; + + selectedModelProperties.oldRadius = selectedModelProperties.radius; + selectedModelProperties.oldPosition = { + x: selectedModelProperties.position.x, + y: selectedModelProperties.position.y, + z: selectedModelProperties.position.z, + }; + selectedModelProperties.oldRotation = { + x: selectedModelProperties.modelRotation.x, + y: selectedModelProperties.modelRotation.y, + z: selectedModelProperties.modelRotation.z, + w: selectedModelProperties.modelRotation.w, + }; + + + orientation = MyAvatar.orientation; + intersection = rayPlaneIntersection(pickRay, P, Quat.getFront(orientation)); print("Clicked on " + selectedModelID.id + " " + modelSelected); + return; } } } } +var oldModifier = 0; +var modifier = 0; +var wasShifted = false; function mouseMoveEvent(event) { if (!modelSelected) { return; } - print("Dragging"); + + if (event.isLeftButton) { + if (event.isRightButton) { + modifier = 1; // Scale + } else { + modifier = 2; // Translate + } + } else if (event.isRightButton) { + modifier = 3; // rotate + } else { + modifier = 0; + } + + var pickRay = Camera.computePickRay(event.x, event.y); + if (wasShifted != event.isShifted || modifier != oldModifier) { + selectedModelProperties.oldRadius = selectedModelProperties.radius; + + selectedModelProperties.oldPosition = { + x: selectedModelProperties.position.x, + y: selectedModelProperties.position.y, + z: selectedModelProperties.position.z, + }; + selectedModelProperties.oldRotation = { + x: selectedModelProperties.modelRotation.x, + y: selectedModelProperties.modelRotation.y, + z: selectedModelProperties.modelRotation.z, + w: selectedModelProperties.modelRotation.w, + }; + orientation = MyAvatar.orientation; + intersection = rayPlaneIntersection(pickRay, + selectedModelProperties.oldPosition, + Quat.getFront(orientation)); + + mouseLastPosition = { x: event.x, y: event.y }; + wasShifted = event.isShifted; + oldModifier = modifier; + return; + } - //Model.editModel(selectedModelID, selectedModelProperties); + switch (modifier) { + case 0: + return; + case 1: + // Let's Scale + selectedModelProperties.radius = (selectedModelProperties.oldRadius * + (1.0 + (mouseLastPosition.y - event.y) / SCALE_FACTOR)); + + if (selectedModelProperties.radius < 0.01) { + print("Scale too small ... bailling."); + return; + } + break; + + case 2: + // Let's translate + var newIntersection = rayPlaneIntersection(pickRay, + selectedModelProperties.oldPosition, + Quat.getFront(orientation)); + var vector = Vec3.subtract(newIntersection, intersection) + if (event.isShifted) { + var i = Vec3.dot(vector, Quat.getRight(orientation)); + var j = Vec3.dot(vector, Quat.getUp(orientation)); + vector = Vec3.sum(Vec3.multiply(Quat.getRight(orientation), i), + Vec3.multiply(Quat.getFront(orientation), j)); + } + + selectedModelProperties.position = Vec3.sum(selectedModelProperties.oldPosition, vector); + break; + case 3: + // Let's rotate + var rotation = Quat.fromVec3Degrees({ x: event.y - mouseLastPosition.y, y: event.x - mouseLastPosition.x, z: 0 }); + if (event.isShifted) { + rotation = Quat.fromVec3Degrees({ x: event.y - mouseLastPosition.y, y: 0, z: mouseLastPosition.x - event.x }); + } + + var newRotation = Quat.multiply(orientation, rotation); + newRotation = Quat.multiply(newRotation, Quat.inverse(orientation)); + + selectedModelProperties.modelRotation = Quat.multiply(newRotation, selectedModelProperties.oldRotation); + break; + } + + Models.editModel(selectedModelID, selectedModelProperties); } function scriptEnding() { diff --git a/libraries/models/src/ModelsScriptingInterface.cpp b/libraries/models/src/ModelsScriptingInterface.cpp index 446b0280a4..7625eef998 100644 --- a/libraries/models/src/ModelsScriptingInterface.cpp +++ b/libraries/models/src/ModelsScriptingInterface.cpp @@ -105,7 +105,6 @@ ModelItemID ModelsScriptingInterface::editModel(ModelItemID modelID, const Model _modelTree->updateModel(modelID, properties); _modelTree->unlock(); } - return modelID; } From 53d7aeab4f1b6a38d4820d1d055725522d0b9ea7 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 14 May 2014 12:02:38 -0700 Subject: [PATCH 7/7] Fixed typo --- examples/toolBars.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toolBars.js b/examples/toolBars.js index 7f8f09575b..88b07276f0 100644 --- a/examples/toolBars.js +++ b/examples/toolBars.js @@ -1,5 +1,5 @@ // -// testScript.js +// toolBars.js // examples // // Created by Clément Brisset on 5/7/14.