diff --git a/examples/example/games/satellite.js b/examples/example/games/satellite.js index fd1243fbe0..8e37472ea4 100644 --- a/examples/example/games/satellite.js +++ b/examples/example/games/satellite.js @@ -19,7 +19,8 @@ Script.include('../utilities/tools/vector.js'); var URL = "https://s3.amazonaws.com/hifi-public/marketplace/hificontent/Scripts/planets/"; -SatelliteGame = function() { +SatelliteCreator = function() { + print("initializing satellite game"); var MAX_RANGE = 50.0; @@ -38,6 +39,9 @@ SatelliteGame = function() { var ZONE_DIM = 100.0; var LIGHT_INTENSITY = 1.5; + var center, distance; + + Earth = function(position, size) { this.earth = Entities.addEntity({ type: "Model", @@ -109,10 +113,35 @@ SatelliteGame = function() { } } - // Create earth model - var center = Vec3.sum(Camera.getPosition(), Vec3.multiply(MAX_RANGE, Quat.getFront(Camera.getOrientation()))); - var distance = Vec3.length(Vec3.subtract(center, Camera.getPosition())); - var earth = new Earth(center, EARTH_SIZE); + + this.init = function() { + if (this.isActive) { + this.quitGame(); + } + var confirmed = Window.confirm("Start satellite game?"); + if (!confirmed) { + return false; + } + + this.isActive = true; + MyAvatar.position = { + x: 200, + y: 200, + z: 200 + }; + Camera.setPosition({ + x: 200, + y: 200, + z: 200 + }); + + // Create earth model + center = Vec3.sum(Camera.getPosition(), Vec3.multiply(MAX_RANGE, Quat.getFront(Camera.getOrientation()))); + distance = Vec3.length(Vec3.subtract(center, Camera.getPosition())); + var earth = new Earth(center, EARTH_SIZE); + return true; + }; + var satellites = []; var SATELLITE_SIZE = 2.0; @@ -259,11 +288,12 @@ SatelliteGame = function() { } } - this.endGame = function() { + this.quitGame = function() { for (var i = 0; i < satellites.length; i++) { Entities.deleteEntity(satellites[i].satellite); satellites[i].arrow.cleanup(); } + this.isActive = false; earth.cleanup(); } @@ -285,6 +315,7 @@ SatelliteGame = function() { Controller.mouseMoveEvent.connect(mouseMoveEvent); Controller.mouseReleaseEvent.connect(mouseReleaseEvent); Script.update.connect(update); - Script.scriptEnding.connect(this.endGame); + Script.scriptEnding.connect(this.quitGame); + +} -} \ No newline at end of file diff --git a/examples/example/planets-ui.js b/examples/example/planets-ui.js new file mode 100644 index 0000000000..56cf7b18e1 --- /dev/null +++ b/examples/example/planets-ui.js @@ -0,0 +1,458 @@ +// +// widgets-example.js +// games +// +// Copyright 2015 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 +// +var ICONS_URL = 'https://s3.amazonaws.com/hifi-public/marketplace/hificontent/Scripts/planets/images/'; + +var panelX = 1250; +var panelY = 500; +var panelWidth = 50; +var panelHeight = 210; + +Script.include('../libraries/uiwidgets.js'); + +UI.setDefaultVisibility(true); + +var ICON_WIDTH = 40.0; +var ICON_HEIGHT = 40.0; +var ICON_COLOR = UI.rgba(45, 45, 45, 0.7); +var FOCUSED_COLOR = UI.rgba(250, 250, 250, 1.0); + +var PANEL_BACKGROUND_COLOR = UI.rgba(100, 100, 100, 0.7); + +var PANEL_PADDING = 7.0; +var PANEL_BORDER = 12.0; +var SUBPANEL_GAP = 1.0; + +var icons = []; + +function addImage(panel, iconId) { + var icon = panel.add(new UI.Image({ + 'imageURL': ICONS_URL + iconId + '.svg', + 'width': ICON_WIDTH, + 'height': ICON_HEIGHT, + 'color': ICON_COLOR, + 'alpha': ICON_COLOR.a + })); + icons.push(icon); + return icon; +} + + +var panels = []; + +function addPanel(properties) { + properties.background = properties.background || {}; + properties.background.backgroundColor = properties.background.backgroundColor || + PANEL_BACKGROUND_COLOR; + properties.background.backgroundAlpha = properties.background.backgroundAlpha || + PANEL_BACKGROUND_COLOR.a; + properties.padding = properties.padding || { + x: PANEL_PADDING, + y: PANEL_PADDING + }; + properties.border = properties.border || { + x: PANEL_BORDER, + y: PANEL_BORDER + }; + + var panel = new UI.WidgetStack(properties); + panels.push(panel); + return panel; +} + +function makeDraggable(panel, target) { + if (!target) { + target = panel; + } + var dragStart = null; + var initialPos = null; + + panel.addAction('onDragBegin', function(event) { + dragStart = { + x: event.x, + y: event.y + }; + initialPos = { + x: target.position.x, + y: target.position.y + }; + }); + panel.addAction('onDragUpdate', function(event) { + target.setPosition( + initialPos.x + event.x - dragStart.x, + initialPos.y + event.y - dragStart.y + ); + UI.updateLayout(); + }); + panel.addAction('onDragEnd', function() { + dragStart = dragEnd = null; + }); +} + +function setText(text) { + return function() { + demoLabel.setText(text); + UI.updateLayout(); + }; +} + +function join(obj) { + var s = "{"; + var sep = "\n"; + for (var k in obj) { + s += sep + k + ": " + ("" + obj[k]).replace("\n", "\n"); + sep = ",\n"; + } + if (s.length > 1) + return s + " }"; + return s + "}"; +} + +setText = undefined; + +var tooltipWidget = new UI.Label({ + text: "", + width: 500, + height: 20, + visible: false +}); + +function addTooltip(widget, text) { + widget.addAction('onMouseOver', function(event, widget) { + tooltipWidget.setVisible(true); + tooltipWidget.setPosition(widget.position.x + widget.getWidth() + 20, widget.position.y); + tooltipWidget.setText(text); + UI.updateLayout(); + }); + widget.addAction('onMouseExit', function() { + tooltipWidget.setVisible(false); + UI.updateLayout(); + }); +} + +var mainPanel = addPanel({ + dir: '+y' +}); +makeDraggable(mainPanel); +mainPanel.setPosition(1200, 250); +mainPanel.setVisible(true); + +var systemViewButton = addImage(mainPanel, 'solarsystems'); +var zoomButton = addImage(mainPanel, 'magnifier'); +var satelliteButton = addImage(mainPanel, 'satellite'); +var settingsButton = addImage(mainPanel, 'settings'); +var stopButton = addImage(mainPanel, 'close'); + +addTooltip(systemViewButton, "system view"); +addTooltip(zoomButton, "zoom"); +addTooltip(satelliteButton, "satelite view"); +addTooltip(settingsButton, "settings"); +addTooltip(stopButton, "exit"); + +var systemViewPanel = addPanel({ + dir: '+x', + visible: false +}); +var restartButton = addImage(systemViewPanel, 'reverse'); +var pauseButton = addImage(systemViewPanel, 'playpause'); +var rideButton = addImage(systemViewPanel, 'forward'); + +pauseButton.addAction('onClick', function() { + if (!paused) { + pause(); + } else { + resume(); + } +}); + +// rideButton.addAction('onClick', function() { +// Script.include('orbit-ride.js'); +// new OrbitRider(); +// }); + +restartButton.addAction('onClick', function() { + Script.stop(); + var thisScript = Script.resolvePath("solarsystem.js"); + Script.load(thisScript); +}); + +var zoomPanel = addPanel({ + dir: '+x', + visible: false +}); +var zoomButtons = []; +for (var i = 0; i < planets.length; ++i) { + var label = zoomPanel.add(new UI.Label({ + text: planets[i].name, + width: 80, + height: 20, + backgroundAlpha: 1.0 + })); + zoomButtons.push(label); + UI.updateLayout(); +} +UI.updateLayout(); + +zoomButtons.forEach(function(button, i) { + var planet = planets[i]; + button.addAction('onClick', function() { + planet.zoom(); + }); +}); + + +var settingsPanel = addPanel({ + dir: '+y', + visible: false +}); + +function addCheckbox(parent, label, labelWidth, enabled, onValueChanged) { + var layout = parent.add(new UI.WidgetStack({ + dir: '+x', + visible: true, + backgroundAlpha: 0.0 + })); + var label = layout.add(new UI.Label({ + text: label, + width: labelWidth, + height: 20, + backgroundAlpha: 0.0 + })); + + var defaultColor = UI.rgb(10, 10, 10); + + var checkbox = layout.add(new UI.Checkbox({ + width: 20, + height: 20, + padding: { + x: 3, + y: 3 + }, + backgroundColor: defaultColor, + backgroundAlpha: 0.9, + checked: enabled, + onValueChanged: onValueChanged + })); + + checkbox.label = label; + checkbox.layout = layout; + checkbox.setValue = function(value) { + checkbox.setChecked(value); + } + return checkbox; +} + +function addSlider(parent, label, labelWidth, defaultValue, min, max, valueChanged) { + var layout = parent.add(new UI.WidgetStack({ + dir: '+x', + visible: true + })); + var label = layout.add(new UI.Label({ + text: label, + width: labelWidth, + height: 27 + })); + var display = layout.add(new UI.Label({ + text: " ", + width: 50, + height: 27 + })); + var slider = layout.add(new UI.Slider({ + value: defaultValue, + maxValue: max, + minValue: min, + width: 300, + height: 20, + backgroundColor: UI.rgb(10, 10, 10), + backgroundAlpha: 1.0, + slider: { // slider knob + width: 30, + height: 18, + backgroundColor: UI.rgb(120, 120, 120), + backgroundAlpha: 1.0 + } + })); + slider.addAction('onDoubleClick', function() { + slider.setValue(defaultValue); + UI.updateLayout(); + }); + display.setText("" + (+slider.getValue().toFixed(2))); + slider.onValueChanged = function(value) { + valueChanged(value); + display.setText("" + (+value.toFixed(2))); + UI.updateLayout(); + } + slider.label = label; + slider.layout = layout; + return slider; +} + +settingsPanel.showTrailsButton = addCheckbox(settingsPanel, "show trails", 120, trailsEnabled, function(trailsEnabled) { + if (trailsEnabled) { + for (var i = 0; i < planets.length; ++i) { + planets[i].resetTrails(); + } + //if trails are off and we've already created trails, remove existing trails + } else { + for (var i = 0; i < planets.length; ++i) { + planets[i].clearTrails(); + } + } +}); +var g_multiplier = 1.0; +settingsPanel.gravitySlider = addSlider(settingsPanel, "gravity scale ", 200, g_multiplier, 0.0, 5.0, function (value) { + g_multiplier = value; + GRAVITY = REFERENCE_GRAVITY * g_multiplier; +}); + +var period_multiplier = 1.0; +var last_alpha = period_multiplier; + +settingsPanel.periodSlider = addSlider(settingsPanel, "orbital period scale ", 200, period_multiplier, 0.0, 3.0, function (value) { + period_multiplier = value; + changePeriod(period_multiplier); +}); + +function changePeriod(alpha) { + var ratio = last_alpha / alpha; + GRAVITY = Math.pow(ratio, 2.0) * GRAVITY; + for (var i = 0; i < planets.length; ++i) { + planets[i].period = ratio * planets[i].period; + planets[i].velocity = Vec3.multiply(ratio, planets[i].velocity); + planets[i].resetTrails(); + } + last_alpha = alpha; +} + +var satelliteGame; +satelliteButton.addAction('onClick', function() { + if (satelliteGame && satelliteGame.isActive) { + MyAvatar.position = startingPosition; + satelliteGame.quitGame(); + resume(); + } else { + pause(); + satelliteGame = new SatelliteCreator(); + satelliteGame.init(); + } +}); + + +var subpanels = [systemViewPanel, zoomPanel, settingsPanel]; + +function hideSubpanelsExcept(panel) { + subpanels.forEach(function(x) { + if (x != panel) { + x.setVisible(false); + } + }); +} + +function attachPanel(panel, button) { + button.addAction('onClick', function() { + hideSubpanelsExcept(panel); + panel.setVisible(!panel.isVisible()); + UI.updateLayout(); + }) + + UI.addAttachment(panel, button, function(target, rel) { + target.setPosition( + rel.position.x - (target.getWidth() + target.border.x + SUBPANEL_GAP), + rel.position.y - target.border.y + ); + }); +} +attachPanel(systemViewPanel, systemViewButton); +attachPanel(zoomPanel, zoomButton); +attachPanel(settingsPanel, settingsButton); + + +var addColorToggle = function(widget) { + widget.addAction('onMouseOver', function() { + widget.setColor(FOCUSED_COLOR); + }); + widget.addAction('onMouseExit', function() { + widget.setColor(ICON_COLOR); + }); +} + + +systemViewPanel.addAction('onMouseOver', function() { + hideSubpanelsExcept(systemViewPanel); + UI.updateLayout(); +}); + + +zoomButton.addAction('onClick', function() { + hideSubpanelsExcept(zoomPanel); + UI.updateLayout(); +}); +UI.updateLayout(); + +stopButton.addAction('onClick', function() { + teardown(); + Script.stop(); +}); + +// Panel drag behavior +// (click + drag on border to drag) +(function() { + var dragged = null; + this.startDrag = function(dragAction) { + dragged = dragAction; + } + this.updateDrag = function(event) { + if (dragged) { + print("Update drag"); + dragged.updateDrag(event); + } + } + this.clearDrag = function(event) { + if (dragged) + print("End drag"); + dragged = null; + } +})(); + +var buttons = icons; + +buttons.map(addColorToggle); +panels.map(function(panel) { + makeDraggable(panel, mainPanel); +}); + +// Cleanup script resources +function teardown() { + if (satelliteGame) { + satelliteGame.quitGame(); + } + UI.teardown(); +}; + +UI.debug.setVisible(false); + +var inputHandler = { + onMouseMove: function(event) { + updateDrag(event); + UI.handleMouseMove(event); + }, + onMousePress: function(event) { + UI.handleMousePress(event); + }, + onMouseRelease: function(event) { + clearDrag(event); + UI.handleMouseRelease(event); + }, + onMouseDoublePress: function(event) { + UI.handleMouseDoublePress(event); + } +}; +Controller.mousePressEvent.connect(inputHandler.onMousePress); +Controller.mouseMoveEvent.connect(inputHandler.onMouseMove); +Controller.mouseReleaseEvent.connect(inputHandler.onMouseRelease); +Controller.mouseDoublePressEvent.connect(inputHandler.onMouseDoublePress); diff --git a/examples/example/solarsystem.js b/examples/example/solarsystem.js index 196ad57f86..3e4a39ed71 100644 --- a/examples/example/solarsystem.js +++ b/examples/example/solarsystem.js @@ -18,797 +18,463 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include([ - 'games/satellite.js' -]); +CreateSimulation = function() { + Script.include("https://hifi-public.s3.amazonaws.com/eric/scripts/tween.js"); + Script.include('games/satellite.js'); -var DAMPING = 0.0; -var LIFETIME = 6000; -var BASE_URL = "https://s3.amazonaws.com/hifi-public/marketplace/hificontent/Scripts/planets/planets/"; + var DAMPING = this.DAMPING = 0.0; + var LIFETIME = this.LIFETIME = 6000; + var BASE_URL = this.BASE_URL = "https://s3.amazonaws.com/hifi-public/marketplace/hificontent/Scripts/planets/planets/"; -// Save intiial avatar and camera position -var startingPosition = { - x: 8000, - y: 8000, - z: 8000 -}; -MyAvatar.position = startingPosition; -var cameraStart = Camera.getOrientation(); + // Save intiial avatar and camera position + var startingPosition = this.startingPosition = { + x: 8000, + y: 8000, + z: 8000 + }; + MyAvatar.position = startingPosition; + var cameraStart = this.cameraStart = Camera.getOrientation(); -// Place the sun -var MAX_RANGE = 80.0; -var center = Vec3.sum(startingPosition, Vec3.multiply(MAX_RANGE, Vec3.normalize(Quat.getFront(Camera.getOrientation())))); -var SUN_SIZE = 7.0; + // Place the sun + var MAX_RANGE = this.MAX_RANGE = 80.0; + var center = this.center = Vec3.sum(startingPosition, Vec3.multiply(MAX_RANGE, Vec3.normalize(Quat.getFront(Camera.getOrientation())))); + var SUN_SIZE = this.SUN_SIZE = 7.0; -var theSun = Entities.addEntity({ - type: "Model", - modelURL: BASE_URL + "sun.fbx", - position: center, - dimensions: { - x: SUN_SIZE, - y: SUN_SIZE, - z: SUN_SIZE - }, - angularVelocity: { - x: 0.0, - y: 0.1, - z: 0.0 - }, - angularDamping: DAMPING, - damping: DAMPING, - ignoreCollisions: false, - lifetime: LIFETIME, - collisionsWillMove: false -}); - - - -// Reference values for physical constants -var referenceRadius = 15.0; -var referenceDiameter = 0.6; -var referencePeriod = 3.0; -var LARGE_BODY_MASS = 250.0; -var SMALL_BODY_MASS = LARGE_BODY_MASS * 0.000000333; -var GRAVITY = (Math.pow(referenceRadius, 3.0) / Math.pow((referencePeriod / (2.0 * Math.PI)), 2.0)) / LARGE_BODY_MASS; -var REFERENCE_GRAVITY = GRAVITY; - -var planets = []; -var planetCount = 0; - -var trailsEnabled = true; -var MAX_POINTS_PER_LINE = 60; -var LINE_DIM = 200; -var LINE_WIDTH = 20; - -var VELOCITY_OFFSET_Y = -0.3; -var VELOCITY_OFFSET_Z = 0.9; - -var index = 0; - -var Planet = function(name, trailColor, radiusScale, sizeScale) { - - this.name = name; - this.trailColor = trailColor; - - this.trail = []; - this.lineStack = []; - - this.radius = radiusScale * referenceRadius; - this.position = Vec3.sum(center, { - x: this.radius, - y: 0.0, - z: 0.0 - }); - this.period = (2.0 * Math.PI) * Math.sqrt(Math.pow(this.radius, 3.0) / (GRAVITY * LARGE_BODY_MASS)); - this.gravity = GRAVITY; - this.initialVelocity = Math.sqrt((GRAVITY * LARGE_BODY_MASS) / this.radius); - this.velocity = Vec3.multiply(this.initialVelocity, Vec3.normalize({ - x: 0, - y: VELOCITY_OFFSET_Y, - z: VELOCITY_OFFSET_Z - })); - this.dimensions = sizeScale * referenceDiameter; - this.sizeScale = sizeScale; - - this.planet = Entities.addEntity({ + var theSun = this.theSun = Entities.addEntity({ type: "Model", - modelURL: BASE_URL + name + ".fbx", - position: this.position, + modelURL: BASE_URL + "sun.fbx", + position: center, dimensions: { - x: this.dimensions, - y: this.dimensions, - z: this.dimensions + x: SUN_SIZE, + y: SUN_SIZE, + z: SUN_SIZE + }, + angularVelocity: { + x: 0.0, + y: 0.1, + z: 0.0 }, - velocity: this.velocity, angularDamping: DAMPING, damping: DAMPING, ignoreCollisions: false, lifetime: LIFETIME, - collisionsWillMove: true, + collisionsWillMove: false }); - this.computeAcceleration = function() { - var acc = -(this.gravity * LARGE_BODY_MASS) * Math.pow(this.radius, (-2.0)); - return acc; - }; - this.update = function(timeStep) { - var between = Vec3.subtract(this.position, center); - var speed = this.computeAcceleration(this.radius) * timeStep; - var vel = Vec3.multiply(speed, Vec3.normalize(between)); - // Update velocity and position - this.velocity = Vec3.sum(this.velocity, vel); - this.position = Vec3.sum(this.position, Vec3.multiply(timeStep, this.velocity)); - Entities.editEntity(this.planet, { - velocity: this.velocity, - position: this.position - }); + // Reference values for physical constants + var referenceRadius = this.referenceRadius = 15.0; + var referenceDiameter = this.referenceDiameter = 0.6; + var referencePeriod = this.referencePeriod = 3.0; + var LARGE_BODY_MASS = this.LARGE_BODY_MASS = 250.0; + var SMALL_BODY_MASS = this.SMALL_BODY_MASS = LARGE_BODY_MASS * 0.000000333; + var GRAVITY = this.GRAVITY = (Math.pow(referenceRadius, 3.0) / Math.pow((referencePeriod / (2.0 * Math.PI)), 2.0)) / LARGE_BODY_MASS; + var REFERENCE_GRAVITY = this.REFERENCE_GRAVITY = GRAVITY; + + var planets = this.planets = []; + var trailsEnabled = this.trailsEnabled = true; + var MAX_POINTS_PER_LINE = this.MAX_POINTS_PER_LINE = 60; + var LINE_DIM = this.LINE_DIM = 200; + var LINE_WIDTH = this.LINE_WIDTH = 20; + + var VELOCITY_OFFSET_Y = this.VELOCITY_OFFSET_Y = -0.3; + var VELOCITY_OFFSET_Z = this.VELOCITY_OFFSET_Z = 0.9; + + var index = this.index = 0; + + this.computeLocalPoint = function(linePos, worldPoint) { + var localPoint = Vec3.subtract(worldPoint, linePos); + return localPoint; + } + + // Create a new line + this.newLine = function(lineStack, point, period, color) { + if (elapsed < period) { + var line = Entities.addEntity({ + position: point, + type: "Line", + color: color, + dimensions: { + x: LINE_DIM, + y: LINE_DIM, + z: LINE_DIM + }, + lifetime: LIFETIME, + lineWidth: LINE_WIDTH + }); + lineStack.push(line); + } else { + // Begin overwriting first lines after one full revolution (one period) + var firstLine = lineStack.shift(); + print("editing first line"); + Entities.editEntity(firstLine, { + position: point, + linePoints: [{ + x: 0.0, + y: 0.0, + z: 0.0 + }] + }); + lineStack.push(firstLine); - if (trailsEnabled) { - this.updateTrail(); } - }; + var points = []; + points.push(computeLocalPoint(point, point)); + return points; + } - this.resetTrails = function() { - elapsed = 0.0; + this.pause = function() { + for (var i = 0; i < planets.length; ++i) { + Entities.editEntity(planets[i].planet, { + velocity: { + x: 0.0, + y: 0.0, + z: 0.0 + } + }); + planets[i].label = new PlanetLabel(planets[i].name, i); + planets[i].label.show(); + } + paused = true; + } + + this.resume = function() { + for (var i = 0; i < planets.length; ++i) { + planets[i].label.hide(); + } + paused = false; + } + + var Planet = function(name, trailColor, radiusScale, sizeScale) { + + this.name = name; + this.trailColor = trailColor; this.trail = []; this.lineStack = []; - //add the first line to both the line entity stack and the trail - this.trail.push(newLine(this.lineStack, this.position, this.period, this.trailColor)); - }; + this.radius = radiusScale * referenceRadius; + this.position = Vec3.sum(center, { + x: this.radius, + y: 0.0, + z: 0.0 + }); + this.period = (2.0 * Math.PI) * Math.sqrt(Math.pow(this.radius, 3.0) / (GRAVITY * LARGE_BODY_MASS)); - this.updateTrail = function() { - var point = this.position; - var linePos = Entities.getEntityProperties(this.lineStack[this.lineStack.length - 1]).position; + this.initialVelocity = Math.sqrt((GRAVITY * LARGE_BODY_MASS) / this.radius); - this.trail.push(computeLocalPoint(linePos, point)); + this.velocity = Vec3.multiply(this.initialVelocity, Vec3.normalize({ + x: 0, + y: VELOCITY_OFFSET_Y, + z: VELOCITY_OFFSET_Z + })); + this.dimensions = sizeScale * referenceDiameter; + this.sizeScale = sizeScale; - Entities.editEntity(this.lineStack[this.lineStack.length - 1], { - linePoints: this.trail + this.planet = Entities.addEntity({ + type: "Model", + modelURL: BASE_URL + name + ".fbx", + position: this.position, + dimensions: { + x: this.dimensions, + y: this.dimensions, + z: this.dimensions + }, + velocity: this.velocity, + angularDamping: DAMPING, + damping: DAMPING, + ignoreCollisions: false, + lifetime: LIFETIME, + collisionsWillMove: false, }); - if (this.trail.length == MAX_POINTS_PER_LINE) { - this.trail = newLine(this.lineStack, point, this.period, this.trailColor); + this.computeAcceleration = function() { + var acc = -(GRAVITY * LARGE_BODY_MASS) * Math.pow(this.radius, (-2.0)); + return acc; + }; + + this.update = function(deltaTime) { + var between = Vec3.subtract(this.position, center); + var speed = this.computeAcceleration(this.radius) * deltaTime; + var vel = Vec3.multiply(speed, Vec3.normalize(between)); + + // Update velocity and position + this.velocity = Vec3.sum(this.velocity, vel); + this.position = Vec3.sum(this.position, Vec3.multiply(deltaTime, this.velocity)); + Entities.editEntity(this.planet, { + velocity: this.velocity, + position: this.position + }); + + if (trailsEnabled) { + this.updateTrail(); + } + }; + + this.clearTrails = function() { + + for (var j = 0; j < this.lineStack.length; ++j) { + Entities.editEntity(this.lineStack[j], { + visible: false + }); + } + this.lineStack = []; + } - }; + this.resetTrails = function() { + elapsed = 0.0; - this.zoom = function() { - Script.include('file:///Users/bridget/Desktop/tween.js'); - init(this); - // var viewingRange = sizeScale * 2.0; - // var direction = Vec3.subtract(this.position, MyAvatar.position); - // var dist = Vec3.length(direction); - // var timer = 0; - // while (dist > viewingRange && timer < 8000000) { - // timer++; - // if (timer % 10000 == 0) { - // MyAvatar.position = Vec3.sum(MyAvatar.position, Vec3.normalize(direction)); - // direction = Vec3.subtract(this.position, MyAvatar.position); - // dist = Vec3.length(direction); - // } - // } - }; + this.trail = []; + this.lineStack = []; + //add the first line to both the line entity stack and the trail + this.trail.push(newLine(this.lineStack, this.position, this.period, this.trailColor)); + }; - this.adjustPeriod = function(alpha) { - // Update global G constant, period, poke velocity to new value - var ratio = this.last_alpha / alpha; - this.gravity = Math.pow(ratio, 2.0) * GRAVITY; - this.period = ratio * this.period; - this.velocity = Vec3.multiply(ratio, this.velocity); + this.updateTrail = function() { + var point = this.position; + var linePos = Entities.getEntityProperties(this.lineStack[this.lineStack.length - 1]).position; - this.last_alpha = alpha; - }; + this.trail.push(computeLocalPoint(linePos, point)); + Entities.editEntity(this.lineStack[this.lineStack.length - 1], { + linePoints: this.trail + }); - index++; - this.resetTrails(); + if (this.trail.length == MAX_POINTS_PER_LINE) { + this.trail = newLine(this.lineStack, point, this.period, this.trailColor); + } + }; -} + this.zoom = function() { + pause(); -// rideOrbit = function() { - -// Script.include('file:///Users/bridget/Desktop/tween.js'); -// init(); - -// } - - -var MERCURY_LINE_COLOR = { - red: 255, - green: 255, - blue: 255 -}; -var VENUS_LINE_COLOR = { - red: 255, - green: 160, - blue: 110 -}; -var EARTH_LINE_COLOR = { - red: 10, - green: 150, - blue: 160 -}; -var MARS_LINE_COLOR = { - red: 180, - green: 70, - blue: 10 -}; -var JUPITER_LINE_COLOR = { - red: 250, - green: 140, - blue: 0 -}; -var SATURN_LINE_COLOR = { - red: 235, - green: 215, - blue: 0 -}; -var URANUS_LINE_COLOR = { - red: 135, - green: 205, - blue: 240 -}; -var NEPTUNE_LINE_COLOR = { - red: 30, - green: 140, - blue: 255 -}; -var PLUTO_LINE_COLOR = { - red: 255, - green: 255, - blue: 255 -}; - -planets.push(new Planet("mercury", MERCURY_LINE_COLOR, 0.387, 0.383)); -planets.push(new Planet("venus", VENUS_LINE_COLOR, 0.723, 0.949)); -planets.push(new Planet("earth", EARTH_LINE_COLOR, 1.0, 1.0)); -planets.push(new Planet("mars", MARS_LINE_COLOR, 1.52, 0.532)); -planets.push(new Planet("jupiter", JUPITER_LINE_COLOR, 5.20, 11.21)); -planets.push(new Planet("saturn", SATURN_LINE_COLOR, 9.58, 9.45)); -planets.push(new Planet("uranus", URANUS_LINE_COLOR, 19.20, 4.01)); -planets.push(new Planet("neptune", NEPTUNE_LINE_COLOR, 30.05, 3.88)); -planets.push(new Planet("pluto", PLUTO_LINE_COLOR, 39.48, 0.186)); - -var LABEL_X = 8.0; -var LABEL_Y = 3.0; -var LABEL_Z = 1.0; -var LABEL_DIST = 8.0; -var TEXT_HEIGHT = 1.0; - -var PlanetLabel = function(name, index) { - var text = name + " Speed: " + Vec3.length(planets[index].velocity).toFixed(2); - this.labelPos = Vec3.sum(planets[index].position, { - x: 0.0, - y: LABEL_DIST, - z: LABEL_DIST - }); - this.linePos = planets[index].position; - - this.line = Entities.addEntity({ - type: "Line", - position: this.linePos, - dimensions: { - x: 20, - y: 20, - z: 20 - }, - lineWidth: LINE_WIDTH, - color: { - red: 255, - green: 255, - blue: 255 - }, - linePoints: [{ + this.tweening = true; + var tweenTime = 800; + var startingPosition = MyAvatar.position; + var endingPosition = Vec3.sum({ x: 0, y: 0, - z: 0 - }, - computeLocalPoint(this.linePos, this.labelPos) - ], - visible: false - }); + z: this.sizeScale + }, this.position); + var currentProps = { + x: startingPosition.x, + y: startingPosition.y, + z: startingPosition.z, + }; + var endProps = { + x: endingPosition.x, + y: endingPosition.y, + z: endingPosition.z, + }; - this.label = Entities.addEntity({ - type: "Text", - text: text, - lineHeight: TEXT_HEIGHT, - dimensions: { - x: LABEL_X, - y: LABEL_Y, - z: LABEL_Z - }, - position: this.labelPos, - backgroundColor: { - red: 10, - green: 10, - blue: 10 - }, - faceCamera: true, - visible: false - }); + var moveTween = new TWEEN.Tween(currentProps). + to(endProps, tweenTime). + easing(TWEEN.Easing.Cubic.InOut). + onUpdate(function() { + print(JSON.stringify(currentProps)); + MyAvatar.position = { + x: currentProps.x, + y: currentProps.y, + z: currentProps.z + }; + }).start(); - this.show = function() { - this.showing = true; - Entities.editEntity(this.line, { - visible: true + moveTween.onComplete(function() { + this.tweening = false; + }); + + } + + index++; + this.resetTrails(); + + } + + + var MERCURY_LINE_COLOR = { + red: 255, + green: 255, + blue: 255 + }; + var VENUS_LINE_COLOR = { + red: 255, + green: 160, + blue: 110 + }; + var EARTH_LINE_COLOR = { + red: 10, + green: 150, + blue: 160 + }; + var MARS_LINE_COLOR = { + red: 180, + green: 70, + blue: 10 + }; + var JUPITER_LINE_COLOR = { + red: 250, + green: 140, + blue: 0 + }; + var SATURN_LINE_COLOR = { + red: 235, + green: 215, + blue: 0 + }; + var URANUS_LINE_COLOR = { + red: 135, + green: 205, + blue: 240 + }; + var NEPTUNE_LINE_COLOR = { + red: 30, + green: 140, + blue: 255 + }; + var PLUTO_LINE_COLOR = { + red: 255, + green: 255, + blue: 255 + }; + + planets.push(new Planet("mercury", MERCURY_LINE_COLOR, 0.387, 0.383)); + planets.push(new Planet("venus", VENUS_LINE_COLOR, 0.723, 0.949)); + planets.push(new Planet("earth", EARTH_LINE_COLOR, 1.0, 1.0)); + planets.push(new Planet("mars", MARS_LINE_COLOR, 1.52, 0.532)); + planets.push(new Planet("jupiter", JUPITER_LINE_COLOR, 5.20, 11.21)); + planets.push(new Planet("saturn", SATURN_LINE_COLOR, 9.58, 9.45)); + planets.push(new Planet("uranus", URANUS_LINE_COLOR, 19.20, 4.01)); + planets.push(new Planet("neptune", NEPTUNE_LINE_COLOR, 30.05, 3.88)); + planets.push(new Planet("pluto", PLUTO_LINE_COLOR, 39.48, 0.186)); + + var LABEL_X = 8.0; + var LABEL_Y = 3.0; + var LABEL_Z = 1.0; + var LABEL_DIST = 8.0; + var TEXT_HEIGHT = 1.0; + + var PlanetLabel = function(name, index) { + var text = name + " Speed: " + Vec3.length(planets[index].velocity).toFixed(2); + this.labelPos = Vec3.sum(planets[index].position, { + x: 0.0, + y: LABEL_DIST, + z: LABEL_DIST }); - Entities.editEntity(this.label, { - visible: true - }); - } + this.linePos = planets[index].position; - this.hide = function() { - this.showing = false; - Entities.editEntity(this.line, { - visible: false - }); - Entities.editEntity(this.label, { - visible: false - }); - } -} - - -var time = 0.0; -var elapsed; -var TIME_STEP = 60.0; -var dt = 1.0 / TIME_STEP; - -var planetLines = []; -var trails = []; -var paused = false; - -function update(deltaTime) { - if (paused) { - return; - } - //deltaTime = dt; - time++; - if (time % TIME_STEP == 0) { - elapsed++; - } - - for (var i = 0; i < planets.length; ++i) { - planets[i].update(deltaTime); - } -} - -function pause() { - for (var i = 0; i < planets.length; ++i) { - Entities.editEntity(planets[i].planet, { - velocity: { - x: 0.0, - y: 0.0, - z: 0.0 - } - }); - planets[i].label = new PlanetLabel(planets[i].name, i); - planets[i].label.show(); - } - paused = true; -} - -function resume() { - for (var i = 0; i < planets.length; ++i) { - planets[i].label.hide(); - } - paused = false; -} - -function computeLocalPoint(linePos, worldPoint) { - var localPoint = Vec3.subtract(worldPoint, linePos); - return localPoint; -} - -// Create a new line -function newLine(lineStack, point, period, color) { - if (elapsed < period) { - var line = Entities.addEntity({ - position: point, + this.line = Entities.addEntity({ type: "Line", - color: color, + position: this.linePos, dimensions: { - x: LINE_DIM, - y: LINE_DIM, - z: LINE_DIM + x: 20, + y: 20, + z: 20 }, - lifetime: LIFETIME, - lineWidth: LINE_WIDTH - }); - lineStack.push(line); - } else { - // Begin overwriting first lines after one full revolution (one period) - var firstLine = lineStack.shift(); - Entities.editEntity(firstLine, { - position: point, - linePoints: [{ - x: 0.0, - y: 0.0, - z: 0.0 - }] - }); - lineStack.push(firstLine); - - } - var points = []; - points.push(computeLocalPoint(point, point)); - return points; -} - - - -var spacing = 8; -var textWidth = 70; -var buttonWidth = 30; -var buttonHeight = 30; - -var ICONS_URL = 'https://s3.amazonaws.com/hifi-public/marketplace/hificontent/Scripts/planets/images/'; - -var UIPanel = function(x, y, orientation) { - this.visible = false; - this.buttons = []; - this.x = x; - this.y = y; - this.nextX = x + spacing; - this.nextY = y + spacing; - this.width = spacing * 2.0; - this.height = spacing * 2.0; - - this.background = Overlays.addOverlay("text", { - backgroundColor: { - red: 240, - green: 240, - blue: 255 - }, - x: this.x, - y: this.y, - width: this.width, - height: this.height, - alpha: 1.0, - backgroundAlpha: 0.7, - visible: false - }); - - this.addIcon = function(iconID) { - var icon = Overlays.addOverlay("image", { + lineWidth: LINE_WIDTH, color: { red: 255, green: 255, blue: 255 }, - imageURL: ICONS_URL + iconID + '.svg', - x: this.nextX, - y: this.nextY, - width: buttonWidth, - height: buttonHeight, - alpha: 1.0, + linePoints: [{ + x: 0, + y: 0, + z: 0 + }, + computeLocalPoint(this.linePos, this.labelPos) + ], visible: false }); - - if (orientation === 'horizontal') { - this.nextX += buttonWidth + spacing; - this.width += buttonWidth; - - } else if (orientation === 'vertical') { - this.nextY += buttonHeight + spacing; - this.height += buttonHeight; - } - - Overlays.editOverlay(this.background, { - width: buttonWidth + this.width, - height: buttonHeight + this.height - }); - - this.buttons.push(icon); - return icon; - }; - - this.addText = function(text) { - var icon = Overlays.addOverlay("text", { - color: { - red: 240, - green: 240, - blue: 255 - }, + this.label = Entities.addEntity({ + type: "Text", text: text, - x: this.nextX, - y: this.nextY, - width: textWidth, - height: buttonHeight, + lineHeight: TEXT_HEIGHT, + dimensions: { + x: LABEL_X, + y: LABEL_Y, + z: LABEL_Z + }, + position: this.labelPos, + backgroundColor: { + red: 10, + green: 10, + blue: 10 + }, + faceCamera: true, visible: false }); - if (orientation === 'horizontal') { - this.nextX += textWidth + spacing; - this.width += textWidth; - - } else if (orientation === 'vertical') { - this.nextY += buttonHeight + spacing; - this.height += buttonHeight; - } - - Overlays.editOverlay(this.background, { - width: textWidth + this.width, - height: buttonHeight + this.height - }); - - this.buttons.push(icon); - return icon; - }; - - - this.show = function() { - Overlays.editOverlay(this.background, { - visible: true - }); - for (var i in this.buttons) { - Overlays.editOverlay(this.buttons[i], { + this.show = function() { + this.showing = true; + Entities.editEntity(this.line, { + visible: true + }); + Entities.editEntity(this.label, { visible: true }); } - this.visible = true; - }; - this.hide = function() { - Overlays.editOverlay(this.background, { - visible: false - }); - for (var i in this.buttons) { - Overlays.editOverlay(this.buttons[i], { + this.hide = function() { + this.showing = false; + Entities.editEntity(this.line, { + visible: false + }); + Entities.editEntity(this.label, { visible: false }); } - this.visible = false; - }; + } - this.remove = function() { - Overlays.deleteOverlay(this.background); - for (var i in this.buttons) { - Overlays.deleteOverlay(this.buttons[i]); - } - }; + var planetLines = []; + var trails = this.trails = []; + var paused = this.paused = false; -} - -var panelX = 1250; -var panelY = 500; -var panelWidth = 50; -var panelHeight = 210; - -var mainPanel = new UIPanel(panelX, panelY, 'vertical'); - -var systemViewButton = mainPanel.addIcon('solarsystems'); -var systemViewPanel = new UIPanel(panelX - 140, panelY, 'horizontal'); -var reverseButton = systemViewPanel.addIcon('reverse'); -var pauseButton = systemViewPanel.addIcon('playpause'); -var forwardButton = systemViewPanel.addIcon('forward'); - -var zoomButton = mainPanel.addIcon('magnifier'); -var zoomPanel = new UIPanel(panelX - 900, panelY + (buttonHeight + spacing) * 4.0, 'horizontal'); -for (var i = 0; i < planets.length; ++i) { - zoomPanel.addText(planets[i].name); -} - -var satelliteButton = mainPanel.addIcon('satellite'); -var settingsButton = mainPanel.addIcon('settings'); -var stopButton = mainPanel.addIcon('close'); - -mainPanel.show(); - -Script.include('../utilities/tools/cookies.js'); - - -var satelliteView; -var satelliteGame; - var settings = new Panel(panelX - 610, panelY - 80); - - var g_multiplier = 1.0; - settings.newSlider("Gravitational Force ", 0.1, 5.0, - function(value) { - g_multiplier = value; - GRAVITY = REFERENCE_GRAVITY * g_multiplier; - }, - - function() { - return g_multiplier; - }, - function(value) { - return value.toFixed(1) + "x"; - }); - - - var subPanel = settings.newSubPanel("Orbital Periods"); - - for (var i = 0; i < planets.length; ++i) { - planets[i].period_multiplier = 1.0; - planets[i].last_alpha = planets[i].period_multiplier; - - subPanel.newSlider(planets[i].name, 0.1, 3.0, - function(value) { - planets[i].period_multiplier = value; - planets[i].adjustPeriod(value); - }, - function() { - return planets[i].period_multiplier; - }, - function(value) { - return (value).toFixed(2) + "x"; - }); - } - settings.newCheckbox("Leave Trails: ", - function(value) { - trailsEnabled = value; - if (trailsEnabled) { - for (var i = 0; i < planets.length; ++i) { - planets[i].resetTrails(); - } - //if trails are off and we've already created trails, remove existing trails - } else { - for (var i = 0; i < planets.length; ++i) { - for (var j = 0; j < planets[i].lineStack.length; ++j) { - Entities.editEntity(planets[i].lineStack[j], { - visible: false - }); - } - planets[i].lineStack = []; - } - } - }, - function() { - return trailsEnabled; - }, - function(value) { - return value; - }); - settings.hide(); - - -function mousePressEvent(event) { - - var clicked = Overlays.getOverlayAtPoint({ - x: event.x, - y: event.y - }); - - if (clicked == systemViewButton) { - MyAvatar.position = startingPosition; - Camera.setOrientation(cameraStart); + this.update = function(deltaTime) { if (paused) { - resume(); + return; } - - if (!systemViewPanel.visible) { - systemViewPanel.show(); - } else { - systemViewPanel.hide(); - } - } - var zoomed = false; - if (clicked == zoomButton && !satelliteView) { - if (!zoomPanel.visible) { - zoomPanel.show(); - pause(); - } else { - zoomPanel.hide(); - if (zoomed) { - - MyAvatar.position = startingPosition; - Camera.setOrientation(cameraStart); - resume(); - } - - } - } - - for (var i = 0; i < planets.length; ++i) { - if (zoomPanel.visible && clicked == zoomPanel.buttons[i]) { - planets[i].zoom(); - zoomed = true; - break; - } - } - - if (systemViewPanel.visible && clicked == pauseButton) { - if (!paused) { - pause(); - } else { - resume(); - } - } - - - - if (clicked == satelliteButton) { - if (satelliteView) { - satelliteGame.endGame(); - MyAvatar.position = startingPosition; - satelliteView = false; - resume(); - } else { - pause(); - var confirmed = Window.confirm("Start satellite game?"); - if (!confirmed) { - resume(); + for (var i = 0; i < planets.length; ++i) { + if (planets[i].tweening) { + TWEEN.update(); continue; } - satelliteView = true; - MyAvatar.position = { - x: 200, - y: 200, - z: 200 - }; - Camera.setPosition({ - x: 200, - y: 200, - z: 200 - }); - satelliteGame = new SatelliteGame(); + planets[i].update(deltaTime); } } - if (clicked == settingsButton) { - if (!settings.visible) { - settings.show(); - } else { - settings.hide(); - } - } + Script.include('planets-ui.js'); - if (clicked == stopButton) { - Script.stop(); - } + // Clean up models, UI panels, lines, and button overlays + this.scriptEnding = function() { + Entities.deleteEntity(theSun); + for (var i = 0; i < planets.length; ++i) { + Entities.deleteEntity(planets[i].planet); + } + var e = Entities.findEntities(MyAvatar.position, 10000); + for (i = 0; i < e.length; i++) { + var props = Entities.getEntityProperties(e[i]); + if (props.type === "Line" || props.type === "Text") { + Entities.deleteEntity(e[i]); + } + } + }; + Script.update.connect(update); + } -// Clean up models, UI panels, lines, and button overlays -function scriptEnding() { - mainPanel.remove(); - systemViewPanel.remove(); - zoomPanel.remove(); - - settings.destroy(); - - Entities.deleteEntity(theSun); - for (var i = 0; i < planets.length; ++i) { - Entities.deleteEntity(planets[i].planet); - } +Script.scriptEnding.connect(function() { + scriptEnding(); + teardown(); +}); + +CreateSimulation(); - var e = Entities.findEntities(MyAvatar.position, 16000); - for (i = 0; i < e.length; i++) { - var props = Entities.getEntityProperties(e[i]); - if (props.type === "Line" || props.type === "Text") { - Entities.deleteEntity(e[i]); - } - } -}; - -Controller.mousePressEvent.connect(mousePressEvent); - - Controller.mouseMoveEvent.connect(function panelMouseMoveEvent(event) { - return settings.mouseMoveEvent(event); - }); - Controller.mousePressEvent.connect(function panelMousePressEvent(event) { - return settings.mousePressEvent(event); - }); - Controller.mouseDoublePressEvent.connect(function panelMouseDoublePressEvent(event) { - return settings.mouseDoublePressEvent(event); - }); - Controller.mouseReleaseEvent.connect(function(event) { - return settings.mouseReleaseEvent(event); - }); - Controller.keyPressEvent.connect(function(event) { - return settings.keyPressEvent(event); - }); - -Script.scriptEnding.connect(scriptEnding); -Script.update.connect(update); \ No newline at end of file diff --git a/examples/libraries/uiwidgets.js b/examples/libraries/uiwidgets.js index fa898ea7bc..70eda8e5f2 100644 --- a/examples/libraries/uiwidgets.js +++ b/examples/libraries/uiwidgets.js @@ -501,7 +501,7 @@ Box.prototype.destroy = function () { } } Box.prototype.hasOverlay = function (overlayId) { - return this.overlay && this.overlay.getId() === overlayId; + return /*this.overlay &&*/ this.overlay.getId() === overlayId; } Box.prototype.getOverlay = function () { return this.overlay; @@ -615,7 +615,7 @@ Slider.prototype.toString = function () { } Slider.prototype.applyLayout = function () { if (!this.slider) { - ui.complain("Slider.applyLayout on " + this + " failed"); + // ui.complain("Slider.applyLayout on " + this + " failed"); return; } var val = (this.value - this.minValue) / (this.maxValue - this.minValue); @@ -654,6 +654,7 @@ var Checkbox = UI.Checkbox = function (properties) { this.position.x + (this.width - this.checkMark.width) * 0.5, this.position.y + (this.height - this.checkMark.height) * 0.5 ); + this.checkMark.parent = this; this.onValueChanged = properties.onValueChanged || function () {}; @@ -919,9 +920,16 @@ var getFocusedWidget = function (event) { var dispatchEvent = function (action, event, widget) { function dispatchActions (actions) { + var dispatchedActions = false; + ui.logEvent("dispatching to [" + actions.join(", ") + "]"); actions.forEach(function(action) { action(event, widget); + ui.logEvent("dispatched to " + action); + dispatchedActions = true; }); + if (!dispatchedActions) { + // ui.logEvent("No actions to dispatch"); + } } if (widget.actions[action]) { @@ -963,7 +971,7 @@ UI.handleMouseMove = function (event, canStartDrag) { } UI.handleMousePress = function (event) { - print("Mouse clicked"); + // print("Mouse clicked"); UI.handleMouseMove(event); ui.clickedWidget = ui.focusedWidget; if (ui.clickedWidget) { @@ -971,8 +979,18 @@ UI.handleMousePress = function (event) { } } +UI.handleMouseDoublePress = function (event) { + // print("DOUBLE CLICK!"); + var focused = getFocusedWidget(event); + UI.handleMouseMove(event); + if (focused) { + // print("dispatched onDoubleClick"); + dispatchEvent('onDoubleClick', event, focused); + } +} + UI.handleMouseRelease = function (event) { - print("Mouse released"); + // print("Mouse released"); if (ui.draggedWidget) { dispatchEvent('onDragEnd', event, ui.draggedWidget);