From fc68b31b712f0506e3f6b4e6eb225f3153350f1b Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 12 Sep 2015 08:23:50 -0700 Subject: [PATCH 001/212] Revert "Revert "edit.js adjustment"" --- examples/edit.js | 7 ++----- examples/libraries/entityList.js | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/examples/edit.js b/examples/edit.js index d778ff324d..55b745a4e1 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -260,7 +260,6 @@ var toolBar = (function () { cameraManager.disable(); } else { hasShownPropertiesTool = false; - cameraManager.enable(); entityListTool.setVisible(true); gridTool.setVisible(true); grid.setEnabled(true); @@ -670,15 +669,11 @@ function mouseMove(event) { lastMousePosition = { x: event.x, y: event.y }; - highlightEntityUnderCursor(lastMousePosition, false); idleMouseTimerId = Script.setTimeout(handleIdleMouse, IDLE_MOUSE_TIMEOUT); } function handleIdleMouse() { idleMouseTimerId = null; - if (isActive) { - highlightEntityUnderCursor(lastMousePosition, true); - } } function highlightEntityUnderCursor(position, accurateRay) { @@ -802,6 +797,7 @@ function mouseClickEvent(event) { selectionDisplay.select(selectedEntityID, event); if (Menu.isOptionChecked(MENU_AUTO_FOCUS_ON_SELECT)) { + cameraManager.enable(); cameraManager.focus(selectionManager.worldPosition, selectionManager.worldDimensions, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); @@ -1142,6 +1138,7 @@ Controller.keyReleaseEvent.connect(function (event) { } else if (event.text == "f") { if (isActive) { if (selectionManager.hasSelection()) { + cameraManager.enable(); cameraManager.focus(selectionManager.worldPosition, selectionManager.worldDimensions, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); diff --git a/examples/libraries/entityList.js b/examples/libraries/entityList.js index 66dc9f336f..3d6bf4d14f 100644 --- a/examples/libraries/entityList.js +++ b/examples/libraries/entityList.js @@ -49,7 +49,7 @@ EntityListTool = function(opts) { var selectedIDs = []; for (var i = 0; i < selectionManager.selections.length; i++) { - selectedIDs.push(selectionManager.selections[i].id); // ? + selectedIDs.push(selectionManager.selections[i].id); } var data = { @@ -70,6 +70,7 @@ EntityListTool = function(opts) { } selectionManager.setSelections(entityIDs); if (data.focus) { + cameraManager.enable(); cameraManager.focus(selectionManager.worldPosition, selectionManager.worldDimensions, Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); From b9985031dacaa6e762a7f717a1562840e473f702 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 09:03:42 -0700 Subject: [PATCH 002/212] adding blocks --- examples/acScripts/toybox.js | 17 ++++++++++ examples/toybox/spawners/blockSpawner.js | 43 ++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 examples/acScripts/toybox.js create mode 100644 examples/toybox/spawners/blockSpawner.js diff --git a/examples/acScripts/toybox.js b/examples/acScripts/toybox.js new file mode 100644 index 0000000000..f4b9fc3d95 --- /dev/null +++ b/examples/acScripts/toybox.js @@ -0,0 +1,17 @@ +//TODO: Figure out why importing svo is only working locally + +print("SHNUR SHNUR SHNUR") + +var light = Entities.addEntity({ + type: "Box", + position: {x: 493, y: 505, z: 602}, + dimensions: {x: 3, y: 3, z: 3}, + color: {red: 200, green : 10, blue: 200} +}); + + +// function cleanup() { +// Entities.deleteEntity(light); +// } + +// Script.scriptEnding.connect(cleanup); diff --git a/examples/toybox/spawners/blockSpawner.js b/examples/toybox/spawners/blockSpawner.js new file mode 100644 index 0000000000..b62f62b594 --- /dev/null +++ b/examples/toybox/spawners/blockSpawner.js @@ -0,0 +1,43 @@ +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; +var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; + +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); +var BASE_DIMENSIONS = Vec3.multiply({x: 0.2, y: 0.1, z: 0.8}, 0.2); +var NUM_BLOCKS = 4; + +var blocks = []; + +spawnBlocks(); + +var table = Entities.addEntity({ + type: "Box", + position: Vec3.sum(center, {x: 0, y: -0.2, z: 0}), + dimensions: {x: 2, y: .01, z: 2}, + color: {red: 20, green: 20, blue: 20} +}) +function spawnBlocks() { + for (var i = 0; i < NUM_BLOCKS; i++) { + var block = Entities.addEntity({ + type: "Model", + modelURL: modelUrl, + position: center, + shapeType: 'box', + name: "block", + dimensions: Vec3.sum(BASE_DIMENSIONS, {x: Math.random()/10, y: Math.random()/10, z:Math.random()/10}), + collisionsWillMove: true, + gravity: {x: 0, y: -9.8, z: 0}, + velocity: {x: 0, y: -.01, z: 0} + + }); + blocks.push(block); + } +} + +function cleanup() { + Entities.deleteEntity(table); + blocks.forEach(function(block) { + Entities.deleteEntity(block); + }); +} + +Script.scriptEnding.connect(cleanup); \ No newline at end of file From 7ffcce589dcf30405cde806d99fc2d5dbfd188e6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 09:09:25 -0700 Subject: [PATCH 003/212] blocks spawning --- examples/toybox/spawners/blockSpawner.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/toybox/spawners/blockSpawner.js b/examples/toybox/spawners/blockSpawner.js index b62f62b594..2ea17988f0 100644 --- a/examples/toybox/spawners/blockSpawner.js +++ b/examples/toybox/spawners/blockSpawner.js @@ -9,18 +9,18 @@ var blocks = []; spawnBlocks(); -var table = Entities.addEntity({ - type: "Box", - position: Vec3.sum(center, {x: 0, y: -0.2, z: 0}), - dimensions: {x: 2, y: .01, z: 2}, - color: {red: 20, green: 20, blue: 20} -}) +// var table = Entities.addEntity({ +// type: "Box", +// position: Vec3.sum(center, {x: 0, y: -0.2, z: 0}), +// dimensions: {x: 2, y: .01, z: 2}, +// color: {red: 20, green: 20, blue: 20} +// }) function spawnBlocks() { for (var i = 0; i < NUM_BLOCKS; i++) { var block = Entities.addEntity({ type: "Model", modelURL: modelUrl, - position: center, + position: {x: 548.3, y:495.55, z:504.4}, shapeType: 'box', name: "block", dimensions: Vec3.sum(BASE_DIMENSIONS, {x: Math.random()/10, y: Math.random()/10, z:Math.random()/10}), @@ -34,10 +34,10 @@ function spawnBlocks() { } function cleanup() { - Entities.deleteEntity(table); - blocks.forEach(function(block) { - Entities.deleteEntity(block); - }); + // Entities.deleteEntity(table); +// blocks.forEach(function(block) { +// Entities.deleteEntity(block); +// }); } Script.scriptEnding.connect(cleanup); \ No newline at end of file From c5b7de2156fb3d8ad099712968036c158c5240a5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 10:00:01 -0700 Subject: [PATCH 004/212] added fire spawner --- examples/toybox/spawners/fireSpawner.js | 103 ++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 examples/toybox/spawners/fireSpawner.js diff --git a/examples/toybox/spawners/fireSpawner.js b/examples/toybox/spawners/fireSpawner.js new file mode 100644 index 0000000000..b361c6bdfb --- /dev/null +++ b/examples/toybox/spawners/fireSpawner.js @@ -0,0 +1,103 @@ +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); +var ZERO_VEC = { + x: 0, + y: 0, + z: 0 +} +var totalTime = 0; +var FIRE_COLOR = { + red: 255, + green: 255, + blue: 255 +}; +var minLightIntensity = 3; +var maxLightIntensity = 11; + +var minTimeFactor = .1; +var maxTimeFactor = 1; + +var LIGHT_COLOR = { + red: 255, + green: 100, + blue: 28 +} + +var animationSettings = JSON.stringify({ + fps: 30, + running: true, + loop: true, + firstFrame: 1, + lastFrame: 10000 +}); + + +var fire = Entities.addEntity({ + type: "ParticleEffect", + animationSettings: animationSettings, + textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", + position: { + x: 551.5435791015625, + y: 494.87728881835938, + z: 502.01531982421875 + }, + emitRate: 100, + colorStart: { + red: 46, + green: 39, + blue: 137 + }, + color: { + red: 200, + green: 99, + blue: 42 + }, + colorFinish: { + red: 255, + green: 99, + blue: 32 + }, + emitVelocity: { + x: .0, + y: 0.1, + z: 0 + }, + + velocitySpread: { + x: .1, + y: .01, + z: .1 + }, + radiusSpread: .1, + radiusStart: .1, + particleRadius: .05, + radiusFinish: 0.01, + + alphaStart: 0.5, + alpha: 1, + alphaFinish: 0.0, + emitAcceleration: { + x: 0.1, + y: 1, + z: .0 + }, + accelerationSpread: { + x: .01, + y: .1, + z: .01 + }, + lifespan: 2 +}); + + +function cleanup() { + Entities.deleteEntity(fire); +} +Script.scriptEnding.connect(cleanup); + +function randFloat(min, max) { + return Math.random() * (max - min) + min; +} + +function randInt(min, max) { + return Math.floor(Math.random() * (max - min)) + min; +} \ No newline at end of file From cdae5452ceca496f252b1bf1f9d3509fe2009045 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 14:21:11 -0700 Subject: [PATCH 005/212] going ac script route for entity reset --- examples/acScripts/toybox.js | 17 --- .../{spawners => managers}/blockSpawner.js | 0 examples/toybox/managers/fireManager.js | 103 ++++++++++++++++++ examples/toybox/managers/lightSpawner.js | 14 +++ examples/toybox/masterResetEntity.js | 14 +++ examples/toybox/masterResetEntitySpawner.js | 19 ++++ examples/toybox/spawners/fireSpawner.js | 103 ------------------ 7 files changed, 150 insertions(+), 120 deletions(-) delete mode 100644 examples/acScripts/toybox.js rename examples/toybox/{spawners => managers}/blockSpawner.js (100%) create mode 100644 examples/toybox/managers/fireManager.js create mode 100644 examples/toybox/managers/lightSpawner.js create mode 100644 examples/toybox/masterResetEntity.js create mode 100644 examples/toybox/masterResetEntitySpawner.js delete mode 100644 examples/toybox/spawners/fireSpawner.js diff --git a/examples/acScripts/toybox.js b/examples/acScripts/toybox.js deleted file mode 100644 index f4b9fc3d95..0000000000 --- a/examples/acScripts/toybox.js +++ /dev/null @@ -1,17 +0,0 @@ -//TODO: Figure out why importing svo is only working locally - -print("SHNUR SHNUR SHNUR") - -var light = Entities.addEntity({ - type: "Box", - position: {x: 493, y: 505, z: 602}, - dimensions: {x: 3, y: 3, z: 3}, - color: {red: 200, green : 10, blue: 200} -}); - - -// function cleanup() { -// Entities.deleteEntity(light); -// } - -// Script.scriptEnding.connect(cleanup); diff --git a/examples/toybox/spawners/blockSpawner.js b/examples/toybox/managers/blockSpawner.js similarity index 100% rename from examples/toybox/spawners/blockSpawner.js rename to examples/toybox/managers/blockSpawner.js diff --git a/examples/toybox/managers/fireManager.js b/examples/toybox/managers/fireManager.js new file mode 100644 index 0000000000..15afb0d5ea --- /dev/null +++ b/examples/toybox/managers/fireManager.js @@ -0,0 +1,103 @@ +FireManager = function() { + + this.reset = function() { + if (!this.fire) { + var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); + var ZERO_VEC = { + x: 0, + y: 0, + z: 0 + } + var totalTime = 0; + var FIRE_COLOR = { + red: 255, + green: 255, + blue: 255 + }; + var minLightIntensity = 3; + var maxLightIntensity = 11; + + var minTimeFactor = .1; + var maxTimeFactor = 1; + + var LIGHT_COLOR = { + red: 255, + green: 100, + blue: 28 + } + + var animationSettings = JSON.stringify({ + fps: 30, + running: true, + loop: true, + firstFrame: 1, + lastFrame: 10000 + }); + + var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); + + this.fire = Entities.addEntity({ + type: "ParticleEffect", + animationSettings: animationSettings, + textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", + position: { + x: 551.5435791015625, + y: 494.87728881835938, + z: 502.01531982421875 + }, + name: "fire", + emitRate: 100, + colorStart: { + red: 46, + green: 39, + blue: 137 + }, + color: { + red: 200, + green: 99, + blue: 42 + }, + colorFinish: { + red: 255, + green: 99, + blue: 32 + }, + emitVelocity: { + x: .0, + y: 0.1, + z: 0 + }, + + velocitySpread: { + x: .1, + y: .01, + z: .1 + }, + radiusSpread: .1, + radiusStart: .1, + particleRadius: .05, + radiusFinish: 0.01, + + alphaStart: 0.5, + alpha: 1, + alphaFinish: 0.0, + emitAcceleration: { + x: 0.1, + y: 1, + z: .0 + }, + accelerationSpread: { + x: .01, + y: .1, + z: .01 + }, + lifespan: 2 + }); + + } else { + Entities.deleteEntity(this.fire); + this.fire = null; + } + + } +} \ No newline at end of file diff --git a/examples/toybox/managers/lightSpawner.js b/examples/toybox/managers/lightSpawner.js new file mode 100644 index 0000000000..4a52d4775b --- /dev/null +++ b/examples/toybox/managers/lightSpawner.js @@ -0,0 +1,14 @@ +var light = Entities.addEntity({ + type: "light", + position: {x: 544, y: 498.9, z: 506.7}, + intensity: 10, + dimensions: {x: 10, y: 10, z: 10}, + color: {red: 200, green : 10, blue: 200} +}); + + +function cleanup() { + Entities.deleteEntity(light); +} + +Script.scriptEnding.connect(cleanup); diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js new file mode 100644 index 0000000000..cefaa61fe3 --- /dev/null +++ b/examples/toybox/masterResetEntity.js @@ -0,0 +1,14 @@ +var fireScriptURL = Script.resolvePath("managers/fireManager.js"); +Script.include(fireScriptURL); + +var fireManager = new FireManager(); + +fireManager.reset(); + + + +function cleanup() { + fireManager.reset(); +} + +Script.scriptEnding.connect(cleanup); diff --git a/examples/toybox/masterResetEntitySpawner.js b/examples/toybox/masterResetEntitySpawner.js new file mode 100644 index 0000000000..8938595d7f --- /dev/null +++ b/examples/toybox/masterResetEntitySpawner.js @@ -0,0 +1,19 @@ +var scriptURL = Script.resolvePath("masterResetEntity.js?v1" + Math.random()); + +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(1, Quat.getFront(Camera.getOrientation()))); + +var resetEntity = Entities.addEntity({ + type: "Box", + dimensions: {x: .3, y: 0.3, z: 0.3}, + position: center, + color: {red: 100, green: 10, blue: 100}, + script: scriptURL +}); + + + +function cleanup() { + Entities.deleteEntity(resetEntity); +} + +Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/toybox/spawners/fireSpawner.js b/examples/toybox/spawners/fireSpawner.js deleted file mode 100644 index b361c6bdfb..0000000000 --- a/examples/toybox/spawners/fireSpawner.js +++ /dev/null @@ -1,103 +0,0 @@ -var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); -var ZERO_VEC = { - x: 0, - y: 0, - z: 0 -} -var totalTime = 0; -var FIRE_COLOR = { - red: 255, - green: 255, - blue: 255 -}; -var minLightIntensity = 3; -var maxLightIntensity = 11; - -var minTimeFactor = .1; -var maxTimeFactor = 1; - -var LIGHT_COLOR = { - red: 255, - green: 100, - blue: 28 -} - -var animationSettings = JSON.stringify({ - fps: 30, - running: true, - loop: true, - firstFrame: 1, - lastFrame: 10000 -}); - - -var fire = Entities.addEntity({ - type: "ParticleEffect", - animationSettings: animationSettings, - textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", - position: { - x: 551.5435791015625, - y: 494.87728881835938, - z: 502.01531982421875 - }, - emitRate: 100, - colorStart: { - red: 46, - green: 39, - blue: 137 - }, - color: { - red: 200, - green: 99, - blue: 42 - }, - colorFinish: { - red: 255, - green: 99, - blue: 32 - }, - emitVelocity: { - x: .0, - y: 0.1, - z: 0 - }, - - velocitySpread: { - x: .1, - y: .01, - z: .1 - }, - radiusSpread: .1, - radiusStart: .1, - particleRadius: .05, - radiusFinish: 0.01, - - alphaStart: 0.5, - alpha: 1, - alphaFinish: 0.0, - emitAcceleration: { - x: 0.1, - y: 1, - z: .0 - }, - accelerationSpread: { - x: .01, - y: .1, - z: .01 - }, - lifespan: 2 -}); - - -function cleanup() { - Entities.deleteEntity(fire); -} -Script.scriptEnding.connect(cleanup); - -function randFloat(min, max) { - return Math.random() * (max - min) + min; -} - -function randInt(min, max) { - return Math.floor(Math.random() * (max - min)) + min; -} \ No newline at end of file From 75c1e4956785188ce3aa0f6a2198a5adb34c0018 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 15:32:40 -0700 Subject: [PATCH 006/212] more tweaks yeah --- examples/toybox/managers/blockManager.js | 68 ++++++++++++++++++++++++ examples/toybox/managers/blockSpawner.js | 43 --------------- examples/toybox/masterResetEntity.js | 8 ++- 3 files changed, 75 insertions(+), 44 deletions(-) create mode 100644 examples/toybox/managers/blockManager.js delete mode 100644 examples/toybox/managers/blockSpawner.js diff --git a/examples/toybox/managers/blockManager.js b/examples/toybox/managers/blockManager.js new file mode 100644 index 0000000000..3f2ee15151 --- /dev/null +++ b/examples/toybox/managers/blockManager.js @@ -0,0 +1,68 @@ +BlockManager = function() { + + this.spawned = false; + this.blocks = []; + + this.reset = function() { + if (this.spawned) { + this.clearBlocks(); + } else { + this.createBlocks(); + } + + this.spawned = !this.spawned; + } + + this.clearBlocks = function() { + this.blocks.forEach(function(block) { + Entities.deleteEntity(block); + }); + this.blocks = []; + } + + this.createBlocks = function() { + + HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; + var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; + + var BASE_DIMENSIONS = Vec3.multiply({ + x: 0.2, + y: 0.1, + z: 0.8 + }, 0.2); + var NUM_BLOCKS = 4; + + for (var i = 0; i < NUM_BLOCKS; i++) { + var block = Entities.addEntity({ + type: "Model", + modelURL: modelUrl, + position: { + x: 548.3, + y: 495.55 + i/5, + z: 504.4 + }, + shapeType: 'box', + name: "block", + dimensions: Vec3.sum(BASE_DIMENSIONS, { + x: Math.random() / 10, + y: Math.random() / 10, + z: Math.random() / 10 + }), + collisionsWillMove: true, + gravity: { + x: 0, + y: -2.5, + z: 0 + }, + velocity: { + x: 0, + y: -.01, + z: 0 + } + + }); + this.blocks.push(block); + } + + } +} \ No newline at end of file diff --git a/examples/toybox/managers/blockSpawner.js b/examples/toybox/managers/blockSpawner.js deleted file mode 100644 index 2ea17988f0..0000000000 --- a/examples/toybox/managers/blockSpawner.js +++ /dev/null @@ -1,43 +0,0 @@ -HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; -var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; - -var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); -var BASE_DIMENSIONS = Vec3.multiply({x: 0.2, y: 0.1, z: 0.8}, 0.2); -var NUM_BLOCKS = 4; - -var blocks = []; - -spawnBlocks(); - -// var table = Entities.addEntity({ -// type: "Box", -// position: Vec3.sum(center, {x: 0, y: -0.2, z: 0}), -// dimensions: {x: 2, y: .01, z: 2}, -// color: {red: 20, green: 20, blue: 20} -// }) -function spawnBlocks() { - for (var i = 0; i < NUM_BLOCKS; i++) { - var block = Entities.addEntity({ - type: "Model", - modelURL: modelUrl, - position: {x: 548.3, y:495.55, z:504.4}, - shapeType: 'box', - name: "block", - dimensions: Vec3.sum(BASE_DIMENSIONS, {x: Math.random()/10, y: Math.random()/10, z:Math.random()/10}), - collisionsWillMove: true, - gravity: {x: 0, y: -9.8, z: 0}, - velocity: {x: 0, y: -.01, z: 0} - - }); - blocks.push(block); - } -} - -function cleanup() { - // Entities.deleteEntity(table); -// blocks.forEach(function(block) { -// Entities.deleteEntity(block); -// }); -} - -Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index cefaa61fe3..783926daad 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -1,14 +1,20 @@ var fireScriptURL = Script.resolvePath("managers/fireManager.js"); Script.include(fireScriptURL); -var fireManager = new FireManager(); +var blockScriptURL = Script.resolvePath("managers/blockManager.js"); +Script.include(blockScriptURL); +var fireManager = new FireManager(); fireManager.reset(); +var blockManager = new BlockManager(); +blockManager.reset(); + function cleanup() { fireManager.reset(); + blockManager.reset(); } Script.scriptEnding.connect(cleanup); From 109f2d8a1afd30d2cb02d7077ad195b63c721655 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 15:39:31 -0700 Subject: [PATCH 007/212] base positions --- examples/toybox/managers/blockManager.js | 10 +++------- examples/toybox/managers/fireManager.js | 12 +++--------- examples/toybox/masterResetEntity.js | 15 ++++++++++++--- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/examples/toybox/managers/blockManager.js b/examples/toybox/managers/blockManager.js index 3f2ee15151..7158e4499f 100644 --- a/examples/toybox/managers/blockManager.js +++ b/examples/toybox/managers/blockManager.js @@ -1,5 +1,5 @@ -BlockManager = function() { - +BlockManager = function(position) { + this.position = position; this.spawned = false; this.blocks = []; @@ -36,11 +36,7 @@ BlockManager = function() { var block = Entities.addEntity({ type: "Model", modelURL: modelUrl, - position: { - x: 548.3, - y: 495.55 + i/5, - z: 504.4 - }, + position: Vec3.sum(this.position, {x: 0, y: i/5, z:0}), shapeType: 'box', name: "block", dimensions: Vec3.sum(BASE_DIMENSIONS, { diff --git a/examples/toybox/managers/fireManager.js b/examples/toybox/managers/fireManager.js index 15afb0d5ea..30a65698fd 100644 --- a/examples/toybox/managers/fireManager.js +++ b/examples/toybox/managers/fireManager.js @@ -1,5 +1,5 @@ -FireManager = function() { - +FireManager = function(position) { + this.position = position; this.reset = function() { if (!this.fire) { var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); @@ -34,17 +34,11 @@ FireManager = function() { lastFrame: 10000 }); - var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); - this.fire = Entities.addEntity({ type: "ParticleEffect", animationSettings: animationSettings, textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", - position: { - x: 551.5435791015625, - y: 494.87728881835938, - z: 502.01531982421875 - }, + position: this.position, name: "fire", emitRate: 100, colorStart: { diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 783926daad..9612745d93 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -4,10 +4,19 @@ Script.include(fireScriptURL); var blockScriptURL = Script.resolvePath("managers/blockManager.js"); Script.include(blockScriptURL); -var fireManager = new FireManager(); +var fireManager = new FireManager({ + x: 551.5435791015625, + y: 494.87728881835938, + z: 502.01531982421875 +}); + fireManager.reset(); -var blockManager = new BlockManager(); +var blockManager = new BlockManager({ + x: 548.3, + y: 495.55, + z: 504.4 + }); blockManager.reset(); @@ -17,4 +26,4 @@ function cleanup() { blockManager.reset(); } -Script.scriptEnding.connect(cleanup); +Script.scriptEnding.connect(cleanup); \ No newline at end of file From 9614a69b19f48e1fb2b80c5fd9c6961f335e6917 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 16:12:16 -0700 Subject: [PATCH 008/212] adding spray can --- examples/toybox/managers/lightSpawner.js | 14 -------------- examples/toybox/managers/sprayCanManager.js | 0 2 files changed, 14 deletions(-) delete mode 100644 examples/toybox/managers/lightSpawner.js create mode 100644 examples/toybox/managers/sprayCanManager.js diff --git a/examples/toybox/managers/lightSpawner.js b/examples/toybox/managers/lightSpawner.js deleted file mode 100644 index 4a52d4775b..0000000000 --- a/examples/toybox/managers/lightSpawner.js +++ /dev/null @@ -1,14 +0,0 @@ -var light = Entities.addEntity({ - type: "light", - position: {x: 544, y: 498.9, z: 506.7}, - intensity: 10, - dimensions: {x: 10, y: 10, z: 10}, - color: {red: 200, green : 10, blue: 200} -}); - - -function cleanup() { - Entities.deleteEntity(light); -} - -Script.scriptEnding.connect(cleanup); diff --git a/examples/toybox/managers/sprayCanManager.js b/examples/toybox/managers/sprayCanManager.js new file mode 100644 index 0000000000..e69de29bb2 From 78642e3c79858f8e3134d43328e90cdeebd570dc Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 17:04:09 -0700 Subject: [PATCH 009/212] Getting rid of managers --- examples/toybox/managers/blockManager.js | 64 -------------- examples/toybox/managers/fireManager.js | 97 --------------------- examples/toybox/managers/sprayCanManager.js | 0 examples/toybox/masterResetEntity.js | 97 ++++++++++++++++----- 4 files changed, 77 insertions(+), 181 deletions(-) delete mode 100644 examples/toybox/managers/blockManager.js delete mode 100644 examples/toybox/managers/fireManager.js delete mode 100644 examples/toybox/managers/sprayCanManager.js diff --git a/examples/toybox/managers/blockManager.js b/examples/toybox/managers/blockManager.js deleted file mode 100644 index 7158e4499f..0000000000 --- a/examples/toybox/managers/blockManager.js +++ /dev/null @@ -1,64 +0,0 @@ -BlockManager = function(position) { - this.position = position; - this.spawned = false; - this.blocks = []; - - this.reset = function() { - if (this.spawned) { - this.clearBlocks(); - } else { - this.createBlocks(); - } - - this.spawned = !this.spawned; - } - - this.clearBlocks = function() { - this.blocks.forEach(function(block) { - Entities.deleteEntity(block); - }); - this.blocks = []; - } - - this.createBlocks = function() { - - HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; - var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; - - var BASE_DIMENSIONS = Vec3.multiply({ - x: 0.2, - y: 0.1, - z: 0.8 - }, 0.2); - var NUM_BLOCKS = 4; - - for (var i = 0; i < NUM_BLOCKS; i++) { - var block = Entities.addEntity({ - type: "Model", - modelURL: modelUrl, - position: Vec3.sum(this.position, {x: 0, y: i/5, z:0}), - shapeType: 'box', - name: "block", - dimensions: Vec3.sum(BASE_DIMENSIONS, { - x: Math.random() / 10, - y: Math.random() / 10, - z: Math.random() / 10 - }), - collisionsWillMove: true, - gravity: { - x: 0, - y: -2.5, - z: 0 - }, - velocity: { - x: 0, - y: -.01, - z: 0 - } - - }); - this.blocks.push(block); - } - - } -} \ No newline at end of file diff --git a/examples/toybox/managers/fireManager.js b/examples/toybox/managers/fireManager.js deleted file mode 100644 index 30a65698fd..0000000000 --- a/examples/toybox/managers/fireManager.js +++ /dev/null @@ -1,97 +0,0 @@ -FireManager = function(position) { - this.position = position; - this.reset = function() { - if (!this.fire) { - var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); - var ZERO_VEC = { - x: 0, - y: 0, - z: 0 - } - var totalTime = 0; - var FIRE_COLOR = { - red: 255, - green: 255, - blue: 255 - }; - var minLightIntensity = 3; - var maxLightIntensity = 11; - - var minTimeFactor = .1; - var maxTimeFactor = 1; - - var LIGHT_COLOR = { - red: 255, - green: 100, - blue: 28 - } - - var animationSettings = JSON.stringify({ - fps: 30, - running: true, - loop: true, - firstFrame: 1, - lastFrame: 10000 - }); - - this.fire = Entities.addEntity({ - type: "ParticleEffect", - animationSettings: animationSettings, - textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", - position: this.position, - name: "fire", - emitRate: 100, - colorStart: { - red: 46, - green: 39, - blue: 137 - }, - color: { - red: 200, - green: 99, - blue: 42 - }, - colorFinish: { - red: 255, - green: 99, - blue: 32 - }, - emitVelocity: { - x: .0, - y: 0.1, - z: 0 - }, - - velocitySpread: { - x: .1, - y: .01, - z: .1 - }, - radiusSpread: .1, - radiusStart: .1, - particleRadius: .05, - radiusFinish: 0.01, - - alphaStart: 0.5, - alpha: 1, - alphaFinish: 0.0, - emitAcceleration: { - x: 0.1, - y: 1, - z: .0 - }, - accelerationSpread: { - x: .01, - y: .1, - z: .01 - }, - lifespan: 2 - }); - - } else { - Entities.deleteEntity(this.fire); - this.fire = null; - } - - } -} \ No newline at end of file diff --git a/examples/toybox/managers/sprayCanManager.js b/examples/toybox/managers/sprayCanManager.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 9612745d93..cb82034f11 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -1,29 +1,86 @@ -var fireScriptURL = Script.resolvePath("managers/fireManager.js"); -Script.include(fireScriptURL); +var utilitiesScript = Script.resolvePath("../libraries/utils.js"); +Script.include(utilitiesScript); -var blockScriptURL = Script.resolvePath("managers/blockManager.js"); -Script.include(blockScriptURL); +var resetKey = "resetMe"; -var fireManager = new FireManager({ - x: 551.5435791015625, - y: 494.87728881835938, - z: 502.01531982421875 -}); - -fireManager.reset(); - -var blockManager = new BlockManager({ - x: 548.3, - y: 495.55, - z: 504.4 - }); -blockManager.reset(); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; +//Before creating anything, first search a radius and delete all the things that should be deleted +deleteAllToys(); + +createAllToys(); + + + +function createAllToys() { + createBlocks({ + x: 548.3, + y: 495.55, + z: 504.4 + }); +} + +function deleteAllToys() { + var entities = Entities.findEntities(MyAvatar.position, 100); + + entities.forEach(function(entity) { + //params: customKey, id, defaultValue + var shouldReset = getEntityCustomData(resetKey, entity, false); + if (shouldReset) { + Entities.deleteEntity(entity); + } + }) +} + +function createBlocks(position) { + print("CREATE BLOCKS") + var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; + var BASE_DIMENSIONS = Vec3.multiply({ + x: 0.2, + y: 0.1, + z: 0.8 + }, 0.2); + var NUM_BLOCKS = 4; + + for (var i = 0; i < NUM_BLOCKS; i++) { + var block = Entities.addEntity({ + type: "Model", + modelURL: modelUrl, + position: Vec3.sum(position, { + x: 0, + y: i / 5, + z: 0 + }), + shapeType: 'box', + name: "block", + dimensions: Vec3.sum(BASE_DIMENSIONS, { + x: Math.random() / 10, + y: Math.random() / 10, + z: Math.random() / 10 + }), + collisionsWillMove: true, + gravity: { + x: 0, + y: -2.5, + z: 0 + }, + velocity: { + x: 0, + y: -.01, + z: 0 + } + }); + + //customKey, id, data + setEntityCustomData(resetKey, block, { + resetMe: true + }); + } +} function cleanup() { - fireManager.reset(); - blockManager.reset(); + deleteAllToys(); } Script.scriptEnding.connect(cleanup); \ No newline at end of file From ae795a5c4fad36561332bdf39e2e59373dd40abf Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 17 Sep 2015 17:15:59 -0700 Subject: [PATCH 010/212] spray paint spawner working --- examples/entityScripts/sprayPaintCan.js | 1 + examples/toybox/masterResetEntity.js | 52 +++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/examples/entityScripts/sprayPaintCan.js b/examples/entityScripts/sprayPaintCan.js index aa04e94341..29ff451b76 100644 --- a/examples/entityScripts/sprayPaintCan.js +++ b/examples/entityScripts/sprayPaintCan.js @@ -238,6 +238,7 @@ Entities.deleteEntity(stroke); }); } + Script.update.connect(this.update); }); diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index cb82034f11..964070bd90 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -19,6 +19,12 @@ function createAllToys() { y: 495.55, z: 504.4 }); + + createSprayCan({ + x: 549.12, + y: 495.55, + z: 503.77 + }); } function deleteAllToys() { @@ -33,8 +39,48 @@ function deleteAllToys() { }) } +function createSprayCan(position) { + var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); + var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; + + var entity = Entities.addEntity({ + type: "Model", + name: "spraycan", + modelURL: modelURL, + position: position , + rotation: { + x: 0, + y: 0, + z: 0, + w: 1 + }, + dimensions: { + x: 0.07, + y: 0.17, + z: 0.07 + }, + collisionsWillMove: true, + shapeType: 'box', + script: scriptURL, + gravity: { + x: 0, + y: -0.5, + z: 0 + }, + velocity: { + x: 0, + y: -1, + z: 0 + } + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); + +} + function createBlocks(position) { - print("CREATE BLOCKS") var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; var BASE_DIMENSIONS = Vec3.multiply({ x: 0.2, @@ -44,7 +90,7 @@ function createBlocks(position) { var NUM_BLOCKS = 4; for (var i = 0; i < NUM_BLOCKS; i++) { - var block = Entities.addEntity({ + var entity = Entities.addEntity({ type: "Model", modelURL: modelUrl, position: Vec3.sum(position, { @@ -73,7 +119,7 @@ function createBlocks(position) { }); //customKey, id, data - setEntityCustomData(resetKey, block, { + setEntityCustomData(resetKey, entity, { resetMe: true }); } From d6377ee6bb1f1960a3c97b6340e3c08f167ba185 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 10:55:29 -0700 Subject: [PATCH 011/212] Added basketball to master reset script --- examples/toybox/masterResetEntity.js | 50 +++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 964070bd90..eef5af50e3 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -25,6 +25,12 @@ function createAllToys() { y: 495.55, z: 503.77 }); + + createBasketBall({ + x: 548.1, + y: 497, + z: 504.6 + }); } function deleteAllToys() { @@ -39,6 +45,42 @@ function deleteAllToys() { }) } +function createBasketBall(position) { + + var modelURL = "http://s3.amazonaws.com/hifi-public/models/content/basketball2.fbx"; + + var entity = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + position: position, + collisionsWillMove: true, + shapeType: "sphere", + name: "basketball", + dimensions: { + x: 0.25, + y: 0.26, + z: 0.25 + }, + gravity: { + x: 0, + y: -7, + z: 0 + }, + restitution: 10, + linearDamping: 0.0, + velocity: { + x: 0, + y: -.01, + z: 0 + } + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); + +} + function createSprayCan(position) { var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; @@ -47,7 +89,7 @@ function createSprayCan(position) { type: "Model", name: "spraycan", modelURL: modelURL, - position: position , + position: position, rotation: { x: 0, y: 0, @@ -74,9 +116,9 @@ function createSprayCan(position) { } }); - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } From 6e4b838bf9c97fba4dfae8abe4f187369bd263f1 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 10:59:28 -0700 Subject: [PATCH 012/212] added collision sound to bbal --- examples/toybox/masterResetEntity.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index eef5af50e3..b4c8f370f9 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -72,7 +72,8 @@ function createBasketBall(position) { x: 0, y: -.01, z: 0 - } + }, + collisionSoundURL : "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" }); setEntityCustomData(resetKey, entity, { From 65722dc87036f4215b664daf3e38ac097d8763a3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 11:01:33 -0700 Subject: [PATCH 013/212] Removed master spawner as its no longer needed --- examples/toybox/masterResetEntitySpawner.js | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 examples/toybox/masterResetEntitySpawner.js diff --git a/examples/toybox/masterResetEntitySpawner.js b/examples/toybox/masterResetEntitySpawner.js deleted file mode 100644 index 8938595d7f..0000000000 --- a/examples/toybox/masterResetEntitySpawner.js +++ /dev/null @@ -1,19 +0,0 @@ -var scriptURL = Script.resolvePath("masterResetEntity.js?v1" + Math.random()); - -var center = Vec3.sum(MyAvatar.position, Vec3.multiply(1, Quat.getFront(Camera.getOrientation()))); - -var resetEntity = Entities.addEntity({ - type: "Box", - dimensions: {x: .3, y: 0.3, z: 0.3}, - position: center, - color: {red: 100, green: 10, blue: 100}, - script: scriptURL -}); - - - -function cleanup() { - Entities.deleteEntity(resetEntity); -} - -Script.scriptEnding.connect(cleanup); \ No newline at end of file From 8ada3dec6e335af6e5ff6d59466af12af5fd93d5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 11:29:16 -0700 Subject: [PATCH 014/212] Adding doll in --- examples/toybox/masterResetEntity.js | 42 ++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index b4c8f370f9..c0c6e31287 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -31,6 +31,12 @@ function createAllToys() { y: 497, z: 504.6 }); + + createDoll({ + x: 545.9, + y: 496, + z: 506.2 + }) } function deleteAllToys() { @@ -57,7 +63,7 @@ function createBasketBall(position) { shapeType: "sphere", name: "basketball", dimensions: { - x: 0.25, + x: 0.25, y: 0.26, z: 0.25 }, @@ -73,7 +79,7 @@ function createBasketBall(position) { y: -.01, z: 0 }, - collisionSoundURL : "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" + collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" }); setEntityCustomData(resetKey, entity, { @@ -82,6 +88,38 @@ function createBasketBall(position) { } +function createDoll(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; + + var naturalDimensions = {x: 1.63, y: 1.67, z: 0.26}; + var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); + + var entity = Entities.addEntity({ + type: "Model", + name: "doll", + modelURL: modelURL, + position: position, + shapeType: 'box', + dimensions: desiredDimensions, + gravity: { + x: 0, + y: -5, + z: 0 + }, + velocity: { + x: 0, + y: -.1, + z: 0 + }, + collisionsWillMove: true + }); + + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +} + function createSprayCan(position) { var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; From 86dfa6f590c3feb6784ea33930c8ab892717c10f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 12:35:49 -0700 Subject: [PATCH 015/212] 2 sizes for blocks --- examples/toybox/masterResetEntity.js | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index c0c6e31287..695730b49d 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -163,12 +163,11 @@ function createSprayCan(position) { function createBlocks(position) { var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; - var BASE_DIMENSIONS = Vec3.multiply({ - x: 0.2, - y: 0.1, - z: 0.8 - }, 0.2); - var NUM_BLOCKS = 4; + var dimensionsArray = [ + {x: .1, y: 0.05, z: 0.25}, + {x: 0.06, y: 0.04, z: 0.28} + ]; + var NUM_BLOCKS = 12; for (var i = 0; i < NUM_BLOCKS; i++) { var entity = Entities.addEntity({ @@ -181,11 +180,7 @@ function createBlocks(position) { }), shapeType: 'box', name: "block", - dimensions: Vec3.sum(BASE_DIMENSIONS, { - x: Math.random() / 10, - y: Math.random() / 10, - z: Math.random() / 10 - }), + dimensions: dimensionsArray[randInt(0, dimensionsArray.length)], collisionsWillMove: true, gravity: { x: 0, @@ -210,4 +205,12 @@ function cleanup() { deleteAllToys(); } -Script.scriptEnding.connect(cleanup); \ No newline at end of file +Script.scriptEnding.connect(cleanup); + +function randFloat(low, high) { + return low + Math.random() * (high - low); +} + +function randInt(low, high) { + return Math.floor(randFloat(low, high)); +} From dd3f1301e651095514585ed41865695ad74a9846 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 14:36:41 -0700 Subject: [PATCH 016/212] Blocks are now multi colored --- examples/toybox/masterResetEntity.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 695730b49d..68510c1dfb 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -162,7 +162,8 @@ function createSprayCan(position) { } function createBlocks(position) { - var modelUrl = HIFI_PUBLIC_BUCKET + 'marketplace/hificontent/Games/blocks/block.fbx'; + var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/" + var modelURLs = ['planky_blue.fbx', 'planky_green.fbx', 'planky_natural.fbx', "planky_red.fbx", "planky_yellow.fbx"]; var dimensionsArray = [ {x: .1, y: 0.05, z: 0.25}, {x: 0.06, y: 0.04, z: 0.28} @@ -170,12 +171,13 @@ function createBlocks(position) { var NUM_BLOCKS = 12; for (var i = 0; i < NUM_BLOCKS; i++) { + var modelURL = baseURL + modelURLs[randInt(0, modelURLs.length)]; var entity = Entities.addEntity({ type: "Model", - modelURL: modelUrl, + modelURL: modelURL, position: Vec3.sum(position, { x: 0, - y: i / 5, + y: i / 10, z: 0 }), shapeType: 'box', From de14fc64f60ccb2ec4493a5510965f9e901f2df8 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 17:17:55 -0700 Subject: [PATCH 017/212] screaming on grab. Need to get release working --- examples/toybox/entityScripts/doll.js | 72 +++++++++++++++++++++++++++ examples/toybox/masterResetEntity.js | 18 ++++++- 2 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 examples/toybox/entityScripts/doll.js diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js new file mode 100644 index 0000000000..04a5e4f7eb --- /dev/null +++ b/examples/toybox/entityScripts/doll.js @@ -0,0 +1,72 @@ +// +// detectGrabExample.js +// examples/entityScripts +// +// Created by Brad Hefta-Gaub on 9/3/15. +// Copyright 2015 High Fidelity, Inc. +// +// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { + + var _this; + HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; + + // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember + // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + Doll = function() { + _this = this; + var screamSoundDirectory = HIFI_PUBLIC_BUCKET + "eric/sounds/" + this.screamSound = SoundCache.getSound(screamSoundDirectory + "dollScream1.wav") + this.startAnimationSetting = JSON.stringify({ + running: true + }); + + this.stopAnimationSetting = JSON.stringify({ + running: false + }); + }; + + Doll.prototype = { + + + startNearGrab: function() { + print("I was just grabbed... entity:" + this.entityID); + Entities.editEntity(this.entityID, { + animationSettings: this.startAnimationSetting + }); + + var position = Entities.getEntityProperties(this.entityID, "position").position; + print("POSITIONNN " + JSON.stringify(position)) + print("SCREAM SOUND ") + Audio.playSound(this.screamSound[0], { + position: position, + volume: 0.1 + }); + + }, + + release: function() { + print("RELEASE") + Entities.editEntity(this.entityID, { + animationSettings: this.stopAnimationSetting + }); + }, + + + // preload() will be called when the entity has become visible (or known) to the interface + // it gives us a chance to set our local JavaScript object up. In this case it means: + // * remembering our entityID, so we can access it in cases where we're called without an entityID + // * connecting to the update signal so we can check our grabbed state + preload: function(entityID) { + this.entityID = entityID; + }, + }; + + // entity scripts always need to return a newly constructed object of our type + return new Doll(); +}) \ No newline at end of file diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 68510c1dfb..23f4b46503 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -5,6 +5,8 @@ var resetKey = "resetMe"; HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; +var shouldDeleteOnEndScript = false; + //Before creating anything, first search a radius and delete all the things that should be deleted deleteAllToys(); @@ -90,14 +92,23 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; + var animationURL = "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx"; + var animationSettings = JSON.stringify({ + running: false + }); + + var scriptURL = Script.resolvePath("entityScripts/doll.js"); + // var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); var naturalDimensions = {x: 1.63, y: 1.67, z: 0.26}; var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); - var entity = Entities.addEntity({ type: "Model", name: "doll", modelURL: modelURL, + animationSettings: animationSettings, + animationURL: animationURL, + script: scriptURL, position: position, shapeType: 'box', dimensions: desiredDimensions, @@ -207,7 +218,10 @@ function cleanup() { deleteAllToys(); } -Script.scriptEnding.connect(cleanup); +if(shouldDeleteOnEndScript) { + + Script.scriptEnding.connect(cleanup); +} function randFloat(low, high) { return low + Math.random() * (high - low); From b62807011c8f774d6ab6b5717071f06e635c297d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 17:22:45 -0700 Subject: [PATCH 018/212] Doll screams and writhes when picked up, returns to default position when let go --- examples/toybox/entityScripts/doll.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 04a5e4f7eb..76da29a14b 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -27,6 +27,7 @@ }); this.stopAnimationSetting = JSON.stringify({ + frameIndex: 0, running: false }); }; @@ -43,14 +44,14 @@ var position = Entities.getEntityProperties(this.entityID, "position").position; print("POSITIONNN " + JSON.stringify(position)) print("SCREAM SOUND ") - Audio.playSound(this.screamSound[0], { + Audio.playSound(this.screamSound, { position: position, volume: 0.1 }); }, - release: function() { + releaseGrab: function() { print("RELEASE") Entities.editEntity(this.entityID, { animationSettings: this.stopAnimationSetting From fb9896019400c8de908266802a53de14bb092a08 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 18 Sep 2015 17:45:28 -0700 Subject: [PATCH 019/212] Adding wand to master script --- examples/toybox/entityScripts/wand.js | 0 examples/toybox/masterResetEntity.js | 77 +++++++++++++++++++++------ 2 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 examples/toybox/entityScripts/wand.js diff --git a/examples/toybox/entityScripts/wand.js b/examples/toybox/entityScripts/wand.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 23f4b46503..722705b254 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -38,7 +38,13 @@ function createAllToys() { x: 545.9, y: 496, z: 506.2 - }) + }); + + createWand({ + x: 546.48, + y: 495.63, + z: 506.25 + }); } function deleteAllToys() { @@ -53,6 +59,38 @@ function deleteAllToys() { }) } +function createWand(position) { + var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; + var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/collisionHull.obj'; + //Just using abs path for demo purposes on sunday, since this PR for wand has not been merged + var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/ccf125c047426a2c481d3ee8c58a05fc6048fdde/examples/toys/bubblewand/wand.js" + + var entity = Entities.addEntity({ + name: 'Bubble Wand', + type: "Model", + modelURL: WAND_MODEL, + position: position, + gravity: { + x: 0, + y: 0, + z: 0, + }, + dimensions: { + x: 0.05, + y: 0.25, + z: 0.05 + }, + //must be enabled to be grabbable in the physics engine + collisionsWillMove: true, + compoundShapeURL: WAND_COLLISION_SHAPE, + script: scriptURL + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +} + function createBasketBall(position) { var modelURL = "http://s3.amazonaws.com/hifi-public/models/content/basketball2.fbx"; @@ -93,14 +131,18 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; var animationURL = "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx"; - var animationSettings = JSON.stringify({ + var animationSettings = JSON.stringify({ running: false }); - - var scriptURL = Script.resolvePath("entityScripts/doll.js"); - // var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); - var naturalDimensions = {x: 1.63, y: 1.67, z: 0.26}; + var scriptURL = Script.resolvePath("entityScripts/doll.js"); + // var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); + + var naturalDimensions = { + x: 1.63, + y: 1.67, + z: 0.26 + }; var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); var entity = Entities.addEntity({ type: "Model", @@ -175,10 +217,15 @@ function createSprayCan(position) { function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/" var modelURLs = ['planky_blue.fbx', 'planky_green.fbx', 'planky_natural.fbx', "planky_red.fbx", "planky_yellow.fbx"]; - var dimensionsArray = [ - {x: .1, y: 0.05, z: 0.25}, - {x: 0.06, y: 0.04, z: 0.28} - ]; + var dimensionsArray = [{ + x: .1, + y: 0.05, + z: 0.25 + }, { + x: 0.06, + y: 0.04, + z: 0.28 + }]; var NUM_BLOCKS = 12; for (var i = 0; i < NUM_BLOCKS; i++) { @@ -218,15 +265,15 @@ function cleanup() { deleteAllToys(); } -if(shouldDeleteOnEndScript) { +if (shouldDeleteOnEndScript) { - Script.scriptEnding.connect(cleanup); + Script.scriptEnding.connect(cleanup); } function randFloat(low, high) { - return low + Math.random() * (high - low); + return low + Math.random() * (high - low); } function randInt(low, high) { - return Math.floor(randFloat(low, high)); -} + return Math.floor(randFloat(low, high)); +} \ No newline at end of file From 5cd69c4f03a6ea51097eef19dee7b389a40221d0 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 09:17:23 -0700 Subject: [PATCH 020/212] Added dice to master reset script --- examples/toybox/masterResetEntity.js | 36 ++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 722705b254..57924fb6e2 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -41,10 +41,12 @@ function createAllToys() { }); createWand({ - x: 546.48, + x: 546.45, y: 495.63, - z: 506.25 + z: 506.18 }); + + createDice(); } function deleteAllToys() { @@ -59,6 +61,34 @@ function deleteAllToys() { }) } +function createDice() { + var diceProps = { + type: "Model", + modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", + collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", + name: "dice", + position: {x: 541.1, y: 494.94, z: 509.21 }, + dimensions: {x: 0.09, y: 0.09, z: 0.09}, + gravity: {x: 0, y: -3.5, z: 0}, + velocity: {x: 0, y: -.01, z: 0}, + shapeType: "box", + collisionsWillMove: true + } + var dice1 = Entities.addEntity(diceProps); + + diceProps.position = {x: 540.99, y: 494.4, z: 509.08}; + + var dice2 = Entities.addEntity(diceProps); + + setEntityCustomData(resetKey, dice1, { + resetMe: true + }); + + setEntityCustomData(resetKey, dice2, { + resetMe: true + }); +} + function createWand(position) { var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/collisionHull.obj'; @@ -83,6 +113,8 @@ function createWand(position) { //must be enabled to be grabbable in the physics engine collisionsWillMove: true, compoundShapeURL: WAND_COLLISION_SHAPE, + // gravity: {x: 0, y: -3.5, z: 0}, + // velocity: {x: 0, y: -0.01, z:0}, script: scriptURL }); From a71f1495e91d17d3b9e18b2e9b1da447b24c1ad6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 11:15:40 -0700 Subject: [PATCH 021/212] Lowered sound volume on doll, now choose between two screams --- examples/toybox/entityScripts/doll.js | 24 +++++++++++++++--------- examples/toybox/masterResetEntity.js | 3 +-- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 76da29a14b..f3850d760d 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -21,7 +21,7 @@ Doll = function() { _this = this; var screamSoundDirectory = HIFI_PUBLIC_BUCKET + "eric/sounds/" - this.screamSound = SoundCache.getSound(screamSoundDirectory + "dollScream1.wav") + this.screamSounds = [SoundCache.getSound(screamSoundDirectory + "dollScream2.wav?=v2"), SoundCache.getSound(screamSoundDirectory + "dollScream1.wav?=v2")]; this.startAnimationSetting = JSON.stringify({ running: true }); @@ -36,25 +36,23 @@ startNearGrab: function() { - print("I was just grabbed... entity:" + this.entityID); Entities.editEntity(this.entityID, { + animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", animationSettings: this.startAnimationSetting }); var position = Entities.getEntityProperties(this.entityID, "position").position; - print("POSITIONNN " + JSON.stringify(position)) - print("SCREAM SOUND ") - Audio.playSound(this.screamSound, { + Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], { position: position, - volume: 0.1 + volume: 0.01 }); }, releaseGrab: function() { - print("RELEASE") Entities.editEntity(this.entityID, { - animationSettings: this.stopAnimationSetting + animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", + // animationSettings: this.stopAnimationSetting }); }, @@ -70,4 +68,12 @@ // entity scripts always need to return a newly constructed object of our type return new Doll(); -}) \ No newline at end of file +}) + +function randFloat(low, high) { + return low + Math.random() * (high - low); +} + +function randInt(low, high) { + return Math.floor(randFloat(low, high)); +} \ No newline at end of file diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 57924fb6e2..0ce949562d 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -113,6 +113,7 @@ function createWand(position) { //must be enabled to be grabbable in the physics engine collisionsWillMove: true, compoundShapeURL: WAND_COLLISION_SHAPE, + //Look into why bubble wand is going through table when gravity is enabled // gravity: {x: 0, y: -3.5, z: 0}, // velocity: {x: 0, y: -0.01, z:0}, script: scriptURL @@ -168,7 +169,6 @@ function createDoll(position) { }); var scriptURL = Script.resolvePath("entityScripts/doll.js"); - // var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); var naturalDimensions = { x: 1.63, @@ -199,7 +199,6 @@ function createDoll(position) { collisionsWillMove: true }); - setEntityCustomData(resetKey, entity, { resetMe: true }); From 30198aa6f22ddf29901a94b9f48503538d4d2b10 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 11:22:35 -0700 Subject: [PATCH 022/212] Only play animation once for screaming doll when picked up --- examples/toybox/entityScripts/doll.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index f3850d760d..63b4fcc43d 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -23,11 +23,11 @@ var screamSoundDirectory = HIFI_PUBLIC_BUCKET + "eric/sounds/" this.screamSounds = [SoundCache.getSound(screamSoundDirectory + "dollScream2.wav?=v2"), SoundCache.getSound(screamSoundDirectory + "dollScream1.wav?=v2")]; this.startAnimationSetting = JSON.stringify({ - running: true + running: true, + lastFrame: 64 }); this.stopAnimationSetting = JSON.stringify({ - frameIndex: 0, running: false }); }; From 4e517b78e122acd9e681f1247314d262e5952b0a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 11:26:56 -0700 Subject: [PATCH 023/212] dice spawning higher so they fall onto craps table --- examples/toybox/masterResetEntity.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 0ce949562d..627927e109 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -67,7 +67,7 @@ function createDice() { modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", - position: {x: 541.1, y: 494.94, z: 509.21 }, + position: {x: 541.1, y: 496, z: 509.21 }, dimensions: {x: 0.09, y: 0.09, z: 0.09}, gravity: {x: 0, y: -3.5, z: 0}, velocity: {x: 0, y: -.01, z: 0}, @@ -76,7 +76,7 @@ function createDice() { } var dice1 = Entities.addEntity(diceProps); - diceProps.position = {x: 540.99, y: 494.4, z: 509.08}; + diceProps.position = {x: 540.99, y: 496, z: 509.08}; var dice2 = Entities.addEntity(diceProps); From d24df99445e8c95f0d00de55ae54a642e4ab8a18 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 11:51:00 -0700 Subject: [PATCH 024/212] Updated block logic to sync with desired behavior (each color block maps to a different size) --- examples/toybox/masterResetEntity.js | 95 ++++++++++++++++------------ 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 627927e109..7fbcc97f4a 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -248,47 +248,64 @@ function createSprayCan(position) { function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/" var modelURLs = ['planky_blue.fbx', 'planky_green.fbx', 'planky_natural.fbx', "planky_red.fbx", "planky_yellow.fbx"]; - var dimensionsArray = [{ - x: .1, - y: 0.05, - z: 0.25 - }, { - x: 0.06, - y: 0.04, - z: 0.28 - }]; - var NUM_BLOCKS = 12; + var blockTypes = [ + { + url: "planky_blue.fbx", + dimensions: {x: 0.05, y: 0.05, z: 0.25} + }, + { + url: "planky_green.fbx", + dimensions: {x: 0.1, y: 0.1, z: 0.25} + }, + { + url: "planky_natural.fbx", + dimensions: {x: 0.05, y: 0.05, z: 0.05} + }, + { + url: "planky_yellow.fbx", + dimensions: {x: 0.03, y: 0.05, z: 0.25} + }, + { + url: "planky_red.fbx", + dimensions: {x: 0.1, y: 0.05, z: 0.25} + }, - for (var i = 0; i < NUM_BLOCKS; i++) { - var modelURL = baseURL + modelURLs[randInt(0, modelURLs.length)]; - var entity = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - position: Vec3.sum(position, { - x: 0, - y: i / 10, - z: 0 - }), - shapeType: 'box', - name: "block", - dimensions: dimensionsArray[randInt(0, dimensionsArray.length)], - collisionsWillMove: true, - gravity: { - x: 0, - y: -2.5, - z: 0 - }, - velocity: { - x: 0, - y: -.01, - z: 0 - } - }); - //customKey, id, data - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + ]; + var NUM_BLOCKS_PER_COLOR = 4; + + for (var i = 0; i < blockTypes.length; i++) { + for(j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { + var modelURL = baseURL + blockTypes[i].url; + var entity = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + position: Vec3.sum(position, { + x: j/10, + y: i / 10, + z: 0 + }), + shapeType: 'box', + name: "block", + dimensions: blockTypes[i].dimensions, + collisionsWillMove: true, + gravity: { + x: 0, + y: -2.5, + z: 0 + }, + velocity: { + x: 0, + y: -.01, + z: 0 + } + }); + + //customKey, id, data + setEntityCustomData(resetKey, entity, { + resetMe: true + }); + } } } From b727256377b852244bee7ba499682a580a0aef73 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 13:05:37 -0700 Subject: [PATCH 025/212] animation of doll plays longer now to give user a chance to see it play --- examples/toybox/entityScripts/doll.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 63b4fcc43d..0f4aaf5cd7 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -24,7 +24,8 @@ this.screamSounds = [SoundCache.getSound(screamSoundDirectory + "dollScream2.wav?=v2"), SoundCache.getSound(screamSoundDirectory + "dollScream1.wav?=v2")]; this.startAnimationSetting = JSON.stringify({ running: true, - lastFrame: 64 + startFrame: 0, + lastFrame: 128 }); this.stopAnimationSetting = JSON.stringify({ From 8678e07c21555c35cc05f1bd622358279de7513a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 15:45:54 -0700 Subject: [PATCH 026/212] Adding in light triggering logic --- examples/toybox/entityScripts/doll.js | 8 +- examples/toybox/entityScripts/lightSwitch.js | 97 +++++++++++++++ examples/toybox/entityScripts/wand.js | 0 examples/toybox/masterResetEntity.js | 119 +++++++++++++++---- 4 files changed, 195 insertions(+), 29 deletions(-) create mode 100644 examples/toybox/entityScripts/lightSwitch.js delete mode 100644 examples/toybox/entityScripts/wand.js diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 0f4aaf5cd7..86e7fcc62c 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -1,11 +1,11 @@ // -// detectGrabExample.js -// examples/entityScripts +// doll.js +// examples/toybox/entityScripts // -// Created by Brad Hefta-Gaub on 9/3/15. +// Created by Eric Levin on 9/21/15. // Copyright 2015 High Fidelity, Inc. // -// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script +// This entity script breathes movement and sound- one might even say life- into a doll. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js new file mode 100644 index 0000000000..bb80d76f57 --- /dev/null +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -0,0 +1,97 @@ +// +// detectGrabExample.js +// examples/entityScripts +// +// Created by Eric Levin on 9/21/15. +// Copyright 2015 High Fidelity, Inc. +// +// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { + + var _this; + + + // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember + // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + LightSwitch = function() { + _this = this; + + this.lightStateKey = "lightStateKey"; + this.resetKey = "resetMe"; + + }; + + LightSwitch.prototype = { + + + startNearGrab: function() { + print("TOGGLE LIGHT") + + // var position = Entities.getEntityProperties(this.entityID, "position").position; + // Audio.playSound(clickSound, { + // position: position, + // volume: 0.05 + // }); + + }, + + createLights: function() { + print("CREATE LIGHTS *******************") + this.sconceLight1 = Entities.addEntity({ + type: "Light", + position: { + x: 543.62, + y: 496.24, + z: 511.23 + }, + name: "Sconce 1 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, this.sconceLight1, { + resetMe: true + }); + }, + + // clickReleaseOnEntity: function(entityId, mouseEvent) { + // print("CLIIICK ON MOUSE") + // if (!mouseEvent.isLeftButton) { + // return; + // } + // }, + + // preload() will be called when the entity has become visible (or known) to the interface + // it gives us a chance to set our local JavaScript object up. In this case it means: + preload: function(entityID) { + this.entityID = entityID; + var defaultLightData= { + on: false + }; + this.lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + + //If light is off, then we create two new lights- at the position of the sconces + if (this.lightState.on === false) { + this.createLights(); + } + + }, + }; + + // entity scripts always need to return a newly constructed object of our type + return new LightSwitch(); +}) \ No newline at end of file diff --git a/examples/toybox/entityScripts/wand.js b/examples/toybox/entityScripts/wand.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 7fbcc97f4a..ecc657ecc7 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -47,6 +47,8 @@ function createAllToys() { }); createDice(); + + createLightSwitch(); } function deleteAllToys() { @@ -61,32 +63,84 @@ function deleteAllToys() { }) } +function createLightSwitch() { + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.obj"; + var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v1"); + var lightSwitch = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "Light Switch Hall", + collisionsWillMove: true, + script: scriptURL, + position: { + x: 543.27764892578125, + y: 495.67999267578125, + z: 511.00564575195312 + }, + rotation: { + w: 0.63280689716339111, + x: 0.63280689716339111, + y: -0.31551080942153931, + z: 0.31548023223876953 + }, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + } + }); + + setEntityCustomData(resetKey, lightSwitch, { + resetMe: true + }); +} + function createDice() { var diceProps = { type: "Model", modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", - position: {x: 541.1, y: 496, z: 509.21 }, - dimensions: {x: 0.09, y: 0.09, z: 0.09}, - gravity: {x: 0, y: -3.5, z: 0}, - velocity: {x: 0, y: -.01, z: 0}, + position: { + x: 541.1, + y: 496, + z: 509.21 + }, + dimensions: { + x: 0.09, + y: 0.09, + z: 0.09 + }, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -.01, + z: 0 + }, shapeType: "box", collisionsWillMove: true } var dice1 = Entities.addEntity(diceProps); - diceProps.position = {x: 540.99, y: 496, z: 509.08}; + diceProps.position = { + x: 540.99, + y: 496, + z: 509.08 + }; var dice2 = Entities.addEntity(diceProps); - setEntityCustomData(resetKey, dice1, { + setEntityCustomData(resetKey, dice1, { resetMe: true }); - setEntityCustomData(resetKey, dice2, { + setEntityCustomData(resetKey, dice2, { resetMe: true - }); + }); } function createWand(position) { @@ -248,26 +302,41 @@ function createSprayCan(position) { function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/" var modelURLs = ['planky_blue.fbx', 'planky_green.fbx', 'planky_natural.fbx', "planky_red.fbx", "planky_yellow.fbx"]; - var blockTypes = [ - { + var blockTypes = [{ url: "planky_blue.fbx", - dimensions: {x: 0.05, y: 0.05, z: 0.25} - }, - { + dimensions: { + x: 0.05, + y: 0.05, + z: 0.25 + } + }, { url: "planky_green.fbx", - dimensions: {x: 0.1, y: 0.1, z: 0.25} - }, - { + dimensions: { + x: 0.1, + y: 0.1, + z: 0.25 + } + }, { url: "planky_natural.fbx", - dimensions: {x: 0.05, y: 0.05, z: 0.05} - }, - { + dimensions: { + x: 0.05, + y: 0.05, + z: 0.05 + } + }, { url: "planky_yellow.fbx", - dimensions: {x: 0.03, y: 0.05, z: 0.25} - }, - { + dimensions: { + x: 0.03, + y: 0.05, + z: 0.25 + } + }, { url: "planky_red.fbx", - dimensions: {x: 0.1, y: 0.05, z: 0.25} + dimensions: { + x: 0.1, + y: 0.05, + z: 0.25 + } }, @@ -275,13 +344,13 @@ function createBlocks(position) { var NUM_BLOCKS_PER_COLOR = 4; for (var i = 0; i < blockTypes.length; i++) { - for(j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { + for (j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { var modelURL = baseURL + blockTypes[i].url; var entity = Entities.addEntity({ type: "Model", modelURL: modelURL, position: Vec3.sum(position, { - x: j/10, + x: j / 10, y: i / 10, z: 0 }), From e4d630b1fc6b3899d6862f3e26ed6a1dca792f67 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 15:57:03 -0700 Subject: [PATCH 027/212] more light toggling additions --- examples/toybox/entityScripts/lightSwitch.js | 12 ++++++++++-- examples/toybox/masterResetEntity.js | 5 +++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index bb80d76f57..17709764d6 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -31,7 +31,14 @@ startNearGrab: function() { print("TOGGLE LIGHT") - + this.lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + if (this.lightState.on === true) { + //Delete the all the sconce lights + var entities = Entities.findEntities(MyAvatar.position, 100); + entities.forEach(function(entity){ + var resetData = getEntityCustomData(this.resetKey, entity, {}) + }); + } // var position = Entities.getEntityProperties(this.entityID, "position").position; // Audio.playSound(clickSound, { // position: position, @@ -64,7 +71,8 @@ }); setEntityCustomData(this.resetKey, this.sconceLight1, { - resetMe: true + resetMe: true, + lightType: "sconceLight" }); }, diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index ecc657ecc7..f7e0f3524b 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -56,8 +56,9 @@ function deleteAllToys() { entities.forEach(function(entity) { //params: customKey, id, defaultValue - var shouldReset = getEntityCustomData(resetKey, entity, false); - if (shouldReset) { + var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; + print("should reset " + JSON.stringify(shouldReset)); + if (shouldReset === true) { Entities.deleteEntity(entity); } }) From a4e5f707cc0f78f8c09c7420f0c2cc22659b3bf9 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 21 Sep 2015 16:35:30 -0700 Subject: [PATCH 028/212] Toggling lights --- examples/toybox/entityScripts/lightSwitch.js | 61 +++++++++++++------- examples/toybox/masterResetEntity.js | 1 - 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 17709764d6..30f490a303 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -30,25 +30,39 @@ startNearGrab: function() { - print("TOGGLE LIGHT") - this.lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); - if (this.lightState.on === true) { - //Delete the all the sconce lights - var entities = Entities.findEntities(MyAvatar.position, 100); - entities.forEach(function(entity){ - var resetData = getEntityCustomData(this.resetKey, entity, {}) - }); + + var defaultLightData = { + on: false + }; + var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + if (lightState.on === true) { + this.clearLights(); + } else if (lightState.on === false) { + this.createLights(); } - // var position = Entities.getEntityProperties(this.entityID, "position").position; - // Audio.playSound(clickSound, { - // position: position, - // volume: 0.05 - // }); }, + clearLights: function() { + print("CLEAR LIGHTS") + var entities = Entities.findEntities(MyAvatar.position, 100); + var self = this;0 + entities.forEach(function(entity) { + var resetData = getEntityCustomData(self.resetKey, entity, {}) + print("NAME OF THING " + Entities.getEntityProperties(entity).name) + print("RESET DATA " + JSON.stringify(resetData)) + if (resetData.resetMe === true && resetData.lightType === "Sconce Light") { + print("DELETE LIGHT") + Entities.deleteEntity(entity); + } + }); + + setEntityCustomData(this.lightStateKey, this.entityID, { + on: false + }); + }, + createLights: function() { - print("CREATE LIGHTS *******************") this.sconceLight1 = Entities.addEntity({ type: "Light", position: { @@ -72,8 +86,13 @@ setEntityCustomData(this.resetKey, this.sconceLight1, { resetMe: true, - lightType: "sconceLight" + lightType: "Sconce Light" }); + + setEntityCustomData(this.lightStateKey, this.entityID, { + on: true + }); + }, // clickReleaseOnEntity: function(entityId, mouseEvent) { @@ -85,18 +104,18 @@ // preload() will be called when the entity has become visible (or known) to the interface // it gives us a chance to set our local JavaScript object up. In this case it means: - preload: function(entityID) { + preload: function(entityID) { this.entityID = entityID; - var defaultLightData= { + var defaultLightData = { on: false }; - this.lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); //If light is off, then we create two new lights- at the position of the sconces - if (this.lightState.on === false) { + if (lightState.on === false) { this.createLights(); - } - + } + //If lights are on, do nothing! }, }; diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index f7e0f3524b..5736e0d29f 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -57,7 +57,6 @@ function deleteAllToys() { entities.forEach(function(entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; - print("should reset " + JSON.stringify(shouldReset)); if (shouldReset === true) { Entities.deleteEntity(entity); } From 68bee8228b5f25bbd3d3220eb503a7efa856dad1 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 08:53:46 -0700 Subject: [PATCH 029/212] abstracted toggle logic to work with mouse click as well --- examples/toybox/entityScripts/lightSwitch.js | 56 ++++++++++++++------ examples/toybox/masterResetEntity.js | 3 ++ 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 30f490a303..99d98d943f 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -30,7 +30,18 @@ startNearGrab: function() { + this.toggleLights(); + }, + + clickReleaseOnEntity: function(entityId, mouseEvent) { + if (!mouseEvent.isLeftButton) { + return; + } + this.toggleLights(); + }, + + toggleLights: function() { var defaultLightData = { on: false }; @@ -44,15 +55,11 @@ }, clearLights: function() { - print("CLEAR LIGHTS") var entities = Entities.findEntities(MyAvatar.position, 100); - var self = this;0 + var self = this; entities.forEach(function(entity) { var resetData = getEntityCustomData(self.resetKey, entity, {}) - print("NAME OF THING " + Entities.getEntityProperties(entity).name) - print("RESET DATA " + JSON.stringify(resetData)) if (resetData.resetMe === true && resetData.lightType === "Sconce Light") { - print("DELETE LIGHT") Entities.deleteEntity(entity); } }); @@ -63,7 +70,7 @@ }, createLights: function() { - this.sconceLight1 = Entities.addEntity({ + var sconceLight1 = Entities.addEntity({ type: "Light", position: { x: 543.62, @@ -84,7 +91,33 @@ } }); - setEntityCustomData(this.resetKey, this.sconceLight1, { + setEntityCustomData(this.resetKey, sconceLight1, { + resetMe: true, + lightType: "Sconce Light" + }); + + var sconceLight2 = Entities.addEntity({ + type: "Light", + position: { + x: 539.87, + y: 496.24, + z: 505.77 + }, + name: "Sconce 2 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight2, { resetMe: true, lightType: "Sconce Light" }); @@ -95,13 +128,6 @@ }, - // clickReleaseOnEntity: function(entityId, mouseEvent) { - // print("CLIIICK ON MOUSE") - // if (!mouseEvent.isLeftButton) { - // return; - // } - // }, - // preload() will be called when the entity has become visible (or known) to the interface // it gives us a chance to set our local JavaScript object up. In this case it means: preload: function(entityID) { @@ -114,7 +140,7 @@ //If light is off, then we create two new lights- at the position of the sconces if (lightState.on === false) { this.createLights(); - } + } //If lights are on, do nothing! }, }; diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 5736e0d29f..1fe1f570d9 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -48,6 +48,7 @@ function createAllToys() { createDice(); + //Handles toggling of all sconce lights createLightSwitch(); } @@ -57,6 +58,8 @@ function deleteAllToys() { entities.forEach(function(entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; + print("ENTITY " + Entities.getEntityProperties(entity).name) + print("SHOULD RESET " + JSON.stringify(shouldReset)) if (shouldReset === true) { Entities.deleteEntity(entity); } From 703545bac311904e82d4fd5204a7ba60e1e0f322 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 09:34:54 -0700 Subject: [PATCH 030/212] Modified lightSwitch entity to use new incoming grab API --- examples/toybox/entityScripts/lightSwitch.js | 10 ++++------ examples/toybox/masterResetEntity.js | 3 --- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 99d98d943f..2420011951 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -28,12 +28,6 @@ LightSwitch.prototype = { - - startNearGrab: function() { - this.toggleLights(); - - }, - clickReleaseOnEntity: function(entityId, mouseEvent) { if (!mouseEvent.isLeftButton) { return; @@ -41,6 +35,10 @@ this.toggleLights(); }, + startNearTouch: function(){ + this.toggleLights(); + }, + toggleLights: function() { var defaultLightData = { on: false diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 1fe1f570d9..80a45ef9bc 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -58,8 +58,6 @@ function deleteAllToys() { entities.forEach(function(entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; - print("ENTITY " + Entities.getEntityProperties(entity).name) - print("SHOULD RESET " + JSON.stringify(shouldReset)) if (shouldReset === true) { Entities.deleteEntity(entity); } @@ -73,7 +71,6 @@ function createLightSwitch() { type: "Model", modelURL: modelURL, name: "Light Switch Hall", - collisionsWillMove: true, script: scriptURL, position: { x: 543.27764892578125, From 98faf3d712bec241f1da347c83107fbfcd4c1505 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 09:53:22 -0700 Subject: [PATCH 031/212] Added light switch sound --- examples/controllers/handControllerGrab.js | 98 +++++++++++++++----- examples/toybox/entityScripts/lightSwitch.js | 10 ++ 2 files changed, 83 insertions(+), 25 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index f57e79e974..40e3879220 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -29,9 +29,21 @@ var TRIGGER_ON_VALUE = 0.2; var DISTANCE_HOLDING_RADIUS_FACTOR = 5; // multiplied by distance between hand and object var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did -var NO_INTERSECT_COLOR = {red: 10, green: 10, blue: 255}; // line color when pick misses -var INTERSECT_COLOR = {red: 250, green: 10, blue: 10}; // line color when pick hits -var LINE_ENTITY_DIMENSIONS = {x: 1000, y: 1000, z: 1000}; +var NO_INTERSECT_COLOR = { + red: 10, + green: 10, + blue: 255 +}; // line color when pick misses +var INTERSECT_COLOR = { + red: 250, + green: 10, + blue: 10 +}; // line color when pick hits +var LINE_ENTITY_DIMENSIONS = { + x: 1000, + y: 1000, + z: 1000 +}; var LINE_LENGTH = 500; @@ -54,7 +66,11 @@ var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things var RIGHT_HAND = 1; var LEFT_HAND = 0; -var ZERO_VEC = {x: 0, y: 0, z: 0}; +var ZERO_VEC = { + x: 0, + y: 0, + z: 0 +}; var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}"; var MSEC_PER_SEC = 1000.0; @@ -68,7 +84,9 @@ var STATE_DISTANCE_HOLDING = 1; var STATE_CONTINUE_DISTANCE_HOLDING = 2; var STATE_NEAR_GRABBING = 3; var STATE_CONTINUE_NEAR_GRABBING = 4; -var STATE_RELEASE = 5; +var STATE_NEAR_TOUCHING = 5; +var STATE_CONTINUE_NEAR_TOUCHING = 6; +var STATE_RELEASE = 7; var GRAB_USER_DATA_KEY = "grabKey"; @@ -93,7 +111,7 @@ function controller(hand, triggerAction) { this.triggerValue = 0; // rolling average of trigger value this.update = function() { - switch(this.state) { + switch (this.state) { case STATE_SEARCHING: this.search(); break; @@ -109,6 +127,12 @@ function controller(hand, triggerAction) { case STATE_CONTINUE_NEAR_GRABBING: this.continueNearGrabbing(); break; + case STATE_NEAR_TOUCHING: + this.nearTouching(); + break; + case STATE_CONTINUE_NEAR_TOUCHING: + this.continueNearTouching(); + break; case STATE_RELEASE: this.release(); break; @@ -125,14 +149,14 @@ function controller(hand, triggerAction) { dimensions: LINE_ENTITY_DIMENSIONS, visible: true, position: closePoint, - linePoints: [ ZERO_VEC, farPoint ], + linePoints: [ZERO_VEC, farPoint], color: color, lifetime: LIFETIME }); } else { Entities.editEntity(this.pointer, { position: closePoint, - linePoints: [ ZERO_VEC, farPoint ], + linePoints: [ZERO_VEC, farPoint], color: color, lifetime: (Date.now() - startTime) / MSEC_PER_SEC + LIFETIME }); @@ -171,7 +195,10 @@ function controller(hand, triggerAction) { // the trigger is being pressed, do a ray test var handPosition = this.getHandPosition(); - var pickRay = {origin: handPosition, direction: Quat.getUp(this.getHandRotation())}; + var pickRay = { + origin: handPosition, + direction: Quat.getUp(this.getHandRotation()) + }; var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects && intersection.properties.collisionsWillMove === 1 && @@ -196,17 +223,18 @@ function controller(hand, triggerAction) { for (var i = 0; i < nearbyEntities.length; i++) { var props = Entities.getEntityProperties(nearbyEntities[i]); var distance = Vec3.distance(props.position, handPosition); - if (distance < minDistance && props.name !== "pointer" && - props.collisionsWillMove === 1 && - props.locked === 0) { + if (distance < minDistance && props.name !== "pointer") { this.grabbedEntity = nearbyEntities[i]; minDistance = distance; } } if (this.grabbedEntity === null) { this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } else { + } else if (props.locked === 0 && props.collisionsWillMove === 1) { this.state = STATE_NEAR_GRABBING; + } else if (props.collisionsWillMove === 0) { + // We have grabbed a non-physical object, so we want to trigger a touch event as opposed to a grab event + this.state = STATE_NEAR_TOUCHING; } } } @@ -215,7 +243,7 @@ function controller(hand, triggerAction) { this.distanceHolding = function() { var handControllerPosition = Controller.getSpatialControlPosition(this.palm); var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position","rotation"]); + var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); // add the action and initialize some variables this.currentObjectPosition = grabbedProperties.position; @@ -263,8 +291,8 @@ function controller(hand, triggerAction) { // the action was set up on a previous call. update the targets. var radius = Math.max(Vec3.distance(this.currentObjectPosition, - handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, - DISTANCE_HOLDING_RADIUS_FACTOR); + handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, + DISTANCE_HOLDING_RADIUS_FACTOR); var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition); this.handPreviousPosition = handControllerPosition; @@ -281,16 +309,18 @@ function controller(hand, triggerAction) { // this doubles hand rotation var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation, - DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), - Quat.inverse(this.handPreviousRotation)); + DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), + Quat.inverse(this.handPreviousRotation)); this.handPreviousRotation = handRotation; this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation); Entities.callEntityMethod(this.grabbedEntity, "continueDistantGrab"); Entities.updateAction(this.grabbedEntity, this.actionID, { - targetPosition: this.currentObjectPosition, linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - targetRotation: this.currentObjectRotation, angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME + targetPosition: this.currentObjectPosition, + linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, + targetRotation: this.currentObjectRotation, + angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME }); } @@ -339,6 +369,23 @@ function controller(hand, triggerAction) { this.currentObjectTime = Date.now(); } + this.nearTouching = function() { + if (!this.triggerSmoothedSqueezed()) { + this.state = STATE_RELEASE; + return; + } + Entities.callEntityMethod(this.grabbedEntity, "startNearTouch") + this.state = STATE_CONTINUE_NEAR_TOUCHING; + } + + this.continueNearTouching = function() { + if (!this.triggerSmoothedSqueezed()) { + this.state = STATE_RELEASE; + return; + } + Entities.callEntityMethod(this.grabbedEntity, "continueNearTouch"); + } + this.continueNearGrabbing = function() { if (!this.triggerSmoothedSqueezed()) { @@ -367,9 +414,8 @@ function controller(hand, triggerAction) { // value would otherwise give the held object time to slow down. if (this.triggerSqueezed()) { this.grabbedVelocity = - Vec3.sum(Vec3.multiply(this.grabbedVelocity, - (1.0 - NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)), - Vec3.multiply(grabbedVelocity, NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)); + Vec3.sum(Vec3.multiply(this.grabbedVelocity, (1.0 - NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)), + Vec3.multiply(grabbedVelocity, NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)); } if (useMultiplier) { @@ -389,7 +435,9 @@ function controller(hand, triggerAction) { // the action will tend to quickly bring an object's velocity to zero. now that // the action is gone, set the objects velocity to something the holder might expect. - Entities.editEntity(this.grabbedEntity, {velocity: this.grabbedVelocity}); + Entities.editEntity(this.grabbedEntity, { + velocity: this.grabbedVelocity + }); this.deactivateEntity(this.grabbedEntity); this.grabbedVelocity = ZERO_VEC; @@ -438,4 +486,4 @@ function cleanup() { Script.scriptEnding.connect(cleanup); -Script.update.connect(update) +Script.update.connect(update) \ No newline at end of file diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 2420011951..5bf2b5a04d 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -24,6 +24,8 @@ this.lightStateKey = "lightStateKey"; this.resetKey = "resetMe"; + this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); + }; LightSwitch.prototype = { @@ -50,6 +52,11 @@ this.createLights(); } + Audio.playSound(this.switchSound, { + volume: 1, + position: this.position + }); + }, clearLights: function() { @@ -130,6 +137,9 @@ // it gives us a chance to set our local JavaScript object up. In this case it means: preload: function(entityID) { this.entityID = entityID; + + //The light switch is static, so just cache its position once + this.position = Entities.getEntityProperties(this.entityID, "position").position; var defaultLightData = { on: false }; From b704ebd9348a55b372b309368fe60d2d803be360 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 09:55:24 -0700 Subject: [PATCH 032/212] modified dice starting position --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 80a45ef9bc..be035d4252 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -102,7 +102,7 @@ function createDice() { collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", position: { - x: 541.1, + x: 540.74, y: 496, z: 509.21 }, From 2557b32e1a70cc78724c0e478e938ff27ea9fba4 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 12:40:09 -0700 Subject: [PATCH 033/212] Updated switch model to be fbx --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index be035d4252..8cc25dc3bf 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -65,7 +65,7 @@ function deleteAllToys() { } function createLightSwitch() { - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.obj"; + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v1"); var lightSwitch = Entities.addEntity({ type: "Model", From a266e8d65a47d994515520c9f8b58d95db7aab28 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 12:49:45 -0700 Subject: [PATCH 034/212] updated reset script to use new wand script --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 8cc25dc3bf..4b0a2f986a 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -147,7 +147,7 @@ function createWand(position) { var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/collisionHull.obj'; //Just using abs path for demo purposes on sunday, since this PR for wand has not been merged - var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/ccf125c047426a2c481d3ee8c58a05fc6048fdde/examples/toys/bubblewand/wand.js" + var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/f8d743aff0700f81d7f2ace92b8718e1e5e64978/examples/toys/bubblewand/wand.js" var entity = Entities.addEntity({ name: 'Bubble Wand', From d273852bf9af6d063c30150b317d1fd8539d1ea7 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 12:56:01 -0700 Subject: [PATCH 035/212] New wand script --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 4b0a2f986a..27b07968a9 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -147,7 +147,7 @@ function createWand(position) { var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/collisionHull.obj'; //Just using abs path for demo purposes on sunday, since this PR for wand has not been merged - var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/f8d743aff0700f81d7f2ace92b8718e1e5e64978/examples/toys/bubblewand/wand.js" + var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/bubblewand_hotfix_2/examples/toys/bubblewand/wand.js" var entity = Entities.addEntity({ name: 'Bubble Wand', From 6298dcb2fc9f3b4c374c7192608bdc67bb625c12 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 13:03:44 -0700 Subject: [PATCH 036/212] attempt fix for doll animation --- examples/toybox/entityScripts/doll.js | 2 +- examples/toybox/masterResetEntity.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 86e7fcc62c..ed4f7983ba 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -53,7 +53,7 @@ releaseGrab: function() { Entities.editEntity(this.entityID, { animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", - // animationSettings: this.stopAnimationSetting + animationSettings: this.stopAnimationSetting }); }, diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 27b07968a9..f397616487 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -48,6 +48,8 @@ function createAllToys() { createDice(); + createFlashlight(); + //Handles toggling of all sconce lights createLightSwitch(); } From a0bf7b65297ee65dc2dc529180f5478ec999b554 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 13:20:17 -0700 Subject: [PATCH 037/212] doll animation fixes --- examples/toybox/entityScripts/doll.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index ed4f7983ba..63a3d91ef6 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -29,7 +29,7 @@ }); this.stopAnimationSetting = JSON.stringify({ - running: false + running: false, }); }; @@ -37,6 +37,7 @@ startNearGrab: function() { + print("START GRAB") Entities.editEntity(this.entityID, { animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", animationSettings: this.startAnimationSetting @@ -53,7 +54,8 @@ releaseGrab: function() { Entities.editEntity(this.entityID, { animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", - animationSettings: this.stopAnimationSetting + // animationSettings: this.stopAnimationSetting, + // animationFrameIndex: 0 }); }, From a28cf5ce8bdb5b0eb397e65090d03fa0e55b2d61 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 13:29:16 -0700 Subject: [PATCH 038/212] updated grab script --- examples/controllers/handControllerGrab.js | 2 +- examples/toybox/entityScripts/doll.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 40e3879220..af1c97da68 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -221,7 +221,7 @@ function controller(hand, triggerAction) { var minDistance = GRAB_RADIUS; var grabbedEntity = null; for (var i = 0; i < nearbyEntities.length; i++) { - var props = Entities.getEntityProperties(nearbyEntities[i]); + var props = Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]); var distance = Vec3.distance(props.position, handPosition); if (distance < minDistance && props.name !== "pointer") { this.grabbedEntity = nearbyEntities[i]; diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index 63a3d91ef6..a9c2d4e830 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -37,7 +37,6 @@ startNearGrab: function() { - print("START GRAB") Entities.editEntity(this.entityID, { animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", animationSettings: this.startAnimationSetting From 5546a04f4d83d4fda5fc2c6d2d5ac9bfc934470e Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 13:48:10 -0700 Subject: [PATCH 039/212] Added flashlight to master script --- examples/toybox/masterResetEntity.js | 55 ++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index f397616487..85df03e3b4 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -48,10 +48,18 @@ function createAllToys() { createDice(); - createFlashlight(); + createFlashlight({ + x: 546, + y: 495.65, + z: 506.1 + }); //Handles toggling of all sconce lights - createLightSwitch(); + createLightSwitch({ + x: 543.27764892578125, + y: 495.67999267578125, + z: 511.00564575195312 + }); } function deleteAllToys() { @@ -66,7 +74,42 @@ function deleteAllToys() { }) } -function createLightSwitch() { +function createFlashlight(position) { + var scriptURL = Script.resolvePath('../toys/flashlight/flashlight.js'); + var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; + + var flashlight = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "flashlight", + script: scriptURL, + position: position, + dimensions: { + x: 0.08, + y: 0.30, + z: 0.08 + }, + collisionsWillMove: true, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -.01, + z: 0 + }, + shapeType: 'box', + }); + + setEntityCustomData(resetKey, flashlight, { + resetMe: true + }); + +} + +function createLightSwitch(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v1"); var lightSwitch = Entities.addEntity({ @@ -74,11 +117,7 @@ function createLightSwitch() { modelURL: modelURL, name: "Light Switch Hall", script: scriptURL, - position: { - x: 543.27764892578125, - y: 495.67999267578125, - z: 511.00564575195312 - }, + position: position, rotation: { w: 0.63280689716339111, x: 0.63280689716339111, From 55f76a4296df0a17dd0a9f83384c561f885cb58b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 15:45:18 -0700 Subject: [PATCH 040/212] Added more sconce lights to lightSwitch.js --- examples/toybox/entityScripts/lightSwitch.js | 86 +++++++++++++++++++- 1 file changed, 84 insertions(+), 2 deletions(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 5bf2b5a04d..089e532400 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -37,7 +37,7 @@ this.toggleLights(); }, - startNearTouch: function(){ + startNearTouch: function() { this.toggleLights(); }, @@ -54,7 +54,7 @@ Audio.playSound(this.switchSound, { volume: 1, - position: this.position + position: this.position }); }, @@ -127,6 +127,88 @@ lightType: "Sconce Light" }); + var sconceLight3 = Entities.addEntity({ + type: "Light", + position: { + x: 545.49468994140625, + y: 496.24026489257812, + z: 500.63516235351562 + }, + + name: "Sconce 3 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight3, { + resetMe: true, + lightType: "Sconce Light" + }); + + var sconceLight4 = Entities.addEntity({ + type: "Light", + position: { + x: 550.90399169921875, + y: 496.24026489257812, + z: 507.90237426757812 + }, + + name: "Sconce 4 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight4, { + resetMe: true, + lightType: "Sconce Light" + }); + + var sconceLight5 = Entities.addEntity({ + type: "Light", + position: { + x: 548.407958984375, + y: 496.24026489257812, + z: 509.5504150390625 + }, + name: "Sconce 5 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight5, { + resetMe: true, + lightType: "Sconce Light" + }); + + + setEntityCustomData(this.lightStateKey, this.entityID, { on: true }); From ad0c0d3b2bb8210571475dacd317e164008d8f4f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 15:50:06 -0700 Subject: [PATCH 041/212] no v1 to avoid caching --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 85df03e3b4..06deafce98 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -111,7 +111,7 @@ function createFlashlight(position) { function createLightSwitch(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; - var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v1"); + var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js"); var lightSwitch = Entities.addEntity({ type: "Model", modelURL: modelURL, From f2afd666156f7ac1ad6068a40521d2cd5433d907 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 15:50:46 -0700 Subject: [PATCH 042/212] v2? --- examples/toybox/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 06deafce98..ed1d3727f1 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -111,7 +111,7 @@ function createFlashlight(position) { function createLightSwitch(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; - var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js"); + var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v2"); var lightSwitch = Entities.addEntity({ type: "Model", modelURL: modelURL, From 99dc5a51273ec78c49c7c35e5a61c4d1f0b6f58c Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 22 Sep 2015 15:55:35 -0700 Subject: [PATCH 043/212] updated doll's sound when picked up --- examples/toybox/entityScripts/doll.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toybox/entityScripts/doll.js b/examples/toybox/entityScripts/doll.js index a9c2d4e830..673d143d02 100644 --- a/examples/toybox/entityScripts/doll.js +++ b/examples/toybox/entityScripts/doll.js @@ -21,7 +21,7 @@ Doll = function() { _this = this; var screamSoundDirectory = HIFI_PUBLIC_BUCKET + "eric/sounds/" - this.screamSounds = [SoundCache.getSound(screamSoundDirectory + "dollScream2.wav?=v2"), SoundCache.getSound(screamSoundDirectory + "dollScream1.wav?=v2")]; + this.screamSounds = [SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/KenDoll_1%2303.wav")]; this.startAnimationSetting = JSON.stringify({ running: true, startFrame: 0, @@ -45,7 +45,7 @@ var position = Entities.getEntityProperties(this.entityID, "position").position; Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], { position: position, - volume: 0.01 + volume: 0.1 }); }, From cf701095c4457096c8726bcfa8d228142c0c7c76 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 09:33:02 -0700 Subject: [PATCH 044/212] updated light switch sound volume to be 50% of what it was --- examples/toybox/entityScripts/lightSwitch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitch.js index 089e532400..20c11fe721 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitch.js @@ -53,7 +53,7 @@ } Audio.playSound(this.switchSound, { - volume: 1, + volume: 0.5, position: this.position }); From 9d9de61afa8a215bbed70b32d0f416b3ffcaaeb8 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 09:36:30 -0700 Subject: [PATCH 045/212] updated die starting positions --- examples/toybox/masterResetEntity.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index ed1d3727f1..9355f01419 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -143,9 +143,9 @@ function createDice() { collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", position: { - x: 540.74, - y: 496, - z: 509.21 + x: 540.92, + y: 494.96, + z: 509.8 }, dimensions: { x: 0.09, @@ -168,9 +168,9 @@ function createDice() { var dice1 = Entities.addEntity(diceProps); diceProps.position = { - x: 540.99, - y: 496, - z: 509.08 + x: 541.03, + y: 494.96, + z: 509.25 }; var dice2 = Entities.addEntity(diceProps); From 573cdc5271396bf29ed3a84137142b07bd48056f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 10:07:59 -0700 Subject: [PATCH 046/212] Added another light switch- the garage light switch controls the three lights closest to it, and hallway light controls the two near hall --- .../{lightSwitch.js => lightSwitchGarage.js} | 66 +------- .../toybox/entityScripts/lightSwitchHall.js | 158 ++++++++++++++++++ examples/toybox/masterResetEntity.js | 51 ++++-- 3 files changed, 207 insertions(+), 68 deletions(-) rename examples/toybox/entityScripts/{lightSwitch.js => lightSwitchGarage.js} (76%) create mode 100644 examples/toybox/entityScripts/lightSwitchHall.js diff --git a/examples/toybox/entityScripts/lightSwitch.js b/examples/toybox/entityScripts/lightSwitchGarage.js similarity index 76% rename from examples/toybox/entityScripts/lightSwitch.js rename to examples/toybox/entityScripts/lightSwitchGarage.js index 20c11fe721..090e1260bf 100644 --- a/examples/toybox/entityScripts/lightSwitch.js +++ b/examples/toybox/entityScripts/lightSwitchGarage.js @@ -18,7 +18,7 @@ // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) - LightSwitch = function() { + LightSwitchGarage = function() { _this = this; this.lightStateKey = "lightStateKey"; @@ -28,7 +28,7 @@ }; - LightSwitch.prototype = { + LightSwitchGarage.prototype = { clickReleaseOnEntity: function(entityId, mouseEvent) { if (!mouseEvent.isLeftButton) { @@ -64,7 +64,7 @@ var self = this; entities.forEach(function(entity) { var resetData = getEntityCustomData(self.resetKey, entity, {}) - if (resetData.resetMe === true && resetData.lightType === "Sconce Light") { + if (resetData.resetMe === true && resetData.lightType === "Sconce Light Garage") { Entities.deleteEntity(entity); } }); @@ -75,57 +75,7 @@ }, createLights: function() { - var sconceLight1 = Entities.addEntity({ - type: "Light", - position: { - x: 543.62, - y: 496.24, - z: 511.23 - }, - name: "Sconce 1 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - } - }); - - setEntityCustomData(this.resetKey, sconceLight1, { - resetMe: true, - lightType: "Sconce Light" - }); - - var sconceLight2 = Entities.addEntity({ - type: "Light", - position: { - x: 539.87, - y: 496.24, - z: 505.77 - }, - name: "Sconce 2 Light", - dimensions: { - x: 2.545, - y: 2.545, - z: 2.545 - }, - cutoff: 90, - color: { - red: 217, - green: 146, - blue: 24 - } - }); - - setEntityCustomData(this.resetKey, sconceLight2, { - resetMe: true, - lightType: "Sconce Light" - }); + var sconceLight3 = Entities.addEntity({ type: "Light", @@ -151,7 +101,7 @@ setEntityCustomData(this.resetKey, sconceLight3, { resetMe: true, - lightType: "Sconce Light" + lightType: "Sconce Light Garage" }); var sconceLight4 = Entities.addEntity({ @@ -178,7 +128,7 @@ setEntityCustomData(this.resetKey, sconceLight4, { resetMe: true, - lightType: "Sconce Light" + lightType: "Sconce Light Garage" }); var sconceLight5 = Entities.addEntity({ @@ -204,7 +154,7 @@ setEntityCustomData(this.resetKey, sconceLight5, { resetMe: true, - lightType: "Sconce Light" + lightType: "Sconce Light Garage" }); @@ -236,5 +186,5 @@ }; // entity scripts always need to return a newly constructed object of our type - return new LightSwitch(); + return new LightSwitchGarage(); }) \ No newline at end of file diff --git a/examples/toybox/entityScripts/lightSwitchHall.js b/examples/toybox/entityScripts/lightSwitchHall.js new file mode 100644 index 0000000000..356dee928c --- /dev/null +++ b/examples/toybox/entityScripts/lightSwitchHall.js @@ -0,0 +1,158 @@ +// +// detectGrabExample.js +// examples/entityScripts +// +// Created by Eric Levin on 9/21/15. +// Copyright 2015 High Fidelity, Inc. +// +// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { + + var _this; + + + // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember + // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + LightSwitchHall = function() { + _this = this; + + this.lightStateKey = "lightStateKey"; + this.resetKey = "resetMe"; + + this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); + + }; + + LightSwitchHall.prototype = { + + clickReleaseOnEntity: function(entityId, mouseEvent) { + if (!mouseEvent.isLeftButton) { + return; + } + this.toggleLights(); + }, + + startNearTouch: function() { + this.toggleLights(); + }, + + toggleLights: function() { + var defaultLightData = { + on: false + }; + var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + if (lightState.on === true) { + this.clearLights(); + } else if (lightState.on === false) { + this.createLights(); + } + + Audio.playSound(this.switchSound, { + volume: 0.5, + position: this.position + }); + + }, + + clearLights: function() { + var entities = Entities.findEntities(MyAvatar.position, 100); + var self = this; + entities.forEach(function(entity) { + var resetData = getEntityCustomData(self.resetKey, entity, {}) + if (resetData.resetMe === true && resetData.lightType === "Sconce Light Hall") { + Entities.deleteEntity(entity); + } + }); + + setEntityCustomData(this.lightStateKey, this.entityID, { + on: false + }); + }, + + createLights: function() { + var sconceLight1 = Entities.addEntity({ + type: "Light", + position: { + x: 543.75, + y: 496.24, + z: 511.13 + }, + name: "Sconce 1 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight1, { + resetMe: true, + lightType: "Sconce Light Hall" + }); + + var sconceLight2 = Entities.addEntity({ + type: "Light", + position: { + x: 540.1 , + y: 496.24, + z: 505.57 + }, + name: "Sconce 2 Light", + dimensions: { + x: 2.545, + y: 2.545, + z: 2.545 + }, + cutoff: 90, + color: { + red: 217, + green: 146, + blue: 24 + } + }); + + setEntityCustomData(this.resetKey, sconceLight2, { + resetMe: true, + lightType: "Sconce Light Hall" + }); + + setEntityCustomData(this.lightStateKey, this.entityID, { + on: true + }); + + }, + + // preload() will be called when the entity has become visible (or known) to the interface + // it gives us a chance to set our local JavaScript object up. In this case it means: + preload: function(entityID) { + this.entityID = entityID; + + //The light switch is static, so just cache its position once + this.position = Entities.getEntityProperties(this.entityID, "position").position; + var defaultLightData = { + on: false + }; + var lightState = getEntityCustomData(this.lightStateKey, this.entityID, defaultLightData); + + //If light is off, then we create two new lights- at the position of the sconces + if (lightState.on === false) { + this.createLights(); + } + //If lights are on, do nothing! + }, + }; + + // entity scripts always need to return a newly constructed object of our type + return new LightSwitchHall(); +}) \ No newline at end of file diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 9355f01419..14758fbc73 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -55,11 +55,7 @@ function createAllToys() { }); //Handles toggling of all sconce lights - createLightSwitch({ - x: 543.27764892578125, - y: 495.67999267578125, - z: 511.00564575195312 - }); + createLightSwitches(); } function deleteAllToys() { @@ -109,15 +105,20 @@ function createFlashlight(position) { } -function createLightSwitch(position) { +function createLightSwitches() { var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; - var scriptURL = Script.resolvePath("entityScripts/lightSwitch.js?v2"); - var lightSwitch = Entities.addEntity({ + var scriptURL = Script.resolvePath("entityScripts/lightSwitchHall.js?v1"); + + var lightSwitchHall = Entities.addEntity({ type: "Model", modelURL: modelURL, name: "Light Switch Hall", script: scriptURL, - position: position, + position: { + x: 543.27764892578125, + y: 495.67999267578125, + z: 511.00564575195312 + }, rotation: { w: 0.63280689716339111, x: 0.63280689716339111, @@ -131,9 +132,39 @@ function createLightSwitch(position) { } }); - setEntityCustomData(resetKey, lightSwitch, { + setEntityCustomData(resetKey, lightSwitchHall, { resetMe: true }); + + scriptURL = Script.resolvePath("entityScripts/lightSwitchGarage.js?v1"); + + var lightSwitchGarage = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "Light Switch Garage", + script: scriptURL, + position: { + x: 545.62, + y: 495.68, + z: 500.21 + }, + rotation: { + w: 0.20082402229309082, + x: 0.20082402229309082, + y: -0.67800414562225342, + z: 0.67797362804412842 + }, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + } + }); + + setEntityCustomData(resetKey, lightSwitchGarage, { + resetMe: true + }); + } function createDice() { From 8feabdb51805b6eed3f2108e670954a793c457e1 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 10:54:56 -0700 Subject: [PATCH 047/212] adding cat, modified dice positions --- examples/toybox/masterResetEntity.js | 47 +++++++++++++++++++++------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 14758fbc73..b3ef69b294 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -54,6 +54,12 @@ function createAllToys() { z: 506.1 }); + createCat({ + x: 551.107421875, + y: 494.60513305664062, + z: 503.1910400390625 + }) + //Handles toggling of all sconce lights createLightSwitches(); } @@ -70,6 +76,32 @@ function deleteAllToys() { }) } +function createCat(position) { + var scriptURL = Script.resolvePath("entityScripts/cat.js"); + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; + var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; + Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "cat", + script: scriptURL, + animationURL: animationURL, + animationIsPlaying: 1, + position: position, + rotation: { + w: 0.9510490894317627, + x: -1.52587890625e-05, + y: 0.30901050567626953, + z: -1.52587890625e-05 + }, + dimensions: { + x: 0.15723302960395813, + y: 0.50762706995010376, + z: 0.90716040134429932 + }, + }) +} + function createFlashlight(position) { var scriptURL = Script.resolvePath('../toys/flashlight/flashlight.js'); var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; @@ -174,9 +206,9 @@ function createDice() { collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", position: { - x: 540.92, + x: 541, y: 494.96, - z: 509.8 + z: 509.1 }, dimensions: { x: 0.09, @@ -199,9 +231,9 @@ function createDice() { var dice1 = Entities.addEntity(diceProps); diceProps.position = { - x: 541.03, + x: 541.05, y: 494.96, - z: 509.25 + z: 509.0 }; var dice2 = Entities.addEntity(diceProps); @@ -289,11 +321,6 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var animationURL = "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx"; - var animationSettings = JSON.stringify({ - running: false - }); - var scriptURL = Script.resolvePath("entityScripts/doll.js"); var naturalDimensions = { @@ -306,8 +333,6 @@ function createDoll(position) { type: "Model", name: "doll", modelURL: modelURL, - animationSettings: animationSettings, - animationURL: animationURL, script: scriptURL, position: position, shapeType: 'box', From a7facc9f3c428d08f13a7d7beefc21e6709d4bc8 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 11:10:27 -0700 Subject: [PATCH 048/212] Adding a mew sound to cat when user moves hand close --- examples/toybox/entityScripts/cat.js | 58 ++++++++++++++++++++++++++++ examples/toybox/masterResetEntity.js | 15 +++++-- 2 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 examples/toybox/entityScripts/cat.js diff --git a/examples/toybox/entityScripts/cat.js b/examples/toybox/entityScripts/cat.js new file mode 100644 index 0000000000..573b8997d1 --- /dev/null +++ b/examples/toybox/entityScripts/cat.js @@ -0,0 +1,58 @@ +// +// doll.js +// examples/toybox/entityScripts +// +// Created by Eric Levin on 9/21/15. +// Copyright 2015 High Fidelity, Inc. +// +// This entity script breathes movement and sound- one might even say life- into a doll. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +(function() { + + var _this; + + // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember + // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) + Cat = function() { + _this = this; + this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); + + }; + + Cat.prototype = { + + clickReleaseOnEntity: function(entityId, mouseEvent) { + if (!mouseEvent.isLeftButton) { + return; + } + this.meow(); + }, + + startNearTouch: function() { + this.meow(); + }, + + meow: function() { + print("PLAYYY") + Audio.playSound(this.meowSound, { + position: this.position, + volume: .1 + }); + }, + // preload() will be called when the entity has become visible (or known) to the interface + // it gives us a chance to set our local JavaScript object up. In this case it means: + // * remembering our entityID, so we can access it in cases where we're called without an entityID + // * connecting to the update signal so we can check our grabbed state + preload: function(entityID) { + this.entityID = entityID; + this.position = Entities.getEntityProperties(this.entityID, "position").position; + } + }; + + // entity scripts always need to return a newly constructed object of our type + return new Cat(); +}); diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index b3ef69b294..9ca17eae6b 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -77,16 +77,19 @@ function deleteAllToys() { } function createCat(position) { - var scriptURL = Script.resolvePath("entityScripts/cat.js"); + var scriptURL = Script.resolvePath("entityScripts/cat.js?v1"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; - Entities.addEntity({ + var animationSettings = JSON.stringify({ + running: true, + }); + var cat = Entities.addEntity({ type: "Model", modelURL: modelURL, name: "cat", script: scriptURL, animationURL: animationURL, - animationIsPlaying: 1, + animationSettings: animationSettings, position: position, rotation: { w: 0.9510490894317627, @@ -99,7 +102,11 @@ function createCat(position) { y: 0.50762706995010376, z: 0.90716040134429932 }, - }) + }); + + setEntityCustomData(resetKey, cat, { + resetMe: true + }); } function createFlashlight(position) { From cc69f518823c7fa3e649271a90c2bac44f824c9e Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 11:30:14 -0700 Subject: [PATCH 049/212] Cat meows when hand is close --- examples/toybox/entityScripts/cat.js | 32 +++++++++++++++++----------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/examples/toybox/entityScripts/cat.js b/examples/toybox/entityScripts/cat.js index 573b8997d1..3aae7c6391 100644 --- a/examples/toybox/entityScripts/cat.js +++ b/examples/toybox/entityScripts/cat.js @@ -20,25 +20,28 @@ Cat = function() { _this = this; this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); - + this.distanceThreshold = 0.5; + this.canMeow = true; + this.meowBreakTime = 3000; }; Cat.prototype = { - clickReleaseOnEntity: function(entityId, mouseEvent) { - if (!mouseEvent.isLeftButton) { - return; + update: function() { + var leftHandPosition = MyAvatar.getLeftPalmPosition(); + var rightHandPosition = MyAvatar.getRightPalmPosition(); + if (Vec3.distance(leftHandPosition, _this.position) < _this.distanceThreshold || Vec3.distance(rightHandPosition, _this.position) < _this.distanceThreshold && _this.canMeow) { + _this.meow(); + _this.canMeow = false; + Script.setTimeout(function() { + _this.canMeow = true + }, _this.meowBreakTime) } - this.meow(); - }, - - startNearTouch: function() { - this.meow(); }, meow: function() { - print("PLAYYY") - Audio.playSound(this.meowSound, { + + Audio.playSound(this.meowSound, { position: this.position, volume: .1 }); @@ -50,9 +53,14 @@ preload: function(entityID) { this.entityID = entityID; this.position = Entities.getEntityProperties(this.entityID, "position").position; + Script.update.connect(this.update); + }, + + unload: function() { + Script.update.disconnect(this.update); } }; // entity scripts always need to return a newly constructed object of our type return new Cat(); -}); +}); \ No newline at end of file From 9818e2549c36e01e35a1c08ada6d32a99490d7f3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 11:38:30 -0700 Subject: [PATCH 050/212] handControllerscript is now on par with master --- examples/controllers/handControllerGrab.js | 38 ++++------------------ 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index af1c97da68..251d78e273 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -84,9 +84,7 @@ var STATE_DISTANCE_HOLDING = 1; var STATE_CONTINUE_DISTANCE_HOLDING = 2; var STATE_NEAR_GRABBING = 3; var STATE_CONTINUE_NEAR_GRABBING = 4; -var STATE_NEAR_TOUCHING = 5; -var STATE_CONTINUE_NEAR_TOUCHING = 6; -var STATE_RELEASE = 7; +var STATE_RELEASE = 5; var GRAB_USER_DATA_KEY = "grabKey"; @@ -127,12 +125,6 @@ function controller(hand, triggerAction) { case STATE_CONTINUE_NEAR_GRABBING: this.continueNearGrabbing(); break; - case STATE_NEAR_TOUCHING: - this.nearTouching(); - break; - case STATE_CONTINUE_NEAR_TOUCHING: - this.continueNearTouching(); - break; case STATE_RELEASE: this.release(); break; @@ -221,20 +213,19 @@ function controller(hand, triggerAction) { var minDistance = GRAB_RADIUS; var grabbedEntity = null; for (var i = 0; i < nearbyEntities.length; i++) { - var props = Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]); + var props = Entities.getEntityProperties(nearbyEntities[i]); var distance = Vec3.distance(props.position, handPosition); - if (distance < minDistance && props.name !== "pointer") { + if (distance < minDistance && props.name !== "pointer" && + props.collisionsWillMove === 1 && + props.locked === 0) { this.grabbedEntity = nearbyEntities[i]; minDistance = distance; } } if (this.grabbedEntity === null) { this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } else if (props.locked === 0 && props.collisionsWillMove === 1) { + } else { this.state = STATE_NEAR_GRABBING; - } else if (props.collisionsWillMove === 0) { - // We have grabbed a non-physical object, so we want to trigger a touch event as opposed to a grab event - this.state = STATE_NEAR_TOUCHING; } } } @@ -369,23 +360,6 @@ function controller(hand, triggerAction) { this.currentObjectTime = Date.now(); } - this.nearTouching = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - Entities.callEntityMethod(this.grabbedEntity, "startNearTouch") - this.state = STATE_CONTINUE_NEAR_TOUCHING; - } - - this.continueNearTouching = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - Entities.callEntityMethod(this.grabbedEntity, "continueNearTouch"); - } - this.continueNearGrabbing = function() { if (!this.triggerSmoothedSqueezed()) { From c7cb77a6abf48f28256aa4b50bd5a7e2e88beb77 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 12:08:28 -0700 Subject: [PATCH 051/212] moved spraycan into toybox folder, and added spraypaint sound --- examples/{ => toybox}/entityScripts/sprayPaintCan.js | 8 ++++++++ examples/toybox/masterResetEntity.js | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) rename examples/{ => toybox}/entityScripts/sprayPaintCan.js (96%) diff --git a/examples/entityScripts/sprayPaintCan.js b/examples/toybox/entityScripts/sprayPaintCan.js similarity index 96% rename from examples/entityScripts/sprayPaintCan.js rename to examples/toybox/entityScripts/sprayPaintCan.js index 29ff451b76..a9538f13c0 100644 --- a/examples/entityScripts/sprayPaintCan.js +++ b/examples/toybox/entityScripts/sprayPaintCan.js @@ -6,6 +6,8 @@ GRAB_FRAME_USER_DATA_KEY = "grabFrame"; this.userData = {}; + this.spraySound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/sprayPaintSound.wav"); + var TIP_OFFSET_Z = 0.14; var TIP_OFFSET_Y = 0.04; @@ -101,12 +103,18 @@ }, lifetime: 50, //probably wont be holding longer than this straight }); + + this.sprayInjector = Audio.playSound(this.spraySound, { + position: this.properties.position, + volume: 0.1 + }); } this.letGo = function() { this.activated = false; Entities.deleteEntity(this.paintStream); this.paintStream = null; + this.sprayInjector.stop(); } this.reset = function() { diff --git a/examples/toybox/masterResetEntity.js b/examples/toybox/masterResetEntity.js index 9ca17eae6b..836cbb9d9c 100644 --- a/examples/toybox/masterResetEntity.js +++ b/examples/toybox/masterResetEntity.js @@ -363,7 +363,7 @@ function createDoll(position) { } function createSprayCan(position) { - var scriptURL = Script.resolvePath("../entityScripts/sprayPaintCan.js"); + var scriptURL = Script.resolvePath("entityScripts/sprayPaintCan.js"); var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; var entity = Entities.addEntity({ From 6bd89f968905e347ff13903d41d1148616a17a0f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 12:22:18 -0700 Subject: [PATCH 052/212] Toys re-org --- examples/{toybox/entityScripts => toys}/cat.js | 0 examples/{toybox/entityScripts => toys}/doll.js | 0 examples/{toybox/entityScripts => toys}/lightSwitchGarage.js | 0 examples/{toybox/entityScripts => toys}/lightSwitchHall.js | 0 examples/{toybox => toys}/masterResetEntity.js | 0 examples/{toybox/entityScripts => toys}/sprayPaintCan.js | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename examples/{toybox/entityScripts => toys}/cat.js (100%) rename examples/{toybox/entityScripts => toys}/doll.js (100%) rename examples/{toybox/entityScripts => toys}/lightSwitchGarage.js (100%) rename examples/{toybox/entityScripts => toys}/lightSwitchHall.js (100%) rename examples/{toybox => toys}/masterResetEntity.js (100%) rename examples/{toybox/entityScripts => toys}/sprayPaintCan.js (100%) diff --git a/examples/toybox/entityScripts/cat.js b/examples/toys/cat.js similarity index 100% rename from examples/toybox/entityScripts/cat.js rename to examples/toys/cat.js diff --git a/examples/toybox/entityScripts/doll.js b/examples/toys/doll.js similarity index 100% rename from examples/toybox/entityScripts/doll.js rename to examples/toys/doll.js diff --git a/examples/toybox/entityScripts/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js similarity index 100% rename from examples/toybox/entityScripts/lightSwitchGarage.js rename to examples/toys/lightSwitchGarage.js diff --git a/examples/toybox/entityScripts/lightSwitchHall.js b/examples/toys/lightSwitchHall.js similarity index 100% rename from examples/toybox/entityScripts/lightSwitchHall.js rename to examples/toys/lightSwitchHall.js diff --git a/examples/toybox/masterResetEntity.js b/examples/toys/masterResetEntity.js similarity index 100% rename from examples/toybox/masterResetEntity.js rename to examples/toys/masterResetEntity.js diff --git a/examples/toybox/entityScripts/sprayPaintCan.js b/examples/toys/sprayPaintCan.js similarity index 100% rename from examples/toybox/entityScripts/sprayPaintCan.js rename to examples/toys/sprayPaintCan.js From b0923acc2ff5d14f5c4ee9ca827f1d40b97cfa66 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 12:34:10 -0700 Subject: [PATCH 053/212] Reorg for pathing --- examples/toys/masterResetEntity.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 836cbb9d9c..b8997afe58 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -77,7 +77,7 @@ function deleteAllToys() { } function createCat(position) { - var scriptURL = Script.resolvePath("entityScripts/cat.js?v1"); + var scriptURL = Script.resolvePath("cat.js?v1"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; var animationSettings = JSON.stringify({ @@ -110,7 +110,7 @@ function createCat(position) { } function createFlashlight(position) { - var scriptURL = Script.resolvePath('../toys/flashlight/flashlight.js'); + var scriptURL = Script.resolvePath('flashlight/flashlight.js'); var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; var flashlight = Entities.addEntity({ @@ -146,7 +146,7 @@ function createFlashlight(position) { function createLightSwitches() { var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; - var scriptURL = Script.resolvePath("entityScripts/lightSwitchHall.js?v1"); + var scriptURL = Script.resolvePath("lightSwitchHall.js?v1"); var lightSwitchHall = Entities.addEntity({ type: "Model", @@ -175,7 +175,7 @@ function createLightSwitches() { resetMe: true }); - scriptURL = Script.resolvePath("entityScripts/lightSwitchGarage.js?v1"); + scriptURL = Script.resolvePath("lightSwitchGarage.js?v1"); var lightSwitchGarage = Entities.addEntity({ type: "Model", @@ -258,7 +258,7 @@ function createWand(position) { var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/collisionHull.obj'; //Just using abs path for demo purposes on sunday, since this PR for wand has not been merged - var scriptURL = "https://raw.githubusercontent.com/imgntn/hifi/bubblewand_hotfix_2/examples/toys/bubblewand/wand.js" + var scriptURL = Script.resolvePath("bubblewand/wand.js"); var entity = Entities.addEntity({ name: 'Bubble Wand', @@ -328,7 +328,7 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var scriptURL = Script.resolvePath("entityScripts/doll.js"); + var scriptURL = Script.resolvePath("doll.js"); var naturalDimensions = { x: 1.63, @@ -363,7 +363,7 @@ function createDoll(position) { } function createSprayCan(position) { - var scriptURL = Script.resolvePath("entityScripts/sprayPaintCan.js"); + var scriptURL = Script.resolvePath("sprayPaintCan.js"); var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; var entity = Entities.addEntity({ From 2c20a12f1300045eb17037d50626dd80cef7ad66 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 13:34:21 -0700 Subject: [PATCH 054/212] refactoring spraypaint to use new events --- examples/toys/sprayPaintCan.js | 107 ++++----------------------------- 1 file changed, 13 insertions(+), 94 deletions(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index a9538f13c0..75a2cc10f5 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -21,59 +21,8 @@ var MIN_POINT_DISTANCE = 0.01; var STROKE_WIDTH = 0.02; - var self = this; - - var timeSinceLastMoved = 0; - var RESET_TIME_THRESHOLD = 5; - var DISTANCE_FROM_HOME_THRESHOLD = 0.5; - var HOME_POSITION = { - x: 549.12, - y: 495.555, - z: 503.77 - }; - this.getUserData = function() { - - - if (this.properties.userData) { - this.userData = JSON.parse(this.properties.userData); - } - } - - this.updateUserData = function() { - Entities.editEntity(this.entityId, { - userData: JSON.stringify(this.userData) - }); - } - - this.update = function(deltaTime) { - self.getUserData(); - self.properties = Entities.getEntityProperties(self.entityId); - - if (Vec3.length(self.properties.velocity) < 0.1 && Vec3.distance(HOME_POSITION, self.properties.position) > DISTANCE_FROM_HOME_THRESHOLD) { - timeSinceLastMoved += deltaTime; - if (timeSinceLastMoved > RESET_TIME_THRESHOLD) { - self.reset(); - timeSinceLastMoved = 0; - } - } else { - timeSinceLastMoved = 0; - } - - //Only activate for the user who grabbed the object - if (self.userData.grabKey && self.userData.grabKey.activated === true && self.userData.grabKey.avatarId == MyAvatar.sessionUUID) { - if (self.activated !== true) { - //We were just grabbed, so create a particle system - self.grab(); - } - //Move emitter to where entity is always when its activated - self.sprayStream(); - } else if (self.userData.grabKey && self.userData.grabKey.activated === false && self.activated) { - self.letGo(); - } - } - - this.grab = function() { - this.activated = true; + this.startNearGrab = function() { + var position = Entities.getEntityProperties(this.entityId, "position").position; var animationSettings = JSON.stringify({ fps: 30, loop: true, @@ -85,7 +34,7 @@ this.paintStream = Entities.addEntity({ type: "ParticleEffect", animationSettings: animationSettings, - position: this.properties.position, + position: position, textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", emitVelocity: ZERO_VEC, emitAcceleration: ZERO_VEC, @@ -110,30 +59,24 @@ }); } - this.letGo = function() { - this.activated = false; + + this.releaseGrab = function() { Entities.deleteEntity(this.paintStream); this.paintStream = null; + this.painting = false; this.sprayInjector.stop(); } - this.reset = function() { - Entities.editEntity(self.entityId, { - position: HOME_POSITION, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), - angularVelocity: ZERO_VEC, - velocity: ZERO_VEC - }); - } - this.sprayStream = function() { - var forwardVec = Quat.getFront(Quat.multiply(self.properties.rotation , Quat.fromPitchYawRollDegrees(0, 90, 0))); + this.continueNearGrab = function() { + var props = Entities.getEntityProperties(this.entityId, ["position, rotation"]); + var forwardVec = Quat.getFront(Quat.multiply(props.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); forwardVec = Vec3.normalize(forwardVec); - var upVec = Quat.getUp(self.properties.rotation); - var position = Vec3.sum(self.properties.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); + var upVec = Quat.getUp(props.rotation); + var position = Vec3.sum(props.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) - Entities.editEntity(self.paintStream, { + Entities.editEntity(this.paintStream, { position: position, emitVelocity: Vec3.multiply(5, forwardVec) }); @@ -151,8 +94,6 @@ var normal = Vec3.multiply(-1, Quat.getFront(intersection.properties.rotation)); this.paint(intersection.intersection, normal); } - - } this.paint = function(position, normal) { @@ -214,40 +155,18 @@ this.preload = function(entityId) { this.strokes = []; - this.activated = false; this.entityId = entityId; - this.properties = Entities.getEntityProperties(self.entityId); - this.getUserData(); - - //Only activate for the avatar who is grabbing the can! - if (this.userData.grabKey && this.userData.grabKey.activated) { - this.activated = true; - } - if (!this.userData.grabFrame) { - var data = { - relativePosition: { - x: 0, - y: 0, - z: 0 - }, - relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 0) - } - setEntityCustomData(GRAB_FRAME_USER_DATA_KEY, this.entityId, data); - } } this.unload = function() { - Script.update.disconnect(this.update); - if(this.paintStream) { + if (this.paintStream) { Entities.deleteEntity(this.paintStream); } this.strokes.forEach(function(stroke) { Entities.deleteEntity(stroke); }); } - - Script.update.connect(this.update); }); From a2b0e66e13da7f6395ce3361715346d3c3aab3d6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 13:36:00 -0700 Subject: [PATCH 055/212] Sound working for spraypaint --- examples/toys/sprayPaintCan.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 75a2cc10f5..40a702762a 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -54,7 +54,7 @@ }); this.sprayInjector = Audio.playSound(this.spraySound, { - position: this.properties.position, + position: position, volume: 0.1 }); } From 276b0b71cbfc536cfc3022f10fdbb8316f3c557a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 14:52:59 -0700 Subject: [PATCH 056/212] Added tin can to master script and changed its position --- examples/toys/doll.js | 8 ---- examples/toys/masterResetEntity.js | 70 +++++++++++++++++++++++------- examples/toys/sprayPaintCan.js | 10 ++++- 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/examples/toys/doll.js b/examples/toys/doll.js index 673d143d02..708d6200b1 100644 --- a/examples/toys/doll.js +++ b/examples/toys/doll.js @@ -71,11 +71,3 @@ // entity scripts always need to return a newly constructed object of our type return new Doll(); }) - -function randFloat(low, high) { - return low + Math.random() * (high - low); -} - -function randInt(low, high) { - return Math.floor(randFloat(low, high)); -} \ No newline at end of file diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index b8997afe58..fda7d90908 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -23,42 +23,48 @@ function createAllToys() { }); createSprayCan({ - x: 549.12, - y: 495.55, - z: 503.77 + x: 549.8, + y: 495.6, + z: 503.94 }); createBasketBall({ - x: 548.1, - y: 497, - z: 504.6 + x: 547.73, + y: 495.5, + z: 505.47 }); createDoll({ - x: 545.9, - y: 496, - z: 506.2 + x: 546.67, + y: 495.41, + z: 505.09 }); createWand({ - x: 546.45, - y: 495.63, - z: 506.18 + x: 546.71, + y: 495.55, + z: 506.15 }); createDice(); createFlashlight({ - x: 546, - y: 495.65, - z: 506.1 + x: 545.72, + y: 495.41, + z: 505.78 }); createCat({ x: 551.107421875, y: 494.60513305664062, z: 503.1910400390625 - }) + }); + + createMagballs({ + x: 548.73, + y: 495.51, + z: 503.54 + }); //Handles toggling of all sconce lights createLightSwitches(); @@ -76,6 +82,38 @@ function deleteAllToys() { }) } +function createMagballs(position) { + + + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/tin2.fbx"; + var tinCan = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + name: "Tin Can", + position: position, + rotation: { + w: 0.93041884899139404, + x: -1.52587890625e-05, + y: 0.36647593975067139, + z: -1.52587890625e-05 + }, + dimensions: { + x: 0.16946873068809509, + y: 0.21260403096675873, + z: 0.16946862637996674 + }, + }); + + + setEntityCustomData(resetKey, tinCan, { + resetMe: true + }); + + setEntityCustomData("OmniTool", tinCan, { + script: "../toys/magBalls.js" + }); +} + function createCat(position) { var scriptURL = Script.resolvePath("cat.js?v1"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 40a702762a..e31f7f43c6 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -3,7 +3,6 @@ //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge Script.include("../libraries/utils.js"); - GRAB_FRAME_USER_DATA_KEY = "grabFrame"; this.userData = {}; this.spraySound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/sprayPaintSound.wav"); @@ -21,7 +20,16 @@ var MIN_POINT_DISTANCE = 0.01; var STROKE_WIDTH = 0.02; + this.setRightHand = function() { + this.hand = 'RIGHT'; + } + + this.setLeftHand = function() { + this.hand = 'LEFT'; + } + this.startNearGrab = function() { + this.whichHand = this.hand; var position = Entities.getEntityProperties(this.entityId, "position").position; var animationSettings = JSON.stringify({ fps: 30, From a1dccc2a9236781b49a7b145bff263280b08211d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 16:13:31 -0700 Subject: [PATCH 057/212] Changed cat position --- examples/toys/cat.js | 2 +- examples/toys/masterResetEntity.js | 38 ++++++++++++++++++------------ 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 3aae7c6391..1f1e7cc9d4 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -20,7 +20,7 @@ Cat = function() { _this = this; this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); - this.distanceThreshold = 0.5; + this.distanceThreshold = 1; this.canMeow = true; this.meowBreakTime = 3000; }; diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index fda7d90908..9f8bd036c8 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -1,20 +1,28 @@ +// +// Created by Eric Levin on 9/23/2015 +// 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 +// + +/*global deleteAllToys, print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ +//per script +/*global createAllToys, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches */ var utilitiesScript = Script.resolvePath("../libraries/utils.js"); Script.include(utilitiesScript); var resetKey = "resetMe"; -HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; +var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var shouldDeleteOnEndScript = false; //Before creating anything, first search a radius and delete all the things that should be deleted deleteAllToys(); - createAllToys(); - - function createAllToys() { createBlocks({ x: 548.3, @@ -55,9 +63,9 @@ function createAllToys() { }); createCat({ - x: 551.107421875, - y: 494.60513305664062, - z: 503.1910400390625 + x: 551.49859619140625, + y: 495.49111938476562, + z: 502.26498413085938 }); createMagballs({ @@ -73,13 +81,13 @@ function createAllToys() { function deleteAllToys() { var entities = Entities.findEntities(MyAvatar.position, 100); - entities.forEach(function(entity) { + entities.forEach(function (entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; if (shouldReset === true) { Entities.deleteEntity(entity); } - }) + }); } function createMagballs(position) { @@ -130,9 +138,9 @@ function createCat(position) { animationSettings: animationSettings, position: position, rotation: { - w: 0.9510490894317627, - x: -1.52587890625e-05, - y: 0.30901050567626953, + w: 0.35020983219146729, + x: -4.57763671875e-05, + y: 0.93664455413818359, z: -1.52587890625e-05 }, dimensions: { @@ -170,7 +178,7 @@ function createFlashlight(position) { }, velocity: { x: 0, - y: -.01, + y: -0.01, z: 0 }, shapeType: 'box', @@ -267,12 +275,12 @@ function createDice() { }, velocity: { x: 0, - y: -.01, + y: -0.01, z: 0 }, shapeType: "box", collisionsWillMove: true - } + }; var dice1 = Entities.addEntity(diceProps); diceProps.position = { From d0b5d62bb76cf6bb06c5e5de4173fe5ae460fa8a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 16:21:36 -0700 Subject: [PATCH 058/212] Updated master script to make jslint happy --- examples/toys/masterResetEntity.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 9f8bd036c8..c38e8c0a26 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -360,7 +360,7 @@ function createBasketBall(position) { linearDamping: 0.0, velocity: { x: 0, - y: -.01, + y: -0.01, z: 0 }, collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" @@ -397,7 +397,7 @@ function createDoll(position) { }, velocity: { x: 0, - y: -.1, + y: -0.1, z: 0 }, collisionsWillMove: true @@ -450,8 +450,10 @@ function createSprayCan(position) { } function createBlocks(position) { - var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/" - var modelURLs = ['planky_blue.fbx', 'planky_green.fbx', 'planky_natural.fbx', "planky_red.fbx", "planky_yellow.fbx"]; + var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; + var NUM_BLOCKS_PER_COLOR = 4; + var i, j; + var blockTypes = [{ url: "planky_blue.fbx", dimensions: { @@ -487,16 +489,13 @@ function createBlocks(position) { y: 0.05, z: 0.25 } - }, + }]; - - ]; - var NUM_BLOCKS_PER_COLOR = 4; - - for (var i = 0; i < blockTypes.length; i++) { + var modelURL, entity; + for (i = 0; i < blockTypes.length; i++) { for (j = 0; j < NUM_BLOCKS_PER_COLOR; j++) { - var modelURL = baseURL + blockTypes[i].url; - var entity = Entities.addEntity({ + modelURL = baseURL + blockTypes[i].url; + entity = Entities.addEntity({ type: "Model", modelURL: modelURL, position: Vec3.sum(position, { @@ -515,7 +514,7 @@ function createBlocks(position) { }, velocity: { x: 0, - y: -.01, + y: -0.01, z: 0 } }); From 153a30de0dfa42f2b237a81484af35c3a50df1fd Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 17:24:56 -0700 Subject: [PATCH 059/212] flip --- examples/toys/lightSwitchGarage.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/examples/toys/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js index 090e1260bf..97cd0a6ac3 100644 --- a/examples/toys/lightSwitchGarage.js +++ b/examples/toys/lightSwitchGarage.js @@ -30,7 +30,7 @@ LightSwitchGarage.prototype = { - clickReleaseOnEntity: function(entityId, mouseEvent) { + clickReleaseOnEntity: function(entityID, mouseEvent) { if (!mouseEvent.isLeftButton) { return; } @@ -52,6 +52,18 @@ this.createLights(); } + // flip model to give illusion of light switch being flicked + var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; + var axis = Quat.axis(rotation); + var angle = Quat.angle(rotation); + + angle += 180; + rotation = Quat.angleAxis(angle, axis); + + Entities.editEntity(this.entityID, { + rotation: rotation + }); + Audio.playSound(this.switchSound, { volume: 0.5, position: this.position From 81c175eabf524f44011aa56ba1f4599ef23a113d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Sep 2015 17:34:37 -0700 Subject: [PATCH 060/212] toggle light switch --- examples/toys/lightSwitchGarage.js | 7 +++---- examples/toys/lightSwitchHall.js | 17 ++++++++++++++++- examples/toys/masterResetEntity.js | 2 +- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/examples/toys/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js index 97cd0a6ac3..a68a09cf7d 100644 --- a/examples/toys/lightSwitchGarage.js +++ b/examples/toys/lightSwitchGarage.js @@ -54,11 +54,10 @@ // flip model to give illusion of light switch being flicked var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; - var axis = Quat.axis(rotation); - var angle = Quat.angle(rotation); + var axis = {x: 0, y: 1, z: 0}; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); - angle += 180; - rotation = Quat.angleAxis(angle, axis); Entities.editEntity(this.entityID, { rotation: rotation diff --git a/examples/toys/lightSwitchHall.js b/examples/toys/lightSwitchHall.js index 356dee928c..6bc1eeab83 100644 --- a/examples/toys/lightSwitchHall.js +++ b/examples/toys/lightSwitchHall.js @@ -52,6 +52,21 @@ this.createLights(); } + // flip model to give illusion of light switch being flicked + var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; + var axis = { + x: 0, + y: 1, + z: 0 + }; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); + + + Entities.editEntity(this.entityID, { + rotation: rotation + }); + Audio.playSound(this.switchSound, { volume: 0.5, position: this.position @@ -104,7 +119,7 @@ var sconceLight2 = Entities.addEntity({ type: "Light", position: { - x: 540.1 , + x: 540.1, y: 496.24, z: 505.57 }, diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index c38e8c0a26..c94f1bde9b 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -191,7 +191,7 @@ function createFlashlight(position) { } function createLightSwitches() { - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/dimmer.fbx"; + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx?v1"; var scriptURL = Script.resolvePath("lightSwitchHall.js?v1"); var lightSwitchHall = Entities.addEntity({ From f334651a57eab4dccd07db87cc705a8477d6eb85 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 10:05:27 -0700 Subject: [PATCH 061/212] deleted handControllerGrab --- examples/controllers/handControllerGrab.js | 463 --------------------- 1 file changed, 463 deletions(-) delete mode 100644 examples/controllers/handControllerGrab.js diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js deleted file mode 100644 index 251d78e273..0000000000 --- a/examples/controllers/handControllerGrab.js +++ /dev/null @@ -1,463 +0,0 @@ -// hydraGrab.js -// examples -// -// Created by Eric Levin on 9/2/15 -// Copyright 2015 High Fidelity, Inc. -// -// Grabs physically moveable entities with hydra-like controllers; it works for either near or far objects. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -Script.include("../libraries/utils.js"); - - -///////////////////////////////////////////////////////////////// -// -// these tune time-averaging and "on" value for analog trigger -// - -var TRIGGER_SMOOTH_RATIO = 0.1; // 0.0 disables smoothing of trigger value -var TRIGGER_ON_VALUE = 0.2; - -///////////////////////////////////////////////////////////////// -// -// distant manipulation -// - -var DISTANCE_HOLDING_RADIUS_FACTOR = 5; // multiplied by distance between hand and object -var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position -var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did -var NO_INTERSECT_COLOR = { - red: 10, - green: 10, - blue: 255 -}; // line color when pick misses -var INTERSECT_COLOR = { - red: 250, - green: 10, - blue: 10 -}; // line color when pick hits -var LINE_ENTITY_DIMENSIONS = { - x: 1000, - y: 1000, - z: 1000 -}; -var LINE_LENGTH = 500; - - -///////////////////////////////////////////////////////////////// -// -// near grabbing -// - -var GRAB_RADIUS = 0.3; // if the ray misses but an object is this close, it will still be selected -var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position -var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held object's velocity. 1.0 to disable. -var NEAR_PICK_MAX_DISTANCE = 0.6; // max length of pick-ray for close grabbing to be selected -var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things - -///////////////////////////////////////////////////////////////// -// -// other constants -// - -var RIGHT_HAND = 1; -var LEFT_HAND = 0; - -var ZERO_VEC = { - x: 0, - y: 0, - z: 0 -}; -var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}"; -var MSEC_PER_SEC = 1000.0; - -// these control how long an abandoned pointer line will hang around -var startTime = Date.now(); -var LIFETIME = 10; - -// states for the state machine -var STATE_SEARCHING = 0; -var STATE_DISTANCE_HOLDING = 1; -var STATE_CONTINUE_DISTANCE_HOLDING = 2; -var STATE_NEAR_GRABBING = 3; -var STATE_CONTINUE_NEAR_GRABBING = 4; -var STATE_RELEASE = 5; - -var GRAB_USER_DATA_KEY = "grabKey"; - -function controller(hand, triggerAction) { - this.hand = hand; - if (this.hand === RIGHT_HAND) { - this.getHandPosition = MyAvatar.getRightPalmPosition; - this.getHandRotation = MyAvatar.getRightPalmRotation; - } else { - this.getHandPosition = MyAvatar.getLeftPalmPosition; - this.getHandRotation = MyAvatar.getLeftPalmRotation; - } - this.triggerAction = triggerAction; - this.palm = 2 * hand; - // this.tip = 2 * hand + 1; // unused, but I'm leaving this here for fear it will be needed - - this.actionID = null; // action this script created... - this.grabbedEntity = null; // on this entity. - this.grabbedVelocity = ZERO_VEC; // rolling average of held object's velocity - this.state = 0; - this.pointer = null; // entity-id of line object - this.triggerValue = 0; // rolling average of trigger value - - this.update = function() { - switch (this.state) { - case STATE_SEARCHING: - this.search(); - break; - case STATE_DISTANCE_HOLDING: - this.distanceHolding(); - break; - case STATE_CONTINUE_DISTANCE_HOLDING: - this.continueDistanceHolding(); - break; - case STATE_NEAR_GRABBING: - this.nearGrabbing(); - break; - case STATE_CONTINUE_NEAR_GRABBING: - this.continueNearGrabbing(); - break; - case STATE_RELEASE: - this.release(); - break; - } - } - - - this.lineOn = function(closePoint, farPoint, color) { - // draw a line - if (this.pointer == null) { - this.pointer = Entities.addEntity({ - type: "Line", - name: "pointer", - dimensions: LINE_ENTITY_DIMENSIONS, - visible: true, - position: closePoint, - linePoints: [ZERO_VEC, farPoint], - color: color, - lifetime: LIFETIME - }); - } else { - Entities.editEntity(this.pointer, { - position: closePoint, - linePoints: [ZERO_VEC, farPoint], - color: color, - lifetime: (Date.now() - startTime) / MSEC_PER_SEC + LIFETIME - }); - } - } - - - this.lineOff = function() { - if (this.pointer != null) { - Entities.deleteEntity(this.pointer); - } - this.pointer = null; - } - - - this.triggerSmoothedSqueezed = function() { - var triggerValue = Controller.getActionValue(this.triggerAction); - // smooth out trigger value - this.triggerValue = (this.triggerValue * TRIGGER_SMOOTH_RATIO) + - (triggerValue * (1.0 - TRIGGER_SMOOTH_RATIO)); - return this.triggerValue > TRIGGER_ON_VALUE; - } - - - this.triggerSqueezed = function() { - var triggerValue = Controller.getActionValue(this.triggerAction); - return triggerValue > TRIGGER_ON_VALUE; - } - - - this.search = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - - // the trigger is being pressed, do a ray test - var handPosition = this.getHandPosition(); - var pickRay = { - origin: handPosition, - direction: Quat.getUp(this.getHandRotation()) - }; - var intersection = Entities.findRayIntersection(pickRay, true); - if (intersection.intersects && - intersection.properties.collisionsWillMove === 1 && - intersection.properties.locked === 0) { - // the ray is intersecting something we can move. - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); - var intersectionDistance = Vec3.distance(handControllerPosition, intersection.intersection); - this.grabbedEntity = intersection.entityID; - if (intersectionDistance < NEAR_PICK_MAX_DISTANCE) { - // the hand is very close to the intersected object. go into close-grabbing mode. - this.state = STATE_NEAR_GRABBING; - } else { - // the hand is far from the intersected object. go into distance-holding mode - this.state = STATE_DISTANCE_HOLDING; - this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } - } else { - // forward ray test failed, try sphere test. - var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS); - var minDistance = GRAB_RADIUS; - var grabbedEntity = null; - for (var i = 0; i < nearbyEntities.length; i++) { - var props = Entities.getEntityProperties(nearbyEntities[i]); - var distance = Vec3.distance(props.position, handPosition); - if (distance < minDistance && props.name !== "pointer" && - props.collisionsWillMove === 1 && - props.locked === 0) { - this.grabbedEntity = nearbyEntities[i]; - minDistance = distance; - } - } - if (this.grabbedEntity === null) { - this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } else { - this.state = STATE_NEAR_GRABBING; - } - } - } - - - this.distanceHolding = function() { - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); - var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); - - // add the action and initialize some variables - this.currentObjectPosition = grabbedProperties.position; - this.currentObjectRotation = grabbedProperties.rotation; - this.currentObjectTime = Date.now(); - this.handPreviousPosition = handControllerPosition; - this.handPreviousRotation = handRotation; - - this.actionID = Entities.addAction("spring", this.grabbedEntity, { - targetPosition: this.currentObjectPosition, - linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME - }); - if (this.actionID == NULL_ACTION_ID) { - this.actionID = null; - } - - if (this.actionID != null) { - this.state = STATE_CONTINUE_DISTANCE_HOLDING; - this.activateEntity(this.grabbedEntity); - Entities.callEntityMethod(this.grabbedEntity, "startDistantGrab"); - - if (this.hand === RIGHT_HAND) { - Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); - } else { - Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); - } - } - } - - - this.continueDistanceHolding = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - - var handPosition = this.getHandPosition(); - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); - var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm)); - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); - - this.lineOn(handPosition, Vec3.subtract(grabbedProperties.position, handPosition), INTERSECT_COLOR); - - // the action was set up on a previous call. update the targets. - var radius = Math.max(Vec3.distance(this.currentObjectPosition, - handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, - DISTANCE_HOLDING_RADIUS_FACTOR); - - var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition); - this.handPreviousPosition = handControllerPosition; - var superHandMoved = Vec3.multiply(handMoved, radius); - - var newObjectPosition = Vec3.sum(this.currentObjectPosition, superHandMoved); - var deltaPosition = Vec3.subtract(newObjectPosition, this.currentObjectPosition); // meters - var now = Date.now(); - var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds - this.computeReleaseVelocity(deltaPosition, deltaTime, false); - - this.currentObjectPosition = newObjectPosition; - this.currentObjectTime = now; - - // this doubles hand rotation - var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation, - DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), - Quat.inverse(this.handPreviousRotation)); - this.handPreviousRotation = handRotation; - this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation); - - Entities.callEntityMethod(this.grabbedEntity, "continueDistantGrab"); - - Entities.updateAction(this.grabbedEntity, this.actionID, { - targetPosition: this.currentObjectPosition, - linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, - targetRotation: this.currentObjectRotation, - angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME - }); - } - - - this.nearGrabbing = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - - this.lineOff(); - - this.activateEntity(this.grabbedEntity); - - var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]); - - var handRotation = this.getHandRotation(); - var handPosition = this.getHandPosition(); - - var objectRotation = grabbedProperties.rotation; - var offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); - - currentObjectPosition = grabbedProperties.position; - var offset = Vec3.subtract(currentObjectPosition, handPosition); - var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); - - this.actionID = Entities.addAction("hold", this.grabbedEntity, { - hand: this.hand == RIGHT_HAND ? "right" : "left", - timeScale: NEAR_GRABBING_ACTION_TIMEFRAME, - relativePosition: offsetPosition, - relativeRotation: offsetRotation - }); - if (this.actionID == NULL_ACTION_ID) { - this.actionID = null; - } else { - this.state = STATE_CONTINUE_NEAR_GRABBING; - Entities.callEntityMethod(this.grabbedEntity, "startNearGrab"); - if (this.hand === RIGHT_HAND) { - Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); - } else { - Entities.callEntityMethod(this.grabbedEntity, "setLeftHand"); - } - } - - this.currentHandControllerPosition = Controller.getSpatialControlPosition(this.palm); - this.currentObjectTime = Date.now(); - } - - - this.continueNearGrabbing = function() { - if (!this.triggerSmoothedSqueezed()) { - this.state = STATE_RELEASE; - return; - } - - // keep track of the measured velocity of the held object - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); - var now = Date.now(); - - var deltaPosition = Vec3.subtract(handControllerPosition, this.currentHandControllerPosition); // meters - var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds - this.computeReleaseVelocity(deltaPosition, deltaTime, true); - - this.currentHandControllerPosition = handControllerPosition; - this.currentObjectTime = now; - Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); - } - - - this.computeReleaseVelocity = function(deltaPosition, deltaTime, useMultiplier) { - if (deltaTime > 0.0 && !vec3equal(deltaPosition, ZERO_VEC)) { - var grabbedVelocity = Vec3.multiply(deltaPosition, 1.0 / deltaTime); - // don't update grabbedVelocity if the trigger is off. the smoothing of the trigger - // value would otherwise give the held object time to slow down. - if (this.triggerSqueezed()) { - this.grabbedVelocity = - Vec3.sum(Vec3.multiply(this.grabbedVelocity, (1.0 - NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)), - Vec3.multiply(grabbedVelocity, NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)); - } - - if (useMultiplier) { - this.grabbedVelocity = Vec3.multiply(this.grabbedVelocity, RELEASE_VELOCITY_MULTIPLIER); - } - } - } - - - this.release = function() { - this.lineOff(); - - if (this.grabbedEntity != null && this.actionID != null) { - Entities.deleteAction(this.grabbedEntity, this.actionID); - Entities.callEntityMethod(this.grabbedEntity, "releaseGrab"); - } - - // the action will tend to quickly bring an object's velocity to zero. now that - // the action is gone, set the objects velocity to something the holder might expect. - Entities.editEntity(this.grabbedEntity, { - velocity: this.grabbedVelocity - }); - this.deactivateEntity(this.grabbedEntity); - - this.grabbedVelocity = ZERO_VEC; - this.grabbedEntity = null; - this.actionID = null; - this.state = STATE_SEARCHING; - } - - - this.cleanup = function() { - release(); - } - - this.activateEntity = function(entity) { - var data = { - activated: true, - avatarId: MyAvatar.sessionUUID - }; - setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data); - } - - this.deactivateEntity = function(entity) { - var data = { - activated: false, - avatarId: null - }; - setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data); - } -} - - -var rightController = new controller(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); -var leftController = new controller(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); - - -function update() { - rightController.update(); - leftController.update(); -} - - -function cleanup() { - rightController.cleanup(); - leftController.cleanup(); -} - - -Script.scriptEnding.connect(cleanup); -Script.update.connect(update) \ No newline at end of file From 1e1cfb6aae197aa5af6828a768a064c1471b87dd Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 10:15:50 -0700 Subject: [PATCH 062/212] Flipped lights so up is lights on and vica versa --- examples/toys/lightSwitchGarage.js | 33 ++++++++++++++++++--------- examples/toys/lightSwitchHall.js | 36 ++++++++++++++++++------------ 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/examples/toys/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js index a68a09cf7d..99d827aa06 100644 --- a/examples/toys/lightSwitchGarage.js +++ b/examples/toys/lightSwitchGarage.js @@ -52,16 +52,7 @@ this.createLights(); } - // flip model to give illusion of light switch being flicked - var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; - var axis = {x: 0, y: 1, z: 0}; - var dQ = Quat.angleAxis(180, axis); - rotation = Quat.multiply(rotation, dQ); - - - Entities.editEntity(this.entityID, { - rotation: rotation - }); + this.flipLights(); Audio.playSound(this.switchSound, { volume: 0.5, @@ -86,7 +77,7 @@ }, createLights: function() { - + var sconceLight3 = Entities.addEntity({ type: "Light", @@ -176,6 +167,25 @@ }, + flipLights: function() { + // flip model to give illusion of light switch being flicked + var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; + var axis = { + x: 0, + y: 1, + z: 0 + }; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); + + + Entities.editEntity(this.entityID, { + rotation: rotation + }); + + }, + + // preload() will be called when the entity has become visible (or known) to the interface // it gives us a chance to set our local JavaScript object up. In this case it means: preload: function(entityID) { @@ -191,6 +201,7 @@ //If light is off, then we create two new lights- at the position of the sconces if (lightState.on === false) { this.createLights(); + this.flipLights(); } //If lights are on, do nothing! }, diff --git a/examples/toys/lightSwitchHall.js b/examples/toys/lightSwitchHall.js index 6bc1eeab83..49ccc51b79 100644 --- a/examples/toys/lightSwitchHall.js +++ b/examples/toys/lightSwitchHall.js @@ -53,19 +53,7 @@ } // flip model to give illusion of light switch being flicked - var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; - var axis = { - x: 0, - y: 1, - z: 0 - }; - var dQ = Quat.angleAxis(180, axis); - rotation = Quat.multiply(rotation, dQ); - - - Entities.editEntity(this.entityID, { - rotation: rotation - }); + this.flipLights(); Audio.playSound(this.switchSound, { volume: 0.5, @@ -148,9 +136,27 @@ }, + flipLights: function() { + // flip model to give illusion of light switch being flicked + var rotation = Entities.getEntityProperties(this.entityID, "rotation").rotation; + var axis = { + x: 0, + y: 1, + z: 0 + }; + var dQ = Quat.angleAxis(180, axis); + rotation = Quat.multiply(rotation, dQ); + + + Entities.editEntity(this.entityID, { + rotation: rotation + }); + + }, + // preload() will be called when the entity has become visible (or known) to the interface // it gives us a chance to set our local JavaScript object up. In this case it means: - preload: function(entityID) { + preload: function(entityID) { this.entityID = entityID; //The light switch is static, so just cache its position once @@ -163,6 +169,8 @@ //If light is off, then we create two new lights- at the position of the sconces if (lightState.on === false) { this.createLights(); + this.flipLights(); + } //If lights are on, do nothing! }, From 8609769c2081f539f2b0c8fdeafabd032f7f1f38 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 11:58:54 -0700 Subject: [PATCH 063/212] cat now listens for touch event from controller --- examples/toys/cat.js | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 1f1e7cc9d4..f1fcb81e8f 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -27,17 +27,10 @@ Cat.prototype = { - update: function() { - var leftHandPosition = MyAvatar.getLeftPalmPosition(); - var rightHandPosition = MyAvatar.getRightPalmPosition(); - if (Vec3.distance(leftHandPosition, _this.position) < _this.distanceThreshold || Vec3.distance(rightHandPosition, _this.position) < _this.distanceThreshold && _this.canMeow) { - _this.meow(); - _this.canMeow = false; - Script.setTimeout(function() { - _this.canMeow = true - }, _this.meowBreakTime) - } - }, + startTouch: function() { + print("START TOUCH") + this.meow(); + } meow: function() { From 2883319fb0fe4d3810df53983262c850830dda7c Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 13:33:43 -0700 Subject: [PATCH 064/212] Add potted plant, arm chair, and pillow --- examples/toys/masterResetEntity.js | 195 +++++++++++++++++++++++------ 1 file changed, 158 insertions(+), 37 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index c94f1bde9b..901777be09 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -8,7 +8,7 @@ /*global deleteAllToys, print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ //per script -/*global createAllToys, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches */ +/*global createAllToys, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches,createPottedPlant,createArmChair,createPillow */ var utilitiesScript = Script.resolvePath("../libraries/utils.js"); Script.include(utilitiesScript); @@ -455,41 +455,41 @@ function createBlocks(position) { var i, j; var blockTypes = [{ - url: "planky_blue.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_green.fbx", - dimensions: { - x: 0.1, - y: 0.1, - z: 0.25 - } - }, { - url: "planky_natural.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.05 - } - }, { - url: "planky_yellow.fbx", - dimensions: { - x: 0.03, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_red.fbx", - dimensions: { - x: 0.1, - y: 0.05, - z: 0.25 - } - }]; + url: "planky_blue.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_green.fbx", + dimensions: { + x: 0.1, + y: 0.1, + z: 0.25 + } + }, { + url: "planky_natural.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.05 + } + }, { + url: "planky_yellow.fbx", + dimensions: { + x: 0.03, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_red.fbx", + dimensions: { + x: 0.1, + y: 0.05, + z: 0.25 + } + }]; var modelURL, entity; for (i = 0; i < blockTypes.length; i++) { @@ -527,12 +527,133 @@ function createBlocks(position) { } } +//createPottedPlant,createArmChair,createPillow + +function createPottedPlant() { + var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/potted_plant.fbx"; + + var position = { + x: 554.26, + y: 495.23, + z: 504.53 + } + + var entity = Entities.addEntity({ + type: "Model", + name: "Potted Plant", + modelURL: modelURL, + position: position, + dimensions: { + x: 1.10 + y: 2.18, + z: 1.07 + }, + collisionsWillMove: true, + shapeType: 'box', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + }, + linearDamping: 0.4 + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + +function createArmChair() { + var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/red_arm_chair.fbx"; + var position = { + x: 549.39, + y: 494.57, + z: 508.37 + } + + var ARM_CHAIR_COLLISION_SHAPE = ""; + var entity = Entities.addEntity({ + type: "Model", + name: "Arm Chair", + modelURL: modelURL, + shapeType:'compound', + compoundShapeURL: ARM_CHAIR_COLLISION_SHAPE, + position: position, + rotation: { + x: 0, + y: -143.01, + z: 0 + }, + dimensions: { + x: 1.26, + y: 1.56, + z: 1.35 + }, + collisionsWillMove: true, + shapeType: 'box', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + } + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + +function createPillow() { + var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/red_arm_chair_pillow.fbx"; + var position = { + x: 549.39, + y: 495.00, + z: 508.37 + } + var entity = Entities.addEntity({ + type: "Model", + name: "Arm Chair Pillow", + modelURL: modelURL, + position: position, + dimensions: { + x: 0.07, + y: 0.17, + z: 0.07 + }, + collisionsWillMove: true, + shapeType: 'box', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + } + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + function cleanup() { deleteAllToys(); } if (shouldDeleteOnEndScript) { - Script.scriptEnding.connect(cleanup); } From 16f9140a08ca4dacb34805eb644958caab439e02 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 14:04:37 -0700 Subject: [PATCH 065/212] updated master script so objects with fewer properties are on one line --- examples/toys/masterResetEntity.js | 344 +++++------------------------ 1 file changed, 60 insertions(+), 284 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index c94f1bde9b..eebcefaaed 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -24,54 +24,24 @@ deleteAllToys(); createAllToys(); function createAllToys() { - createBlocks({ - x: 548.3, - y: 495.55, - z: 504.4 - }); + createBlocks({ x: 548.3, y: 495.55, z: 504.4 }); - createSprayCan({ - x: 549.8, - y: 495.6, - z: 503.94 - }); + createSprayCan({ x: 549.8, y: 495.6, z: 503.94 }); - createBasketBall({ - x: 547.73, - y: 495.5, - z: 505.47 - }); + createBasketBall({ x: 547.73, y: 495.5, z: 505.47}); - createDoll({ - x: 546.67, - y: 495.41, - z: 505.09 - }); + createDoll({x: 546.67, y: 495.41, z: 505.09}); - createWand({ - x: 546.71, - y: 495.55, - z: 506.15 - }); + createWand({ x: 546.71, y: 495.55, z: 506.15}); createDice(); - createFlashlight({ - x: 545.72, - y: 495.41, - z: 505.78 + createFlashlight({ x: 545.72, y: 495.41, z: 505.78 }); - createCat({ - x: 551.49859619140625, - y: 495.49111938476562, - z: 502.26498413085938 - }); + createCat({ x: 551.49859619140625, y: 495.49111938476562, z: 502.26498413085938 }); - createMagballs({ - x: 548.73, - y: 495.51, - z: 503.54 + createMagballs({ x: 548.73, y: 495.51, z: 503.54 }); //Handles toggling of all sconce lights @@ -99,36 +69,21 @@ function createMagballs(position) { modelURL: modelURL, name: "Tin Can", position: position, - rotation: { - w: 0.93041884899139404, - x: -1.52587890625e-05, - y: 0.36647593975067139, - z: -1.52587890625e-05 - }, - dimensions: { - x: 0.16946873068809509, - y: 0.21260403096675873, - z: 0.16946862637996674 - }, + rotation: { w: 0.93041884899139404, x: -1.52587890625e-05, y: 0.36647593975067139, z: -1.52587890625e-05}, + dimensions: { x: 0.16946873068809509, y: 0.21260403096675873, z: 0.16946862637996674 }, }); - setEntityCustomData(resetKey, tinCan, { - resetMe: true - }); + setEntityCustomData(resetKey, tinCan, { resetMe: true }); - setEntityCustomData("OmniTool", tinCan, { - script: "../toys/magBalls.js" - }); + setEntityCustomData("OmniTool", tinCan, { script: "../toys/magBalls.js"}); } function createCat(position) { var scriptURL = Script.resolvePath("cat.js?v1"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; - var animationSettings = JSON.stringify({ - running: true, - }); + var animationSettings = JSON.stringify({running: true,}); var cat = Entities.addEntity({ type: "Model", modelURL: modelURL, @@ -137,22 +92,11 @@ function createCat(position) { animationURL: animationURL, animationSettings: animationSettings, position: position, - rotation: { - w: 0.35020983219146729, - x: -4.57763671875e-05, - y: 0.93664455413818359, - z: -1.52587890625e-05 - }, - dimensions: { - x: 0.15723302960395813, - y: 0.50762706995010376, - z: 0.90716040134429932 - }, + rotation: { w: 0.35020983219146729, x: -4.57763671875e-05, y: 0.93664455413818359, z: -1.52587890625e-05}, + dimensions: { x: 0.15723302960395813, y: 0.50762706995010376, z: 0.90716040134429932}, }); - setEntityCustomData(resetKey, cat, { - resetMe: true - }); + setEntityCustomData(resetKey, cat, { resetMe: true }); } function createFlashlight(position) { @@ -165,28 +109,14 @@ function createFlashlight(position) { name: "flashlight", script: scriptURL, position: position, - dimensions: { - x: 0.08, - y: 0.30, - z: 0.08 - }, + dimensions: { x: 0.08, y: 0.30, z: 0.08}, collisionsWillMove: true, - gravity: { - x: 0, - y: -3.5, - z: 0 - }, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, + gravity: {x: 0, y: -3.5, z: 0}, + velocity: { x: 0, y: -0.01, z: 0}, shapeType: 'box', }); - setEntityCustomData(resetKey, flashlight, { - resetMe: true - }); + setEntityCustomData(resetKey, flashlight, {resetMe: true}); } @@ -199,22 +129,9 @@ function createLightSwitches() { modelURL: modelURL, name: "Light Switch Hall", script: scriptURL, - position: { - x: 543.27764892578125, - y: 495.67999267578125, - z: 511.00564575195312 - }, - rotation: { - w: 0.63280689716339111, - x: 0.63280689716339111, - y: -0.31551080942153931, - z: 0.31548023223876953 - }, - dimensions: { - x: 0.10546875, - y: 0.032372996211051941, - z: 0.16242524981498718 - } + position: {x: 543.27764892578125, y: 495.67999267578125, z: 511.00564575195312}, + rotation: {w: 0.63280689716339111, x: 0.63280689716339111, y: -0.31551080942153931, z: 0.31548023223876953}, + dimensions: {x: 0.10546875, y: 0.032372996211051941, z: 0.16242524981498718} }); setEntityCustomData(resetKey, lightSwitchHall, { @@ -228,27 +145,12 @@ function createLightSwitches() { modelURL: modelURL, name: "Light Switch Garage", script: scriptURL, - position: { - x: 545.62, - y: 495.68, - z: 500.21 - }, - rotation: { - w: 0.20082402229309082, - x: 0.20082402229309082, - y: -0.67800414562225342, - z: 0.67797362804412842 - }, - dimensions: { - x: 0.10546875, - y: 0.032372996211051941, - z: 0.16242524981498718 - } + position: {x: 545.62, y: 495.68,z: 500.21}, + rotation: { w: 0.20082402229309082, x: 0.20082402229309082, y: -0.67800414562225342, z: 0.67797362804412842}, + dimensions: { x:0.10546875, y: 0.032372996211051941, z: 0.16242524981498718} }); - setEntityCustomData(resetKey, lightSwitchGarage, { - resetMe: true - }); + setEntityCustomData(resetKey, lightSwitchGarage, {resetMe: true}); } @@ -258,46 +160,22 @@ function createDice() { modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", - position: { - x: 541, - y: 494.96, - z: 509.1 - }, - dimensions: { - x: 0.09, - y: 0.09, - z: 0.09 - }, - gravity: { - x: 0, - y: -3.5, - z: 0 - }, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, + position: {x: 541, y: 494.96, z: 509.1}, + dimensions: {x: 0.09, y: 0.09, z: 0.09}, + gravity: {x: 0, y: -3.5, z: 0}, + velocity: {x: 0,y: -0.01, z: 0}, shapeType: "box", collisionsWillMove: true }; var dice1 = Entities.addEntity(diceProps); - diceProps.position = { - x: 541.05, - y: 494.96, - z: 509.0 - }; + diceProps.position = { x: 541.05, y: 494.96, z: 509.0 }; var dice2 = Entities.addEntity(diceProps); - setEntityCustomData(resetKey, dice1, { - resetMe: true - }); + setEntityCustomData(resetKey, dice1, {resetMe: true}); - setEntityCustomData(resetKey, dice2, { - resetMe: true - }); + setEntityCustomData(resetKey, dice2, {resetMe: true}); } function createWand(position) { @@ -311,16 +189,8 @@ function createWand(position) { type: "Model", modelURL: WAND_MODEL, position: position, - gravity: { - x: 0, - y: 0, - z: 0, - }, - dimensions: { - x: 0.05, - y: 0.25, - z: 0.05 - }, + gravity: {x: 0, y: 0, z: 0}, + dimensions: { x: 0.05, y: 0.25,z: 0.05}, //must be enabled to be grabbable in the physics engine collisionsWillMove: true, compoundShapeURL: WAND_COLLISION_SHAPE, @@ -330,9 +200,7 @@ function createWand(position) { script: scriptURL }); - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + setEntityCustomData(resetKey, entity, {resetMe: true}); } function createBasketBall(position) { @@ -346,41 +214,22 @@ function createBasketBall(position) { collisionsWillMove: true, shapeType: "sphere", name: "basketball", - dimensions: { - x: 0.25, - y: 0.26, - z: 0.25 - }, - gravity: { - x: 0, - y: -7, - z: 0 - }, + dimensions: {x: 0.25, y: 0.26, z: 0.25}, + gravity: {x: 0, y: -7, z: 0}, restitution: 10, linearDamping: 0.0, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, + velocity: { x: 0, y: -0.01, z: 0}, collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" }); - setEntityCustomData(resetKey, entity, { - resetMe: true - }); - + setEntityCustomData(resetKey, entity, {resetMe: true}); } function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; var scriptURL = Script.resolvePath("doll.js"); - var naturalDimensions = { - x: 1.63, - y: 1.67, - z: 0.26 - }; + var naturalDimensions = {x: 1.63, y: 1.67, z: 0.26}; var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); var entity = Entities.addEntity({ type: "Model", @@ -390,22 +239,12 @@ function createDoll(position) { position: position, shapeType: 'box', dimensions: desiredDimensions, - gravity: { - x: 0, - y: -5, - z: 0 - }, - velocity: { - x: 0, - y: -0.1, - z: 0 - }, + gravity: {x: 0, y: -5, z: 0}, + velocity: {x: 0, y: -0.1, z: 0}, collisionsWillMove: true }); - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + setEntityCustomData(resetKey, entity, {resetMe: true}); } function createSprayCan(position) { @@ -417,35 +256,15 @@ function createSprayCan(position) { name: "spraycan", modelURL: modelURL, position: position, - rotation: { - x: 0, - y: 0, - z: 0, - w: 1 - }, - dimensions: { - x: 0.07, - y: 0.17, - z: 0.07 - }, + dimensions: {x: 0.07, y: 0.17, z: 0.07}, collisionsWillMove: true, shapeType: 'box', script: scriptURL, - gravity: { - x: 0, - y: -0.5, - z: 0 - }, - velocity: { - x: 0, - y: -1, - z: 0 - } + gravity: {x: 0, y: -0.5, z: 0}, + velocity: { x: 0, y: -1, z: 0} }); - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + setEntityCustomData(resetKey, entity, {resetMe: true}); } @@ -454,42 +273,13 @@ function createBlocks(position) { var NUM_BLOCKS_PER_COLOR = 4; var i, j; - var blockTypes = [{ - url: "planky_blue.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_green.fbx", - dimensions: { - x: 0.1, - y: 0.1, - z: 0.25 - } - }, { - url: "planky_natural.fbx", - dimensions: { - x: 0.05, - y: 0.05, - z: 0.05 - } - }, { - url: "planky_yellow.fbx", - dimensions: { - x: 0.03, - y: 0.05, - z: 0.25 - } - }, { - url: "planky_red.fbx", - dimensions: { - x: 0.1, - y: 0.05, - z: 0.25 - } - }]; + var blockTypes = [ + { url: "planky_blue.fbx", dimensions: {x: 0.05, y: 0.05, z: 0.25} } + { url: "planky_green.fbx", dimensions: {x: 0.1, y: 0.1, z: 0.25} } + { url: "planky_natural.fbx", dimensions: { x: 0.05, y: 0.05, z: 0.05} } + { url: "planky_yellow.fbx", dimensions: {x: 0.03, y: 0.05, z: 0.25} } + { url: "planky_red.fbx", dimensions: {x: 0.1, y: 0.05, z: 0.25} } + ]; var modelURL, entity; for (i = 0; i < blockTypes.length; i++) { @@ -498,31 +288,17 @@ function createBlocks(position) { entity = Entities.addEntity({ type: "Model", modelURL: modelURL, - position: Vec3.sum(position, { - x: j / 10, - y: i / 10, - z: 0 - }), + position: Vec3.sum(position, { x: j / 10, y: i / 10, z: 0}), shapeType: 'box', name: "block", dimensions: blockTypes[i].dimensions, collisionsWillMove: true, - gravity: { - x: 0, - y: -2.5, - z: 0 - }, - velocity: { - x: 0, - y: -0.01, - z: 0 - } + gravity: {x: 0, y: -2.5, z: 0}, + velocity: { x: 0, y: -0.01, z: 0} }); //customKey, id, data - setEntityCustomData(resetKey, entity, { - resetMe: true - }); + setEntityCustomData(resetKey, entity, {resetMe: true}); } } } From 536adf898184fc0145147a3f817b2afe75acfd8d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 14:39:11 -0700 Subject: [PATCH 066/212] testing paintcan --- examples/toys/cat.js | 1 - examples/toys/masterResetEntity.js | 2 +- examples/toys/sprayPaintCan.js | 145 +++++++++++++++++++++++------ 3 files changed, 116 insertions(+), 32 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index f1fcb81e8f..98d08969a7 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -28,7 +28,6 @@ Cat.prototype = { startTouch: function() { - print("START TOUCH") this.meow(); } diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index c94f1bde9b..f3950eb32c 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -33,7 +33,7 @@ function createAllToys() { createSprayCan({ x: 549.8, y: 495.6, - z: 503.94 + z: 503.84 }); createBasketBall({ diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 28eb8adaf4..8f3bb12307 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -3,10 +3,9 @@ //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge Script.include("../libraries/utils.js"); + GRAB_FRAME_USER_DATA_KEY = "grabFrame"; this.userData = {}; - this.spraySound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/sprayPaintSound.wav"); - var TIP_OFFSET_Z = 0.14; var TIP_OFFSET_Y = 0.04; @@ -20,17 +19,59 @@ var MIN_POINT_DISTANCE = 0.01; var STROKE_WIDTH = 0.02; - this.setRightHand = function() { - this.hand = 'RIGHT'; + var self = this; + + var timeSinceLastMoved = 0; + var RESET_TIME_THRESHOLD = 5; + var DISTANCE_FROM_HOME_THRESHOLD = 0.5; + var HOME_POSITION = { + x: 549.12, + y: 495.555, + z: 503.77 + }; + this.getUserData = function() { + + + if (this.properties.userData) { + this.userData = JSON.parse(this.properties.userData); + } } - this.setLeftHand = function() { - this.hand = 'LEFT'; + this.updateUserData = function() { + Entities.editEntity(this.entityId, { + userData: JSON.stringify(this.userData) + }); } - this.startNearGrab = function() { - this.whichHand = this.hand; - var position = Entities.getEntityProperties(this.entityId, "position").position; + this.update = function(deltaTime) { + self.getUserData(); + self.properties = Entities.getEntityProperties(self.entityId); + + if (Vec3.length(self.properties.velocity) < 0.1 && Vec3.distance(HOME_POSITION, self.properties.position) > DISTANCE_FROM_HOME_THRESHOLD) { + timeSinceLastMoved += deltaTime; + if (timeSinceLastMoved > RESET_TIME_THRESHOLD) { + self.reset(); + timeSinceLastMoved = 0; + } + } else { + timeSinceLastMoved = 0; + } + + //Only activate for the user who grabbed the object + if (self.userData.grabKey && self.userData.grabKey.activated === true && self.userData.grabKey.avatarId == MyAvatar.sessionUUID) { + if (self.activated !== true) { + //We were just grabbed, so create a particle system + self.grab(); + } + //Move emitter to where entity is always when its activated + self.sprayStream(); + } else if (self.userData.grabKey && self.userData.grabKey.activated === false && self.activated) { + self.letGo(); + } + } + + this.grab = function() { + this.activated = true; var animationSettings = JSON.stringify({ fps: 30, loop: true, @@ -44,7 +85,7 @@ this.paintStream = Entities.addEntity({ type: "ParticleEffect", animationSettings: animationSettings, - position: position, + position: this.properties.position, textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", emitSpeed: 0, speedSpread: 0.02, @@ -59,33 +100,34 @@ }, lifetime: 50, //probably wont be holding longer than this straight }); + } - this.sprayInjector = Audio.playSound(this.spraySound, { - position: position, - volume: 0.1 + this.letGo = function() { + this.activated = false; + Entities.deleteEntity(this.paintStream); + this.paintStream = null; + } + + this.reset = function() { + Entities.editEntity(self.entityId, { + position: HOME_POSITION, + rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), + angularVelocity: ZERO_VEC, + velocity: ZERO_VEC }); } - - this.releaseGrab = function() { - Entities.deleteEntity(this.paintStream); - this.paintStream = null; - this.painting = false; - this.sprayInjector.stop(); - } - - - this.continueNearGrab = function() { - var props = Entities.getEntityProperties(this.entityId, ["position, rotation"]); - var forwardVec = Quat.getFront(Quat.multiply(props.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); + this.sprayStream = function() { + var forwardQuat = Quat.multiply(self.properties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0)); + var forwardVec = Quat.getFront(self.properties.rotation); forwardVec = Vec3.normalize(forwardVec); - var upVec = Quat.getUp(props.rotation); - var position = Vec3.sum(props.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); + var upVec = Quat.getUp(self.properties.rotation); + var position = Vec3.sum(self.properties.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) - Entities.editEntity(this.paintStream, { - position: position, - emitOrientation: forwardVec, + Entities.editEntity(self.paintStream, { + position: self.properties.position, + emitOrientation: self.properties.rotation, emitSpeed: 5 }); @@ -163,11 +205,31 @@ this.preload = function(entityId) { this.strokes = []; + this.activated = false; this.entityId = entityId; + this.properties = Entities.getEntityProperties(self.entityId); + this.getUserData(); + + //Only activate for the avatar who is grabbing the can! + if (this.userData.grabKey && this.userData.grabKey.activated) { + this.activated = true; + } + if (!this.userData.grabFrame) { + var data = { + relativePosition: { + x: 0, + y: 0, + z: 0 + }, + relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 0) + } + setEntityCustomData(GRAB_FRAME_USER_DATA_KEY, this.entityId, data); + } } this.unload = function() { + Script.update.disconnect(this.update); if (this.paintStream) { Entities.deleteEntity(this.paintStream); } @@ -175,6 +237,7 @@ Entities.deleteEntity(stroke); }); } + Script.update.connect(this.update); }); @@ -185,4 +248,26 @@ function randFloat(min, max) { function randInt(min, max) { return Math.floor(Math.random() * (max - min)) + min; +} + +function orientationOf(vector) { + var Y_AXIS = { + x: 0, + y: 1, + z: 0 + }; + var X_AXIS = { + x: 1, + y: 0, + z: 0 + }; + + var theta = 0.0; + + var RAD_TO_DEG = 180.0 / Math.PI; + var direction, yaw, pitch; + direction = Vec3.normalize(vector); + yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); + pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); + return Quat.multiply(yaw, pitch); } \ No newline at end of file From 5da8b689c5a182d07c86a556daa89d0a43b557ae Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 14:41:22 -0700 Subject: [PATCH 067/212] fix missing commas --- examples/toys/masterResetEntity.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index eebcefaaed..9eaa0e56d5 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -274,11 +274,11 @@ function createBlocks(position) { var i, j; var blockTypes = [ - { url: "planky_blue.fbx", dimensions: {x: 0.05, y: 0.05, z: 0.25} } - { url: "planky_green.fbx", dimensions: {x: 0.1, y: 0.1, z: 0.25} } - { url: "planky_natural.fbx", dimensions: { x: 0.05, y: 0.05, z: 0.05} } - { url: "planky_yellow.fbx", dimensions: {x: 0.03, y: 0.05, z: 0.25} } - { url: "planky_red.fbx", dimensions: {x: 0.1, y: 0.05, z: 0.25} } + { url: "planky_blue.fbx", dimensions: {x: 0.05, y: 0.05, z: 0.25} }, + { url: "planky_green.fbx", dimensions: {x: 0.1, y: 0.1, z: 0.25} }, + { url: "planky_natural.fbx", dimensions: { x: 0.05, y: 0.05, z: 0.05} }, + { url: "planky_yellow.fbx", dimensions: {x: 0.03, y: 0.05, z: 0.25} }, + { url: "planky_red.fbx", dimensions: {x: 0.1, y: 0.05, z: 0.25} }, ]; var modelURL, entity; From ce0a726eb908f6864ee86f3bf8631664743b3f74 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 16:27:17 -0700 Subject: [PATCH 068/212] Fixed spraypaint for new particles --- examples/toys/sprayPaintCan.js | 138 ++++++++++----------------------- 1 file changed, 40 insertions(+), 98 deletions(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 8f3bb12307..0508cab038 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -3,11 +3,12 @@ //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge Script.include("../libraries/utils.js"); - GRAB_FRAME_USER_DATA_KEY = "grabFrame"; this.userData = {}; - var TIP_OFFSET_Z = 0.14; - var TIP_OFFSET_Y = 0.04; + this.spraySound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/sprayPaintSound.wav"); + + var TIP_OFFSET_Z = 0.02; + var TIP_OFFSET_Y = 0.08; var ZERO_VEC = { x: 0, @@ -19,59 +20,17 @@ var MIN_POINT_DISTANCE = 0.01; var STROKE_WIDTH = 0.02; - var self = this; - - var timeSinceLastMoved = 0; - var RESET_TIME_THRESHOLD = 5; - var DISTANCE_FROM_HOME_THRESHOLD = 0.5; - var HOME_POSITION = { - x: 549.12, - y: 495.555, - z: 503.77 - }; - this.getUserData = function() { - - - if (this.properties.userData) { - this.userData = JSON.parse(this.properties.userData); - } + this.setRightHand = function() { + this.hand = 'RIGHT'; } - this.updateUserData = function() { - Entities.editEntity(this.entityId, { - userData: JSON.stringify(this.userData) - }); + this.setLeftHand = function() { + this.hand = 'LEFT'; } - this.update = function(deltaTime) { - self.getUserData(); - self.properties = Entities.getEntityProperties(self.entityId); - - if (Vec3.length(self.properties.velocity) < 0.1 && Vec3.distance(HOME_POSITION, self.properties.position) > DISTANCE_FROM_HOME_THRESHOLD) { - timeSinceLastMoved += deltaTime; - if (timeSinceLastMoved > RESET_TIME_THRESHOLD) { - self.reset(); - timeSinceLastMoved = 0; - } - } else { - timeSinceLastMoved = 0; - } - - //Only activate for the user who grabbed the object - if (self.userData.grabKey && self.userData.grabKey.activated === true && self.userData.grabKey.avatarId == MyAvatar.sessionUUID) { - if (self.activated !== true) { - //We were just grabbed, so create a particle system - self.grab(); - } - //Move emitter to where entity is always when its activated - self.sprayStream(); - } else if (self.userData.grabKey && self.userData.grabKey.activated === false && self.activated) { - self.letGo(); - } - } - - this.grab = function() { - this.activated = true; + this.startNearGrab = function() { + this.whichHand = this.hand; + var position = Entities.getEntityProperties(this.entityId, "position").position; var animationSettings = JSON.stringify({ fps: 30, loop: true, @@ -85,14 +44,15 @@ this.paintStream = Entities.addEntity({ type: "ParticleEffect", animationSettings: animationSettings, - position: this.properties.position, + position: position, textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", - emitSpeed: 0, + emitSpeed: 3, speedSpread: 0.02, - polarFinish: 2 * DEG_TO_RAD, emitAcceleration: ZERO_VEC, emitRate: 100, particleRadius: 0.01, + radiusSpread: 0.005, + accelerationSpread: {x: 1, y: 1, x: 1}, color: { red: 170, green: 20, @@ -100,35 +60,38 @@ }, lifetime: 50, //probably wont be holding longer than this straight }); - } - this.letGo = function() { - this.activated = false; - Entities.deleteEntity(this.paintStream); - this.paintStream = null; - } - - this.reset = function() { - Entities.editEntity(self.entityId, { - position: HOME_POSITION, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), - angularVelocity: ZERO_VEC, - velocity: ZERO_VEC + this.sprayInjector = Audio.playSound(this.spraySound, { + position: position, + volume: 0.1 }); } - this.sprayStream = function() { - var forwardQuat = Quat.multiply(self.properties.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0)); - var forwardVec = Quat.getFront(self.properties.rotation); + + this.releaseGrab = function() { + Entities.deleteEntity(this.paintStream); + this.paintStream = null; + this.painting = false; + this.sprayInjector.stop(); + } + + + this.continueNearGrab = function() { + var props = Entities.getEntityProperties(this.entityId, ["position, rotation"]); + var forwardVec = Quat.getFront(Quat.multiply(props.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); forwardVec = Vec3.normalize(forwardVec); - var upVec = Quat.getUp(self.properties.rotation); - var position = Vec3.sum(self.properties.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); + + var forwardQuat = orientationOf(forwardVec); + + + var upVec = Quat.getUp(props.rotation); + var position = Vec3.sum(props.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) - Entities.editEntity(self.paintStream, { - position: self.properties.position, - emitOrientation: self.properties.rotation, - emitSpeed: 5 + Entities.editEntity(this.paintStream, { + position: position, + emitOrientation: forwardQuat, + // emitSpeed: 3 }); //Now check for an intersection with an entity @@ -205,31 +168,11 @@ this.preload = function(entityId) { this.strokes = []; - this.activated = false; this.entityId = entityId; - this.properties = Entities.getEntityProperties(self.entityId); - this.getUserData(); - - //Only activate for the avatar who is grabbing the can! - if (this.userData.grabKey && this.userData.grabKey.activated) { - this.activated = true; - } - if (!this.userData.grabFrame) { - var data = { - relativePosition: { - x: 0, - y: 0, - z: 0 - }, - relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 0) - } - setEntityCustomData(GRAB_FRAME_USER_DATA_KEY, this.entityId, data); - } } this.unload = function() { - Script.update.disconnect(this.update); if (this.paintStream) { Entities.deleteEntity(this.paintStream); } @@ -237,7 +180,6 @@ Entities.deleteEntity(stroke); }); } - Script.update.connect(this.update); }); From be1952797c071c609dce76868ad82dd59010ae8d Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 16:31:59 -0700 Subject: [PATCH 069/212] Changes to rotations --- examples/toys/masterResetEntity.js | 82 +++++++++++++++++------------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 901777be09..f674e3673d 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -76,6 +76,24 @@ function createAllToys() { //Handles toggling of all sconce lights createLightSwitches(); + + createArmChair({ + x: 549.39, + y: 494.57, + z: 508.37 + }) + + createPillow({ + x: 549.39, + y: 495.00, + z: 508.37 + }); + + createPottedPlant({ + x: 554.26, + y: 495.23, + z: 504.53 + }); } function deleteAllToys() { @@ -527,16 +545,11 @@ function createBlocks(position) { } } -//createPottedPlant,createArmChair,createPillow -function createPottedPlant() { +function createPottedPlant(position) { var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/potted_plant.fbx"; - var position = { - x: 554.26, - y: 495.23, - z: 504.53 - } + var rotation = Quat.fromPitchYawRollDegress(0,0,0); var entity = Entities.addEntity({ type: "Model", @@ -544,7 +557,7 @@ function createPottedPlant() { modelURL: modelURL, position: position, dimensions: { - x: 1.10 + x: 1.10, y: 2.18, z: 1.07 }, @@ -568,34 +581,28 @@ function createPottedPlant() { }); }; -function createArmChair() { - var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/red_arm_chair.fbx"; - var position = { - x: 549.39, - y: 494.57, - z: 508.37 - } - var ARM_CHAIR_COLLISION_SHAPE = ""; + +function createArmChair(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" + +var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); + var entity = Entities.addEntity({ type: "Model", - name: "Arm Chair", + name: "Red Arm Chair", modelURL: modelURL, - shapeType:'compound', - compoundShapeURL: ARM_CHAIR_COLLISION_SHAPE, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, position: position, - rotation: { - x: 0, - y: -143.01, - z: 0 - }, + rotation:rotation, dimensions: { x: 1.26, y: 1.56, z: 1.35 }, collisionsWillMove: true, - shapeType: 'box', gravity: { x: 0, y: -9.8, @@ -605,7 +612,8 @@ function createArmChair() { x: 0, y: -0.1, z: 0 - } + }, + linearDamping: 0.4 }); setEntityCustomData(resetKey, entity, { @@ -613,25 +621,26 @@ function createArmChair() { }); }; -function createPillow() { - var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/red_arm_chair_pillow.fbx"; - var position = { - x: 549.39, - y: 495.00, - z: 508.37 - } +function createPillow(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow.fbx"; + var RED_ARM_CHAIR_PILLOW_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow_collision_hull.obj" + + var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); + var entity = Entities.addEntity({ type: "Model", - name: "Arm Chair Pillow", + name: "Red Arm Chair Pillow", modelURL: modelURL, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_PILLOW_COLLISION_HULL, position: position, + rotation:rotation, dimensions: { x: 0.07, y: 0.17, z: 0.07 }, collisionsWillMove: true, - shapeType: 'box', gravity: { x: 0, y: -9.8, @@ -641,7 +650,8 @@ function createPillow() { x: 0, y: -0.1, z: 0 - } + }, + linearDamping:0.4 }); setEntityCustomData(resetKey, entity, { From c2f1141d6915fc3cf998babb5d38af158f1d78b6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 16:40:20 -0700 Subject: [PATCH 070/212] fix cat script --- examples/toys/cat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 98d08969a7..a71cec95c2 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -29,7 +29,7 @@ startTouch: function() { this.meow(); - } + }, meow: function() { From baf47777506a89f2f55c252db7788070b80b8727 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Sep 2015 17:13:45 -0700 Subject: [PATCH 071/212] Can now hold spray paint can without painting unless squeezing hard --- examples/toys/masterResetEntity.js | 2 +- examples/toys/sprayPaintCan.js | 83 +++++++++++++++++++++--------- 2 files changed, 59 insertions(+), 26 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index b7bfc708e3..a2f6c9f233 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -26,7 +26,7 @@ createAllToys(); function createAllToys() { createBlocks({ x: 548.3, y: 495.55, z: 504.4 }); - createSprayCan({ x: 549.8, y: 495.6, z: 503.94 }); + createSprayCan({ x: 549.7, y: 495.6, z: 503.91 }); createBasketBall({ x: 547.73, y: 495.5, z: 505.47}); diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 0508cab038..945dc4322f 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -3,7 +3,6 @@ //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge Script.include("../libraries/utils.js"); - this.userData = {}; this.spraySound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/sprayPaintSound.wav"); @@ -16,6 +15,9 @@ z: 0 } + // if the trigger value goes below this while held, the can will stop spraying. if it goes above, it will spray + var DISABLE_SPRAY_THRESHOLD = 0.7; + var MAX_POINTS_PER_LINE = 40; var MIN_POINT_DISTANCE = 0.01; var STROKE_WIDTH = 0.02; @@ -30,6 +32,24 @@ this.startNearGrab = function() { this.whichHand = this.hand; + } + + this.toggleWithTriggerPressure = function() { + var handClickString = this.whichHand + "_HAND_CLICK"; + + var handClick = Controller.findAction(handClickString); + + this.triggerValue = Controller.getActionValue(handClick); + if (this.triggerValue < DISABLE_SPRAY_THRESHOLD && this.spraying === true) { + this.spraying = false; + this.disableStream(); + } else if (this.triggerValue >= DISABLE_SPRAY_THRESHOLD && this.spraying === false) { + this.spraying = true; + this.enableStream(); + } + } + + this.enableStream = function() { var position = Entities.getEntityProperties(this.entityId, "position").position; var animationSettings = JSON.stringify({ fps: 30, @@ -43,6 +63,7 @@ this.paintStream = Entities.addEntity({ type: "ParticleEffect", + name: "streamEffect", animationSettings: animationSettings, position: position, textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", @@ -52,7 +73,6 @@ emitRate: 100, particleRadius: 0.01, radiusSpread: 0.005, - accelerationSpread: {x: 1, y: 1, x: 1}, color: { red: 170, green: 20, @@ -61,14 +81,23 @@ lifetime: 50, //probably wont be holding longer than this straight }); + setEntityCustomData(this.resetKey, this.paintStream, { + resetMe: true + }); + this.sprayInjector = Audio.playSound(this.spraySound, { position: position, volume: 0.1 }); + } - this.releaseGrab = function() { + this.disableStream(); + } + + this.disableStream = function() { + print("DEKETE STEREAAAM") Entities.deleteEntity(this.paintStream); this.paintStream = null; this.painting = false; @@ -77,21 +106,23 @@ this.continueNearGrab = function() { + + this.toggleWithTriggerPressure(); + + if (this.spraying === false) { + return; + } + var props = Entities.getEntityProperties(this.entityId, ["position, rotation"]); var forwardVec = Quat.getFront(Quat.multiply(props.rotation, Quat.fromPitchYawRollDegrees(0, 90, 0))); forwardVec = Vec3.normalize(forwardVec); - - var forwardQuat = orientationOf(forwardVec); - - var upVec = Quat.getUp(props.rotation); var position = Vec3.sum(props.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) Entities.editEntity(this.paintStream, { position: position, emitOrientation: forwardQuat, - // emitSpeed: 3 }); //Now check for an intersection with an entity @@ -168,7 +199,9 @@ this.preload = function(entityId) { this.strokes = []; + this.spraying = false; this.entityId = entityId; + this.resetKey = "resetMe"; } @@ -193,23 +226,23 @@ function randInt(min, max) { } function orientationOf(vector) { - var Y_AXIS = { - x: 0, - y: 1, - z: 0 - }; - var X_AXIS = { - x: 1, - y: 0, - z: 0 - }; + var Y_AXIS = { + x: 0, + y: 1, + z: 0 + }; + var X_AXIS = { + x: 1, + y: 0, + z: 0 + }; - var theta = 0.0; + var theta = 0.0; - var RAD_TO_DEG = 180.0 / Math.PI; - var direction, yaw, pitch; - direction = Vec3.normalize(vector); - yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); - pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); - return Quat.multiply(yaw, pitch); + var RAD_TO_DEG = 180.0 / Math.PI; + var direction, yaw, pitch; + direction = Vec3.normalize(vector); + yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); + pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); + return Quat.multiply(yaw, pitch); } \ No newline at end of file From 337bdfdaf6c07afea435baa5d2bd28467346151f Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 24 Sep 2015 18:35:26 -0700 Subject: [PATCH 072/212] end of day --- examples/toys/masterResetEntity.js | 47 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index f674e3673d..25e97829ad 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -78,15 +78,15 @@ function createAllToys() { createLightSwitches(); createArmChair({ - x: 549.39, - y: 494.57, - z: 508.37 + x: 549.29, + y: 495.05, + z: 508.22 }) createPillow({ - x: 549.39, - y: 495.00, - z: 508.37 + x: 549.29, + y: 495.25, + z: 508.22 }); createPottedPlant({ @@ -99,7 +99,7 @@ function createAllToys() { function deleteAllToys() { var entities = Entities.findEntities(MyAvatar.position, 100); - entities.forEach(function (entity) { + entities.forEach(function(entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; if (shouldReset === true) { @@ -547,9 +547,9 @@ function createBlocks(position) { function createPottedPlant(position) { - var modelURL = "https://hifi-public.s3.amazonaws.com/ryan/potted_plant.fbx"; + var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; - var rotation = Quat.fromPitchYawRollDegress(0,0,0); + var rotation = Quat.fromPitchYawRollDegress(0, 0, 0); var entity = Entities.addEntity({ type: "Model", @@ -570,7 +570,7 @@ function createPottedPlant(position) { }, velocity: { x: 0, - y: -0.1, + y: 0, z: 0 }, linearDamping: 0.4 @@ -587,7 +587,7 @@ function createArmChair(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair.fbx"; var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" -var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); + var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); var entity = Entities.addEntity({ type: "Model", @@ -596,7 +596,7 @@ var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); shapeType: 'compound', compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, position: position, - rotation:rotation, + rotation: rotation, dimensions: { x: 1.26, y: 1.56, @@ -605,15 +605,15 @@ var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); collisionsWillMove: true, gravity: { x: 0, - y: -9.8, + y: -0.5, z: 0 }, velocity: { x: 0, - y: -0.1, + y: 0, z: 0 }, - linearDamping: 0.4 + linearDamping: 0.3 }); setEntityCustomData(resetKey, entity, { @@ -624,8 +624,8 @@ var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); function createPillow(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow.fbx"; var RED_ARM_CHAIR_PILLOW_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow_collision_hull.obj" - - var rotation = Quat.fromPitchYawRollDegrees(0,-143,0); + + var rotation = Quat.fromPitchYawRollDegrees(-0.29, -143.05, 0.32); var entity = Entities.addEntity({ type: "Model", @@ -634,16 +634,17 @@ function createPillow(position) { shapeType: 'compound', compoundShapeURL: RED_ARM_CHAIR_PILLOW_COLLISION_HULL, position: position, - rotation:rotation, + rotation: rotation, dimensions: { - x: 0.07, - y: 0.17, - z: 0.07 + x: 0.4, + y: 0.4, + z: 0.4 }, collisionsWillMove: true, + ignoreForCollisions: false, gravity: { x: 0, - y: -9.8, + y: -10.1, z: 0 }, velocity: { @@ -651,7 +652,7 @@ function createPillow(position) { y: -0.1, z: 0 }, - linearDamping:0.4 + linearDamping: 1 }); setEntityCustomData(resetKey, entity, { From 0815b8e939138402fed27ffbcdd0325e0d7ce63b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 10:59:20 -0700 Subject: [PATCH 073/212] Added polar finish to spray paint stream --- examples/toys/sprayPaintCan.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 945dc4322f..0cce03de89 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -73,6 +73,7 @@ emitRate: 100, particleRadius: 0.01, radiusSpread: 0.005, + polarFinish: 0.1, color: { red: 170, green: 20, From f4007584e120ff880a40479555e3aba15e9a2269 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:02:41 -0700 Subject: [PATCH 074/212] formatted master script --- examples/toys/masterResetEntity.js | 339 +++++++++++++++++++++++------ 1 file changed, 278 insertions(+), 61 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index a2f6c9f233..b65d13a911 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -24,24 +24,54 @@ deleteAllToys(); createAllToys(); function createAllToys() { - createBlocks({ x: 548.3, y: 495.55, z: 504.4 }); + createBlocks({ + x: 548.3, + y: 495.55, + z: 504.4 + }); - createSprayCan({ x: 549.7, y: 495.6, z: 503.91 }); + createSprayCan({ + x: 549.7, + y: 495.6, + z: 503.91 + }); - createBasketBall({ x: 547.73, y: 495.5, z: 505.47}); + createBasketBall({ + x: 547.73, + y: 495.5, + z: 505.47 + }); - createDoll({x: 546.67, y: 495.41, z: 505.09}); + createDoll({ + x: 546.67, + y: 495.41, + z: 505.09 + }); - createWand({ x: 546.71, y: 495.55, z: 506.15}); + createWand({ + x: 546.71, + y: 495.55, + z: 506.15 + }); createDice(); - createFlashlight({ x: 545.72, y: 495.41, z: 505.78 + createFlashlight({ + x: 545.72, + y: 495.41, + z: 505.78 }); - createCat({ x: 551.49859619140625, y: 495.49111938476562, z: 502.26498413085938 }); + createCat({ + x: 551.49859619140625, + y: 495.49111938476562, + z: 502.26498413085938 + }); - createMagballs({ x: 548.73, y: 495.51, z: 503.54 + createMagballs({ + x: 548.73, + y: 495.51, + z: 503.54 }); //Handles toggling of all sconce lights @@ -51,7 +81,7 @@ function createAllToys() { function deleteAllToys() { var entities = Entities.findEntities(MyAvatar.position, 100); - entities.forEach(function (entity) { + entities.forEach(function(entity) { //params: customKey, id, defaultValue var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; if (shouldReset === true) { @@ -69,21 +99,36 @@ function createMagballs(position) { modelURL: modelURL, name: "Tin Can", position: position, - rotation: { w: 0.93041884899139404, x: -1.52587890625e-05, y: 0.36647593975067139, z: -1.52587890625e-05}, - dimensions: { x: 0.16946873068809509, y: 0.21260403096675873, z: 0.16946862637996674 }, + rotation: { + w: 0.93041884899139404, + x: -1.52587890625e-05, + y: 0.36647593975067139, + z: -1.52587890625e-05 + }, + dimensions: { + x: 0.16946873068809509, + y: 0.21260403096675873, + z: 0.16946862637996674 + }, }); - setEntityCustomData(resetKey, tinCan, { resetMe: true }); + setEntityCustomData(resetKey, tinCan, { + resetMe: true + }); - setEntityCustomData("OmniTool", tinCan, { script: "../toys/magBalls.js"}); + setEntityCustomData("OmniTool", tinCan, { + script: "../toys/magBalls.js" + }); } function createCat(position) { var scriptURL = Script.resolvePath("cat.js?v1"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; - var animationSettings = JSON.stringify({running: true,}); + var animationSettings = JSON.stringify({ + running: true, + }); var cat = Entities.addEntity({ type: "Model", modelURL: modelURL, @@ -92,11 +137,22 @@ function createCat(position) { animationURL: animationURL, animationSettings: animationSettings, position: position, - rotation: { w: 0.35020983219146729, x: -4.57763671875e-05, y: 0.93664455413818359, z: -1.52587890625e-05}, - dimensions: { x: 0.15723302960395813, y: 0.50762706995010376, z: 0.90716040134429932}, + rotation: { + w: 0.35020983219146729, + x: -4.57763671875e-05, + y: 0.93664455413818359, + z: -1.52587890625e-05 + }, + dimensions: { + x: 0.15723302960395813, + y: 0.50762706995010376, + z: 0.90716040134429932 + }, }); - setEntityCustomData(resetKey, cat, { resetMe: true }); + setEntityCustomData(resetKey, cat, { + resetMe: true + }); } function createFlashlight(position) { @@ -109,14 +165,28 @@ function createFlashlight(position) { name: "flashlight", script: scriptURL, position: position, - dimensions: { x: 0.08, y: 0.30, z: 0.08}, + dimensions: { + x: 0.08, + y: 0.30, + z: 0.08 + }, collisionsWillMove: true, - gravity: {x: 0, y: -3.5, z: 0}, - velocity: { x: 0, y: -0.01, z: 0}, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, shapeType: 'box', }); - setEntityCustomData(resetKey, flashlight, {resetMe: true}); + setEntityCustomData(resetKey, flashlight, { + resetMe: true + }); } @@ -129,9 +199,22 @@ function createLightSwitches() { modelURL: modelURL, name: "Light Switch Hall", script: scriptURL, - position: {x: 543.27764892578125, y: 495.67999267578125, z: 511.00564575195312}, - rotation: {w: 0.63280689716339111, x: 0.63280689716339111, y: -0.31551080942153931, z: 0.31548023223876953}, - dimensions: {x: 0.10546875, y: 0.032372996211051941, z: 0.16242524981498718} + position: { + x: 543.27764892578125, + y: 495.67999267578125, + z: 511.00564575195312 + }, + rotation: { + w: 0.63280689716339111, + x: 0.63280689716339111, + y: -0.31551080942153931, + z: 0.31548023223876953 + }, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + } }); setEntityCustomData(resetKey, lightSwitchHall, { @@ -145,12 +228,27 @@ function createLightSwitches() { modelURL: modelURL, name: "Light Switch Garage", script: scriptURL, - position: {x: 545.62, y: 495.68,z: 500.21}, - rotation: { w: 0.20082402229309082, x: 0.20082402229309082, y: -0.67800414562225342, z: 0.67797362804412842}, - dimensions: { x:0.10546875, y: 0.032372996211051941, z: 0.16242524981498718} + position: { + x: 545.62, + y: 495.68, + z: 500.21 + }, + rotation: { + w: 0.20082402229309082, + x: 0.20082402229309082, + y: -0.67800414562225342, + z: 0.67797362804412842 + }, + dimensions: { + x: 0.10546875, + y: 0.032372996211051941, + z: 0.16242524981498718 + } }); - setEntityCustomData(resetKey, lightSwitchGarage, {resetMe: true}); + setEntityCustomData(resetKey, lightSwitchGarage, { + resetMe: true + }); } @@ -160,22 +258,46 @@ function createDice() { modelURL: "http://s3.amazonaws.com/hifi-public/models/props/Dice/goldDie.fbx", collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/dice/diceCollide.wav", name: "dice", - position: {x: 541, y: 494.96, z: 509.1}, - dimensions: {x: 0.09, y: 0.09, z: 0.09}, - gravity: {x: 0, y: -3.5, z: 0}, - velocity: {x: 0,y: -0.01, z: 0}, + position: { + x: 541, + y: 494.96, + z: 509.1 + }, + dimensions: { + x: 0.09, + y: 0.09, + z: 0.09 + }, + gravity: { + x: 0, + y: -3.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, shapeType: "box", collisionsWillMove: true }; var dice1 = Entities.addEntity(diceProps); - diceProps.position = { x: 541.05, y: 494.96, z: 509.0 }; + diceProps.position = { + x: 541.05, + y: 494.96, + z: 509.0 + }; var dice2 = Entities.addEntity(diceProps); - setEntityCustomData(resetKey, dice1, {resetMe: true}); + setEntityCustomData(resetKey, dice1, { + resetMe: true + }); - setEntityCustomData(resetKey, dice2, {resetMe: true}); + setEntityCustomData(resetKey, dice2, { + resetMe: true + }); } function createWand(position) { @@ -189,8 +311,16 @@ function createWand(position) { type: "Model", modelURL: WAND_MODEL, position: position, - gravity: {x: 0, y: 0, z: 0}, - dimensions: { x: 0.05, y: 0.25,z: 0.05}, + gravity: { + x: 0, + y: 0, + z: 0 + }, + dimensions: { + x: 0.05, + y: 0.25, + z: 0.05 + }, //must be enabled to be grabbable in the physics engine collisionsWillMove: true, compoundShapeURL: WAND_COLLISION_SHAPE, @@ -200,7 +330,9 @@ function createWand(position) { script: scriptURL }); - setEntityCustomData(resetKey, entity, {resetMe: true}); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } function createBasketBall(position) { @@ -214,22 +346,40 @@ function createBasketBall(position) { collisionsWillMove: true, shapeType: "sphere", name: "basketball", - dimensions: {x: 0.25, y: 0.26, z: 0.25}, - gravity: {x: 0, y: -7, z: 0}, + dimensions: { + x: 0.25, + y: 0.26, + z: 0.25 + }, + gravity: { + x: 0, + y: -7, + z: 0 + }, restitution: 10, linearDamping: 0.0, - velocity: { x: 0, y: -0.01, z: 0}, + velocity: { + x: 0, + y: -0.01, + z: 0 + }, collisionSoundURL: "http://s3.amazonaws.com/hifi-public/sounds/basketball/basketball.wav" }); - setEntityCustomData(resetKey, entity, {resetMe: true}); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; var scriptURL = Script.resolvePath("doll/doll.js"); - var naturalDimensions = {x: 1.63, y: 1.67, z: 0.26}; + var naturalDimensions = { + x: 1.63, + y: 1.67, + z: 0.26 + }; var desiredDimensions = Vec3.multiply(naturalDimensions, 0.15); var entity = Entities.addEntity({ type: "Model", @@ -239,12 +389,22 @@ function createDoll(position) { position: position, shapeType: 'box', dimensions: desiredDimensions, - gravity: {x: 0, y: -5, z: 0}, - velocity: {x: 0, y: -0.1, z: 0}, + gravity: { + x: 0, + y: -5, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + }, collisionsWillMove: true }); - setEntityCustomData(resetKey, entity, {resetMe: true}); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } function createSprayCan(position) { @@ -256,15 +416,29 @@ function createSprayCan(position) { name: "spraycan", modelURL: modelURL, position: position, - dimensions: {x: 0.07, y: 0.17, z: 0.07}, + dimensions: { + x: 0.07, + y: 0.17, + z: 0.07 + }, collisionsWillMove: true, shapeType: 'box', script: scriptURL, - gravity: {x: 0, y: -0.5, z: 0}, - velocity: { x: 0, y: -1, z: 0} + gravity: { + x: 0, + y: -0.5, + z: 0 + }, + velocity: { + x: 0, + y: -1, + z: 0 + } }); - setEntityCustomData(resetKey, entity, {resetMe: true}); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } @@ -273,13 +447,42 @@ function createBlocks(position) { var NUM_BLOCKS_PER_COLOR = 4; var i, j; - var blockTypes = [ - { url: "planky_blue.fbx", dimensions: {x: 0.05, y: 0.05, z: 0.25} }, - { url: "planky_green.fbx", dimensions: {x: 0.1, y: 0.1, z: 0.25} }, - { url: "planky_natural.fbx", dimensions: { x: 0.05, y: 0.05, z: 0.05} }, - { url: "planky_yellow.fbx", dimensions: {x: 0.03, y: 0.05, z: 0.25} }, - { url: "planky_red.fbx", dimensions: {x: 0.1, y: 0.05, z: 0.25} }, - ]; + var blockTypes = [{ + url: "planky_blue.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_green.fbx", + dimensions: { + x: 0.1, + y: 0.1, + z: 0.25 + } + }, { + url: "planky_natural.fbx", + dimensions: { + x: 0.05, + y: 0.05, + z: 0.05 + } + }, { + url: "planky_yellow.fbx", + dimensions: { + x: 0.03, + y: 0.05, + z: 0.25 + } + }, { + url: "planky_red.fbx", + dimensions: { + x: 0.1, + y: 0.05, + z: 0.25 + } + }, ]; var modelURL, entity; for (i = 0; i < blockTypes.length; i++) { @@ -288,17 +491,31 @@ function createBlocks(position) { entity = Entities.addEntity({ type: "Model", modelURL: modelURL, - position: Vec3.sum(position, { x: j / 10, y: i / 10, z: 0}), + position: Vec3.sum(position, { + x: j / 10, + y: i / 10, + z: 0 + }), shapeType: 'box', name: "block", dimensions: blockTypes[i].dimensions, collisionsWillMove: true, - gravity: {x: 0, y: -2.5, z: 0}, - velocity: { x: 0, y: -0.01, z: 0} + gravity: { + x: 0, + y: -2.5, + z: 0 + }, + velocity: { + x: 0, + y: -0.01, + z: 0 + } }); //customKey, id, data - setEntityCustomData(resetKey, entity, {resetMe: true}); + setEntityCustomData(resetKey, entity, { + resetMe: true + }); } } } From a62970136282a22d062468660d4f9c17c716991f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:15:19 -0700 Subject: [PATCH 075/212] couch --- examples/toys/masterResetEntity.js | 134 +++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index b65d13a911..d039bfbb6e 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -74,6 +74,24 @@ function createAllToys() { z: 503.54 }); + createArmChair({ + x: 549.29, + y: 495.05, + z: 508.22 + }) + + createPillow({ + x: 549.29, + y: 495.35, + z: 508.22 + }); + + createPottedPlant({ + x: 554.26, + y: 495.23, + z: 504.53 + }); + //Handles toggling of all sconce lights createLightSwitches(); } @@ -442,6 +460,122 @@ function createSprayCan(position) { } +//createPottedPlant,createArmChair,createPillow +function createPottedPlant(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; + + var rotation = Quat.fromPitchYawRollDegress(0, 0, 0); + + var entity = Entities.addEntity({ + type: "Model", + name: "Potted Plant", + modelURL: modelURL, + position: position, + dimensions: { + x: 1.10, + y: 2.18, + z: 1.07 + }, + collisionsWillMove: true, + shapeType: 'box', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + linearDamping: 0.4 + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + + + +function createArmChair(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" + + var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); + + var entity = Entities.addEntity({ + type: "Model", + name: "Red Arm Chair", + modelURL: modelURL, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, + position: position, + rotation: rotation, + dimensions: { + x: 1.26, + y: 1.56, + z: 1.35 + }, + collisionsWillMove: true, + gravity: { + x: 0, + y: -0.5, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + linearDamping: 0.3 + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + +function createPillow(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow.fbx"; + var RED_ARM_CHAIR_PILLOW_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow_collision_hull.obj" + + var rotation = Quat.fromPitchYawRollDegrees(-0.29, -143.05, 0.32); + + var entity = Entities.addEntity({ + type: "Model", + name: "Red Arm Chair Pillow", + modelURL: modelURL, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_PILLOW_COLLISION_HULL, + position: position, + rotation: rotation, + dimensions: { + x: 0.4, + y: 0.4, + z: 0.4 + }, + collisionsWillMove: true, + ignoreForCollisions: false, + gravity: { + x: 0, + y: -10.1, + z: 0 + }, + restitution: 0, + velocity: { + x: 0, + y: -0.1, + z: 0 + }, + linearDamping: 1 + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; + function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; var NUM_BLOCKS_PER_COLOR = 4; From d29c337e9549a7feb299ab288aadee3e5abd289a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:32:41 -0700 Subject: [PATCH 076/212] moved light switches up --- examples/toys/masterResetEntity.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index d039bfbb6e..b5f08a75d5 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -68,6 +68,9 @@ function createAllToys() { z: 502.26498413085938 }); + //Handles toggling of all sconce lights + createLightSwitches(); + createMagballs({ x: 548.73, y: 495.51, @@ -92,8 +95,7 @@ function createAllToys() { z: 504.53 }); - //Handles toggling of all sconce lights - createLightSwitches(); + } function deleteAllToys() { From 7789d8b3a8c77761c2b8a3f4f0a30adb43144de7 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:37:04 -0700 Subject: [PATCH 077/212] fixed potted plant bug --- examples/toys/masterResetEntity.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index b5f08a75d5..3ee991ea4c 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -466,7 +466,7 @@ function createSprayCan(position) { function createPottedPlant(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; - var rotation = Quat.fromPitchYawRollDegress(0, 0, 0); + var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); var entity = Entities.addEntity({ type: "Model", From ccc6a343fcd0a72842de07ce3095a5e8c230da7d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:49:51 -0700 Subject: [PATCH 078/212] updated lights to use newly named grab events --- examples/controllers/handControllerGrab.js | 1 + examples/toys/lightSwitchGarage.js | 2 +- examples/toys/lightSwitchHall.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index ce2f1b5249..09b73e6808 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -371,6 +371,7 @@ function MyController(hand, triggerAction) { this.state = STATE_RELEASE; return; } + print("JAYKJAGHKJAHKJAHKJAHKJ") Entities.callEntityMethod(this.grabbedEntity, "startNearGrabNonColliding"); this.state = STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING; }; diff --git a/examples/toys/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js index 99d827aa06..5f302ff47e 100644 --- a/examples/toys/lightSwitchGarage.js +++ b/examples/toys/lightSwitchGarage.js @@ -37,7 +37,7 @@ this.toggleLights(); }, - startNearTouch: function() { + startNearGrabNonColliding: function() { this.toggleLights(); }, diff --git a/examples/toys/lightSwitchHall.js b/examples/toys/lightSwitchHall.js index 49ccc51b79..4dd1a867de 100644 --- a/examples/toys/lightSwitchHall.js +++ b/examples/toys/lightSwitchHall.js @@ -37,7 +37,7 @@ this.toggleLights(); }, - startNearTouch: function() { + startNearGrabNonColliding: function() { this.toggleLights(); }, From 65169da64d042a8e4540bebdaf8936f937ba6ca5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 11:58:05 -0700 Subject: [PATCH 079/212] removed old doll script --- examples/toys/doll.js | 73 ------------------------------------------- 1 file changed, 73 deletions(-) delete mode 100644 examples/toys/doll.js diff --git a/examples/toys/doll.js b/examples/toys/doll.js deleted file mode 100644 index 708d6200b1..0000000000 --- a/examples/toys/doll.js +++ /dev/null @@ -1,73 +0,0 @@ -// -// doll.js -// examples/toybox/entityScripts -// -// Created by Eric Levin on 9/21/15. -// Copyright 2015 High Fidelity, Inc. -// -// This entity script breathes movement and sound- one might even say life- into a doll. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -(function() { - - var _this; - HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; - - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember - // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) - Doll = function() { - _this = this; - var screamSoundDirectory = HIFI_PUBLIC_BUCKET + "eric/sounds/" - this.screamSounds = [SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/KenDoll_1%2303.wav")]; - this.startAnimationSetting = JSON.stringify({ - running: true, - startFrame: 0, - lastFrame: 128 - }); - - this.stopAnimationSetting = JSON.stringify({ - running: false, - }); - }; - - Doll.prototype = { - - - startNearGrab: function() { - Entities.editEntity(this.entityID, { - animationURL: "https://hifi-public.s3.amazonaws.com/models/Bboys/zombie_scream.fbx", - animationSettings: this.startAnimationSetting - }); - - var position = Entities.getEntityProperties(this.entityID, "position").position; - Audio.playSound(this.screamSounds[randInt(0, this.screamSounds.length)], { - position: position, - volume: 0.1 - }); - - }, - - releaseGrab: function() { - Entities.editEntity(this.entityID, { - animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", - // animationSettings: this.stopAnimationSetting, - // animationFrameIndex: 0 - }); - }, - - - // preload() will be called when the entity has become visible (or known) to the interface - // it gives us a chance to set our local JavaScript object up. In this case it means: - // * remembering our entityID, so we can access it in cases where we're called without an entityID - // * connecting to the update signal so we can check our grabbed state - preload: function(entityID) { - this.entityID = entityID; - }, - }; - - // entity scripts always need to return a newly constructed object of our type - return new Doll(); -}) From f5e44675bb8493e54ffb9744918647066c8271b3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 12:11:22 -0700 Subject: [PATCH 080/212] removed start and end frame --- examples/toys/doll/doll.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index f97b6de378..09dd06a2ec 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -25,8 +25,8 @@ startAnimationSetting: JSON.stringify({ running: true, fps: 30, - startFrame: 0, - lastFrame: 128, + // startFrame: 0, + // lastFrame: 128, startAutomatically: true }), stopAnimationSetting: JSON.stringify({running: false}), From c53ad3c5340e3821cbd070ff3ffacedf40d7dd82 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 12:34:35 -0700 Subject: [PATCH 081/212] combined arm chair --- examples/toys/doll/doll.js | 9 ++++-- examples/toys/masterResetEntity.js | 51 ++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index 09dd06a2ec..62eac78166 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -25,11 +25,14 @@ startAnimationSetting: JSON.stringify({ running: true, fps: 30, - // startFrame: 0, - // lastFrame: 128, + firstFrame: 0, + lastFrame: 120, startAutomatically: true }), - stopAnimationSetting: JSON.stringify({running: false}), + stopAnimationSetting: JSON.stringify({ + running: false, + frameIndex: 0 + }), audioInjector: null, isGrabbed: false, setLeftHand: function() { diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 3ee991ea4c..2e7f9bdae3 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -77,17 +77,17 @@ function createAllToys() { z: 503.54 }); - createArmChair({ + createCombinedArmChair({ x: 549.29, y: 495.05, z: 508.22 }) - createPillow({ - x: 549.29, - y: 495.35, - z: 508.22 - }); + // createPillow({ + // x: 549.29, + // y: 495.35, + // z: 508.22 + // }); createPottedPlant({ x: 554.26, @@ -393,7 +393,7 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var scriptURL = Script.resolvePath("doll/doll.js"); + var scriptURL = Script.resolvePath("doll/doll.js?v2"+ Math.random()); var naturalDimensions = { x: 1.63, @@ -499,6 +499,43 @@ function createPottedPlant(position) { }; +function createCombinedArmChair(position) { + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/combined_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" + + var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); + + var entity = Entities.addEntity({ + type: "Model", + name: "Red Arm Chair", + modelURL: modelURL, + shapeType: 'compound', + compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, + position: position, + rotation: rotation, + dimensions: { + x: 1.26, + y: 1.56, + z: 1.35 + }, + collisionsWillMove: true, + gravity: { + x: 0, + y: -0.8, + z: 0 + }, + velocity: { + x: 0, + y: 0, + z: 0 + }, + linearDamping: 0.2 + }); + + setEntityCustomData(resetKey, entity, { + resetMe: true + }); +}; function createArmChair(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair.fbx"; From e94d9b39fdb0413a405cd7f2524f2e079316f625 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 15:42:13 -0700 Subject: [PATCH 082/212] made pots and chair not grabbable --- examples/toys/doll/doll.js | 12 ++++++------ examples/toys/masterResetEntity.js | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index 62eac78166..e81f3e0c0e 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -25,13 +25,12 @@ startAnimationSetting: JSON.stringify({ running: true, fps: 30, - firstFrame: 0, - lastFrame: 120, - startAutomatically: true + // firstFrame: 1, + // lastFrame: 120, }), stopAnimationSetting: JSON.stringify({ running: false, - frameIndex: 0 + frameIndex: 1 }), audioInjector: null, isGrabbed: false, @@ -74,10 +73,11 @@ if (this.isGrabbed === true && this.hand === this.initialHand) { this.audioInjector.stop(); - + print("STTTOP ANIMATION") Entities.editEntity(this.entityID, { animationSettings: this.stopAnimationSetting, - animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", + animationIsPlaying: false + // animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", }); this.isGrabbed = false; } diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 2e7f9bdae3..88a71cd58e 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -13,6 +13,7 @@ var utilitiesScript = Script.resolvePath("../libraries/utils.js"); Script.include(utilitiesScript); var resetKey = "resetMe"; +var GRABBABLE_DATA_KEY = "grabbableKey"; var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; @@ -68,7 +69,7 @@ function createAllToys() { z: 502.26498413085938 }); - //Handles toggling of all sconce lights + //Handles toggling of all sconce lights createLightSwitches(); createMagballs({ @@ -393,7 +394,7 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var scriptURL = Script.resolvePath("doll/doll.js?v2"+ Math.random()); + var scriptURL = Script.resolvePath("doll/doll.js?v2" + Math.random()); var naturalDimensions = { x: 1.63, @@ -496,6 +497,11 @@ function createPottedPlant(position) { setEntityCustomData(resetKey, entity, { resetMe: true }); + + + setEntityCustomData(GRABBABLE_DATA_KEY, entity, { + grabbable: false + }); }; @@ -535,6 +541,10 @@ function createCombinedArmChair(position) { setEntityCustomData(resetKey, entity, { resetMe: true }); + + setEntityCustomData(GRABBABLE_DATA_KEY, entity, { + grabbable: false + }); }; function createArmChair(position) { From 534cffcf85d83ab1880701812dfe64e5d2f24b8d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 16:23:35 -0700 Subject: [PATCH 083/212] fixed animation bug with doll --- examples/toys/doll/doll.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index e81f3e0c0e..f0b789273c 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -25,12 +25,14 @@ startAnimationSetting: JSON.stringify({ running: true, fps: 30, - // firstFrame: 1, - // lastFrame: 120, + loop: false, + firstFrame: 1, + lastFrame: 120, }), stopAnimationSetting: JSON.stringify({ running: false, - frameIndex: 1 + frameIndex: 1, + lastFrame: 10000 }), audioInjector: null, isGrabbed: false, @@ -73,13 +75,14 @@ if (this.isGrabbed === true && this.hand === this.initialHand) { this.audioInjector.stop(); - print("STTTOP ANIMATION") Entities.editEntity(this.entityID, { animationSettings: this.stopAnimationSetting, - animationIsPlaying: false - // animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", + animationIsPlaying: false, + animationURL: "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx", }); this.isGrabbed = false; + + var frameIndex = Entities.getEntityProperties(this.entityID, {}) } }, From bcd21714910d5f115692964120a4e99557c039fa Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 25 Sep 2015 16:28:12 -0700 Subject: [PATCH 084/212] updated chair model --- examples/toys/masterResetEntity.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 88a71cd58e..5a8732e348 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -548,8 +548,8 @@ function createCombinedArmChair(position) { }; function createArmChair(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair.fbx"; - var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" + var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/new_red_arm_chair.fbx"; + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/new_red_arm_chair_collision_hull.obj" var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); From 57aca0c4187b736a454c640bdf2b51a38c1cdfee Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 11:18:22 -0700 Subject: [PATCH 085/212] New way to do two-way bindings between dynamically created GUI and in-world object properties. Uses partcile system properties, specifically. --- examples/particle_explorer/dat.gui.min.js | 95 + examples/particle_explorer/index.html | 34 + examples/particle_explorer/main.js | 170 ++ examples/particle_explorer/old.html | 1607 +++++++++++++++++ .../particle_explorer/particleExplorer.js | 173 ++ examples/particle_explorer/underscore-min.js | 6 + 6 files changed, 2085 insertions(+) create mode 100644 examples/particle_explorer/dat.gui.min.js create mode 100644 examples/particle_explorer/index.html create mode 100644 examples/particle_explorer/main.js create mode 100644 examples/particle_explorer/old.html create mode 100644 examples/particle_explorer/particleExplorer.js create mode 100644 examples/particle_explorer/underscore-min.js diff --git a/examples/particle_explorer/dat.gui.min.js b/examples/particle_explorer/dat.gui.min.js new file mode 100644 index 0000000000..8ea141a966 --- /dev/null +++ b/examples/particle_explorer/dat.gui.min.js @@ -0,0 +1,95 @@ +/** + * dat-gui JavaScript Controller Library + * http://code.google.com/p/dat-gui + * + * Copyright 2011 Data Arts Team, Google Creative Lab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ +var dat=dat||{};dat.gui=dat.gui||{};dat.utils=dat.utils||{};dat.controllers=dat.controllers||{};dat.dom=dat.dom||{};dat.color=dat.color||{};dat.utils.css=function(){return{load:function(f,a){a=a||document;var d=a.createElement("link");d.type="text/css";d.rel="stylesheet";d.href=f;a.getElementsByTagName("head")[0].appendChild(d)},inject:function(f,a){a=a||document;var d=document.createElement("style");d.type="text/css";d.innerHTML=f;a.getElementsByTagName("head")[0].appendChild(d)}}}(); +dat.utils.common=function(){var f=Array.prototype.forEach,a=Array.prototype.slice;return{BREAK:{},extend:function(d){this.each(a.call(arguments,1),function(a){for(var c in a)this.isUndefined(a[c])||(d[c]=a[c])},this);return d},defaults:function(d){this.each(a.call(arguments,1),function(a){for(var c in a)this.isUndefined(d[c])&&(d[c]=a[c])},this);return d},compose:function(){var d=a.call(arguments);return function(){for(var e=a.call(arguments),c=d.length-1;0<=c;c--)e=[d[c].apply(this,e)];return e[0]}}, +each:function(a,e,c){if(a)if(f&&a.forEach&&a.forEach===f)a.forEach(e,c);else if(a.length===a.length+0)for(var b=0,p=a.length;bthis.__max&&(a=this.__max);void 0!==this.__step&&0!=a%this.__step&&(a=Math.round(a/this.__step)*this.__step);return e.superclass.prototype.setValue.call(this,a)},min:function(a){this.__min=a;return this},max:function(a){this.__max=a;return this},step:function(a){this.__impliedStep=this.__step=a;this.__precision=d(a);return this}});return e}(dat.controllers.Controller,dat.utils.common); +dat.controllers.NumberControllerBox=function(f,a,d){var e=function(c,b,f){function q(){var a=parseFloat(n.__input.value);d.isNaN(a)||n.setValue(a)}function l(a){var b=u-a.clientY;n.setValue(n.getValue()+b*n.__impliedStep);u=a.clientY}function r(){a.unbind(window,"mousemove",l);a.unbind(window,"mouseup",r)}this.__truncationSuspended=!1;e.superclass.call(this,c,b,f);var n=this,u;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"change",q);a.bind(this.__input, +"blur",function(){q();n.__onFinishChange&&n.__onFinishChange.call(n,n.getValue())});a.bind(this.__input,"mousedown",function(b){a.bind(window,"mousemove",l);a.bind(window,"mouseup",r);u=b.clientY});a.bind(this.__input,"keydown",function(a){13===a.keyCode&&(n.__truncationSuspended=!0,this.blur(),n.__truncationSuspended=!1)});this.updateDisplay();this.domElement.appendChild(this.__input)};e.superclass=f;d.extend(e.prototype,f.prototype,{updateDisplay:function(){var a=this.__input,b;if(this.__truncationSuspended)b= +this.getValue();else{b=this.getValue();var d=Math.pow(10,this.__precision);b=Math.round(b*d)/d}a.value=b;return e.superclass.prototype.updateDisplay.call(this)}});return e}(dat.controllers.NumberController,dat.dom.dom,dat.utils.common); +dat.controllers.NumberControllerSlider=function(f,a,d,e,c){function b(a,b,c,e,d){return e+(a-b)/(c-b)*(d-e)}var p=function(c,e,d,f,u){function A(c){c.preventDefault();var e=a.getOffset(k.__background),d=a.getWidth(k.__background);k.setValue(b(c.clientX,e.left,e.left+d,k.__min,k.__max));return!1}function g(){a.unbind(window,"mousemove",A);a.unbind(window,"mouseup",g);k.__onFinishChange&&k.__onFinishChange.call(k,k.getValue())}p.superclass.call(this,c,e,{min:d,max:f,step:u});var k=this;this.__background= +document.createElement("div");this.__foreground=document.createElement("div");a.bind(this.__background,"mousedown",function(b){a.bind(window,"mousemove",A);a.bind(window,"mouseup",g);A(b)});a.addClass(this.__background,"slider");a.addClass(this.__foreground,"slider-fg");this.updateDisplay();this.__background.appendChild(this.__foreground);this.domElement.appendChild(this.__background)};p.superclass=f;p.useDefaultStyles=function(){d.inject(c)};e.extend(p.prototype,f.prototype,{updateDisplay:function(){var a= +(this.getValue()-this.__min)/(this.__max-this.__min);this.__foreground.style.width=100*a+"%";return p.superclass.prototype.updateDisplay.call(this)}});return p}(dat.controllers.NumberController,dat.dom.dom,dat.utils.css,dat.utils.common,"/**\n * dat-gui JavaScript Controller Library\n * http://code.google.com/p/dat-gui\n *\n * Copyright 2011 Data Arts Team, Google Creative Lab\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n.slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}"); +dat.controllers.FunctionController=function(f,a,d){var e=function(c,b,d){e.superclass.call(this,c,b);var f=this;this.__button=document.createElement("div");this.__button.innerHTML=void 0===d?"Fire":d;a.bind(this.__button,"click",function(a){a.preventDefault();f.fire();return!1});a.addClass(this.__button,"button");this.domElement.appendChild(this.__button)};e.superclass=f;d.extend(e.prototype,f.prototype,{fire:function(){this.__onChange&&this.__onChange.call(this);this.getValue().call(this.object); +this.__onFinishChange&&this.__onFinishChange.call(this,this.getValue())}});return e}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); +dat.controllers.BooleanController=function(f,a,d){var e=function(c,b){e.superclass.call(this,c,b);var d=this;this.__prev=this.getValue();this.__checkbox=document.createElement("input");this.__checkbox.setAttribute("type","checkbox");a.bind(this.__checkbox,"change",function(){d.setValue(!d.__prev)},!1);this.domElement.appendChild(this.__checkbox);this.updateDisplay()};e.superclass=f;d.extend(e.prototype,f.prototype,{setValue:function(a){a=e.superclass.prototype.setValue.call(this,a);this.__onFinishChange&& +this.__onFinishChange.call(this,this.getValue());this.__prev=this.getValue();return a},updateDisplay:function(){!0===this.getValue()?(this.__checkbox.setAttribute("checked","checked"),this.__checkbox.checked=!0):this.__checkbox.checked=!1;return e.superclass.prototype.updateDisplay.call(this)}});return e}(dat.controllers.Controller,dat.dom.dom,dat.utils.common); +dat.color.toString=function(f){return function(a){if(1==a.a||f.isUndefined(a.a)){for(a=a.hex.toString(16);6>a.length;)a="0"+a;return"#"+a}return"rgba("+Math.round(a.r)+","+Math.round(a.g)+","+Math.round(a.b)+","+a.a+")"}}(dat.utils.common); +dat.color.interpret=function(f,a){var d,e,c=[{litmus:a.isString,conversions:{THREE_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);return null===a?!1:{space:"HEX",hex:parseInt("0x"+a[1].toString()+a[1].toString()+a[2].toString()+a[2].toString()+a[3].toString()+a[3].toString())}},write:f},SIX_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9]{6})$/i);return null===a?!1:{space:"HEX",hex:parseInt("0x"+a[1].toString())}},write:f},CSS_RGB:{read:function(a){a=a.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/); +return null===a?!1:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3])}},write:f},CSS_RGBA:{read:function(a){a=a.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);return null===a?!1:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3]),a:parseFloat(a[4])}},write:f}}},{litmus:a.isNumber,conversions:{HEX:{read:function(a){return{space:"HEX",hex:a,conversionName:"HEX"}},write:function(a){return a.hex}}}},{litmus:a.isArray,conversions:{RGB_ARRAY:{read:function(a){return 3!= +a.length?!1:{space:"RGB",r:a[0],g:a[1],b:a[2]}},write:function(a){return[a.r,a.g,a.b]}},RGBA_ARRAY:{read:function(a){return 4!=a.length?!1:{space:"RGB",r:a[0],g:a[1],b:a[2],a:a[3]}},write:function(a){return[a.r,a.g,a.b,a.a]}}}},{litmus:a.isObject,conversions:{RGBA_OBJ:{read:function(b){return a.isNumber(b.r)&&a.isNumber(b.g)&&a.isNumber(b.b)&&a.isNumber(b.a)?{space:"RGB",r:b.r,g:b.g,b:b.b,a:b.a}:!1},write:function(a){return{r:a.r,g:a.g,b:a.b,a:a.a}}},RGB_OBJ:{read:function(b){return a.isNumber(b.r)&& +a.isNumber(b.g)&&a.isNumber(b.b)?{space:"RGB",r:b.r,g:b.g,b:b.b}:!1},write:function(a){return{r:a.r,g:a.g,b:a.b}}},HSVA_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)&&a.isNumber(b.a)?{space:"HSV",h:b.h,s:b.s,v:b.v,a:b.a}:!1},write:function(a){return{h:a.h,s:a.s,v:a.v,a:a.a}}},HSV_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)?{space:"HSV",h:b.h,s:b.s,v:b.v}:!1},write:function(a){return{h:a.h,s:a.s,v:a.v}}}}}];return function(){e=!1; +var b=1\n\n Here\'s the new load parameter for your GUI\'s constructor:\n\n \n\n
\n\n Automatically save\n values to localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
\n \n
\n\n', +".dg {\n /** Clear list styles */\n /* Auto-place container */\n /* Auto-placed GUI's */\n /* Line items that don't contain folders. */\n /** Folder names */\n /** Hides closed items */\n /** Controller row */\n /** Name-half (left) */\n /** Controller-half (right) */\n /** Controller placement */\n /** Shorter number boxes when slider is present. */\n /** Ensure the entire boolean and function row shows a hand */ }\n .dg ul {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n clear: both; }\n .dg.ac {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 0;\n z-index: 0; }\n .dg:not(.ac) .main {\n /** Exclude mains in ac so that we don't hide close button */\n overflow: hidden; }\n .dg.main {\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear; }\n .dg.main.taller-than-window {\n overflow-y: auto; }\n .dg.main.taller-than-window .close-button {\n opacity: 1;\n /* TODO, these are style notes */\n margin-top: -1px;\n border-top: 1px solid #2c2c2c; }\n .dg.main ul.closed .close-button {\n opacity: 1 !important; }\n .dg.main:hover .close-button,\n .dg.main .close-button.drag {\n opacity: 1; }\n .dg.main .close-button {\n /*opacity: 0;*/\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear;\n border: 0;\n position: absolute;\n line-height: 19px;\n height: 20px;\n /* TODO, these are style notes */\n cursor: pointer;\n text-align: center;\n background-color: #000; }\n .dg.main .close-button:hover {\n background-color: #111; }\n .dg.a {\n float: right;\n margin-right: 15px;\n overflow-x: hidden; }\n .dg.a.has-save > ul {\n margin-top: 27px; }\n .dg.a.has-save > ul.closed {\n margin-top: 0; }\n .dg.a .save-row {\n position: fixed;\n top: 0;\n z-index: 1002; }\n .dg li {\n -webkit-transition: height 0.1s ease-out;\n -o-transition: height 0.1s ease-out;\n -moz-transition: height 0.1s ease-out;\n transition: height 0.1s ease-out; }\n .dg li:not(.folder) {\n cursor: auto;\n height: 27px;\n line-height: 27px;\n overflow: hidden;\n padding: 0 4px 0 5px; }\n .dg li.folder {\n padding: 0;\n border-left: 4px solid rgba(0, 0, 0, 0); }\n .dg li.title {\n cursor: pointer;\n margin-left: -4px; }\n .dg .closed li:not(.title),\n .dg .closed ul li,\n .dg .closed ul li > * {\n height: 0;\n overflow: hidden;\n border: 0; }\n .dg .cr {\n clear: both;\n padding-left: 3px;\n height: 27px; }\n .dg .property-name {\n cursor: default;\n float: left;\n clear: left;\n width: 40%;\n overflow: hidden;\n text-overflow: ellipsis; }\n .dg .c {\n float: left;\n width: 60%; }\n .dg .c input[type=text] {\n border: 0;\n margin-top: 4px;\n padding: 3px;\n width: 100%;\n float: right; }\n .dg .has-slider input[type=text] {\n width: 30%;\n /*display: none;*/\n margin-left: 0; }\n .dg .slider {\n float: left;\n width: 66%;\n margin-left: -5px;\n margin-right: 0;\n height: 19px;\n margin-top: 4px; }\n .dg .slider-fg {\n height: 100%; }\n .dg .c input[type=checkbox] {\n margin-top: 9px; }\n .dg .c select {\n margin-top: 5px; }\n .dg .cr.function,\n .dg .cr.function .property-name,\n .dg .cr.function *,\n .dg .cr.boolean,\n .dg .cr.boolean * {\n cursor: pointer; }\n .dg .selector {\n display: none;\n position: absolute;\n margin-left: -9px;\n margin-top: 23px;\n z-index: 10; }\n .dg .c:hover .selector,\n .dg .selector.drag {\n display: block; }\n .dg li.save-row {\n padding: 0; }\n .dg li.save-row .button {\n display: inline-block;\n padding: 0px 6px; }\n .dg.dialogue {\n background-color: #222;\n width: 460px;\n padding: 15px;\n font-size: 13px;\n line-height: 15px; }\n\n/* TODO Separate style and structure */\n#dg-new-constructor {\n padding: 10px;\n color: #222;\n font-family: Monaco, monospace;\n font-size: 10px;\n border: 0;\n resize: none;\n box-shadow: inset 1px 1px 1px #888;\n word-wrap: break-word;\n margin: 12px 0;\n display: block;\n width: 440px;\n overflow-y: scroll;\n height: 100px;\n position: relative; }\n\n#dg-local-explain {\n display: none;\n font-size: 11px;\n line-height: 17px;\n border-radius: 3px;\n background-color: #333;\n padding: 8px;\n margin-top: 10px; }\n #dg-local-explain code {\n font-size: 10px; }\n\n#dat-gui-save-locally {\n display: none; }\n\n/** Main type */\n.dg {\n color: #eee;\n font: 11px 'Lucida Grande', sans-serif;\n text-shadow: 0 -1px 0 #111;\n /** Auto place */\n /* Controller row,
  • */\n /** Controllers */ }\n .dg.main {\n /** Scrollbar */ }\n .dg.main::-webkit-scrollbar {\n width: 5px;\n background: #1a1a1a; }\n .dg.main::-webkit-scrollbar-corner {\n height: 0;\n display: none; }\n .dg.main::-webkit-scrollbar-thumb {\n border-radius: 5px;\n background: #676767; }\n .dg li:not(.folder) {\n background: #1a1a1a;\n border-bottom: 1px solid #2c2c2c; }\n .dg li.save-row {\n line-height: 25px;\n background: #dad5cb;\n border: 0; }\n .dg li.save-row select {\n margin-left: 5px;\n width: 108px; }\n .dg li.save-row .button {\n margin-left: 5px;\n margin-top: 1px;\n border-radius: 2px;\n font-size: 9px;\n line-height: 7px;\n padding: 4px 4px 5px 4px;\n background: #c5bdad;\n color: #fff;\n text-shadow: 0 1px 0 #b0a58f;\n box-shadow: 0 -1px 0 #b0a58f;\n cursor: pointer; }\n .dg li.save-row .button.gears {\n background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;\n height: 7px;\n width: 8px; }\n .dg li.save-row .button:hover {\n background-color: #bab19e;\n box-shadow: 0 -1px 0 #b0a58f; }\n .dg li.folder {\n border-bottom: 0; }\n .dg li.title {\n padding-left: 16px;\n background: black url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\n cursor: pointer;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2); }\n .dg .closed li.title {\n background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }\n .dg .cr.boolean {\n border-left: 3px solid #806787; }\n .dg .cr.function {\n border-left: 3px solid #e61d5f; }\n .dg .cr.number {\n border-left: 3px solid #2fa1d6; }\n .dg .cr.number input[type=text] {\n color: #2fa1d6; }\n .dg .cr.string {\n border-left: 3px solid #1ed36f; }\n .dg .cr.string input[type=text] {\n color: #1ed36f; }\n .dg .cr.function:hover, .dg .cr.boolean:hover {\n background: #111; }\n .dg .c input[type=text] {\n background: #303030;\n outline: none; }\n .dg .c input[type=text]:hover {\n background: #3c3c3c; }\n .dg .c input[type=text]:focus {\n background: #494949;\n color: #fff; }\n .dg .c .slider {\n background: #303030;\n cursor: ew-resize; }\n .dg .c .slider-fg {\n background: #2fa1d6; }\n .dg .c .slider:hover {\n background: #3c3c3c; }\n .dg .c .slider:hover .slider-fg {\n background: #44abda; }\n", +dat.controllers.factory=function(f,a,d,e,c,b,p){return function(q,l,r,n){var u=q[l];if(p.isArray(r)||p.isObject(r))return new f(q,l,r);if(p.isNumber(u))return p.isNumber(r)&&p.isNumber(n)?new d(q,l,r,n):new a(q,l,{min:r,max:n});if(p.isString(u))return new e(q,l);if(p.isFunction(u))return new c(q,l,"");if(p.isBoolean(u))return new b(q,l)}}(dat.controllers.OptionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.StringController=function(f,a,d){var e= +function(c,b){function d(){f.setValue(f.__input.value)}e.superclass.call(this,c,b);var f=this;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"keyup",d);a.bind(this.__input,"change",d);a.bind(this.__input,"blur",function(){f.__onFinishChange&&f.__onFinishChange.call(f,f.getValue())});a.bind(this.__input,"keydown",function(a){13===a.keyCode&&this.blur()});this.updateDisplay();this.domElement.appendChild(this.__input)};e.superclass=f;d.extend(e.prototype, +f.prototype,{updateDisplay:function(){a.isActive(this.__input)||(this.__input.value=this.getValue());return e.superclass.prototype.updateDisplay.call(this)}});return e}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.FunctionController,dat.controllers.BooleanController,dat.utils.common),dat.controllers.Controller,dat.controllers.BooleanController,dat.controllers.FunctionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.OptionController, +dat.controllers.ColorController=function(f,a,d,e,c){function b(a,b,d,e){a.style.background="";c.each(l,function(c){a.style.cssText+="background: "+c+"linear-gradient("+b+", "+d+" 0%, "+e+" 100%); "})}function p(a){a.style.background="";a.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);";a.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"; +a.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}var q=function(f,n){function u(b){v(b);a.bind(window,"mousemove",v);a.bind(window, +"mouseup",l)}function l(){a.unbind(window,"mousemove",v);a.unbind(window,"mouseup",l)}function g(){var a=e(this.value);!1!==a?(t.__color.__state=a,t.setValue(t.__color.toOriginal())):this.value=t.__color.toString()}function k(){a.unbind(window,"mousemove",w);a.unbind(window,"mouseup",k)}function v(b){b.preventDefault();var c=a.getWidth(t.__saturation_field),d=a.getOffset(t.__saturation_field),e=(b.clientX-d.left+document.body.scrollLeft)/c;b=1-(b.clientY-d.top+document.body.scrollTop)/c;1 +b&&(b=0);1e&&(e=0);t.__color.v=b;t.__color.s=e;t.setValue(t.__color.toOriginal());return!1}function w(b){b.preventDefault();var c=a.getHeight(t.__hue_field),d=a.getOffset(t.__hue_field);b=1-(b.clientY-d.top+document.body.scrollTop)/c;1b&&(b=0);t.__color.h=360*b;t.setValue(t.__color.toOriginal());return!1}q.superclass.call(this,f,n);this.__color=new d(this.getValue());this.__temp=new d(0);var t=this;this.domElement=document.createElement("div");a.makeSelectable(this.domElement,!1); +this.__selector=document.createElement("div");this.__selector.className="selector";this.__saturation_field=document.createElement("div");this.__saturation_field.className="saturation-field";this.__field_knob=document.createElement("div");this.__field_knob.className="field-knob";this.__field_knob_border="2px solid ";this.__hue_knob=document.createElement("div");this.__hue_knob.className="hue-knob";this.__hue_field=document.createElement("div");this.__hue_field.className="hue-field";this.__input=document.createElement("input"); +this.__input.type="text";this.__input_textShadow="0 1px 1px ";a.bind(this.__input,"keydown",function(a){13===a.keyCode&&g.call(this)});a.bind(this.__input,"blur",g);a.bind(this.__selector,"mousedown",function(b){a.addClass(this,"drag").bind(window,"mouseup",function(b){a.removeClass(t.__selector,"drag")})});var y=document.createElement("div");c.extend(this.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"});c.extend(this.__field_knob.style, +{position:"absolute",width:"12px",height:"12px",border:this.__field_knob_border+(.5>this.__color.v?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1});c.extend(this.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1});c.extend(this.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"});c.extend(y.style,{width:"100%",height:"100%", +background:"none"});b(y,"top","rgba(0,0,0,0)","#000");c.extend(this.__hue_field.style,{width:"15px",height:"100px",display:"inline-block",border:"1px solid #555",cursor:"ns-resize"});p(this.__hue_field);c.extend(this.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:this.__input_textShadow+"rgba(0,0,0,0.7)"});a.bind(this.__saturation_field,"mousedown",u);a.bind(this.__field_knob,"mousedown",u);a.bind(this.__hue_field,"mousedown",function(b){w(b);a.bind(window, +"mousemove",w);a.bind(window,"mouseup",k)});this.__saturation_field.appendChild(y);this.__selector.appendChild(this.__field_knob);this.__selector.appendChild(this.__saturation_field);this.__selector.appendChild(this.__hue_field);this.__hue_field.appendChild(this.__hue_knob);this.domElement.appendChild(this.__input);this.domElement.appendChild(this.__selector);this.updateDisplay()};q.superclass=f;c.extend(q.prototype,f.prototype,{updateDisplay:function(){var a=e(this.getValue());if(!1!==a){var f=!1; +c.each(d.COMPONENTS,function(b){if(!c.isUndefined(a[b])&&!c.isUndefined(this.__color.__state[b])&&a[b]!==this.__color.__state[b])return f=!0,{}},this);f&&c.extend(this.__color.__state,a)}c.extend(this.__temp.__state,this.__color.__state);this.__temp.a=1;var l=.5>this.__color.v||.5a&&(a+=1);return{h:360*a,s:c/b,v:b/255}},rgb_to_hex:function(a,d,e){a=this.hex_with_component(0,2,a);a=this.hex_with_component(a,1,d);return a=this.hex_with_component(a,0,e)},component_from_hex:function(a,d){return a>>8*d&255},hex_with_component:function(a,d,e){return e<<(f=8*d)|a&~(255< + + + + + + + + + +
    +
    + + \ No newline at end of file diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js new file mode 100644 index 0000000000..fc06ba345b --- /dev/null +++ b/examples/particle_explorer/main.js @@ -0,0 +1,170 @@ +// +// main.js +// +// +// Created by James B. Pollack @imgntnon 9/26/2015 +// Copyright 2014 High Fidelity, Inc. +// +// Web app side of the App - contains GUI. +// Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// todo: folders, color pickers, animation settings, scale gui width with window resizing +// + +var PI = 3.141593, + DEG_TO_RAD = PI / 180.0; + +function radiansToDegrees(radians) { + return radians * (180 / PI) +} + +// need to add '_group' to the end of properties that will need to be made part of a group on the backend +// property_subproperty_group = value +// i.e. color_red_group = 0; + +var ParticleExplorer = function() { + this.animationIsPlaying = true; + this.textures = "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"; + this.lifespan = 5.0; + this.visible = false; + this.locked = false; + this.lifetime = 3600 // 1 hour; just in case + this.accelerationSpread_x_group = 0.1; + this.accelerationSpread_y_group = 0.1; + this.accelerationSpread_z_group = 0.1; + this.alpha = 0.5; + this.alphaStart = 1.0; + this.alphaFinish = 0.1; + this.color_red_group = 0; + this.color_green_group = 0; + this.color_blue_group = 0; + this.colorSpread_red_group = 0; + this.colorSpread_green_group = 0; + this.colorSpread_blue_group = 0; + this.colorStart_red_group = 0; + this.colorStart_green_group = 0; + this.colorStart_blue_group = 0; + this.colorFinish_red_group = 0; + this.colorFinish_green_group = 0; + this.colorFinish_blue_group = 0; + this.azimuthStart = -PI / 2.0; + this.azimuthFinish = PI / 2.0; + this.emitAccceleration_x_group = 0.01; + this.emitAccceleration_y_group = 0.01; + this.emitAccceleration_z_group = 0.01; + this.emitDimensions_x_group = 0.01; + this.emitDimensions_y_group = 0.01; + this.emitDimensions_z_group = 0.01; + this.emitOrientation_x_group = 0.01; + this.emitOrientation_y_group = 0.01; + this.emitOrientation_z_group = 0.01; + this.emitOrientation_w_group = 0.01; + this.emitRate = 0.1; + this.emitSpeed = 0.1; + this.polarStart = 0.01; + this.polarFinish = 2.0 * DEG_TO_RAD; + this.speedSpread = 0.1; + this.radiusSpread = 0.035; + this.radiusStart = 0.0; + this.radiusFinish = 0.0; + this.velocitySpread = 0; + +} + +//we need a way to keep track of our gui controllers +var controllers = []; +window.onload = function() { + + //instantiate our object + var particleExplorer = new ParticleExplorer(); + + //whether or not to autoplace + var gui = new dat.GUI({ + autoPlace: false + }); + + //if not autoplacing, put gui in a custom container + if (gui.autoPlace === false) { + + var customContainer = document.getElementById('my-gui-container'); + customContainer.appendChild(gui.domElement); + gui.width = 400; + + } + + //add save settings ability (try not to use localstorage) + gui.remember(particleExplorer); + + //get object keys + var particleKeys = _.keys(particleExplorer); + + //for each key... + _.each(particleKeys, function(key) { + //add this key as a controller to the gui + var controller = gui.add(particleExplorer, key); + if (key.indexOf('_group') > -1) { + controller.shouldGroup = true; + } else { + controller.shouldGroup = false; + } + + + //keep track of our controller + controllers.push(controller); + + //hook into change events for this gui controller + controller.onChange(function(value) { + // Fires on every change, drag, keypress, etc. + // writeDataToInterface(this.property, value, this.shouldGroup) + }); + + controller.onFinishChange(function(value) { + console.log('should group?', controller.shouldGroup) + // Fires when a controller loses focus. + writeDataToInterface(this.property, value, this.shouldGroup) + }); + + }); + +}; + +function writeDataToInterface(property, value, shouldGroup) { + console.log('shouldgrouppppp', shouldGroup) + var group = null; + var groupProperty = null; + var groupProperties = null; + if (shouldGroup) { + var separated = property.slice(0, property.indexOf('_group')).split("_") + group = separated[0]; + groupProperty = separated[1]; + var groupString = group.toString(); + var groupPropertyString = groupProperty.toString(); + var groupProperties = {} + groupProperties[group] = {}; + groupProperties[group][groupProperty] = value + console.log(groupProperties) + + } + + var data = { + type: "particleExplorer_update", + shouldGroup: shouldGroup, + groupProperties: groupProperties, + singleProperty: {} + } + + data['singleProperty'][property] = value + + var stringifiedData = JSON.stringify(data) + + console.log('stringifiedData', stringifiedData) + if (typeof EventBridge !== 'undefined') { + EventBridge.emitWebEvent( + stringifiedData + ); + } + +} \ No newline at end of file diff --git a/examples/particle_explorer/old.html b/examples/particle_explorer/old.html new file mode 100644 index 0000000000..f2d91bda70 --- /dev/null +++ b/examples/particle_explorer/old.html @@ -0,0 +1,1607 @@ + + + Properties + + + + + + + + +
    +
    +
    + +
    +
    +
    + + + +
    + +
    +
    +
    + Name +
    + +
    +
    + +
    + Locked + + + +
    + +
    + Visible + + + +
    + +
    +
    User Data
    +
    + +
    +
    + + +
    + +
    + +
    +
    Href
    +
    + +
    +
    +
    +
    Description
    +
    + +
    +
    + + +
    + +
    + +
    +
    Position
    +
    +
    X
    +
    Y
    +
    Z
    +
    + + +
    +
    +
    + +
    +
    Registration
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    + +
    +
    Dimensions
    +
    +
    X
    +
    Y
    +
    Z
    +
    + +
    +
    + % +
    + + + +
    +
    + +
    +
    Voxel Volume Size
    +
    +
    X
    +
    Y
    +
    Z
    +
    + +
    Surface Extractor
    +
    + +
    + +
    X-axis Texture URL
    +
    + +
    + +
    Y-axis Texture URL
    +
    + +
    + +
    Z-axis Texture URL
    +
    + +
    +
    + +
    +
    Rotation
    +
    +
    Pitch
    +
    Yaw
    +
    Roll
    +
    +
    + + +
    + +
    + +
    +
    Linear Velocity
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    +
    +
    Linear Damping
    +
    + +
    +
    +
    +
    Angular Velocity
    +
    +
    Pitch
    +
    Yaw
    +
    Roll
    +
    +
    +
    +
    Angular Damping
    +
    + +
    +
    +
    +
    Restitution
    +
    + +
    +
    +
    +
    Friction
    +
    + +
    +
    + +
    +
    Gravity
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    + +
    +
    Acceleration
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    + +
    +
    Density
    +
    + +
    +
    + +
    +
    Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    + + +
    + +
    + +
    + Ignore For Collisions + + + +
    + +
    + Collisions Will Move + + + +
    + +
    +
    Collision Sound URL
    +
    + +
    +
    + +
    +
    Lifetime
    +
    + +
    +
    + +
    +
    Script URL + + +
    +
    + +
    +
    + + +
    + +
    + +
    +
    Model URL
    +
    + +
    +
    + +
    +
    Shape Type
    +
    + +
    +
    +
    +
    Compound Shape URL
    +
    + +
    +
    +
    +
    Animation URL
    +
    + +
    +
    +
    + Animation Playing + + + +
    +
    +
    Animation FPS
    +
    + +
    +
    +
    +
    Animation Frame
    +
    + +
    +
    +
    +
    Animation Settings
    +
    + +
    +
    +
    +
    Textures
    +
    + +
    +
    +
    +
    Original Textures
    +
    + +
    +
    + + +
    + +
    + +
    +
    Source URL
    +
    + +
    +
    + + +
    + +
    + +
    +
    Max Particles
    +
    + +
    +
    +
    +
    Particle Life Span
    +
    + +
    +
    +
    +
    Particle Emission Rate
    +
    + +
    +
    +
    +
    Particle Emission Direction
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    +
    +
    Particle Emission Strength
    +
    + +
    +
    +
    +
    Particle Local Gravity
    +
    + +
    +
    +
    +
    Particle Radius
    +
    + +
    +
    + + +
    + +
    + +
    +
    Text Content
    +
    + +
    +
    +
    +
    Line Height
    +
    + +
    +
    +
    +
    Text Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    +
    +
    Background Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    + + +
    + +
    + +
    + Spot Light + + + +
    +
    +
    Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    +
    +
    Intensity
    +
    + +
    +
    +
    +
    Spot Light Exponent
    +
    + +
    +
    +
    +
    Spot Light Cutoff (degrees)
    +
    + +
    +
    + + +
    + +
    + +
    + Stage Sun Model Enabled + + + +
    + +
    +
    Key Light Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    +
    +
    Key Light Intensity
    +
    + +
    +
    +
    +
    Key Light Ambient Intensity
    +
    + +
    +
    +
    +
    Key Light Direction
    +
    +
    Pitch
    +
    Yaw
    +
    Roll
    +
    +
    + +
    +
    Stage Latitude
    +
    + +
    +
    +
    +
    Stage Longitude
    +
    + +
    +
    +
    +
    Stage Altitude
    +
    + +
    +
    + +
    + Automatically calculate stage hour and day from location and clock. + + + +
    + +
    +
    Stage Day
    +
    + +
    +
    +
    +
    Stage Hour
    +
    + +
    +
    + +
    +
    Background Mode
    +
    + +
    +
    + + +
    + +
    + +
    +
    Skybox Color
    +
    +
    +
    R
    +
    G
    +
    B
    +
    +
    +
    +
    Skybox URL
    +
    + +
    +
    + + +
    + +
    + +
    +
    Atmosphere Center
    +
    +
    X
    +
    Y
    +
    Z
    +
    + +
    +
    +
    +
    +
    Atmosphere Inner Radius
    +
    + +
    +
    +
    +
    Atmosphere Outer Radius
    +
    + +
    +
    +
    +
    Atmosphere Mie Scattering
    +
    + +
    +
    +
    +
    Atmosphere Rayleigh Scattering
    +
    + +
    +
    +
    +
    Atmosphere Scattering Wavelenghts
    +
    +
    X
    +
    Y
    +
    Z
    +
    +
    + +
    + + \ No newline at end of file diff --git a/examples/particle_explorer/particleExplorer.js b/examples/particle_explorer/particleExplorer.js new file mode 100644 index 0000000000..a0116a0f34 --- /dev/null +++ b/examples/particle_explorer/particleExplorer.js @@ -0,0 +1,173 @@ +// +// particleExplorer.js +// +// +// Created by James B. Pollack @imgntnon 9/26/2015 +// Copyright 2014 High Fidelity, Inc. +// +// Interface side of the App. +// Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// todo: folders, color pickers, animation settings, scale gui width with window resizing +// +var boxPoint, + spawnPoint, + animation = { + fps: 30, + frameIndex: 0, + running: true, + firstFrame: 0, + lastFrame: 30, + loop: true + }; + + +var boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); +boxPoint = Vec3.sum(boxPoint, { + x: 0.0, + y: -0.5, + z: 0.0 +}); +spawnPoint = Vec3.sum(boxPoint, { + x: 0.0, + y: 1.0, + z: 0.0 +}); + +var PI = 3.141593, + DEG_TO_RAD = PI / 180.0; + +BlankBox = function() { + this.animationIsPlaying = true; + this.accelerationSpread_x_group = 0.1; + this.accelerationSpread_y_group = 0.1; + this.accelerationSpread_z_group = 0.1; + this.alpha = 0.5; + this.alphaStart = 1.0; + this.alphaFinish = 0.1; + this.color_red_group = 0; + this.color_green_group = 0; + this.color_blue_group = 0; + this.colorSpread_red_group = 0; + this.colorSpread_green_group = 0; + this.colorSpread_blue_group = 0; + this.colorStart_red_group = 0; + this.colorStart_green_group = 0; + this.colorStart_blue_group = 0; + this.colorFinish_red_group = 0; + this.colorFinish_green_group = 0; + this.colorFinish_blue_group = 0; + this.azimuthStart = -PI / 2.0; + this.azimuthFinish = PI / 2.0; + this.emitAccceleration_x_group = 0.01; + this.emitAccceleration_y_group = 0.01; + this.emitAccceleration_z_group = 0.01; + this.emitDimensions_x_group = 0.01; + this.emitDimensions_y_group = 0.01; + this.emitDimensions_z_group = 0.01; + this.emitOrientation_x_group = 0.01; + this.emitOrientation_y_group = 0.01; + this.emitOrientation_z_group = 0.01; + this.emitOrientation_w_group = 0.01; + this.emitRate = 0.1; + this.emitSpeed = 0.1; + this.polarStart = 0.01; + this.polarFinish = 2.0 * DEG_TO_RAD; + this.speedSpread = 0.1; + this.radiusSpread = 0.035; + this.radiusStart = 0.0; + this.radiusFinish = 0.0; + this.velocitySpread = 0; + // + this.type = "ParticleEffect"; + this.name = "ParticlesTest Emitter"; + this.position = spawnPoint; + this.textures = "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"; + this.lifespan = 5.0; + this.visible = false; + this.locked = false; + this.animationSettings = animation; + this.lifetime = 3600 // 1 hour; just in case +} + +var blankBox = new BlankBox(); + +var box = Entities.addEntity({ + type: "Box", + name: "ParticlesTest Box", + position: boxPoint, + rotation: { + x: -0.7071067690849304, + y: 0, + z: 0, + w: 0.7071067690849304 + }, + dimensions: { + x: 0.3, + y: 0.3, + z: 0.3 + }, + color: { + red: 128, + green: 128, + blue: 128 + }, + lifetime: 3600, // 1 hour; just in case + visible: true +}); + +var testParticles = Entities.addEntity(blankBox); + +SettingsWindow = function() { + var _this = this; + this.webWindow = null; + this.init = function() { + _this.webWindow = new WebWindow('ParticleExplorer', Script.resolvePath('index.html'), 400, 600, true); + _this.webWindow.setVisible(true); + _this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived); + print('INIT testParticles' + testParticles) + }; + this.onWebEventReceived = function(data) { + print('DATA ' + data) + + + var _data = JSON.parse(data) + if (_data.type !== 'particleExplorer_update') { + return; + } + if (_data.shouldGroup === true) { + print('USE GROUP PROPERTIES') + editEntity(_data.groupProperties) + return; + } else { + print('USE A SINGLE PROPERTY') + editEntity(_data.singleProperty) + + } + + + }; + +} + + +function editEntity(properties) { + // print('TEST PARTICLES??' + testParticles) + print('PROPS' + JSON.stringify(properties)); + Entities.editEntity(testParticles, properties); + var currentProperties = Entities.getEntityProperties(testParticles) + print('CURRENT PROPS', JSON.stringify(currentProperties)) +} + + +var settingsWindow = new SettingsWindow(); +settingsWindow.init(); + +function cleanup() { + Entities.deleteEntity(testParticles); + Entities.deleteEntity(box); +} +Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/particle_explorer/underscore-min.js b/examples/particle_explorer/underscore-min.js new file mode 100644 index 0000000000..f01025b7bc --- /dev/null +++ b/examples/particle_explorer/underscore-min.js @@ -0,0 +1,6 @@ +// Underscore.js 1.8.3 +// http://underscorejs.org +// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// Underscore may be freely distributed under the MIT license. +(function(){function n(n){function t(t,r,e,u,i,o){for(;i>=0&&o>i;i+=n){var a=u?u[i]:i;e=r(e,t[a],a,t)}return e}return function(r,e,u,i){e=b(e,i,4);var o=!k(r)&&m.keys(r),a=(o||r).length,c=n>0?0:a-1;return arguments.length<3&&(u=r[o?o[c]:c],c+=n),t(r,e,u,o,c,a)}}function t(n){return function(t,r,e){r=x(r,e);for(var u=O(t),i=n>0?0:u-1;i>=0&&u>i;i+=n)if(r(t[i],i,t))return i;return-1}}function r(n,t,r){return function(e,u,i){var o=0,a=O(e);if("number"==typeof i)n>0?o=i>=0?i:Math.max(i+a,o):a=i>=0?Math.min(i+1,a):i+a+1;else if(r&&i&&a)return i=r(e,u),e[i]===u?i:-1;if(u!==u)return i=t(l.call(e,o,a),m.isNaN),i>=0?i+o:-1;for(i=n>0?o:a-1;i>=0&&a>i;i+=n)if(e[i]===u)return i;return-1}}function e(n,t){var r=I.length,e=n.constructor,u=m.isFunction(e)&&e.prototype||a,i="constructor";for(m.has(n,i)&&!m.contains(t,i)&&t.push(i);r--;)i=I[r],i in n&&n[i]!==u[i]&&!m.contains(t,i)&&t.push(i)}var u=this,i=u._,o=Array.prototype,a=Object.prototype,c=Function.prototype,f=o.push,l=o.slice,s=a.toString,p=a.hasOwnProperty,h=Array.isArray,v=Object.keys,g=c.bind,y=Object.create,d=function(){},m=function(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=m),exports._=m):u._=m,m.VERSION="1.8.3";var b=function(n,t,r){if(t===void 0)return n;switch(null==r?3:r){case 1:return function(r){return n.call(t,r)};case 2:return function(r,e){return n.call(t,r,e)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)}}return function(){return n.apply(t,arguments)}},x=function(n,t,r){return null==n?m.identity:m.isFunction(n)?b(n,t,r):m.isObject(n)?m.matcher(n):m.property(n)};m.iteratee=function(n,t){return x(n,t,1/0)};var _=function(n,t){return function(r){var e=arguments.length;if(2>e||null==r)return r;for(var u=1;e>u;u++)for(var i=arguments[u],o=n(i),a=o.length,c=0;a>c;c++){var f=o[c];t&&r[f]!==void 0||(r[f]=i[f])}return r}},j=function(n){if(!m.isObject(n))return{};if(y)return y(n);d.prototype=n;var t=new d;return d.prototype=null,t},w=function(n){return function(t){return null==t?void 0:t[n]}},A=Math.pow(2,53)-1,O=w("length"),k=function(n){var t=O(n);return"number"==typeof t&&t>=0&&A>=t};m.each=m.forEach=function(n,t,r){t=b(t,r);var e,u;if(k(n))for(e=0,u=n.length;u>e;e++)t(n[e],e,n);else{var i=m.keys(n);for(e=0,u=i.length;u>e;e++)t(n[i[e]],i[e],n)}return n},m.map=m.collect=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=Array(u),o=0;u>o;o++){var a=e?e[o]:o;i[o]=t(n[a],a,n)}return i},m.reduce=m.foldl=m.inject=n(1),m.reduceRight=m.foldr=n(-1),m.find=m.detect=function(n,t,r){var e;return e=k(n)?m.findIndex(n,t,r):m.findKey(n,t,r),e!==void 0&&e!==-1?n[e]:void 0},m.filter=m.select=function(n,t,r){var e=[];return t=x(t,r),m.each(n,function(n,r,u){t(n,r,u)&&e.push(n)}),e},m.reject=function(n,t,r){return m.filter(n,m.negate(x(t)),r)},m.every=m.all=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(!t(n[o],o,n))return!1}return!0},m.some=m.any=function(n,t,r){t=x(t,r);for(var e=!k(n)&&m.keys(n),u=(e||n).length,i=0;u>i;i++){var o=e?e[i]:i;if(t(n[o],o,n))return!0}return!1},m.contains=m.includes=m.include=function(n,t,r,e){return k(n)||(n=m.values(n)),("number"!=typeof r||e)&&(r=0),m.indexOf(n,t,r)>=0},m.invoke=function(n,t){var r=l.call(arguments,2),e=m.isFunction(t);return m.map(n,function(n){var u=e?t:n[t];return null==u?u:u.apply(n,r)})},m.pluck=function(n,t){return m.map(n,m.property(t))},m.where=function(n,t){return m.filter(n,m.matcher(t))},m.findWhere=function(n,t){return m.find(n,m.matcher(t))},m.max=function(n,t,r){var e,u,i=-1/0,o=-1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],e>i&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(u>o||u===-1/0&&i===-1/0)&&(i=n,o=u)});return i},m.min=function(n,t,r){var e,u,i=1/0,o=1/0;if(null==t&&null!=n){n=k(n)?n:m.values(n);for(var a=0,c=n.length;c>a;a++)e=n[a],i>e&&(i=e)}else t=x(t,r),m.each(n,function(n,r,e){u=t(n,r,e),(o>u||1/0===u&&1/0===i)&&(i=n,o=u)});return i},m.shuffle=function(n){for(var t,r=k(n)?n:m.values(n),e=r.length,u=Array(e),i=0;e>i;i++)t=m.random(0,i),t!==i&&(u[i]=u[t]),u[t]=r[i];return u},m.sample=function(n,t,r){return null==t||r?(k(n)||(n=m.values(n)),n[m.random(n.length-1)]):m.shuffle(n).slice(0,Math.max(0,t))},m.sortBy=function(n,t,r){return t=x(t,r),m.pluck(m.map(n,function(n,r,e){return{value:n,index:r,criteria:t(n,r,e)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=x(r,e),m.each(t,function(e,i){var o=r(e,i,t);n(u,e,o)}),u}};m.groupBy=F(function(n,t,r){m.has(n,r)?n[r].push(t):n[r]=[t]}),m.indexBy=F(function(n,t,r){n[r]=t}),m.countBy=F(function(n,t,r){m.has(n,r)?n[r]++:n[r]=1}),m.toArray=function(n){return n?m.isArray(n)?l.call(n):k(n)?m.map(n,m.identity):m.values(n):[]},m.size=function(n){return null==n?0:k(n)?n.length:m.keys(n).length},m.partition=function(n,t,r){t=x(t,r);var e=[],u=[];return m.each(n,function(n,r,i){(t(n,r,i)?e:u).push(n)}),[e,u]},m.first=m.head=m.take=function(n,t,r){return null==n?void 0:null==t||r?n[0]:m.initial(n,n.length-t)},m.initial=function(n,t,r){return l.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))},m.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:m.rest(n,Math.max(0,n.length-t))},m.rest=m.tail=m.drop=function(n,t,r){return l.call(n,null==t||r?1:t)},m.compact=function(n){return m.filter(n,m.identity)};var S=function(n,t,r,e){for(var u=[],i=0,o=e||0,a=O(n);a>o;o++){var c=n[o];if(k(c)&&(m.isArray(c)||m.isArguments(c))){t||(c=S(c,t,r));var f=0,l=c.length;for(u.length+=l;l>f;)u[i++]=c[f++]}else r||(u[i++]=c)}return u};m.flatten=function(n,t){return S(n,t,!1)},m.without=function(n){return m.difference(n,l.call(arguments,1))},m.uniq=m.unique=function(n,t,r,e){m.isBoolean(t)||(e=r,r=t,t=!1),null!=r&&(r=x(r,e));for(var u=[],i=[],o=0,a=O(n);a>o;o++){var c=n[o],f=r?r(c,o,n):c;t?(o&&i===f||u.push(c),i=f):r?m.contains(i,f)||(i.push(f),u.push(c)):m.contains(u,c)||u.push(c)}return u},m.union=function(){return m.uniq(S(arguments,!0,!0))},m.intersection=function(n){for(var t=[],r=arguments.length,e=0,u=O(n);u>e;e++){var i=n[e];if(!m.contains(t,i)){for(var o=1;r>o&&m.contains(arguments[o],i);o++);o===r&&t.push(i)}}return t},m.difference=function(n){var t=S(arguments,!0,!0,1);return m.filter(n,function(n){return!m.contains(t,n)})},m.zip=function(){return m.unzip(arguments)},m.unzip=function(n){for(var t=n&&m.max(n,O).length||0,r=Array(t),e=0;t>e;e++)r[e]=m.pluck(n,e);return r},m.object=function(n,t){for(var r={},e=0,u=O(n);u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},m.findIndex=t(1),m.findLastIndex=t(-1),m.sortedIndex=function(n,t,r,e){r=x(r,e,1);for(var u=r(t),i=0,o=O(n);o>i;){var a=Math.floor((i+o)/2);r(n[a])i;i++,n+=r)u[i]=n;return u};var E=function(n,t,r,e,u){if(!(e instanceof t))return n.apply(r,u);var i=j(n.prototype),o=n.apply(i,u);return m.isObject(o)?o:i};m.bind=function(n,t){if(g&&n.bind===g)return g.apply(n,l.call(arguments,1));if(!m.isFunction(n))throw new TypeError("Bind must be called on a function");var r=l.call(arguments,2),e=function(){return E(n,e,t,this,r.concat(l.call(arguments)))};return e},m.partial=function(n){var t=l.call(arguments,1),r=function(){for(var e=0,u=t.length,i=Array(u),o=0;u>o;o++)i[o]=t[o]===m?arguments[e++]:t[o];for(;e=e)throw new Error("bindAll must be passed function names");for(t=1;e>t;t++)r=arguments[t],n[r]=m.bind(n[r],n);return n},m.memoize=function(n,t){var r=function(e){var u=r.cache,i=""+(t?t.apply(this,arguments):e);return m.has(u,i)||(u[i]=n.apply(this,arguments)),u[i]};return r.cache={},r},m.delay=function(n,t){var r=l.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},m.defer=m.partial(m.delay,m,1),m.throttle=function(n,t,r){var e,u,i,o=null,a=0;r||(r={});var c=function(){a=r.leading===!1?0:m.now(),o=null,i=n.apply(e,u),o||(e=u=null)};return function(){var f=m.now();a||r.leading!==!1||(a=f);var l=t-(f-a);return e=this,u=arguments,0>=l||l>t?(o&&(clearTimeout(o),o=null),a=f,i=n.apply(e,u),o||(e=u=null)):o||r.trailing===!1||(o=setTimeout(c,l)),i}},m.debounce=function(n,t,r){var e,u,i,o,a,c=function(){var f=m.now()-o;t>f&&f>=0?e=setTimeout(c,t-f):(e=null,r||(a=n.apply(i,u),e||(i=u=null)))};return function(){i=this,u=arguments,o=m.now();var f=r&&!e;return e||(e=setTimeout(c,t)),f&&(a=n.apply(i,u),i=u=null),a}},m.wrap=function(n,t){return m.partial(t,n)},m.negate=function(n){return function(){return!n.apply(this,arguments)}},m.compose=function(){var n=arguments,t=n.length-1;return function(){for(var r=t,e=n[t].apply(this,arguments);r--;)e=n[r].call(this,e);return e}},m.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},m.before=function(n,t){var r;return function(){return--n>0&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}},m.once=m.partial(m.before,2);var M=!{toString:null}.propertyIsEnumerable("toString"),I=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"];m.keys=function(n){if(!m.isObject(n))return[];if(v)return v(n);var t=[];for(var r in n)m.has(n,r)&&t.push(r);return M&&e(n,t),t},m.allKeys=function(n){if(!m.isObject(n))return[];var t=[];for(var r in n)t.push(r);return M&&e(n,t),t},m.values=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},m.mapObject=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=u.length,o={},a=0;i>a;a++)e=u[a],o[e]=t(n[e],e,n);return o},m.pairs=function(n){for(var t=m.keys(n),r=t.length,e=Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},m.invert=function(n){for(var t={},r=m.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},m.functions=m.methods=function(n){var t=[];for(var r in n)m.isFunction(n[r])&&t.push(r);return t.sort()},m.extend=_(m.allKeys),m.extendOwn=m.assign=_(m.keys),m.findKey=function(n,t,r){t=x(t,r);for(var e,u=m.keys(n),i=0,o=u.length;o>i;i++)if(e=u[i],t(n[e],e,n))return e},m.pick=function(n,t,r){var e,u,i={},o=n;if(null==o)return i;m.isFunction(t)?(u=m.allKeys(o),e=b(t,r)):(u=S(arguments,!1,!1,1),e=function(n,t,r){return t in r},o=Object(o));for(var a=0,c=u.length;c>a;a++){var f=u[a],l=o[f];e(l,f,o)&&(i[f]=l)}return i},m.omit=function(n,t,r){if(m.isFunction(t))t=m.negate(t);else{var e=m.map(S(arguments,!1,!1,1),String);t=function(n,t){return!m.contains(e,t)}}return m.pick(n,t,r)},m.defaults=_(m.allKeys,!0),m.create=function(n,t){var r=j(n);return t&&m.extendOwn(r,t),r},m.clone=function(n){return m.isObject(n)?m.isArray(n)?n.slice():m.extend({},n):n},m.tap=function(n,t){return t(n),n},m.isMatch=function(n,t){var r=m.keys(t),e=r.length;if(null==n)return!e;for(var u=Object(n),i=0;e>i;i++){var o=r[i];if(t[o]!==u[o]||!(o in u))return!1}return!0};var N=function(n,t,r,e){if(n===t)return 0!==n||1/n===1/t;if(null==n||null==t)return n===t;n instanceof m&&(n=n._wrapped),t instanceof m&&(t=t._wrapped);var u=s.call(n);if(u!==s.call(t))return!1;switch(u){case"[object RegExp]":case"[object String]":return""+n==""+t;case"[object Number]":return+n!==+n?+t!==+t:0===+n?1/+n===1/t:+n===+t;case"[object Date]":case"[object Boolean]":return+n===+t}var i="[object Array]"===u;if(!i){if("object"!=typeof n||"object"!=typeof t)return!1;var o=n.constructor,a=t.constructor;if(o!==a&&!(m.isFunction(o)&&o instanceof o&&m.isFunction(a)&&a instanceof a)&&"constructor"in n&&"constructor"in t)return!1}r=r||[],e=e||[];for(var c=r.length;c--;)if(r[c]===n)return e[c]===t;if(r.push(n),e.push(t),i){if(c=n.length,c!==t.length)return!1;for(;c--;)if(!N(n[c],t[c],r,e))return!1}else{var f,l=m.keys(n);if(c=l.length,m.keys(t).length!==c)return!1;for(;c--;)if(f=l[c],!m.has(t,f)||!N(n[f],t[f],r,e))return!1}return r.pop(),e.pop(),!0};m.isEqual=function(n,t){return N(n,t)},m.isEmpty=function(n){return null==n?!0:k(n)&&(m.isArray(n)||m.isString(n)||m.isArguments(n))?0===n.length:0===m.keys(n).length},m.isElement=function(n){return!(!n||1!==n.nodeType)},m.isArray=h||function(n){return"[object Array]"===s.call(n)},m.isObject=function(n){var t=typeof n;return"function"===t||"object"===t&&!!n},m.each(["Arguments","Function","String","Number","Date","RegExp","Error"],function(n){m["is"+n]=function(t){return s.call(t)==="[object "+n+"]"}}),m.isArguments(arguments)||(m.isArguments=function(n){return m.has(n,"callee")}),"function"!=typeof/./&&"object"!=typeof Int8Array&&(m.isFunction=function(n){return"function"==typeof n||!1}),m.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},m.isNaN=function(n){return m.isNumber(n)&&n!==+n},m.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"===s.call(n)},m.isNull=function(n){return null===n},m.isUndefined=function(n){return n===void 0},m.has=function(n,t){return null!=n&&p.call(n,t)},m.noConflict=function(){return u._=i,this},m.identity=function(n){return n},m.constant=function(n){return function(){return n}},m.noop=function(){},m.property=w,m.propertyOf=function(n){return null==n?function(){}:function(t){return n[t]}},m.matcher=m.matches=function(n){return n=m.extendOwn({},n),function(t){return m.isMatch(t,n)}},m.times=function(n,t,r){var e=Array(Math.max(0,n));t=b(t,r,1);for(var u=0;n>u;u++)e[u]=t(u);return e},m.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},m.now=Date.now||function(){return(new Date).getTime()};var B={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},T=m.invert(B),R=function(n){var t=function(t){return n[t]},r="(?:"+m.keys(n).join("|")+")",e=RegExp(r),u=RegExp(r,"g");return function(n){return n=null==n?"":""+n,e.test(n)?n.replace(u,t):n}};m.escape=R(B),m.unescape=R(T),m.result=function(n,t,r){var e=null==n?void 0:n[t];return e===void 0&&(e=r),m.isFunction(e)?e.call(n):e};var q=0;m.uniqueId=function(n){var t=++q+"";return n?n+t:t},m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var K=/(.)^/,z={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\u2028|\u2029/g,L=function(n){return"\\"+z[n]};m.template=function(n,t,r){!t&&r&&(t=r),t=m.defaults({},t,m.templateSettings);var e=RegExp([(t.escape||K).source,(t.interpolate||K).source,(t.evaluate||K).source].join("|")+"|$","g"),u=0,i="__p+='";n.replace(e,function(t,r,e,o,a){return i+=n.slice(u,a).replace(D,L),u=a+t.length,r?i+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'":e?i+="'+\n((__t=("+e+"))==null?'':__t)+\n'":o&&(i+="';\n"+o+"\n__p+='"),t}),i+="';\n",t.variable||(i="with(obj||{}){\n"+i+"}\n"),i="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+i+"return __p;\n";try{var o=new Function(t.variable||"obj","_",i)}catch(a){throw a.source=i,a}var c=function(n){return o.call(this,n,m)},f=t.variable||"obj";return c.source="function("+f+"){\n"+i+"}",c},m.chain=function(n){var t=m(n);return t._chain=!0,t};var P=function(n,t){return n._chain?m(t).chain():t};m.mixin=function(n){m.each(m.functions(n),function(t){var r=m[t]=n[t];m.prototype[t]=function(){var n=[this._wrapped];return f.apply(n,arguments),P(this,r.apply(m,n))}})},m.mixin(m),m.each(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=o[n];m.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!==n&&"splice"!==n||0!==r.length||delete r[0],P(this,r)}}),m.each(["concat","join","slice"],function(n){var t=o[n];m.prototype[n]=function(){return P(this,t.apply(this._wrapped,arguments))}}),m.prototype.value=function(){return this._wrapped},m.prototype.valueOf=m.prototype.toJSON=m.prototype.value,m.prototype.toString=function(){return""+this._wrapped},"function"==typeof define&&define.amd&&define("underscore",[],function(){return m})}).call(this); +//# sourceMappingURL=underscore-min.map \ No newline at end of file From d8e7cd89ada48e862d4b19408ffd5894912a9132 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 11:27:58 -0700 Subject: [PATCH 086/212] Cleanup, comments --- examples/particle_explorer/main.js | 2 +- examples/particle_explorer/particleExplorer.js | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index fc06ba345b..6509a6e865 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -122,7 +122,7 @@ window.onload = function() { }); controller.onFinishChange(function(value) { - console.log('should group?', controller.shouldGroup) + // console.log('should group?', controller.shouldGroup) // Fires when a controller loses focus. writeDataToInterface(this.property, value, this.shouldGroup) }); diff --git a/examples/particle_explorer/particleExplorer.js b/examples/particle_explorer/particleExplorer.js index a0116a0f34..a39b3e0307 100644 --- a/examples/particle_explorer/particleExplorer.js +++ b/examples/particle_explorer/particleExplorer.js @@ -131,19 +131,17 @@ SettingsWindow = function() { print('INIT testParticles' + testParticles) }; this.onWebEventReceived = function(data) { - print('DATA ' + data) - - + // print('DATA ' + data) var _data = JSON.parse(data) if (_data.type !== 'particleExplorer_update') { return; } if (_data.shouldGroup === true) { - print('USE GROUP PROPERTIES') + // print('USE GROUP PROPERTIES') editEntity(_data.groupProperties) return; } else { - print('USE A SINGLE PROPERTY') + // print('USE A SINGLE PROPERTY') editEntity(_data.singleProperty) } @@ -155,11 +153,9 @@ SettingsWindow = function() { function editEntity(properties) { - // print('TEST PARTICLES??' + testParticles) - print('PROPS' + JSON.stringify(properties)); Entities.editEntity(testParticles, properties); var currentProperties = Entities.getEntityProperties(testParticles) - print('CURRENT PROPS', JSON.stringify(currentProperties)) + // print('CURRENT PROPS', JSON.stringify(currentProperties)) } From a0b3bd91a3076d5bcbdfb6b0b626f55e21fee804 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 11:40:31 -0700 Subject: [PATCH 087/212] cleanup logging --- examples/particle_explorer/main.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 6509a6e865..057932f309 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -132,7 +132,6 @@ window.onload = function() { }; function writeDataToInterface(property, value, shouldGroup) { - console.log('shouldgrouppppp', shouldGroup) var group = null; var groupProperty = null; var groupProperties = null; @@ -145,7 +144,7 @@ function writeDataToInterface(property, value, shouldGroup) { var groupProperties = {} groupProperties[group] = {}; groupProperties[group][groupProperty] = value - console.log(groupProperties) + // console.log(groupProperties) } @@ -160,7 +159,6 @@ function writeDataToInterface(property, value, shouldGroup) { var stringifiedData = JSON.stringify(data) - console.log('stringifiedData', stringifiedData) if (typeof EventBridge !== 'undefined') { EventBridge.emitWebEvent( stringifiedData From 50dd8eba4586c9494efdd5bfa31ba1793daa246a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sat, 12 Sep 2015 08:23:50 -0700 Subject: [PATCH 088/212] Relay joint translations across network. Apply animation's root-joint translation to avatar. --- .../src/avatars/ScriptableAvatar.cpp | 14 +- interface/src/avatar/Avatar.cpp | 17 +- interface/src/avatar/Avatar.h | 1 + interface/src/avatar/MyAvatar.cpp | 37 ++- interface/src/avatar/MyAvatar.h | 5 +- interface/src/avatar/SkeletonModel.cpp | 1 + libraries/animation/src/AnimClip.cpp | 8 +- .../animation/src/AnimInverseKinematics.cpp | 3 + libraries/animation/src/AnimManipulator.cpp | 2 + libraries/animation/src/AnimationHandle.cpp | 11 + libraries/animation/src/AvatarRig.cpp | 27 +- libraries/animation/src/AvatarRig.h | 4 + libraries/animation/src/EntityRig.cpp | 14 + libraries/animation/src/EntityRig.h | 1 + libraries/animation/src/JointState.cpp | 32 ++- libraries/animation/src/JointState.h | 14 +- libraries/animation/src/Rig.cpp | 37 ++- libraries/animation/src/Rig.h | 12 +- libraries/avatars/src/AvatarData.cpp | 264 ++++++++++++++++-- libraries/avatars/src/AvatarData.h | 15 +- libraries/avatars/src/Player.cpp | 11 +- libraries/avatars/src/Recording.cpp | 14 +- libraries/avatars/src/Recording.h | 5 +- .../src/RenderableModelEntityItem.cpp | 9 +- libraries/entities/src/ModelEntityItem.cpp | 33 ++- libraries/entities/src/ModelEntityItem.h | 5 +- libraries/fbx/src/FBXReader.cpp | 39 ++- libraries/fbx/src/FBXReader.h | 2 +- .../networking/src/udt/PacketHeaders.cpp | 3 + libraries/render-utils/src/Model.cpp | 16 +- libraries/render-utils/src/Model.h | 5 +- libraries/shared/src/GLMHelpers.cpp | 2 + libraries/shared/src/GLMHelpers.h | 6 + 33 files changed, 585 insertions(+), 84 deletions(-) diff --git a/assignment-client/src/avatars/ScriptableAvatar.cpp b/assignment-client/src/avatars/ScriptableAvatar.cpp index 0b7af01c94..36a527009e 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.cpp +++ b/assignment-client/src/avatars/ScriptableAvatar.cpp @@ -77,7 +77,19 @@ void ScriptableAvatar::update(float deltatime) { int mapping = animationJoints.indexOf(modelJoints[i]); if (mapping != -1 && !_maskedJoints.contains(modelJoints[i])) { JointData& data = _jointData[i]; - data.rotation = safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction); + + auto newRotation = safeMix(floorFrame.rotations.at(i), ceilFrame.rotations.at(i), frameFraction); + auto newTranslation = floorFrame.translations.at(i) * (1.0f - frameFraction) + + ceilFrame.translations.at(i) * frameFraction; + + if (data.rotation != newRotation) { + data.rotation = newRotation; + data.rotationSet = true; + } + if (data.translation != newTranslation) { + data.translation = newTranslation; + data.translationSet = true; + } } } } else { diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 0d1c3b8a20..faf4bffeba 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -202,11 +202,14 @@ void Avatar::simulate(float deltaTime) { PerformanceTimer perfTimer("skeleton"); for (int i = 0; i < _jointData.size(); i++) { const JointData& data = _jointData.at(i); - _skeletonModel.setJointState(i, true, data.rotation); + _skeletonModel.setJointRotation(i, data.rotationSet, data.rotation, 1.0f); + _skeletonModel.setJointTranslation(i, data.translationSet, data.translation, 1.0f); } - _skeletonModel.simulate(deltaTime, _hasNewJointRotations); + + _skeletonModel.simulate(deltaTime, _hasNewJointRotations || _hasNewJointTranslations); simulateAttachments(deltaTime); _hasNewJointRotations = false; + _hasNewJointTranslations = false; } { PerformanceTimer perfTimer("head"); @@ -879,6 +882,16 @@ glm::quat Avatar::getJointRotation(int index) const { return rotation; } +glm::vec3 Avatar::getJointTranslation(int index) const { + if (QThread::currentThread() != thread()) { + return AvatarData::getJointTranslation(index); + } + glm::vec3 translation; + _skeletonModel.getJointTranslation(index, translation); + return translation; +} + + int Avatar::getJointIndex(const QString& name) const { if (QThread::currentThread() != thread()) { int result; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 6cfbf939a2..5ff3f37ef5 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -115,6 +115,7 @@ public: virtual QVector getJointRotations() const; virtual glm::quat getJointRotation(int index) const; + virtual glm::vec3 getJointTranslation(int index) const; virtual int getJointIndex(const QString& name) const; virtual QStringList getJointNames() const; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4cf1b69ce4..e6013638c8 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -239,9 +239,11 @@ void MyAvatar::simulate(float deltaTime) { PerformanceTimer perfTimer("joints"); // copy out the skeleton joints from the model _jointData.resize(_rig->getJointStateCount()); + for (int i = 0; i < _jointData.size(); i++) { JointData& data = _jointData[i]; - _rig->getJointStateRotation(i, data.rotation); + data.rotationSet |= _rig->getJointStateRotation(i, data.rotation); + data.translationSet |= _rig->getJointStateTranslation(i, data.translation); } } @@ -1083,21 +1085,43 @@ void MyAvatar::setJointRotations(QVector jointRotations) { int numStates = glm::min(_skeletonModel.getJointStateCount(), jointRotations.size()); for (int i = 0; i < numStates; ++i) { // HACK: ATM only Recorder calls setJointRotations() so we hardcode its priority here - _skeletonModel.setJointState(i, true, jointRotations[i], RECORDER_PRIORITY); + _skeletonModel.setJointRotation(i, true, jointRotations[i], RECORDER_PRIORITY); } } -void MyAvatar::setJointData(int index, const glm::quat& rotation) { +void MyAvatar::setJointTranslations(QVector jointTranslations) { + int numStates = glm::min(_skeletonModel.getJointStateCount(), jointTranslations.size()); + for (int i = 0; i < numStates; ++i) { + // HACK: ATM only Recorder calls setJointTranslations() so we hardcode its priority here + _skeletonModel.setJointTranslation(i, true, jointTranslations[i], RECORDER_PRIORITY); + } +} + +void MyAvatar::setJointData(int index, const glm::quat& rotation, const glm::vec3& translation) { if (QThread::currentThread() == thread()) { // HACK: ATM only JS scripts call setJointData() on MyAvatar so we hardcode the priority - _rig->setJointState(index, true, rotation, SCRIPT_PRIORITY); + _rig->setJointState(index, true, rotation, translation, SCRIPT_PRIORITY); + } +} + +void MyAvatar::setJointRotation(int index, const glm::quat& rotation) { + if (QThread::currentThread() == thread()) { + // HACK: ATM only JS scripts call setJointData() on MyAvatar so we hardcode the priority + _rig->setJointRotation(index, true, rotation, SCRIPT_PRIORITY); + } +} + +void MyAvatar::setJointTranslation(int index, const glm::vec3& translation) { + if (QThread::currentThread() == thread()) { + // HACK: ATM only JS scripts call setJointData() on MyAvatar so we hardcode the priority + _rig->setJointTranslation(index, true, translation, SCRIPT_PRIORITY); } } void MyAvatar::clearJointData(int index) { if (QThread::currentThread() == thread()) { // HACK: ATM only JS scripts call clearJointData() on MyAvatar so we hardcode the priority - _rig->setJointState(index, false, glm::quat(), 0.0f); + _rig->setJointState(index, false, glm::quat(), glm::vec3(), 0.0f); _rig->clearJointAnimationPriority(index); } } @@ -1396,7 +1420,10 @@ void MyAvatar::preRender(RenderArgs* renderArgs) { AnimPose pose = _debugDrawSkeleton->getRelativeBindPose(i); glm::quat jointRot; _rig->getJointRotationInConstrainedFrame(i, jointRot); + glm::vec3 jointTrans; + _rig->getJointTranslation(i, jointTrans); pose.rot = pose.rot * jointRot; + pose.trans = jointTrans; poses.push_back(pose); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index c1a6ada751..6ee42778c8 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -139,7 +139,10 @@ public: void clearLookAtTargetAvatar(); virtual void setJointRotations(QVector jointRotations); - virtual void setJointData(int index, const glm::quat& rotation); + virtual void setJointTranslations(QVector jointTranslations); + virtual void setJointData(int index, const glm::quat& rotation, const glm::vec3& translation); + virtual void setJointRotation(int index, const glm::quat& rotation); + virtual void setJointTranslation(int index, const glm::vec3& translation); virtual void clearJointData(int index); virtual void clearJointsData(); diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 703f3983ee..9cffe5956f 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -648,6 +648,7 @@ void SkeletonModel::computeBoundingShape() { // RECOVER FROM BOUNINDG SHAPE HACK: now that we're all done, restore the default pose for (int i = 0; i < numStates; i++) { _rig->restoreJointRotation(i, 1.0f, 1.0f); + _rig->restoreJointTranslation(i, 1.0f, 1.0f); } } diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index 23aa884933..f33c958fa8 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -147,8 +147,14 @@ void AnimClip::copyFromNetworkAnim() { for (int j = 0; j < animJointCount; j++) { int k = jointMap[j]; if (k >= 0 && k < skeletonJointCount) { - // currently FBX animations only have rotation. _anim[i][k].rot = _skeleton->getRelativeBindPose(k).rot * geom.animationFrames[i].rotations[j]; + + // TODO -- why does applying all the joint translations make a mutant? + if (animJoints[j].parentIndex == -1) { + _anim[i][k].trans = geom.animationFrames[i].translations[j] * extractScale(geom.offset); + } else { + _anim[i][k].trans = _skeleton->getRelativeBindPose(k).trans; + } } } } diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index de226092f1..037db8747c 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -322,9 +322,11 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar std::map::iterator constraintItr = _constraints.begin(); while (constraintItr != _constraints.end()) { int index = constraintItr->first; + glm::quat rotation = _relativePoses[index].rot; constraintItr->second->apply(rotation); _relativePoses[index].rot = rotation; + ++constraintItr; } } else { @@ -354,6 +356,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars } else { _relativePoses[i].rot = underPoses[i].rot; } + _relativePoses[i].trans = underPoses[i].trans; } } return evaluate(animVars, dt, triggersOut); diff --git a/libraries/animation/src/AnimManipulator.cpp b/libraries/animation/src/AnimManipulator.cpp index 8b9089f450..6ab4017aa3 100644 --- a/libraries/animation/src/AnimManipulator.cpp +++ b/libraries/animation/src/AnimManipulator.cpp @@ -55,6 +55,7 @@ const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, floa defaultRelPose = underPoses[jointVar.jointIndex]; defaultAbsPose = _skeleton->getAbsolutePose(jointVar.jointIndex, underPoses); defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot); + defaultAbsPose.trans = animVars.lookup(jointVar.var, defaultAbsPose.trans); // because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose. int parentIndex = _skeleton->getParentIndex(jointVar.jointIndex); @@ -68,6 +69,7 @@ const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, floa defaultRelPose = AnimPose::identity; defaultAbsPose = _skeleton->getAbsoluteBindPose(jointVar.jointIndex); defaultAbsPose.rot = animVars.lookup(jointVar.var, defaultAbsPose.rot); + defaultAbsPose.trans = animVars.lookup(jointVar.var, defaultAbsPose.trans); // because jointVar is absolute, we must use an absolute parent frame to convert into a relative pose // here we use the bind pose diff --git a/libraries/animation/src/AnimationHandle.cpp b/libraries/animation/src/AnimationHandle.cpp index f2d12b398e..a6ac9c1f97 100644 --- a/libraries/animation/src/AnimationHandle.cpp +++ b/libraries/animation/src/AnimationHandle.cpp @@ -173,6 +173,7 @@ void AnimationHandle::applyFrame(float frameIndex) { const FBXAnimationFrame& floorFrame = animationGeometry.animationFrames.at((int)glm::floor(frameIndex) % frameCount); const FBXAnimationFrame& ceilFrame = animationGeometry.animationFrames.at((int)glm::ceil(frameIndex) % frameCount); float frameFraction = glm::fract(frameIndex); + for (int i = 0; i < _jointMappings.size(); i++) { int mapping = _jointMappings.at(i); if (mapping != -1) { // allow missing bones @@ -183,6 +184,15 @@ void AnimationHandle::applyFrame(float frameIndex) { _priority, false, _mix); + + // This isn't working. + // glm::vec3 floorTranslationPart = floorFrame.translations.at(i) * (1.0f - frameFraction); + // glm::vec3 ceilTranslationPart = ceilFrame.translations.at(i) * frameFraction; + // glm::vec3 floorCeilFraction = floorTranslationPart + ceilTranslationPart; + // glm::vec3 defaultTrans = _rig->getJointDefaultTranslationInConstrainedFrame(i); + // glm::vec3 mixedTranslation = floorCeilFraction * (1.0f - _mix) + defaultTrans * _mix; + // _rig->setJointTranslation(mapping, true, mixedTranslation, _priority); + } } } @@ -203,6 +213,7 @@ void AnimationHandle::restoreJoints() { int mapping = _jointMappings.at(i); if (mapping != -1) { _rig->restoreJointRotation(mapping, 1.0f, _rig->getJointAnimatinoPriority(mapping)); + _rig->restoreJointTranslation(mapping, 1.0f, _rig->getJointAnimatinoPriority(mapping)); } } } diff --git a/libraries/animation/src/AvatarRig.cpp b/libraries/animation/src/AvatarRig.cpp index 0727d0956d..4dbf5207b1 100644 --- a/libraries/animation/src/AvatarRig.cpp +++ b/libraries/animation/src/AvatarRig.cpp @@ -20,9 +20,7 @@ void AvatarRig::updateJointState(int index, glm::mat4 rootTransform) { // compute model transforms if (index == _rootJointIndex) { - // we always zero-out the translation part of an avatar's root join-transform. state.computeTransform(rootTransform); - clearJointTransformTranslation(index); } else { // guard against out-of-bounds access to _jointStates int parentIndex = state.getParentIndex(); @@ -97,3 +95,28 @@ void AvatarRig::setHandPosition(int jointIndex, shoulderRotation, priority); setJointRotationInBindFrame(jointIndex, rotation, priority); } + +void AvatarRig::setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority) { + if (index != -1 && index < _jointStates.size()) { + JointState& state = _jointStates[index]; + if (valid) { + state.setTranslation(translation, priority); + } else { + state.restoreTranslation(1.0f, priority); + } + } +} + + +void AvatarRig::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) { + if (index != -1 && index < _jointStates.size()) { + JointState& state = _jointStates[index]; + if (valid) { + state.setRotationInConstrainedFrame(rotation, priority); + state.setTranslation(translation, priority); + } else { + state.restoreRotation(1.0f, priority); + state.restoreTranslation(1.0f, priority); + } + } +} diff --git a/libraries/animation/src/AvatarRig.h b/libraries/animation/src/AvatarRig.h index f137e89939..f45c2951e9 100644 --- a/libraries/animation/src/AvatarRig.h +++ b/libraries/animation/src/AvatarRig.h @@ -24,6 +24,10 @@ class AvatarRig : public Rig { virtual void updateJointState(int index, glm::mat4 rootTransform); virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, float scale, float priority); + virtual void setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority); + virtual void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority); }; + + #endif // hifi_AvatarRig_h diff --git a/libraries/animation/src/EntityRig.cpp b/libraries/animation/src/EntityRig.cpp index e65407116b..8748214734 100644 --- a/libraries/animation/src/EntityRig.cpp +++ b/libraries/animation/src/EntityRig.cpp @@ -27,3 +27,17 @@ void EntityRig::updateJointState(int index, glm::mat4 rootTransform) { } } } + + +void EntityRig::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) { + if (index != -1 && index < _jointStates.size()) { + JointState& state = _jointStates[index]; + if (valid) { + state.setRotationInConstrainedFrame(rotation, priority); + // state.setTranslation(translation, priority); + } else { + state.restoreRotation(1.0f, priority); + // state.restoreTranslation(1.0f, priority); + } + } +} diff --git a/libraries/animation/src/EntityRig.h b/libraries/animation/src/EntityRig.h index b36ffb9874..17486bad78 100644 --- a/libraries/animation/src/EntityRig.h +++ b/libraries/animation/src/EntityRig.h @@ -24,6 +24,7 @@ class EntityRig : public Rig { virtual void updateJointState(int index, glm::mat4 rootTransform); virtual void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation, float scale, float priority) {} + virtual void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority); }; #endif // hifi_EntityRig_h diff --git a/libraries/animation/src/JointState.cpp b/libraries/animation/src/JointState.cpp index 9597a46726..935319b489 100644 --- a/libraries/animation/src/JointState.cpp +++ b/libraries/animation/src/JointState.cpp @@ -43,6 +43,7 @@ void JointState::copyState(const JointState& other) { _isFree = other._isFree; _parentIndex = other._parentIndex; _defaultRotation = other._defaultRotation; + _defaultTranslation = other._defaultTranslation; _inverseDefaultRotation = other._inverseDefaultRotation; _translation = other._translation; _rotationMin = other._rotationMin; @@ -60,6 +61,7 @@ JointState::JointState(const FBXJoint& joint) { _parentIndex = joint.parentIndex; _translation = joint.translation; _defaultRotation = joint.rotation; + _defaultTranslation = _translation; _inverseDefaultRotation = joint.inverseDefaultRotation; _rotationMin = joint.rotationMin; _rotationMax = joint.rotationMax; @@ -92,6 +94,9 @@ glm::quat JointState::getRotation() const { } void JointState::initTransform(const glm::mat4& parentTransform) { + + _unitsScale = extractScale(parentTransform); + computeTransform(parentTransform); _positionInParentFrame = glm::inverse(extractRotation(parentTransform)) * (extractTranslation(_transform) - extractTranslation(parentTransform)); _distanceToParent = glm::length(_positionInParentFrame); @@ -101,11 +106,11 @@ void JointState::computeTransform(const glm::mat4& parentTransform, bool parentT if (!parentTransformChanged && !_transformChanged) { return; } - + glm::quat rotationInParentFrame = _preRotation * _rotationInConstrainedFrame * _postRotation; glm::mat4 transformInParentFrame = _preTransform * glm::mat4_cast(rotationInParentFrame) * _postTransform; glm::mat4 newTransform = parentTransform * glm::translate(_translation) * transformInParentFrame; - + if (newTransform != _transform) { _transform = newTransform; _transformChanged = true; @@ -139,6 +144,13 @@ void JointState::restoreRotation(float fraction, float priority) { } } +void JointState::restoreTranslation(float fraction, float priority) { + if (priority == _animationPriority || _animationPriority == 0.0f) { + _translation = _translation * (1.0f - fraction) + _defaultTranslation * fraction; + _animationPriority = 0.0f; + } +} + void JointState::setRotationInBindFrame(const glm::quat& rotation, float priority, bool constrain) { // rotation is from bind- to model-frame if (priority >= _animationPriority) { @@ -245,6 +257,14 @@ void JointState::setRotationInConstrainedFrame(glm::quat targetRotation, float p } } +void JointState::setTranslation(const glm::vec3& translation, float priority) { + if (priority >= _animationPriority || _animationPriority == 0.0f) { + _translation = translation / _unitsScale; + _transformChanged = true; + _animationPriority = priority; + } +} + void JointState::setRotationInConstrainedFrameInternal(const glm::quat& targetRotation) { if (_rotationInConstrainedFrame != targetRotation) { glm::quat parentRotation = computeParentRotation(); @@ -269,13 +289,17 @@ bool JointState::rotationIsDefault(const glm::quat& rotation, float tolerance) c glm::abs(rotation.w - defaultRotation.w) < tolerance; } +bool JointState::translationIsDefault(const glm::vec3& translation, float tolerance) const { + return glm::distance(_defaultTranslation, translation * _unitsScale) < tolerance; +} + glm::quat JointState::getDefaultRotationInParentFrame() const { // NOTE: the result is constant and could be cached return _preRotation * _defaultRotation * _postRotation; } -const glm::vec3& JointState::getDefaultTranslationInConstrainedFrame() const { - return _translation; +glm::vec3 JointState::getDefaultTranslationInConstrainedFrame() const { + return _defaultTranslation * _unitsScale; } void JointState::slaveVisibleTransform() { diff --git a/libraries/animation/src/JointState.h b/libraries/animation/src/JointState.h index 07ed010104..d11f98cdd6 100644 --- a/libraries/animation/src/JointState.h +++ b/libraries/animation/src/JointState.h @@ -77,6 +77,8 @@ public: /// \param priority priority level of this animation blend void restoreRotation(float fraction, float priority); + void restoreTranslation(float fraction, float priority); + /// \param rotation is from bind- to model-frame /// computes and sets new _rotationInConstrainedFrame /// NOTE: the JointState's model-frame transform/rotation are NOT updated! @@ -88,14 +90,18 @@ public: void setRotationInModelFrame(const glm::quat& rotationInModelFrame, float priority, bool constrain); void setRotationInConstrainedFrame(glm::quat targetRotation, float priority, bool constrain = false, float mix = 1.0f); + + void setTranslation(const glm::vec3& translation, float priority); + void setVisibleRotationInConstrainedFrame(const glm::quat& targetRotation); const glm::quat& getRotationInConstrainedFrame() const { return _rotationInConstrainedFrame; } const glm::quat& getVisibleRotationInConstrainedFrame() const { return _visibleRotationInConstrainedFrame; } bool rotationIsDefault(const glm::quat& rotation, float tolerance = EPSILON) const; + bool translationIsDefault(const glm::vec3& translation, float tolerance = EPSILON) const; glm::quat getDefaultRotationInParentFrame() const; - const glm::vec3& getDefaultTranslationInConstrainedFrame() const; + glm::vec3 getDefaultTranslationInConstrainedFrame() const; void clearTransformTranslation(); @@ -110,12 +116,13 @@ public: void setTransform(const glm::mat4& transform) { _transform = transform; } void setVisibleTransform(const glm::mat4& transform) { _visibleTransform = transform; } - const glm::vec3& getTranslation() const { return _translation; } + glm::vec3 getTranslation() const { return _translation * _unitsScale; } const glm::mat4& getPreTransform() const { return _preTransform; } const glm::mat4& getPostTransform() const { return _postTransform; } const glm::quat& getPreRotation() const { return _preRotation; } const glm::quat& getPostRotation() const { return _postRotation; } const glm::quat& getDefaultRotation() const { return _defaultRotation; } + glm::vec3 getDefaultTranslation() const { return _defaultTranslation * _unitsScale; } const glm::quat& getInverseDefaultRotation() const { return _inverseDefaultRotation; } const QString& getName() const { return _name; } bool getIsFree() const { return _isFree; } @@ -144,6 +151,7 @@ private: glm::quat _defaultRotation; // Not necessarilly bind rotation. See FBXJoint transform/bindTransform glm::quat _inverseDefaultRotation; + glm::vec3 _defaultTranslation; glm::vec3 _translation; QString _name; int _parentIndex; @@ -155,6 +163,8 @@ private: glm::mat4 _preTransform; glm::mat4 _postTransform; glm::quat _inverseBindRotation; + + glm::vec3 _unitsScale{1.0f, 1.0f, 1.0f}; }; #endif // hifi_JointState_h diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 1874939b3d..eaad5e6bb6 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -270,6 +270,7 @@ void Rig::reset(const QVector& fbxJoints) { } for (int i = 0; i < _jointStates.size(); i++) { _jointStates[i].setRotationInConstrainedFrame(fbxJoints.at(i).rotation, 0.0f); + _jointStates[i].setTranslation(fbxJoints.at(i).translation, 0.0f); } } @@ -289,6 +290,16 @@ bool Rig::getJointStateRotation(int index, glm::quat& rotation) const { return !state.rotationIsDefault(rotation); } +bool Rig::getJointStateTranslation(int index, glm::vec3& translation) const { + if (index == -1 || index >= _jointStates.size()) { + return false; + } + const JointState& state = _jointStates.at(index); + translation = state.getTranslation(); + return !state.translationIsDefault(translation); +} + + bool Rig::getVisibleJointState(int index, glm::quat& rotation) const { if (index == -1 || index >= _jointStates.size()) { return false; @@ -302,6 +313,7 @@ void Rig::clearJointState(int index) { if (index != -1 && index < _jointStates.size()) { JointState& state = _jointStates[index]; state.setRotationInConstrainedFrame(glm::quat(), 0.0f); + state.setTranslation(state.getDefaultTranslationInConstrainedFrame(), 0.0f); } } @@ -328,7 +340,7 @@ void Rig::setJointAnimatinoPriority(int index, float newPriority) { } } -void Rig::setJointState(int index, bool valid, const glm::quat& rotation, float priority) { +void Rig::setJointRotation(int index, bool valid, const glm::quat& rotation, float priority) { if (index != -1 && index < _jointStates.size()) { JointState& state = _jointStates[index]; if (valid) { @@ -345,6 +357,12 @@ void Rig::restoreJointRotation(int index, float fraction, float priority) { } } +void Rig::restoreJointTranslation(int index, float fraction, float priority) { + if (index != -1 && index < _jointStates.size()) { + _jointStates[index].restoreTranslation(fraction, priority); + } +} + bool Rig::getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { @@ -380,6 +398,14 @@ bool Rig::getJointRotation(int jointIndex, glm::quat& rotation) const { return true; } +bool Rig::getJointTranslation(int jointIndex, glm::vec3& translation) const { + if (jointIndex == -1 || jointIndex >= _jointStates.size()) { + return false; + } + translation = _jointStates[jointIndex].getTranslation(); + return true; +} + bool Rig::getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const { if (jointIndex == -1 || jointIndex >= _jointStates.size()) { return false; @@ -590,7 +616,13 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { // copy poses into jointStates const float PRIORITY = 1.0f; for (size_t i = 0; i < poses.size(); i++) { - setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, PRIORITY, false); + setJointRotationInConstrainedFrame((int)i, + glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, + PRIORITY, + false); + + JointState& state = _jointStates[i]; + setJointTranslation((int)i, true, poses[i].trans, PRIORITY); } } else { @@ -866,6 +898,7 @@ bool Rig::restoreJointPosition(int jointIndex, float fraction, float priority, c foreach (int index, freeLineage) { JointState& state = _jointStates[index]; state.restoreRotation(fraction, priority); + state.restoreTranslation(fraction, priority); } return true; } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 90082ca38b..f31d030910 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -123,12 +123,13 @@ public: int rightShoulderJointIndex); bool jointStatesEmpty() { return _jointStates.isEmpty(); }; int getJointStateCount() const { return _jointStates.size(); } - int indexOfJoint(const QString& jointName) ; + int indexOfJoint(const QString& jointName); void initJointTransforms(glm::mat4 rootTransform); void clearJointTransformTranslation(int jointIndex); void reset(const QVector& fbxJoints); bool getJointStateRotation(int index, glm::quat& rotation) const; + bool getJointStateTranslation(int index, glm::vec3& translation) const; void applyJointRotationDelta(int jointIndex, const glm::quat& delta, bool constrain, float priority); JointState getJointState(int jointIndex) const; // XXX bool getVisibleJointState(int index, glm::quat& rotation) const; @@ -137,14 +138,21 @@ public: void clearJointAnimationPriority(int index); float getJointAnimatinoPriority(int index); void setJointAnimatinoPriority(int index, float newPriority); - void setJointState(int index, bool valid, const glm::quat& rotation, float priority); + + virtual void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, + float priority) = 0; + virtual void setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority) {} + void setJointRotation(int index, bool valid, const glm::quat& rotation, float priority); + void restoreJointRotation(int index, float fraction, float priority); + void restoreJointTranslation(int index, float fraction, float priority); bool getJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const; bool getJointPosition(int jointIndex, glm::vec3& position) const; bool getJointRotationInWorldFrame(int jointIndex, glm::quat& result, const glm::quat& rotation) const; bool getJointRotation(int jointIndex, glm::quat& rotation) const; + bool getJointTranslation(int jointIndex, glm::vec3& translation) const; bool getJointCombinedRotation(int jointIndex, glm::quat& result, const glm::quat& rotation) const; bool getVisibleJointPositionInWorldFrame(int jointIndex, glm::vec3& position, glm::vec3 translation, glm::quat rotation) const; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 104b592c1a..3ef53e245b 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -49,6 +49,7 @@ AvatarData::AvatarData() : _keyState(NO_KEY_DOWN), _forceFaceTrackerConnected(false), _hasNewJointRotations(true), + _hasNewJointTranslations(true), _headData(NULL), _handData(NULL), _faceModelURL("http://invalid.com"), @@ -278,12 +279,16 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { // pupil dilation destinationBuffer += packFloatToByte(destinationBuffer, _headData->_pupilDilation, 1.0f); - // joint data + // joint rotation data *destinationBuffer++ = _jointData.size(); unsigned char* validityPosition = destinationBuffer; unsigned char validity = 0; int validityBit = 0; + #ifdef WANT_DEBUG + int rotationSentCount = 0; + #endif + _lastSentJointData.resize(_jointData.size()); for (int i=0; i < _jointData.size(); i++) { @@ -292,7 +297,12 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { if (sendAll || !cullSmallChanges || fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= AVATAR_MIN_ROTATION_DOT) { - validity |= (1 << validityBit); + if (data.rotationSet) { + validity |= (1 << validityBit); + #ifdef WANT_DEBUG + rotationSentCount++; + #endif + } } } if (++validityBit == BITS_IN_BYTE) { @@ -317,6 +327,73 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) { } } + + // joint translation data + validityPosition = destinationBuffer; + validity = 0; + validityBit = 0; + + #ifdef WANT_DEBUG + int translationSentCount = 0; + #endif + + float maxTranslationDimension = 0.0; + for (int i=0; i < _jointData.size(); i++) { + const JointData& data = _jointData.at(i); + if (sendAll || _lastSentJointData[i].translation != data.translation) { + if (sendAll || + !cullSmallChanges || + glm::distance(data.translation, _lastSentJointData[i].translation) > AVATAR_MIN_TRANSLATION) { + if (data.translationSet) { + validity |= (1 << validityBit); + #ifdef WANT_DEBUG + translationSentCount++; + #endif + maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension); + maxTranslationDimension = glm::max(fabsf(data.translation.y), maxTranslationDimension); + maxTranslationDimension = glm::max(fabsf(data.translation.z), maxTranslationDimension); + } + } + } + if (++validityBit == BITS_IN_BYTE) { + *destinationBuffer++ = validity; + validityBit = validity = 0; + } + } + + + if (validityBit != 0) { + *destinationBuffer++ = validity; + } + + // TODO -- automatically pick translationCompressionRadix + int translationCompressionRadix = 12; + + *destinationBuffer++ = translationCompressionRadix; + + validityBit = 0; + validity = *validityPosition++; + for (int i = 0; i < _jointData.size(); i ++) { + const JointData& data = _jointData[ i ]; + if (validity & (1 << validityBit)) { + destinationBuffer += + packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, translationCompressionRadix); + } + if (++validityBit == BITS_IN_BYTE) { + validityBit = 0; + validity = *validityPosition++; + } + } + + #ifdef WANT_DEBUG + if (sendAll) { + qDebug() << "SENDING -- rotations:" << rotationSentCount << "translations:" << translationSentCount + << "largest:" << maxTranslationDimension + << "radix:" << translationCompressionRadix + << "size:" << (int)(destinationBuffer - startPosition); + } + #endif + return avatarDataByteArray.left(destinationBuffer - startPosition); } @@ -328,7 +405,16 @@ void AvatarData::doneEncoding(bool cullSmallChanges) { if (_lastSentJointData[i].rotation != data.rotation) { if (!cullSmallChanges || fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= AVATAR_MIN_ROTATION_DOT) { - _lastSentJointData[i].rotation = data.rotation; + if (data.rotationSet) { + _lastSentJointData[i].rotation = data.rotation; + } + } + + if (!cullSmallChanges || + glm::distance(data.translation, _lastSentJointData[i].translation) > AVATAR_MIN_TRANSLATION) { + if (data.translationSet) { + _lastSentJointData[i].translation = data.translation; + } } } } @@ -374,7 +460,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { // + 1 byte for numJoints (0) // = 39 bytes int minPossibleSize = 39; - + int maxAvailableSize = buffer.size(); if (minPossibleSize > maxAvailableSize) { if (shouldLogError(now)) { @@ -556,7 +642,11 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { sourceBuffer += unpackFloatFromByte(sourceBuffer, _headData->_pupilDilation, 1.0f); } // 1 byte - // joint data + + //----------------------- + // joint rotations + //----------------------- + int numJoints = *sourceBuffer++; int bytesOfValidity = (int)ceil((float)numJoints / (float)BITS_IN_BYTE); minPossibleSize += bytesOfValidity; @@ -569,13 +659,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } return maxAvailableSize; } - int numValidJoints = 0; + int numValidJointRotations = 0; _jointData.resize(numJoints); - QVector valids; - valids.resize(numJoints); + QVector validRotations; + validRotations.resize(numJoints); - { // validity bits + { // rotation validity bits unsigned char validity = 0; int validityBit = 0; for (int i = 0; i < numJoints; i++) { @@ -584,20 +674,19 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } bool valid = (bool)(validity & (1 << validityBit)); if (valid) { - ++numValidJoints; + ++numValidJointRotations; } - valids[i] = valid; + validRotations[i] = valid; validityBit = (validityBit + 1) % BITS_IN_BYTE; } - } - // 1 + bytesOfValidity bytes + } // 1 + bytesOfValidity bytes // each joint rotation component is stored in two bytes (sizeof(uint16_t)) int COMPONENTS_PER_QUATERNION = 4; - minPossibleSize += numValidJoints * COMPONENTS_PER_QUATERNION * sizeof(uint16_t); + minPossibleSize += numValidJointRotations * COMPONENTS_PER_QUATERNION * sizeof(uint16_t); if (minPossibleSize > maxAvailableSize) { if (shouldLogError(now)) { - qCDebug(avatars) << "Malformed AvatarData packet after JointData;" + qCDebug(avatars) << "Malformed AvatarData packet after JointData rotation validity;" << " displayName = '" << _displayName << "'" << " minPossibleSize = " << minPossibleSize << " maxAvailableSize = " << maxAvailableSize; @@ -608,13 +697,75 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { { // joint data for (int i = 0; i < numJoints; i++) { JointData& data = _jointData[i]; - if (valids[i]) { + if (validRotations[i]) { _hasNewJointRotations = true; + data.rotationSet = true; sourceBuffer += unpackOrientationQuatFromBytes(sourceBuffer, data.rotation); } } } // numJoints * 8 bytes + + //----------------------- + // joint translations + //----------------------- + + // get translation validity bits -- these indicate which translations were packed + int numValidJointTranslations = 0; + QVector validTranslations; + validTranslations.resize(numJoints); + + { // translation validity bits + unsigned char validity = 0; + int validityBit = 0; + for (int i = 0; i < numJoints; i++) { + if (validityBit == 0) { + validity = *sourceBuffer++; + } + bool valid = (bool)(validity & (1 << validityBit)); + if (valid) { + ++numValidJointTranslations; + } + validTranslations[i] = valid; + validityBit = (validityBit + 1) % BITS_IN_BYTE; + } + } // 1 + bytesOfValidity bytes + + // each joint translation component is stored in 6 bytes. 1 byte for translationCompressionRadix + minPossibleSize += numValidJointTranslations * 6 + 1; + if (minPossibleSize > maxAvailableSize) { + if (shouldLogError(now)) { + qCDebug(avatars) << "Malformed AvatarData packet after JointData translation validity;" + << " displayName = '" << _displayName << "'" + << " minPossibleSize = " << minPossibleSize + << " maxAvailableSize = " << maxAvailableSize; + } + return maxAvailableSize; + } + + int translationCompressionRadix = *sourceBuffer++; + + { // joint data + for (int i = 0; i < numJoints; i++) { + JointData& data = _jointData[i]; + if (validTranslations[i]) { + sourceBuffer += + unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, data.translation, translationCompressionRadix); + _hasNewJointTranslations = true; + data.translationSet = true; + } + } + } // numJoints * 12 bytes + + #ifdef WANT_DEBUG + if (numValidJointRotations > 15) { + qDebug() << "RECEIVING -- rotations:" << numValidJointRotations + << "translations:" << numValidJointTranslations + << "radix:" << translationCompressionRadix + << "size:" << (int)(sourceBuffer - startPosition); + } + #endif + int numBytesRead = sourceBuffer - startPosition; _averageBytesReceived.updateAverage(numBytesRead); return numBytesRead; @@ -800,7 +951,7 @@ void AvatarData::changeReferential(Referential* ref) { _referential = ref; } -void AvatarData::setJointData(int index, const glm::quat& rotation) { +void AvatarData::setJointData(int index, const glm::quat& rotation, const glm::vec3& translation) { if (index == -1) { return; } @@ -813,6 +964,7 @@ void AvatarData::setJointData(int index, const glm::quat& rotation) { } JointData& data = _jointData[index]; data.rotation = rotation; + data.translation = translation; } void AvatarData::clearJointData(int index) { @@ -854,13 +1006,67 @@ glm::quat AvatarData::getJointRotation(int index) const { return index < _jointData.size() ? _jointData.at(index).rotation : glm::quat(); } -void AvatarData::setJointData(const QString& name, const glm::quat& rotation) { + +glm::vec3 AvatarData::getJointTranslation(int index) const { + if (index == -1) { + return glm::vec3(); + } + if (QThread::currentThread() != thread()) { + glm::vec3 result; + QMetaObject::invokeMethod(const_cast(this), "getJointTranslation", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(glm::vec3, result), Q_ARG(int, index)); + return result; + } + return index < _jointData.size() ? _jointData.at(index).translation : glm::vec3(); +} + +glm::vec3 AvatarData::getJointTranslation(const QString& name) const { + if (QThread::currentThread() != thread()) { + glm::vec3 result; + QMetaObject::invokeMethod(const_cast(this), "getJointTranslation", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(glm::vec3, result), Q_ARG(const QString&, name)); + return result; + } + return getJointTranslation(getJointIndex(name)); +} + +void AvatarData::setJointData(const QString& name, const glm::quat& rotation, const glm::vec3& translation) { if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "setJointData", Q_ARG(const QString&, name), Q_ARG(const glm::quat&, rotation)); return; } - setJointData(getJointIndex(name), rotation); + setJointData(getJointIndex(name), rotation, translation); +} + +void AvatarData::setJointRotation(int index, const glm::quat& rotation) { + if (index == -1) { + return; + } + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setJointRotation", Q_ARG(int, index), Q_ARG(const glm::quat&, rotation)); + return; + } + if (_jointData.size() <= index) { + _jointData.resize(index + 1); + } + JointData& data = _jointData[index]; + data.rotation = rotation; +} + +void AvatarData::setJointTranslation(int index, const glm::vec3& translation) { + if (index == -1) { + return; + } + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "setJointTranslation", Q_ARG(int, index), Q_ARG(const glm::vec3&, translation)); + return; + } + if (_jointData.size() <= index) { + _jointData.resize(index + 1); + } + JointData& data = _jointData[index]; + data.translation = translation; } void AvatarData::clearJointData(const QString& name) { @@ -918,7 +1124,25 @@ void AvatarData::setJointRotations(QVector jointRotations) { } for (int i = 0; i < jointRotations.size(); ++i) { if (i < _jointData.size()) { - setJointData(i, jointRotations[i]); + setJointRotation(i, jointRotations[i]); + } + } +} + +void AvatarData::setJointTranslations(QVector jointTranslations) { + if (QThread::currentThread() != thread()) { + QVector result; + QMetaObject::invokeMethod(const_cast(this), + "setJointTranslations", Qt::BlockingQueuedConnection, + Q_ARG(QVector, jointTranslations)); + } + + if (_jointData.size() < jointTranslations.size()) { + _jointData.resize(jointTranslations.size()); + } + for (int i = 0; i < jointTranslations.size(); ++i) { + if (i < _jointData.size()) { + setJointTranslation(i, jointTranslations[i]); } } } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index a934b98037..e4022fd474 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -117,6 +117,7 @@ const QString DEFAULT_FULL_AVATAR_MODEL_NAME = QString("Default"); const float AVATAR_SEND_FULL_UPDATE_RATIO = 0.02f; // this controls how large a change in joint-rotation must be before the interface sends it to the avatar mixer const float AVATAR_MIN_ROTATION_DOT = 0.9999999f; +const float AVATAR_MIN_TRANSLATION = 0.0001f; // Where one's own Avatar begins in the world (will be overwritten if avatar data file is found). @@ -240,20 +241,24 @@ public: Q_INVOKABLE char getHandState() const { return _handState; } const QVector& getJointData() const { return _jointData; } - void setJointData(const QVector& jointData) { _jointData = jointData; } - Q_INVOKABLE virtual void setJointData(int index, const glm::quat& rotation); + Q_INVOKABLE virtual void setJointData(int index, const glm::quat& rotation, const glm::vec3& translation); + Q_INVOKABLE virtual void setJointRotation(int index, const glm::quat& rotation); + Q_INVOKABLE virtual void setJointTranslation(int index, const glm::vec3& translation); Q_INVOKABLE virtual void clearJointData(int index); Q_INVOKABLE bool isJointDataValid(int index) const; Q_INVOKABLE virtual glm::quat getJointRotation(int index) const; + Q_INVOKABLE virtual glm::vec3 getJointTranslation(int index) const; - Q_INVOKABLE void setJointData(const QString& name, const glm::quat& rotation); + Q_INVOKABLE void setJointData(const QString& name, const glm::quat& rotation, const glm::vec3& translation); Q_INVOKABLE void clearJointData(const QString& name); Q_INVOKABLE bool isJointDataValid(const QString& name) const; Q_INVOKABLE glm::quat getJointRotation(const QString& name) const; + Q_INVOKABLE glm::vec3 getJointTranslation(const QString& name) const; Q_INVOKABLE virtual QVector getJointRotations() const; Q_INVOKABLE virtual void setJointRotations(QVector jointRotations); + Q_INVOKABLE virtual void setJointTranslations(QVector jointTranslations); Q_INVOKABLE virtual void clearJointsData(); @@ -387,6 +392,7 @@ protected: bool _forceFaceTrackerConnected; bool _hasNewJointRotations; // set in AvatarData, cleared in Avatar + bool _hasNewJointTranslations; // set in AvatarData, cleared in Avatar HeadData* _headData; HandData* _handData; @@ -435,6 +441,9 @@ Q_DECLARE_METATYPE(AvatarData*) class JointData { public: glm::quat rotation; + bool rotationSet = false; + glm::vec3 translation; + bool translationSet = false; }; class AttachmentData { diff --git a/libraries/avatars/src/Player.cpp b/libraries/avatars/src/Player.cpp index 29544924b2..a425323a41 100644 --- a/libraries/avatars/src/Player.cpp +++ b/libraries/avatars/src/Player.cpp @@ -254,8 +254,17 @@ void Player::play() { nextFrame.getJointRotations()[i], _frameInterpolationFactor); } + + QVector jointTranslations(currentFrame.getJointTranslations().size()); + for (int i = 0; i < currentFrame.getJointTranslations().size(); ++i) { + jointTranslations[i] = + currentFrame.getJointTranslations()[i] * (1.0f - _frameInterpolationFactor) + + nextFrame.getJointTranslations()[i] * _frameInterpolationFactor; + } + _avatar->setJointRotations(jointRotations); - + _avatar->setJointTranslations(jointTranslations); + HeadData* head = const_cast(_avatar->getHeadData()); if (head) { // Make sure fake face tracker connection doesn't get turned off diff --git a/libraries/avatars/src/Recording.cpp b/libraries/avatars/src/Recording.cpp index 76e1d68050..2c87485d01 100644 --- a/libraries/avatars/src/Recording.cpp +++ b/libraries/avatars/src/Recording.cpp @@ -239,6 +239,7 @@ void writeRecordingToFile(RecordingPointer recording, const QString& filename) { if (i == 0 || frame._jointRotations[j] != previousFrame._jointRotations[j]) { writeQuat(stream, frame._jointRotations[j]); + // XXX handle translations mask.setBit(maskIndex); } maskIndex++; @@ -561,7 +562,10 @@ RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString frame._jointRotations[j] = previousFrame._jointRotations[j]; } } - + + // XXX handle translations + + if (!mask[maskIndex++] || !readVec3(stream, frame._translation)) { frame._translation = previousFrame._translation; } @@ -670,7 +674,9 @@ RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QStr for (int i = 0; i < jointRotationSize; ++i) { fileStream >> baseFrame._jointRotations[i].x >> baseFrame._jointRotations[i].y >> baseFrame._jointRotations[i].z >> baseFrame._jointRotations[i].w; } - + + // XXX handle translations + fileStream >> baseFrame._translation.x >> baseFrame._translation.y >> baseFrame._translation.z; fileStream >> baseFrame._rotation.x >> baseFrame._rotation.y >> baseFrame._rotation.z >> baseFrame._rotation.w; fileStream >> baseFrame._scale; @@ -736,7 +742,9 @@ RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QStr frame._jointRotations[i] = previousFrame._jointRotations[i]; } } - + + // XXX handle translations + if (mask[maskIndex++]) { stream >> frame._translation.x >> frame._translation.y >> frame._translation.z; frame._translation = context.orientationInv * frame._translation; diff --git a/libraries/avatars/src/Recording.h b/libraries/avatars/src/Recording.h index 49d12ec5b5..3533af6535 100644 --- a/libraries/avatars/src/Recording.h +++ b/libraries/avatars/src/Recording.h @@ -83,6 +83,7 @@ class RecordingFrame { public: QVector getBlendshapeCoefficients() const { return _blendshapeCoefficients; } QVector getJointRotations() const { return _jointRotations; } + QVector getJointTranslations() const { return _jointTranslations; } glm::vec3 getTranslation() const { return _translation; } glm::quat getRotation() const { return _rotation; } float getScale() const { return _scale; } @@ -94,6 +95,7 @@ public: protected: void setBlendshapeCoefficients(QVector blendshapeCoefficients); void setJointRotations(QVector jointRotations) { _jointRotations = jointRotations; } + void setJointTranslations(QVector jointTranslations) { _jointTranslations = jointTranslations; } void setTranslation(const glm::vec3& translation) { _translation = translation; } void setRotation(const glm::quat& rotation) { _rotation = rotation; } void setScale(float scale) { _scale = scale; } @@ -105,6 +107,7 @@ protected: private: QVector _blendshapeCoefficients; QVector _jointRotations; + QVector _jointTranslations; glm::vec3 _translation; glm::quat _rotation; float _scale; @@ -124,4 +127,4 @@ void writeRecordingToFile(RecordingPointer recording, const QString& filename); RecordingPointer readRecordingFromFile(RecordingPointer recording, const QString& filename); RecordingPointer readRecordingFromRecFile(RecordingPointer recording, const QString& filename, const QByteArray& byteArray); -#endif // hifi_Recording_h \ No newline at end of file +#endif // hifi_Recording_h diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 74317b7eff..6d7399b07a 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -276,10 +276,13 @@ void RenderableModelEntityItem::render(RenderArgs* args) { if (jointsMapped()) { bool newFrame; - auto frameData = getAnimationFrame(newFrame); + QVector frameDataRotations; + QVector frameDataTranslations; + getAnimationFrame(newFrame, frameDataRotations, frameDataTranslations); + assert(frameDataRotations.size() == frameDataTranslations.size()); if (newFrame) { - for (int i = 0; i < frameData.size(); i++) { - _model->setJointState(i, true, frameData[i]); + for (int i = 0; i < frameDataRotations.size(); i++) { + _model->setJointState(i, true, frameDataRotations[i], frameDataTranslations[i], 1.0f); } } } diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 70747937d8..44b4aa99bf 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -218,18 +218,20 @@ void ModelEntityItem::mapJoints(const QStringList& modelJointNames) { } } -const QVector& ModelEntityItem::getAnimationFrame(bool& newFrame) { +void ModelEntityItem::getAnimationFrame(bool& newFrame, + QVector& rotationsResult, QVector& translationsResult) { newFrame = false; if (!hasAnimation() || !_jointMappingCompleted) { - return _lastKnownFrameData; + rotationsResult = _lastKnownFrameDataRotations; + translationsResult = _lastKnownFrameDataTranslations; } - + AnimationPointer myAnimation = getAnimation(_animationURL); // FIXME: this could be optimized if (myAnimation && myAnimation->isLoaded()) { - + const QVector& frames = myAnimation->getFramesReference(); // NOTE: getFrames() is too heavy - + int frameCount = frames.size(); if (frameCount > 0) { int animationFrameIndex = (int)(glm::floor(getAnimationFrameIndex())) % frameCount; @@ -240,20 +242,27 @@ const QVector& ModelEntityItem::getAnimationFrame(bool& newFrame) { if (animationFrameIndex != _lastKnownFrameIndex) { _lastKnownFrameIndex = animationFrameIndex; newFrame = true; - - const QVector& rotations = frames[animationFrameIndex].rotations; - _lastKnownFrameData.resize(_jointMapping.size()); + const QVector& rotations = frames[animationFrameIndex].rotations; + const QVector& translations = frames[animationFrameIndex].translations; + + _lastKnownFrameDataRotations.resize(_jointMapping.size()); + _lastKnownFrameDataTranslations.resize(_jointMapping.size()); for (int j = 0; j < _jointMapping.size(); j++) { - int rotationIndex = _jointMapping[j]; - if (rotationIndex != -1 && rotationIndex < rotations.size()) { - _lastKnownFrameData[j] = rotations[rotationIndex]; + int index = _jointMapping[j]; + if (index != -1 && index < rotations.size()) { + _lastKnownFrameDataRotations[j] = rotations[index]; + } + if (index != -1 && index < translations.size()) { + _lastKnownFrameDataTranslations[j] = translations[index]; } } } } } - return _lastKnownFrameData; + + rotationsResult = _lastKnownFrameDataRotations; + translationsResult = _lastKnownFrameDataTranslations; } bool ModelEntityItem::isAnimatingSomething() const { diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index bf6d7a9785..8bf6658bf3 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -106,7 +106,7 @@ public: float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); } void mapJoints(const QStringList& modelJointNames); - const QVector& getAnimationFrame(bool& newFrame); + void getAnimationFrame(bool& newFrame, QVector& rotationsResult, QVector& translationsResult); bool jointsMapped() const { return _jointMappingCompleted; } bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); } @@ -123,7 +123,8 @@ public: static void cleanupLoadedAnimations(); protected: - QVector _lastKnownFrameData; + QVector _lastKnownFrameDataRotations; + QVector _lastKnownFrameDataTranslations; int _lastKnownFrameIndex; diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index da240e826a..1accbf4238 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -530,6 +530,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS QHash typeFlags; QHash localRotations; + QHash localTranslations; QHash xComponents; QHash yComponents; QHash zComponents; @@ -1104,16 +1105,16 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS normalTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); } else if (type.contains("specular") || type.contains("reflection")) { specularTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1)); - + } else if (type == "lcl rotation") { localRotations.insert(getID(connection.properties, 2), getID(connection.properties, 1)); - + } else if (type == "lcl translation") { + localTranslations.insert(getID(connection.properties, 2), getID(connection.properties, 1)); + } else if (type == "d|x") { xComponents.insert(getID(connection.properties, 2), getID(connection.properties, 1)); - } else if (type == "d|y") { yComponents.insert(getID(connection.properties, 2), getID(connection.properties, 1)); - } else if (type == "d|z") { zComponents.insert(getID(connection.properties, 2), getID(connection.properties, 1)); @@ -1224,6 +1225,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS for (int i = 0; i < frameCount; i++) { FBXAnimationFrame frame; frame.rotations.resize(modelIDs.size()); + frame.translations.resize(modelIDs.size()); geometry.animationFrames.append(frame); } @@ -1247,7 +1249,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS joint.freeLineage.append(index); } joint.freeLineage.remove(lastFreeIndex + 1, joint.freeLineage.size() - lastFreeIndex - 1); - joint.translation = model.translation; + joint.translation = model.translation; // these are usually in centimeters joint.preTransform = model.preTransform; joint.preRotation = model.preRotation; joint.rotation = model.rotation; @@ -1272,7 +1274,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } joint.inverseBindRotation = joint.inverseDefaultRotation; joint.name = model.name; - + foreach (const QString& childID, _connectionChildMap.values(modelID)) { QString type = typeFlags.value(childID); if (!type.isEmpty()) { @@ -1285,17 +1287,28 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS geometry.joints.append(joint); geometry.jointIndices.insert(model.name, geometry.joints.size()); - + QString rotationID = localRotations.value(modelID); - AnimationCurve xCurve = animationCurves.value(xComponents.value(rotationID)); - AnimationCurve yCurve = animationCurves.value(yComponents.value(rotationID)); - AnimationCurve zCurve = animationCurves.value(zComponents.value(rotationID)); + AnimationCurve xRotCurve = animationCurves.value(xComponents.value(rotationID)); + AnimationCurve yRotCurve = animationCurves.value(yComponents.value(rotationID)); + AnimationCurve zRotCurve = animationCurves.value(zComponents.value(rotationID)); + + QString translationID = localTranslations.value(modelID); + AnimationCurve xPosCurve = animationCurves.value(xComponents.value(translationID)); + AnimationCurve yPosCurve = animationCurves.value(yComponents.value(translationID)); + AnimationCurve zPosCurve = animationCurves.value(zComponents.value(translationID)); + glm::vec3 defaultValues = glm::degrees(safeEulerAngles(joint.rotation)); + for (int i = 0; i < frameCount; i++) { geometry.animationFrames[i].rotations[jointIndex] = glm::quat(glm::radians(glm::vec3( - xCurve.values.isEmpty() ? defaultValues.x : xCurve.values.at(i % xCurve.values.size()), - yCurve.values.isEmpty() ? defaultValues.y : yCurve.values.at(i % yCurve.values.size()), - zCurve.values.isEmpty() ? defaultValues.z : zCurve.values.at(i % zCurve.values.size())))); + xRotCurve.values.isEmpty() ? defaultValues.x : xRotCurve.values.at(i % xRotCurve.values.size()), + yRotCurve.values.isEmpty() ? defaultValues.y : yRotCurve.values.at(i % yRotCurve.values.size()), + zRotCurve.values.isEmpty() ? defaultValues.z : zRotCurve.values.at(i % zRotCurve.values.size())))); + geometry.animationFrames[i].translations[jointIndex] = glm::vec3( + xPosCurve.values.isEmpty() ? defaultValues.x : xPosCurve.values.at(i % xPosCurve.values.size()), + yPosCurve.values.isEmpty() ? defaultValues.y : yPosCurve.values.at(i % yPosCurve.values.size()), + zPosCurve.values.isEmpty() ? defaultValues.z : zPosCurve.values.at(i % zPosCurve.values.size())); } } diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 5cfff9826f..20f8fffe44 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -208,8 +208,8 @@ public: /// A single animation frame extracted from an FBX document. class FBXAnimationFrame { public: - QVector rotations; + QVector translations; }; /// A light in an FBX document. diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index a8cf743686..ca75a86158 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -39,6 +39,9 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityEdit: case PacketType::EntityData: return VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER; + case PacketType::AvatarData: + case PacketType::BulkAvatarData: + return 15; default: return 14; } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 7aee46b108..34896d5714 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1001,8 +1001,16 @@ void Model::clearJointState(int index) { _rig->clearJointState(index); } -void Model::setJointState(int index, bool valid, const glm::quat& rotation, float priority) { - _rig->setJointState(index, valid, rotation, priority); +void Model::setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority) { + _rig->setJointState(index, valid, rotation, translation, priority); +} + +void Model::setJointRotation(int index, bool valid, const glm::quat& rotation, float priority) { + _rig->setJointRotation(index, valid, rotation, priority); +} + +void Model::setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority) { + _rig->setJointTranslation(index, valid, translation, priority); } int Model::getParentJointIndex(int jointIndex) const { @@ -1074,6 +1082,10 @@ bool Model::getJointRotation(int jointIndex, glm::quat& rotation) const { return _rig->getJointRotation(jointIndex, rotation); } +bool Model::getJointTranslation(int jointIndex, glm::vec3& translation) const { + return _rig->getJointTranslation(jointIndex, translation); +} + bool Model::getJointCombinedRotation(int jointIndex, glm::quat& rotation) const { return _rig->getJointCombinedRotation(jointIndex, rotation, _rotation); } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index de760dc793..460bc4f044 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -126,7 +126,9 @@ public: QStringList getJointNames() const; /// Sets the joint state at the specified index. - void setJointState(int index, bool valid, const glm::quat& rotation = glm::quat(), float priority = 1.0f); + void setJointState(int index, bool valid, const glm::quat& rotation, const glm::vec3& translation, float priority); + void setJointRotation(int index, bool valid, const glm::quat& rotation, float priority); + void setJointTranslation(int index, bool valid, const glm::vec3& translation, float priority); bool findRayIntersectionAgainstSubMeshes(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, QString& extraInfo, bool pickAgainstTriangles = false); @@ -160,6 +162,7 @@ public: /// \param rotation[out] rotation of joint in model-frame /// \return true if joint exists bool getJointRotation(int jointIndex, glm::quat& rotation) const; + bool getJointTranslation(int jointIndex, glm::vec3& translation) const; /// Returns the index of the parent of the indexed joint, or -1 if not found. int getParentJointIndex(int jointIndex) const; diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index 7d56157e53..31a6096d13 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -33,6 +33,8 @@ const vec3& Vectors::RIGHT = Vectors::UNIT_X; const vec3& Vectors::UP = Vectors::UNIT_Y; const vec3& Vectors::FRONT = Vectors::UNIT_NEG_Z; +const quat Quaternions::ZERO{ 1.0f, 0.0f, 0.0f, 0.0f }; + // Safe version of glm::mix; based on the code in Nick Bobick's article, // http://www.gamasutra.com/features/19980703/quaternions_01.htm (via Clyde, // https://github.com/threerings/clyde/blob/master/src/main/java/com/threerings/math/Quaternion.java) diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 6683088306..e2833b46e3 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -53,6 +53,12 @@ const glm::vec3 IDENTITY_FRONT = glm::vec3( 0.0f, 0.0f,-1.0f); glm::quat safeMix(const glm::quat& q1, const glm::quat& q2, float alpha); + +class Quaternions { + public: + static const quat ZERO; +}; + class Vectors { public: static const vec3 UNIT_X; From 46fabf964dfdc61288279521ed1a58a959697414 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 11:54:57 -0700 Subject: [PATCH 089/212] cleanup --- examples/particle_explorer/main.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 057932f309..f98c09a321 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -111,7 +111,6 @@ window.onload = function() { controller.shouldGroup = false; } - //keep track of our controller controllers.push(controller); @@ -135,17 +134,15 @@ function writeDataToInterface(property, value, shouldGroup) { var group = null; var groupProperty = null; var groupProperties = null; + if (shouldGroup) { var separated = property.slice(0, property.indexOf('_group')).split("_") group = separated[0]; groupProperty = separated[1]; - var groupString = group.toString(); - var groupPropertyString = groupProperty.toString(); var groupProperties = {} groupProperties[group] = {}; groupProperties[group][groupProperty] = value // console.log(groupProperties) - } var data = { From f84762f2d7adabbbef8608852f402e5aaf16cde0 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:02:59 -0700 Subject: [PATCH 090/212] remove old gui file --- examples/particle_explorer/old.html | 1607 --------------------------- 1 file changed, 1607 deletions(-) delete mode 100644 examples/particle_explorer/old.html diff --git a/examples/particle_explorer/old.html b/examples/particle_explorer/old.html deleted file mode 100644 index f2d91bda70..0000000000 --- a/examples/particle_explorer/old.html +++ /dev/null @@ -1,1607 +0,0 @@ - - - Properties - - - - - - - - -
    -
    -
    - -
    -
    -
    - - - -
    - -
    -
    -
    - Name -
    - -
    -
    - -
    - Locked - - - -
    - -
    - Visible - - - -
    - -
    -
    User Data
    -
    - -
    -
    - - -
    - -
    - -
    -
    Href
    -
    - -
    -
    -
    -
    Description
    -
    - -
    -
    - - -
    - -
    - -
    -
    Position
    -
    -
    X
    -
    Y
    -
    Z
    -
    - - -
    -
    -
    - -
    -
    Registration
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    - -
    -
    Dimensions
    -
    -
    X
    -
    Y
    -
    Z
    -
    - -
    -
    - % -
    - - - -
    -
    - -
    -
    Voxel Volume Size
    -
    -
    X
    -
    Y
    -
    Z
    -
    - -
    Surface Extractor
    -
    - -
    - -
    X-axis Texture URL
    -
    - -
    - -
    Y-axis Texture URL
    -
    - -
    - -
    Z-axis Texture URL
    -
    - -
    -
    - -
    -
    Rotation
    -
    -
    Pitch
    -
    Yaw
    -
    Roll
    -
    -
    - - -
    - -
    - -
    -
    Linear Velocity
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    -
    -
    Linear Damping
    -
    - -
    -
    -
    -
    Angular Velocity
    -
    -
    Pitch
    -
    Yaw
    -
    Roll
    -
    -
    -
    -
    Angular Damping
    -
    - -
    -
    -
    -
    Restitution
    -
    - -
    -
    -
    -
    Friction
    -
    - -
    -
    - -
    -
    Gravity
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    - -
    -
    Acceleration
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    - -
    -
    Density
    -
    - -
    -
    - -
    -
    Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    - - -
    - -
    - -
    - Ignore For Collisions - - - -
    - -
    - Collisions Will Move - - - -
    - -
    -
    Collision Sound URL
    -
    - -
    -
    - -
    -
    Lifetime
    -
    - -
    -
    - -
    -
    Script URL - - -
    -
    - -
    -
    - - -
    - -
    - -
    -
    Model URL
    -
    - -
    -
    - -
    -
    Shape Type
    -
    - -
    -
    -
    -
    Compound Shape URL
    -
    - -
    -
    -
    -
    Animation URL
    -
    - -
    -
    -
    - Animation Playing - - - -
    -
    -
    Animation FPS
    -
    - -
    -
    -
    -
    Animation Frame
    -
    - -
    -
    -
    -
    Animation Settings
    -
    - -
    -
    -
    -
    Textures
    -
    - -
    -
    -
    -
    Original Textures
    -
    - -
    -
    - - -
    - -
    - -
    -
    Source URL
    -
    - -
    -
    - - -
    - -
    - -
    -
    Max Particles
    -
    - -
    -
    -
    -
    Particle Life Span
    -
    - -
    -
    -
    -
    Particle Emission Rate
    -
    - -
    -
    -
    -
    Particle Emission Direction
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    -
    -
    Particle Emission Strength
    -
    - -
    -
    -
    -
    Particle Local Gravity
    -
    - -
    -
    -
    -
    Particle Radius
    -
    - -
    -
    - - -
    - -
    - -
    -
    Text Content
    -
    - -
    -
    -
    -
    Line Height
    -
    - -
    -
    -
    -
    Text Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    -
    -
    Background Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    - - -
    - -
    - -
    - Spot Light - - - -
    -
    -
    Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    -
    -
    Intensity
    -
    - -
    -
    -
    -
    Spot Light Exponent
    -
    - -
    -
    -
    -
    Spot Light Cutoff (degrees)
    -
    - -
    -
    - - -
    - -
    - -
    - Stage Sun Model Enabled - - - -
    - -
    -
    Key Light Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    -
    -
    Key Light Intensity
    -
    - -
    -
    -
    -
    Key Light Ambient Intensity
    -
    - -
    -
    -
    -
    Key Light Direction
    -
    -
    Pitch
    -
    Yaw
    -
    Roll
    -
    -
    - -
    -
    Stage Latitude
    -
    - -
    -
    -
    -
    Stage Longitude
    -
    - -
    -
    -
    -
    Stage Altitude
    -
    - -
    -
    - -
    - Automatically calculate stage hour and day from location and clock. - - - -
    - -
    -
    Stage Day
    -
    - -
    -
    -
    -
    Stage Hour
    -
    - -
    -
    - -
    -
    Background Mode
    -
    - -
    -
    - - -
    - -
    - -
    -
    Skybox Color
    -
    -
    -
    R
    -
    G
    -
    B
    -
    -
    -
    -
    Skybox URL
    -
    - -
    -
    - - -
    - -
    - -
    -
    Atmosphere Center
    -
    -
    X
    -
    Y
    -
    Z
    -
    - -
    -
    -
    -
    -
    Atmosphere Inner Radius
    -
    - -
    -
    -
    -
    Atmosphere Outer Radius
    -
    - -
    -
    -
    -
    Atmosphere Mie Scattering
    -
    - -
    -
    -
    -
    Atmosphere Rayleigh Scattering
    -
    - -
    -
    -
    -
    Atmosphere Scattering Wavelenghts
    -
    -
    X
    -
    Y
    -
    Z
    -
    -
    - -
    - - \ No newline at end of file From f3c13f5d691208421663e7ecc1f74e3ed6a8feab Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:18:20 -0700 Subject: [PATCH 091/212] do grouping differently so names look better --- examples/particle_explorer/main.js | 76 +++++++++++++++++++----------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index f98c09a321..ba6938ee23 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -25,6 +25,17 @@ function radiansToDegrees(radians) { // property_subproperty_group = value // i.e. color_red_group = 0; +var groups = [ +'accelerationSpread', +'color', +'colorSpread', +'colorStart', +'colorFinish', +'emitAcceleration', +'emitDimensions', +'emitOrientation' +] + var ParticleExplorer = function() { this.animationIsPlaying = true; this.textures = "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"; @@ -32,36 +43,36 @@ var ParticleExplorer = function() { this.visible = false; this.locked = false; this.lifetime = 3600 // 1 hour; just in case - this.accelerationSpread_x_group = 0.1; - this.accelerationSpread_y_group = 0.1; - this.accelerationSpread_z_group = 0.1; + this.accelerationSpread_x = 0.1; + this.accelerationSpread_y = 0.1; + this.accelerationSpread_z = 0.1; this.alpha = 0.5; this.alphaStart = 1.0; this.alphaFinish = 0.1; - this.color_red_group = 0; - this.color_green_group = 0; - this.color_blue_group = 0; - this.colorSpread_red_group = 0; - this.colorSpread_green_group = 0; - this.colorSpread_blue_group = 0; - this.colorStart_red_group = 0; - this.colorStart_green_group = 0; - this.colorStart_blue_group = 0; - this.colorFinish_red_group = 0; - this.colorFinish_green_group = 0; - this.colorFinish_blue_group = 0; + this.color_red= 0; + this.color_green = 0; + this.color_blue = 0; + this.colorSpread_red= 0; + this.colorSpread_green = 0; + this.colorSpread_blue = 0; + this.colorStart_red = 0; + this.colorStart_green = 0; + this.colorStart_blue= 0; + this.colorFinish_red = 0; + this.colorFinish_green = 0; + this.colorFinish_blue = 0; this.azimuthStart = -PI / 2.0; this.azimuthFinish = PI / 2.0; - this.emitAccceleration_x_group = 0.01; - this.emitAccceleration_y_group = 0.01; - this.emitAccceleration_z_group = 0.01; - this.emitDimensions_x_group = 0.01; - this.emitDimensions_y_group = 0.01; - this.emitDimensions_z_group = 0.01; - this.emitOrientation_x_group = 0.01; - this.emitOrientation_y_group = 0.01; - this.emitOrientation_z_group = 0.01; - this.emitOrientation_w_group = 0.01; + this.emitAcceleration_x= 0.01; + this.emitAcceleration_y = 0.01; + this.emitAcceleration_z= 0.01; + this.emitDimensions_x= 0.01; + this.emitDimensions_y = 0.01; + this.emitDimensions_z = 0.01; + this.emitOrientation_x = 0.01; + this.emitOrientation_y = 0.01; + this.emitOrientation_z = 0.01; + this.emitOrientation_w = 0.01; this.emitRate = 0.1; this.emitSpeed = 0.1; this.polarStart = 0.01; @@ -105,7 +116,15 @@ window.onload = function() { _.each(particleKeys, function(key) { //add this key as a controller to the gui var controller = gui.add(particleExplorer, key); - if (key.indexOf('_group') > -1) { + + var putInGroup = false; + _.each(groups,function(group){ + if(key.indexOf(group)>-1){ + putInGroup=true; + } + }) + + if (putInGroup===true) { controller.shouldGroup = true; } else { controller.shouldGroup = false; @@ -131,12 +150,14 @@ window.onload = function() { }; function writeDataToInterface(property, value, shouldGroup) { + // console.log('property, value, shouldGroup',property, value, shouldGroup) var group = null; var groupProperty = null; var groupProperties = null; if (shouldGroup) { - var separated = property.slice(0, property.indexOf('_group')).split("_") + var separated = property.split("_"); + console.log(separated) group = separated[0]; groupProperty = separated[1]; var groupProperties = {} @@ -156,6 +177,7 @@ function writeDataToInterface(property, value, shouldGroup) { var stringifiedData = JSON.stringify(data) + // console.log('stringifiedData',stringifiedData) if (typeof EventBridge !== 'undefined') { EventBridge.emitWebEvent( stringifiedData From f953456007cdf489049388f419859a667322243f Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:21:55 -0700 Subject: [PATCH 092/212] comments --- examples/particle_explorer/main.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index ba6938ee23..0c22f8541a 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -21,10 +21,7 @@ function radiansToDegrees(radians) { return radians * (180 / PI) } -// need to add '_group' to the end of properties that will need to be made part of a group on the backend -// property_subproperty_group = value -// i.e. color_red_group = 0; - +//specify properties that are groups because we have to read them a little differently than single properties at the moment. var groups = [ 'accelerationSpread', 'color', From 51de351c50ac99427e7488832ca244f26b02bdee Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:28:15 -0700 Subject: [PATCH 093/212] convert tabs to spaces --- .../particle_explorer/particleExplorer.js | 232 +++++++++--------- 1 file changed, 116 insertions(+), 116 deletions(-) diff --git a/examples/particle_explorer/particleExplorer.js b/examples/particle_explorer/particleExplorer.js index a39b3e0307..ad4fd36df7 100644 --- a/examples/particle_explorer/particleExplorer.js +++ b/examples/particle_explorer/particleExplorer.js @@ -5,7 +5,7 @@ // Created by James B. Pollack @imgntnon 9/26/2015 // Copyright 2014 High Fidelity, Inc. // -// Interface side of the App. +// Interface side of the App. // Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. // // Distributed under the Apache License, Version 2.0. @@ -14,148 +14,148 @@ // todo: folders, color pickers, animation settings, scale gui width with window resizing // var boxPoint, - spawnPoint, - animation = { - fps: 30, - frameIndex: 0, - running: true, - firstFrame: 0, - lastFrame: 30, - loop: true - }; + spawnPoint, + animation = { + fps: 30, + frameIndex: 0, + running: true, + firstFrame: 0, + lastFrame: 30, + loop: true + }; var boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); boxPoint = Vec3.sum(boxPoint, { - x: 0.0, - y: -0.5, - z: 0.0 + x: 0.0, + y: -0.5, + z: 0.0 }); spawnPoint = Vec3.sum(boxPoint, { - x: 0.0, - y: 1.0, - z: 0.0 + x: 0.0, + y: 1.0, + z: 0.0 }); var PI = 3.141593, - DEG_TO_RAD = PI / 180.0; + DEG_TO_RAD = PI / 180.0; BlankBox = function() { - this.animationIsPlaying = true; - this.accelerationSpread_x_group = 0.1; - this.accelerationSpread_y_group = 0.1; - this.accelerationSpread_z_group = 0.1; - this.alpha = 0.5; - this.alphaStart = 1.0; - this.alphaFinish = 0.1; - this.color_red_group = 0; - this.color_green_group = 0; - this.color_blue_group = 0; - this.colorSpread_red_group = 0; - this.colorSpread_green_group = 0; - this.colorSpread_blue_group = 0; - this.colorStart_red_group = 0; - this.colorStart_green_group = 0; - this.colorStart_blue_group = 0; - this.colorFinish_red_group = 0; - this.colorFinish_green_group = 0; - this.colorFinish_blue_group = 0; - this.azimuthStart = -PI / 2.0; - this.azimuthFinish = PI / 2.0; - this.emitAccceleration_x_group = 0.01; - this.emitAccceleration_y_group = 0.01; - this.emitAccceleration_z_group = 0.01; - this.emitDimensions_x_group = 0.01; - this.emitDimensions_y_group = 0.01; - this.emitDimensions_z_group = 0.01; - this.emitOrientation_x_group = 0.01; - this.emitOrientation_y_group = 0.01; - this.emitOrientation_z_group = 0.01; - this.emitOrientation_w_group = 0.01; - this.emitRate = 0.1; - this.emitSpeed = 0.1; - this.polarStart = 0.01; - this.polarFinish = 2.0 * DEG_TO_RAD; - this.speedSpread = 0.1; - this.radiusSpread = 0.035; - this.radiusStart = 0.0; - this.radiusFinish = 0.0; - this.velocitySpread = 0; - // - this.type = "ParticleEffect"; - this.name = "ParticlesTest Emitter"; - this.position = spawnPoint; - this.textures = "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"; - this.lifespan = 5.0; - this.visible = false; - this.locked = false; - this.animationSettings = animation; - this.lifetime = 3600 // 1 hour; just in case + this.animationIsPlaying = true; + this.accelerationSpread_x_group = 0.1; + this.accelerationSpread_y_group = 0.1; + this.accelerationSpread_z_group = 0.1; + this.alpha = 0.5; + this.alphaStart = 1.0; + this.alphaFinish = 0.1; + this.color_red_group = 0; + this.color_green_group = 0; + this.color_blue_group = 0; + this.colorSpread_red_group = 0; + this.colorSpread_green_group = 0; + this.colorSpread_blue_group = 0; + this.colorStart_red_group = 0; + this.colorStart_green_group = 0; + this.colorStart_blue_group = 0; + this.colorFinish_red_group = 0; + this.colorFinish_green_group = 0; + this.colorFinish_blue_group = 0; + this.azimuthStart = -PI / 2.0; + this.azimuthFinish = PI / 2.0; + this.emitAccceleration_x_group = 0.01; + this.emitAccceleration_y_group = 0.01; + this.emitAccceleration_z_group = 0.01; + this.emitDimensions_x_group = 0.01; + this.emitDimensions_y_group = 0.01; + this.emitDimensions_z_group = 0.01; + this.emitOrientation_x_group = 0.01; + this.emitOrientation_y_group = 0.01; + this.emitOrientation_z_group = 0.01; + this.emitOrientation_w_group = 0.01; + this.emitRate = 0.1; + this.emitSpeed = 0.1; + this.polarStart = 0.01; + this.polarFinish = 2.0 * DEG_TO_RAD; + this.speedSpread = 0.1; + this.radiusSpread = 0.035; + this.radiusStart = 0.0; + this.radiusFinish = 0.0; + this.velocitySpread = 0; + // + this.type = "ParticleEffect"; + this.name = "ParticlesTest Emitter"; + this.position = spawnPoint; + this.textures = "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png"; + this.lifespan = 5.0; + this.visible = false; + this.locked = false; + this.animationSettings = animation; + this.lifetime = 3600 // 1 hour; just in case } var blankBox = new BlankBox(); var box = Entities.addEntity({ - type: "Box", - name: "ParticlesTest Box", - position: boxPoint, - rotation: { - x: -0.7071067690849304, - y: 0, - z: 0, - w: 0.7071067690849304 - }, - dimensions: { - x: 0.3, - y: 0.3, - z: 0.3 - }, - color: { - red: 128, - green: 128, - blue: 128 - }, - lifetime: 3600, // 1 hour; just in case - visible: true + type: "Box", + name: "ParticlesTest Box", + position: boxPoint, + rotation: { + x: -0.7071067690849304, + y: 0, + z: 0, + w: 0.7071067690849304 + }, + dimensions: { + x: 0.3, + y: 0.3, + z: 0.3 + }, + color: { + red: 128, + green: 128, + blue: 128 + }, + lifetime: 3600, // 1 hour; just in case + visible: true }); var testParticles = Entities.addEntity(blankBox); SettingsWindow = function() { - var _this = this; - this.webWindow = null; - this.init = function() { - _this.webWindow = new WebWindow('ParticleExplorer', Script.resolvePath('index.html'), 400, 600, true); - _this.webWindow.setVisible(true); - _this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived); - print('INIT testParticles' + testParticles) - }; - this.onWebEventReceived = function(data) { - // print('DATA ' + data) - var _data = JSON.parse(data) - if (_data.type !== 'particleExplorer_update') { - return; - } - if (_data.shouldGroup === true) { - // print('USE GROUP PROPERTIES') - editEntity(_data.groupProperties) - return; - } else { - // print('USE A SINGLE PROPERTY') - editEntity(_data.singleProperty) + var _this = this; + this.webWindow = null; + this.init = function() { + _this.webWindow = new WebWindow('ParticleExplorer', Script.resolvePath('index.html'), 400, 600, true); + _this.webWindow.setVisible(true); + _this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived); + print('INIT testParticles' + testParticles) + }; + this.onWebEventReceived = function(data) { + // print('DATA ' + data) + var _data = JSON.parse(data) + if (_data.type !== 'particleExplorer_update') { + return; + } + if (_data.shouldGroup === true) { + // print('USE GROUP PROPERTIES') + editEntity(_data.groupProperties) + return; + } else { + // print('USE A SINGLE PROPERTY') + editEntity(_data.singleProperty) - } + } - }; + }; } function editEntity(properties) { - Entities.editEntity(testParticles, properties); - var currentProperties = Entities.getEntityProperties(testParticles) - // print('CURRENT PROPS', JSON.stringify(currentProperties)) + Entities.editEntity(testParticles, properties); + var currentProperties = Entities.getEntityProperties(testParticles) + // print('CURRENT PROPS', JSON.stringify(currentProperties)) } @@ -163,7 +163,7 @@ var settingsWindow = new SettingsWindow(); settingsWindow.init(); function cleanup() { - Entities.deleteEntity(testParticles); - Entities.deleteEntity(box); + Entities.deleteEntity(testParticles); + Entities.deleteEntity(box); } Script.scriptEnding.connect(cleanup); \ No newline at end of file From 22515a9375e1127e99f1adcd7ec8f1234e2cac19 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:40:46 -0700 Subject: [PATCH 094/212] fix naming, match initial properties --- examples/particle_explorer/main.js | 6 +- .../particle_explorer/particleExplorer.js | 87 +++++++++++-------- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 0c22f8541a..eca05ff303 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -76,9 +76,9 @@ var ParticleExplorer = function() { this.polarFinish = 2.0 * DEG_TO_RAD; this.speedSpread = 0.1; this.radiusSpread = 0.035; - this.radiusStart = 0.0; - this.radiusFinish = 0.0; - this.velocitySpread = 0; + this.radiusStart = 0.1; + this.radiusFinish = 0.1; + this.velocitySpread = 0.1; } diff --git a/examples/particle_explorer/particleExplorer.js b/examples/particle_explorer/particleExplorer.js index ad4fd36df7..5b34ea5b13 100644 --- a/examples/particle_explorer/particleExplorer.js +++ b/examples/particle_explorer/particleExplorer.js @@ -24,7 +24,6 @@ var boxPoint, loop: true }; - var boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); boxPoint = Vec3.sum(boxPoint, { x: 0.0, @@ -40,48 +39,65 @@ spawnPoint = Vec3.sum(boxPoint, { var PI = 3.141593, DEG_TO_RAD = PI / 180.0; -BlankBox = function() { +StartingParticles = function() { this.animationIsPlaying = true; - this.accelerationSpread_x_group = 0.1; - this.accelerationSpread_y_group = 0.1; - this.accelerationSpread_z_group = 0.1; + this.accelerationSpread = { + x: 0.1, + y: 0.1, + z: 0.1 + }; this.alpha = 0.5; this.alphaStart = 1.0; this.alphaFinish = 0.1; - this.color_red_group = 0; - this.color_green_group = 0; - this.color_blue_group = 0; - this.colorSpread_red_group = 0; - this.colorSpread_green_group = 0; - this.colorSpread_blue_group = 0; - this.colorStart_red_group = 0; - this.colorStart_green_group = 0; - this.colorStart_blue_group = 0; - this.colorFinish_red_group = 0; - this.colorFinish_green_group = 0; - this.colorFinish_blue_group = 0; + this.color = { + red: 0, + green: 0, + blue: 0 + }; + this.colorSpread = { + red: 0, + green: 0, + blue: 0 + }; + + this.colorStart = { + red: 0, + green: 0, + blue: 0 + }; + + this.colorFinish = { + red: 0, + green: 0, + blue: 0 + }; this.azimuthStart = -PI / 2.0; this.azimuthFinish = PI / 2.0; - this.emitAccceleration_x_group = 0.01; - this.emitAccceleration_y_group = 0.01; - this.emitAccceleration_z_group = 0.01; - this.emitDimensions_x_group = 0.01; - this.emitDimensions_y_group = 0.01; - this.emitDimensions_z_group = 0.01; - this.emitOrientation_x_group = 0.01; - this.emitOrientation_y_group = 0.01; - this.emitOrientation_z_group = 0.01; - this.emitOrientation_w_group = 0.01; + this.emitAccceleration = { + x: 0.1, + y: 0.1, + z: 0.1 + }; + this.emitDimensions = { + x: 0.01, + y: 0.01, + z: 0.01 + }; + this.emitOrientation = { + x: 0.01, + y: 0.01, + z: 0.01, + w: 0.01 + }; this.emitRate = 0.1; this.emitSpeed = 0.1; this.polarStart = 0.01; this.polarFinish = 2.0 * DEG_TO_RAD; this.speedSpread = 0.1; this.radiusSpread = 0.035; - this.radiusStart = 0.0; - this.radiusFinish = 0.0; - this.velocitySpread = 0; - // + this.radiusStart = 0.1; + this.radiusFinish = 0.1; + this.velocitySpread = 0.1; this.type = "ParticleEffect"; this.name = "ParticlesTest Emitter"; this.position = spawnPoint; @@ -93,7 +109,7 @@ BlankBox = function() { this.lifetime = 3600 // 1 hour; just in case } -var blankBox = new BlankBox(); +var startingParticles = new StartingParticles(); var box = Entities.addEntity({ type: "Box", @@ -115,11 +131,10 @@ var box = Entities.addEntity({ green: 128, blue: 128 }, - lifetime: 3600, // 1 hour; just in case - visible: true + }); -var testParticles = Entities.addEntity(blankBox); +var testParticles = Entities.addEntity(startingParticles); SettingsWindow = function() { var _this = this; @@ -155,7 +170,7 @@ SettingsWindow = function() { function editEntity(properties) { Entities.editEntity(testParticles, properties); var currentProperties = Entities.getEntityProperties(testParticles) - // print('CURRENT PROPS', JSON.stringify(currentProperties)) + // print('CURRENT PROPS', JSON.stringify(currentProperties)) } From 5013e98b6cd4ac27eaeb4b92b880fb3257d64034 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 12:47:22 -0700 Subject: [PATCH 095/212] cleanup, comments --- examples/particle_explorer/index.html | 2 +- examples/particle_explorer/main.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/particle_explorer/index.html b/examples/particle_explorer/index.html index 1bcbba05da..a389bf125c 100644 --- a/examples/particle_explorer/index.html +++ b/examples/particle_explorer/index.html @@ -5,7 +5,7 @@ // Created by James B. Pollack @imgntnon 9/26/2015 // Copyright 2014 High Fidelity, Inc. // -// Web app side of the App - contains GUI. +// Loads dat.gui, underscore, and the app // Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. // // Distributed under the Apache License, Version 2.0. diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index eca05ff303..ae235b1846 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -154,7 +154,6 @@ function writeDataToInterface(property, value, shouldGroup) { if (shouldGroup) { var separated = property.split("_"); - console.log(separated) group = separated[0]; groupProperty = separated[1]; var groupProperties = {} From 7a59a7dc43a04304fd9a41907b7e4f129e460c1a Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 14:10:30 -0700 Subject: [PATCH 096/212] add two-way code but dont enable --- examples/particle_explorer/main.js | 61 ++++++++++++------- .../particle_explorer/particleExplorer.js | 6 +- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index ae235b1846..93cdb02cbf 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -23,14 +23,14 @@ function radiansToDegrees(radians) { //specify properties that are groups because we have to read them a little differently than single properties at the moment. var groups = [ -'accelerationSpread', -'color', -'colorSpread', -'colorStart', -'colorFinish', -'emitAcceleration', -'emitDimensions', -'emitOrientation' + 'accelerationSpread', + 'color', + 'colorSpread', + 'colorStart', + 'colorFinish', + 'emitAcceleration', + 'emitDimensions', + 'emitOrientation' ] var ParticleExplorer = function() { @@ -46,24 +46,24 @@ var ParticleExplorer = function() { this.alpha = 0.5; this.alphaStart = 1.0; this.alphaFinish = 0.1; - this.color_red= 0; + this.color_red = 0; this.color_green = 0; this.color_blue = 0; - this.colorSpread_red= 0; + this.colorSpread_red = 0; this.colorSpread_green = 0; this.colorSpread_blue = 0; this.colorStart_red = 0; this.colorStart_green = 0; - this.colorStart_blue= 0; + this.colorStart_blue = 0; this.colorFinish_red = 0; this.colorFinish_green = 0; this.colorFinish_blue = 0; this.azimuthStart = -PI / 2.0; this.azimuthFinish = PI / 2.0; - this.emitAcceleration_x= 0.01; + this.emitAcceleration_x = 0.01; this.emitAcceleration_y = 0.01; - this.emitAcceleration_z= 0.01; - this.emitDimensions_x= 0.01; + this.emitAcceleration_z = 0.01; + this.emitDimensions_x = 0.01; this.emitDimensions_y = 0.01; this.emitDimensions_z = 0.01; this.emitOrientation_x = 0.01; @@ -84,10 +84,11 @@ var ParticleExplorer = function() { //we need a way to keep track of our gui controllers var controllers = []; +var particleExplorer; window.onload = function() { //instantiate our object - var particleExplorer = new ParticleExplorer(); + particleExplorer = new ParticleExplorer(); //whether or not to autoplace var gui = new dat.GUI({ @@ -113,15 +114,17 @@ window.onload = function() { _.each(particleKeys, function(key) { //add this key as a controller to the gui var controller = gui.add(particleExplorer, key); + // the call below is potentially expensive but will enable two way binding. needs testing to see how many it supports at once. + //var controller = gui.add(particleExplorer, key).listen(); - var putInGroup = false; - _.each(groups,function(group){ - if(key.indexOf(group)>-1){ - putInGroup=true; + var putInGroup = false; + _.each(groups, function(group) { + if (key.indexOf(group) > -1) { + putInGroup = true; } }) - if (putInGroup===true) { + if (putInGroup === true) { controller.shouldGroup = true; } else { controller.shouldGroup = false; @@ -138,7 +141,7 @@ window.onload = function() { controller.onFinishChange(function(value) { // console.log('should group?', controller.shouldGroup) - // Fires when a controller loses focus. + // Fires when a controller loses focus. writeDataToInterface(this.property, value, this.shouldGroup) }); @@ -151,7 +154,7 @@ function writeDataToInterface(property, value, shouldGroup) { var group = null; var groupProperty = null; var groupProperties = null; - + if (shouldGroup) { var separated = property.split("_"); group = separated[0]; @@ -159,7 +162,7 @@ function writeDataToInterface(property, value, shouldGroup) { var groupProperties = {} groupProperties[group] = {}; groupProperties[group][groupProperty] = value - // console.log(groupProperties) + // console.log(groupProperties) } var data = { @@ -180,4 +183,16 @@ function writeDataToInterface(property, value, shouldGroup) { ); } +} + +function listenForSettingsUpdates() { + if (typeof EventBridge !== 'undefined') { + EventBridge.scriptEventReceived.connect(function(data) { + data = JSON.parse(data); + if (data.type === 'particleSettingsUpdate') { + var particleSettings = data.particleSettings + //parse the settings and change particle explorer, add .listen() to controllers + } + }); + } } \ No newline at end of file diff --git a/examples/particle_explorer/particleExplorer.js b/examples/particle_explorer/particleExplorer.js index 5b34ea5b13..bc5810d652 100644 --- a/examples/particle_explorer/particleExplorer.js +++ b/examples/particle_explorer/particleExplorer.js @@ -145,6 +145,9 @@ SettingsWindow = function() { _this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived); print('INIT testParticles' + testParticles) }; + this.sendData = function(data) { + _this.webWindow.eventBridge.emitScriptEvent(JSON.stringify(data)); + }; this.onWebEventReceived = function(data) { // print('DATA ' + data) var _data = JSON.parse(data) @@ -170,7 +173,8 @@ SettingsWindow = function() { function editEntity(properties) { Entities.editEntity(testParticles, properties); var currentProperties = Entities.getEntityProperties(testParticles) - // print('CURRENT PROPS', JSON.stringify(currentProperties)) + // print('CURRENT PROPS', JSON.stringify(currentProperties)) + SettingsWindow.sendData({type:'particleSettingsUpdate',particleSettings:currentProperties}) } From 06a646263637d8e66c7414cb7c8c29fc800224cf Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 14:14:21 -0700 Subject: [PATCH 097/212] add function for manually updating display --- examples/particle_explorer/main.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 93cdb02cbf..6b0531392d 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -195,4 +195,12 @@ function listenForSettingsUpdates() { } }); } +} + + +function manuallyUpdateDisplay(gui) { + // Iterate over all controllers + for (var i in gui.__controllers) { + gui.__controllers[i].updateDisplay(); + } } \ No newline at end of file From 4f7e7e1d5fb0ca2718e72e6f7875c85f4ebbf7e5 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sat, 26 Sep 2015 23:24:00 -0700 Subject: [PATCH 098/212] start generic two-way implementation, fix some typos --- examples/particle_explorer/generic.js | 130 ++++++++++++++++++ .../particle_explorer/genericProperties.js | 99 +++++++++++++ examples/particle_explorer/index.html | 4 +- .../particle_explorer/particleExplorer.js | 2 +- 4 files changed, 232 insertions(+), 3 deletions(-) create mode 100644 examples/particle_explorer/generic.js create mode 100644 examples/particle_explorer/genericProperties.js diff --git a/examples/particle_explorer/generic.js b/examples/particle_explorer/generic.js new file mode 100644 index 0000000000..22510cc357 --- /dev/null +++ b/examples/particle_explorer/generic.js @@ -0,0 +1,130 @@ +// +// main.js +// +// +// Created by James B. Pollack @imgntnon 9/26/2015 +// Copyright 2014 High Fidelity, Inc. +// +// Web app side of the App - contains GUI. +// Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// todo: folders, color pickers, animation settings, scale gui width with window resizing +// + +var Settings = function() { + return; +} + +//we need a way to keep track of our gui controllers +var controllers = []; +var settings = new Settings(); + +function loadGUI() { + console.log('loadGUI loadGUI loadGUI loadGUI') + //instantiate our object + + //whether or not to autoplace + var gui = new dat.GUI({ + autoPlace: false + }); + + //if not autoplacing, put gui in a custom container + if (gui.autoPlace === false) { + + var customContainer = document.getElementById('my-gui-container'); + customContainer.appendChild(gui.domElement); + gui.width = 400; + + } + + //add save settings ability (try not to use localstorage) + gui.remember(settings); + + //get object keys + var keys = _.keys(settings); + + //for each key... + _.each(keys, function(key) { + console.log('KEY KEY KEY' + key); + //add this key as a controller to the gui + var controller = gui.add(settings, key).listen(); + // the call below is potentially expensive but will enable two way binding. needs testing to see how many it supports at once. + //var controller = gui.add(particleExplorer, key).listen(); + //keep track of our controller + controllers.push(controller); + + //hook into change events for this gui controller + controller.onChange(function(value) { + // Fires on every change, drag, keypress, etc. + }); + + controller.onFinishChange(function(value) { + // Fires when a controller loses focus. + writeDataToInterface(this.property, value) + }); + + }); + +}; + +function writeDataToInterface(property, value, shouldGroup) { + var data = { + type: "settings_update", + updatedSettings: settings, + } + + var stringifiedData = JSON.stringify(data) + + // console.log('stringifiedData',stringifiedData) + if (typeof EventBridge !== 'undefined') { + EventBridge.emitWebEvent( + stringifiedData + ); + } + +} + +function listenForSettingsUpdates() { + console.log('listening for messages') + if (typeof EventBridge !== 'undefined') { + console.log('WE HAVE AN EVENT BRIDGE') + EventBridge.scriptEventReceived.connect(function(data) { + console.log('GOT MESSAGE FROM EVENT BRIDGE') + data = JSON.parse(data); + if (data.messageType === 'initialSettings') { + console.log('INITIAL SETTINGS:::' + JSON.stringify(data.initialSettings)) + var initialSettings = data.initialSettings; + _.each(initialSettings, function(value, key) { + console.log('key ' + key); + console.log('value ' + JSON.stringify(value)); + + settings[key] = {}; + settings[key] = value; + }) + loadGUI(); + } + if (data.messageType === 'settingsUpdate') { + var initialSettings = data.updatedSettings; + _.each(initialSettings, function(value, key) { + console.log('setting,value', setting, value) + settings[key] = value; + }) + + + } + }); + } +} + + +function manuallyUpdateDisplay(gui) { + // Iterate over all controllers + for (var i in gui.__controllers) { + gui.__controllers[i].updateDisplay(); + } +} + +listenForSettingsUpdates(); \ No newline at end of file diff --git a/examples/particle_explorer/genericProperties.js b/examples/particle_explorer/genericProperties.js new file mode 100644 index 0000000000..2444d78d2d --- /dev/null +++ b/examples/particle_explorer/genericProperties.js @@ -0,0 +1,99 @@ +// +// particleExplorer.js +// +// +// Created by James B. Pollack @imgntnon 9/26/2015 +// Copyright 2014 High Fidelity, Inc. +// +// Interface side of the App. +// Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +// todo: folders, color pickers, animation settings, scale gui width with window resizing +// + +SettingsWindow = function() { + var _this = this; + this.webWindow = null; + this.init = function() { + _this.webWindow = new WebWindow('genericProperties', Script.resolvePath('index.html'), 400, 600, true); + _this.webWindow.setVisible(true); + _this.webWindow.eventBridge.webEventReceived.connect(_this.onWebEventReceived); + var boxPoint; + + var boxPoint = Vec3.sum(MyAvatar.position, Vec3.multiply(4.0, Quat.getFront(Camera.getOrientation()))); + + _this.box = Entities.addEntity({ + type: 'box', + visible: true, + collisionsWillMove: true, + color: { + red: 0, + green: 255, + blue: 0 + + }, + dimensions: { + x: 1, + y: 1, + z: 1, + }, + position: boxPoint + }); + + }; + this.sendData = function(data) { + print('sending data' + JSON.stringify(data)); + _this.webWindow.eventBridge.emitScriptEvent(JSON.stringify(data)); + }; + this.onWebEventReceived = function(data) { + // print('DATA ' + data) + var _data = JSON.parse(data) + if (_data.type !== 'settings_update') { + return; + } + print('GOT A SETTINGS UPDATE EVENT') + editEntity(_data.updatedSettings) + + } + + +} + +function sendInitialSettings() { + + + var settings = { + messageType: 'initialSettings', + initialSettings: Entities.getEntityProperties(SettingsWindow.box) + } + settingsWindow.sendData(settings) + + + +} + +function editEntity(properties) { + Entities.editEntity(SettingsWindow.box, properties); + var currentProperties = Entities.getEntityProperties(SettingsWindow.box); + settingsWindow.sendData({ + messageType: 'settingsUpdate', + updatedSettings: currentProperties + }) +} + + +var settingsWindow = new SettingsWindow(); +settingsWindow.init(); +Script.setTimeout(function() { + sendInitialSettings(); +}, 1000) + + +function cleanup() { + Entities.deleteEntity(testParticles); + Entities.deleteEntity(box); +} +Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/particle_explorer/index.html b/examples/particle_explorer/index.html index a389bf125c..033954ba73 100644 --- a/examples/particle_explorer/index.html +++ b/examples/particle_explorer/index.html @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // // todo: folders, color pickers, animation settings, scale gui width with window resizing - --> + --> @@ -21,7 +21,7 @@ +
    +
    +    
    +
    +
    diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index b08823acc3..831d5a167a 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -13,6 +13,9 @@ /*global window, EventBridge, dat, convertBinaryToBoolean, listenForSettingsUpdates,createVec3Folder,createQuatFolder,writeVec3ToInterface,writeDataToInterface*/ var Settings = function() { + this.saveParticleSettings = function() { + showPreselectedPrompt(); + } return; }; @@ -136,9 +139,13 @@ function loadGUI() { vec3Keys.sort(); quatKeys.sort(); colorKeys.sort(); + gui.add(settings, 'saveParticleSettings'); addIndividualKeys(); addFolders(); + setInterval(manuallyUpdateDisplay, UPDATE_ALL_FREQUENCY); + // showParticleSettings(); + // showPreselectedPrompt(); } @@ -146,8 +153,8 @@ function addIndividualKeys() { _.each(individualKeys, function(key) { var controller = gui.add(settings, key) - //need to fix not being able to input values if constantly listening - //.listen(); + //need to fix not being able to input values if constantly listening + //.listen(); // keep track of our controller controllers.push(controller); @@ -382,4 +389,30 @@ function manuallyUpdateDisplay() { function removeContainerDomElement() { var elem = document.getElementById("my-gui-container"); elem.parentNode.removeChild(elem); +} + +function showParticleSettings() { + var codeBlock = document.getElementById("export-code"); + codeBlock.innerHTML = prepareSettingsForExport(); +} + + +function prepareSettingsForExport() { + var keys = _.keys(settings); + var exportSettings = {}; + //for each key... + _.each(keys, function(key) { + var shouldIgnore = _.contains(keysToIgnore, key); + if (shouldIgnore) { + return + } + + exportSettings[key] = settings[key]; + }) + return JSON.stringify(exportSettings); +} + + +function showPreselectedPrompt() { + window.prompt("Copy to clipboard: Ctrl+C, Enter", prepareSettingsForExport()); } \ No newline at end of file From 8fc696c5f8eef9e288fde0c1a0212369863cf71b Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 12:41:08 -0700 Subject: [PATCH 149/212] add ability to explort particle settings in nice format for interface --- examples/particle_explorer/index.html | 5 ----- examples/particle_explorer/main.js | 21 +++++++++++++++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/examples/particle_explorer/index.html b/examples/particle_explorer/index.html index fdfd6f35c7..1772423d02 100644 --- a/examples/particle_explorer/index.html +++ b/examples/particle_explorer/index.html @@ -27,11 +27,6 @@ -
    -
    -    
    -
    -
    diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 831d5a167a..4db3f4b9e9 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -13,7 +13,7 @@ /*global window, EventBridge, dat, convertBinaryToBoolean, listenForSettingsUpdates,createVec3Folder,createQuatFolder,writeVec3ToInterface,writeDataToInterface*/ var Settings = function() { - this.saveParticleSettings = function() { + this.exportSettings = function() { showPreselectedPrompt(); } return; @@ -95,8 +95,7 @@ function loadGUI() { gui.width = 400; } - //add save settings ability (try not to use localstorage) - gui.remember(settings); + // gui.remember(settings); //get object keys var keys = _.keys(settings); @@ -139,7 +138,7 @@ function loadGUI() { vec3Keys.sort(); quatKeys.sort(); colorKeys.sort(); - gui.add(settings, 'saveParticleSettings'); + gui.add(settings, 'exportSettings'); addIndividualKeys(); addFolders(); @@ -412,6 +411,20 @@ function prepareSettingsForExport() { return JSON.stringify(exportSettings); } +function importSettings(incomingSettings) { + var importedSettings = JSON.parse(incomingSettings); + var keys = _.keys(importedSettings); + + //for each key... + _.each(keys, function(key) { + var shouldIgnore = _.contains(keysToIgnore, key); + if (shouldIgnore) { + return + } + settings[key] = importedSettings[key]; + }) +} + function showPreselectedPrompt() { window.prompt("Copy to clipboard: Ctrl+C, Enter", prepareSettingsForExport()); From 3cdb4e7186fc9bb73f897ad38ddfc68c115b776f Mon Sep 17 00:00:00 2001 From: James Pollack Date: Wed, 30 Sep 2015 14:23:11 -0700 Subject: [PATCH 150/212] importing --- examples/particle_explorer/index.html | 22 +++++++++ examples/particle_explorer/main.js | 69 +++++++++++++++++---------- 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/examples/particle_explorer/index.html b/examples/particle_explorer/index.html index 1772423d02..06ffc0390b 100644 --- a/examples/particle_explorer/index.html +++ b/examples/particle_explorer/index.html @@ -24,10 +24,32 @@ width:100%; height:100%; } + +.importer{ + margin:5px; + width:100%; +} + +::-webkit-input-placeholder { + + margin:4px; + font-family: Helvetica +} + +#importer-input{ + width:90%; + line-height: 2; + margin-left:5%; +} + +
    + +
    + \ No newline at end of file diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 4db3f4b9e9..9ac556f961 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -15,7 +15,11 @@ var Settings = function() { this.exportSettings = function() { showPreselectedPrompt(); + }; + this.importSettings = function() { + importSettings(); } + return; }; @@ -27,6 +31,8 @@ var updateInterval; var UPDATE_ALL_FREQUENCY = 1000; var keysToIgnore = [ + 'importSettings', + 'exportSettings', 'script', 'visible', 'locked', @@ -92,7 +98,7 @@ function loadGUI() { if (gui.autoPlace === false) { var customContainer = document.getElementById('my-gui-container'); customContainer.appendChild(gui.domElement); - gui.width = 400; + gui.width = 500; } // gui.remember(settings); @@ -105,7 +111,7 @@ function loadGUI() { var shouldIgnore = _.contains(keysToIgnore, key); if (shouldIgnore) { - return + return; } var subKeys = _.keys(settings[key]); var hasX = _.contains(subKeys, 'x'); @@ -120,7 +126,7 @@ function loadGUI() { vec3Keys.push(key); } else if (hasX && hasY && hasZ && hasW) { // console.log(key + " is a quaternion"); - quatKeys.push(key) + quatKeys.push(key); } else if (hasRed || hasGreen || hasBlue) { // console.log(key + " is a color"); colorKeys.push(key); @@ -138,22 +144,20 @@ function loadGUI() { vec3Keys.sort(); quatKeys.sort(); colorKeys.sort(); + gui.add(settings, 'importSettings'); gui.add(settings, 'exportSettings'); addIndividualKeys(); addFolders(); - setInterval(manuallyUpdateDisplay, UPDATE_ALL_FREQUENCY); - // showParticleSettings(); - // showPreselectedPrompt(); } function addIndividualKeys() { _.each(individualKeys, function(key) { - var controller = gui.add(settings, key) - //need to fix not being able to input values if constantly listening - //.listen(); + var controller = gui.add(settings, key); + //need to fix not being able to input values if constantly listening + //.listen(); // keep track of our controller controllers.push(controller); @@ -163,19 +167,19 @@ function addIndividualKeys() { // Fires on every change, drag, keypress, etc. writeDataToInterface(this.property, value); }); - }) + }); } function addFolders() { _.each(vec3Keys, function(key) { createVec3Folder(key); - }) + }); _.each(quatKeys, function(key) { createQuatFolder(key); - }) + }); _.each(colorKeys, function(key) { createColorFolder(key); - }) + }); } function createVec3Folder(category) { @@ -395,7 +399,6 @@ function showParticleSettings() { codeBlock.innerHTML = prepareSettingsForExport(); } - function prepareSettingsForExport() { var keys = _.keys(settings); var exportSettings = {}; @@ -403,7 +406,7 @@ function prepareSettingsForExport() { _.each(keys, function(key) { var shouldIgnore = _.contains(keysToIgnore, key); if (shouldIgnore) { - return + return; } exportSettings[key] = settings[key]; @@ -411,20 +414,34 @@ function prepareSettingsForExport() { return JSON.stringify(exportSettings); } -function importSettings(incomingSettings) { - var importedSettings = JSON.parse(incomingSettings); - var keys = _.keys(importedSettings); +function importSettings() { + var importInput = document.getElementById('importer-input'); + console.log('import value' + importInput.value) + try { + var importedSettings = JSON.parse(importInput.value); + // importedSettings = importInput.value; + var keys = _.keys(importedSettings); + _.each(keys, function(key) { + var shouldIgnore = _.contains(keysToIgnore, key); + if (shouldIgnore) { + return; + } + settings[key] = importedSettings[key]; + }); + writeVec3ToInterface(settings); + manuallyUpdateDisplay(); + } catch (e) { + alert('Not properly formatted JSON'); //error in the above string(in this case,yes)! + } - //for each key... - _.each(keys, function(key) { - var shouldIgnore = _.contains(keysToIgnore, key); - if (shouldIgnore) { - return - } - settings[key] = importedSettings[key]; - }) } +function handleInputKeyPress(e) { + if (e.keyCode === 13) { + importSettings(); + } + return false; +} function showPreselectedPrompt() { window.prompt("Copy to clipboard: Ctrl+C, Enter", prepareSettingsForExport()); From 75e858cd1314009181c21c0764996dbf266f9ccf Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 15:54:03 -0700 Subject: [PATCH 151/212] Putting together the stencil buffer for opaque vs background and using it for the backgroud render items --- interface/src/Stars.cpp | 2 ++ libraries/gpu/src/gpu/GLBackendState.cpp | 5 +-- libraries/gpu/src/gpu/State.h | 6 ++-- libraries/model/src/model/Skybox.cpp | 1 + .../src/procedural/ProceduralSkybox.cpp | 3 +- libraries/render-utils/src/Environment.cpp | 3 +- .../render-utils/src/FramebufferCache.cpp | 14 ++++----- libraries/render-utils/src/FramebufferCache.h | 4 +-- .../render-utils/src/RenderDeferredTask.cpp | 31 ++++++++++--------- .../render-utils/src/drawOpaqueStencil.slf | 14 +++------ 10 files changed, 44 insertions(+), 39 deletions(-) diff --git a/interface/src/Stars.cpp b/interface/src/Stars.cpp index 4af1a26612..6145529b52 100644 --- a/interface/src/Stars.cpp +++ b/interface/src/Stars.cpp @@ -141,6 +141,7 @@ void Stars::render(RenderArgs* renderArgs, float alpha) { auto state = gpu::StatePointer(new gpu::State()); // enable decal blend state->setDepthTest(gpu::State::DepthTest(false)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _gridPipeline.reset(gpu::Pipeline::create(program, state)); } @@ -152,6 +153,7 @@ void Stars::render(RenderArgs* renderArgs, float alpha) { auto state = gpu::StatePointer(new gpu::State()); // enable decal blend state->setDepthTest(gpu::State::DepthTest(false)); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setAntialiasedLineEnable(true); // line smoothing also smooth points state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _starsPipeline.reset(gpu::Pipeline::create(program, state)); diff --git a/libraries/gpu/src/gpu/GLBackendState.cpp b/libraries/gpu/src/gpu/GLBackendState.cpp index 9fdcbc0870..feba6e6853 100644 --- a/libraries/gpu/src/gpu/GLBackendState.cpp +++ b/libraries/gpu/src/gpu/GLBackendState.cpp @@ -655,11 +655,12 @@ void GLBackend::do_setStateStencil(State::StencilActivation activation, State::S GL_INCR, GL_DECR }; - glStencilFuncSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); + glStencilOpSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); glStencilFuncSeparate(GL_FRONT, GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); - glStencilFuncSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); + glStencilOpSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); glStencilFuncSeparate(GL_BACK, GL_COMPARISON_FUNCTIONS[backTest.getFunction()], backTest.getReference(), backTest.getReadMask()); + } else { glDisable(GL_STENCIL_TEST); } diff --git a/libraries/gpu/src/gpu/State.h b/libraries/gpu/src/gpu/State.h index 5500f20e06..7740506bce 100755 --- a/libraries/gpu/src/gpu/State.h +++ b/libraries/gpu/src/gpu/State.h @@ -143,11 +143,11 @@ public: static const int PASS_OP_OFFSET = 12; uint16 _functionAndOperations; - uint8 _reference = 0; + int8 _reference = 0; uint8 _readMask = 0xff; public: - StencilTest(uint8 reference = 0, uint8 readMask =0xFF, ComparisonFunction func = ALWAYS, StencilOp failOp = STENCIL_OP_KEEP, StencilOp depthFailOp = STENCIL_OP_KEEP, StencilOp passOp = STENCIL_OP_KEEP) : + StencilTest(int8 reference = 0, uint8 readMask =0xFF, ComparisonFunction func = ALWAYS, StencilOp failOp = STENCIL_OP_KEEP, StencilOp depthFailOp = STENCIL_OP_KEEP, StencilOp passOp = STENCIL_OP_KEEP) : _functionAndOperations(func | (failOp << FAIL_OP_OFFSET) | (depthFailOp << DEPTH_FAIL_OP_OFFSET) | (passOp << PASS_OP_OFFSET)), _reference(reference), _readMask(readMask) {} @@ -157,7 +157,7 @@ public: StencilOp getDepthFailOp() const { return StencilOp((_functionAndOperations & DEPTH_FAIL_OP_MASK) >> DEPTH_FAIL_OP_OFFSET); } StencilOp getPassOp() const { return StencilOp((_functionAndOperations & PASS_OP_MASK) >> PASS_OP_OFFSET); } - uint8 getReference() const { return _reference; } + int8 getReference() const { return _reference; } uint8 getReadMask() const { return _readMask; } int32 getRaw() const { return *(reinterpret_cast(this)); } diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index e27a0d25ce..944d16a6dd 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -89,6 +89,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky } auto skyState = std::make_shared(); + skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index 8d34f0e7e5..f69e0575de 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -32,7 +32,8 @@ void ProceduralSkybox::setProcedural(const ProceduralPointer& procedural) { if (_procedural) { _procedural->_vertexSource = ProceduralSkybox_vert; _procedural->_fragmentSource = ProceduralSkybox_frag; - // No pipeline state customization + // Adjust the pipeline state for background using the stencil test + _procedural->_state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } } diff --git a/libraries/render-utils/src/Environment.cpp b/libraries/render-utils/src/Environment.cpp index 365fbdb16a..acb149a3cc 100644 --- a/libraries/render-utils/src/Environment.cpp +++ b/libraries/render-utils/src/Environment.cpp @@ -63,7 +63,8 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra state->setCullMode(gpu::State::CULL_NONE); // state->setDepthTest(false); - state->setDepthTest(true, false, gpu::LESS_EQUAL); + // state->setDepthTest(true, false, gpu::LESS_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); diff --git a/libraries/render-utils/src/FramebufferCache.cpp b/libraries/render-utils/src/FramebufferCache.cpp index eb154f77c9..cd81a21f9a 100644 --- a/libraries/render-utils/src/FramebufferCache.cpp +++ b/libraries/render-utils/src/FramebufferCache.cpp @@ -35,7 +35,7 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { _frameBufferSize = frameBufferSize; _primaryFramebufferFull.reset(); _primaryFramebufferDepthColor.reset(); - _primaryFramebufferDepthStencilColor.reset(); + _primaryFramebufferStencilColor.reset(); _primaryDepthTexture.reset(); _primaryStencilTexture.reset(); _primaryColorTexture.reset(); @@ -49,7 +49,7 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) { void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferFull = gpu::FramebufferPointer(gpu::Framebuffer::create()); _primaryFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); - _primaryFramebufferDepthStencilColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); + _primaryFramebufferStencilColor = gpu::FramebufferPointer(gpu::Framebuffer::create()); auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA); auto width = _frameBufferSize.width(); @@ -66,7 +66,7 @@ void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferDepthColor->setRenderBuffer(0, _primaryColorTexture); - _primaryFramebufferDepthStencilColor->setRenderBuffer(0, _primaryColorTexture); + _primaryFramebufferStencilColor->setRenderBuffer(0, _primaryColorTexture); auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH); _primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler)); @@ -78,7 +78,7 @@ void FramebufferCache::createPrimaryFramebuffer() { _primaryFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat); - _primaryFramebufferDepthStencilColor->setDepthStencilBuffer(_primaryStencilTexture, stencilFormat); + _primaryFramebufferStencilColor->setDepthStencilBuffer(_primaryStencilTexture, stencilFormat); _selfieFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create()); auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler)); @@ -99,11 +99,11 @@ gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthColor() { return _primaryFramebufferDepthColor; } -gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthStencilColor() { - if (!_primaryFramebufferDepthStencilColor) { +gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferStencilColor() { + if (!_primaryFramebufferStencilColor) { createPrimaryFramebuffer(); } - return _primaryFramebufferDepthStencilColor; + return _primaryFramebufferStencilColor; } gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() { diff --git a/libraries/render-utils/src/FramebufferCache.h b/libraries/render-utils/src/FramebufferCache.h index baca07af24..8951ceee80 100644 --- a/libraries/render-utils/src/FramebufferCache.h +++ b/libraries/render-utils/src/FramebufferCache.h @@ -31,7 +31,7 @@ public: /// used for scene rendering. gpu::FramebufferPointer getPrimaryFramebuffer(); gpu::FramebufferPointer getPrimaryFramebufferDepthColor(); - gpu::FramebufferPointer getPrimaryFramebufferDepthStencilColor(); + gpu::FramebufferPointer getPrimaryFramebufferStencilColor(); gpu::TexturePointer getPrimaryDepthTexture(); gpu::TexturePointer getPrimaryStencilTexture(); @@ -60,7 +60,7 @@ private: gpu::FramebufferPointer _primaryFramebufferFull; gpu::FramebufferPointer _primaryFramebufferDepthColor; - gpu::FramebufferPointer _primaryFramebufferDepthStencilColor; + gpu::FramebufferPointer _primaryFramebufferStencilColor; gpu::TexturePointer _primaryDepthTexture; gpu::TexturePointer _primaryStencilTexture; gpu::TexturePointer _primaryColorTexture; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 71bc41e6b6..e16544f5cd 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -301,12 +301,18 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon gpu::PipelinePointer DrawStencilDeferred::_opaquePipeline; const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { if (!_opaquePipeline) { + const gpu::int8 STENCIL_OPAQUE = 1; auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag))); auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); + + + gpu::Shader::makeProgram((*program)); auto state = std::make_shared(); - state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); + // state->setStencilTest(false, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR)); + state->setColorWriteMask(0); _opaquePipeline.reset(gpu::Pipeline::create(program, state)); } @@ -322,23 +328,20 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; - auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthStencilColor(); + auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); auto primaryDepth = DependencyManager::get()->getPrimaryDepthTexture(); + + batch.enableStereo(false); batch.setFramebuffer(primaryFboColorDepthStencil); - - batch.enableStereo(false); + batch.clearStencilFramebuffer(0, true); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); + Transform modelMat; + batch.setModelTransform(modelMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); batch.setPipeline(getOpaquePipeline()); batch.setResourceTexture(0, primaryDepth); @@ -369,13 +372,13 @@ void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const doInBatch(args->_context, [=](gpu::Batch& batch) { args->_batch = &batch; - // auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthStencilColor(); - auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferDepthColor(); + auto primaryFboColorStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); - batch.setFramebuffer(primaryFboColorDepthStencil); - batch.enableSkybox(true); + + batch.setFramebuffer(primaryFboColorStencil); + batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); diff --git a/libraries/render-utils/src/drawOpaqueStencil.slf b/libraries/render-utils/src/drawOpaqueStencil.slf index dae3e56c4d..883154c624 100644 --- a/libraries/render-utils/src/drawOpaqueStencil.slf +++ b/libraries/render-utils/src/drawOpaqueStencil.slf @@ -12,22 +12,18 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // - -<@include gpu/Transform.slh@> - -<$declareStandardTransform()$> - in vec2 varTexCoord0; out vec4 outFragColor; uniform sampler2D depthTexture; void main(void) { + // outFragColor = vec4(varTexCoord0, 0.0, 1.0); - float depth = texture(depthTexture, varTexCoord0).r; - - if (depth >= 0.9) { - outFragColor = vec4(1.0, 0.0, 0.0, 1.0); + float depth = texture(depthTexture, varTexCoord0.xy).r; + outFragColor = vec4(1.0, 0.0, 0.0, 1.0); + if (depth < 1.0) { + outFragColor = vec4(0.0, 1.0, 0.0, 1.0); } else { discard; } From e516281da8c3993be8a702e766145eef0153556a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 30 Sep 2015 16:15:52 -0700 Subject: [PATCH 152/212] Added closePaint script and removed no longer used spray paint scripts --- examples/closePaint.js | 258 ++++++++++++++++++++++++ examples/entityScripts/sprayPaintCan.js | 252 ----------------------- examples/sprayPaintSpawner.js | 41 ---- 3 files changed, 258 insertions(+), 293 deletions(-) create mode 100644 examples/closePaint.js delete mode 100644 examples/entityScripts/sprayPaintCan.js delete mode 100644 examples/sprayPaintSpawner.js diff --git a/examples/closePaint.js b/examples/closePaint.js new file mode 100644 index 0000000000..dc3e567823 --- /dev/null +++ b/examples/closePaint.js @@ -0,0 +1,258 @@ +// +// closePaint.js +// examples +// +// Created by Eric Levina on 9/30/15. +// Copyright 2015 High Fidelity, Inc. +// +// Run this script to be able to paint on entities you are close to, with hydras. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +var RIGHT_HAND = 1; +var LEFT_HAND = 0; + +var MIN_POINT_DISTANCE = 0.01; +var MAX_POINT_DISTANCE = 0.5; + +var SPATIAL_CONTROLLERS_PER_PALM = 2; +var TIP_CONTROLLER_OFFSET = 1; + +var TRIGGER_ON_VALUE = 0.3; + +var MAX_DISTANCE = 10; + +var STROKE_WIDTH = 0.02 +var MAX_POINTS_PER_LINE = 60; + + +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); + + + +function MyController(hand, triggerAction) { + this.hand = hand; + this.strokes = []; + this.painting = false; + + if (this.hand === RIGHT_HAND) { + this.getHandPosition = MyAvatar.getRightPalmPosition; + this.getHandRotation = MyAvatar.getRightPalmRotation; + } else { + this.getHandPosition = MyAvatar.getLeftPalmPosition; + this.getHandRotation = MyAvatar.getLeftPalmRotation; + } + + this.triggerAction = triggerAction; + this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand; + this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET; + + + this.strokeColor = { + red: 200, + green: 20, + blue: 40 + }; + + this.laserPointer = Overlays.addOverlay("circle3d", { + size: { + x: STROKE_WIDTH / 2, + y: STROKE_WIDTH / 2 + }, + color: this.strokeColor, + solid: true, + position: center + }) + this.triggerValue = 0; + this.prevTriggerValue = 0; + var _this = this; + + + this.update = function() { + this.updateControllerState() + this.search(); + if (this.canPaint === true) { + this.paint(this.intersection.intersection, this.intersection.surfaceNormal); + } + }; + + this.paint = function(position, normal) { + // print("POSITION " + position.z) + if (this.painting === false) { + if (this.oldPosition) { + this.newStroke(this.oldPosition); + } else { + this.newStroke(position); + } + this.painting = true; + } + + + + var localPoint = Vec3.subtract(position, this.strokeBasePosition); + //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on + localPoint = Vec3.sum(localPoint, Vec3.multiply(normal, 0.001 + Math.random() * .001)); //rand avoid z fighting + + var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]); + if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) { + //need a minimum distance to avoid binormal NANs + return; + } + if(this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { + //Prevents drawing lines accross models + this.painting = false; + return; + } + if(this.strokePoints.length === 0) { + localPoint = {x: 0, y: 0, z: 0}; + } + + this.strokePoints.push(localPoint); + this.strokeNormals.push(normal); + this.strokeWidths.push(STROKE_WIDTH); + Entities.editEntity(this.currentStroke, { + linePoints: this.strokePoints, + normals: this.strokeNormals, + strokeWidths: this.strokeWidths + }); + if (this.strokePoints.length === MAX_POINTS_PER_LINE) { + this.painting = false; + return; + } + this.oldPosition = position + + } + + this.newStroke = function(position) { + this.strokeBasePosition = position; + this.currentStroke = Entities.addEntity({ + position: position, + type: "PolyLine", + color: this.strokeColor, + dimensions: { + x: 50, + y: 50, + z: 50 + }, + lifetime: 100 + }); + this.strokePoints = []; + this.strokeNormals = []; + this.strokeWidths = []; + + this.strokes.push(this.currentStroke); + + } + + this.updateControllerState = function() { + var triggerValue = Controller.getActionValue(this.triggerAction); + if (triggerValue > TRIGGER_ON_VALUE && this.prevTriggerValue <= TRIGGER_ON_VALUE) { + this.squeeze(); + } else if (triggerValue < TRIGGER_ON_VALUE && this.prevTriggerValue >= TRIGGER_ON_VALUE) { + this.release() + } + + this.prevTriggerValue = triggerValue; + } + + this.squeeze = function() { + this.tryPainting = true; + + } + this.release = function() { + this.painting = false; + this.tryPainting = false; + this.canPaint = false; + this.oldPosition = null; + } + this.search = function() { + + // the trigger is being pressed, do a ray test + var handPosition = this.getHandPosition(); + var pickRay = { + origin: handPosition, + direction: Quat.getUp(this.getHandRotation()) + }; + + + this.intersection = Entities.findRayIntersection(pickRay, true); + if (this.intersection.intersects) { + var distance = Vec3.distance(handPosition, this.intersection.intersection); + if (distance < MAX_DISTANCE) { + var displayPoint = this.intersection.intersection; + displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, .001)); + if (this.tryPainting) { + this.canPaint = true; + } + Overlays.editOverlay(this.laserPointer, { + visible: true, + position: displayPoint, + rotation: orientationOf(this.intersection.surfaceNormal) + }); + + } else { + this.hitFail(); + } + } else { + this.hitFail(); + } + }; + + this.hitFail = function() { + this.canPaint = false; + + Overlays.editOverlay(this.laserPointer, { + visible: false + }); + + } + + this.cleanup = function() { + Overlays.deleteOverlay(this.laserPointer); + this.strokes.forEach(function(stroke) { + Entities.deleteEntity(stroke); + }); + } +} + +var rightController = new MyController(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); +var leftController = new MyController(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); + +function update() { + rightController.update(); + leftController.update(); +} + +function cleanup() { + rightController.cleanup(); + leftController.cleanup(); +} + +Script.scriptEnding.connect(cleanup); +Script.update.connect(update); + + +function orientationOf(vector) { + var Y_AXIS = { + x: 0, + y: 1, + z: 0 + }; + var X_AXIS = { + x: 1, + y: 0, + z: 0 + }; + + var theta = 0.0; + + var RAD_TO_DEG = 180.0 / Math.PI; + var direction, yaw, pitch; + direction = Vec3.normalize(vector); + yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); + pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); + return Quat.multiply(yaw, pitch); +} \ No newline at end of file diff --git a/examples/entityScripts/sprayPaintCan.js b/examples/entityScripts/sprayPaintCan.js deleted file mode 100644 index 21613bdeb5..0000000000 --- a/examples/entityScripts/sprayPaintCan.js +++ /dev/null @@ -1,252 +0,0 @@ -(function() { - // Script.include("../libraries/utils.js"); - //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge - - Script.include("../libraries/utils.js"); - GRAB_FRAME_USER_DATA_KEY = "grabFrame"; - this.userData = {}; - - var TIP_OFFSET_Z = 0.14; - var TIP_OFFSET_Y = 0.04; - - var ZERO_VEC = { - x: 0, - y: 0, - z: 0 - } - - var MAX_POINTS_PER_LINE = 40; - var MIN_POINT_DISTANCE = 0.01; - var STROKE_WIDTH = 0.02; - - var self = this; - - var timeSinceLastMoved = 0; - var RESET_TIME_THRESHOLD = 5; - var DISTANCE_FROM_HOME_THRESHOLD = 0.5; - var HOME_POSITION = { - x: 549.12, - y: 495.555, - z: 503.77 - }; - this.getUserData = function() { - - - if (this.properties.userData) { - this.userData = JSON.parse(this.properties.userData); - } - } - - this.updateUserData = function() { - Entities.editEntity(this.entityId, { - userData: JSON.stringify(this.userData) - }); - } - - this.update = function(deltaTime) { - self.getUserData(); - self.properties = Entities.getEntityProperties(self.entityId); - - if (Vec3.length(self.properties.velocity) < 0.1 && Vec3.distance(HOME_POSITION, self.properties.position) > DISTANCE_FROM_HOME_THRESHOLD) { - timeSinceLastMoved += deltaTime; - if (timeSinceLastMoved > RESET_TIME_THRESHOLD) { - self.reset(); - timeSinceLastMoved = 0; - } - } else { - timeSinceLastMoved = 0; - } - - //Only activate for the user who grabbed the object - if (self.userData.grabKey && self.userData.grabKey.activated === true && self.userData.grabKey.avatarId == MyAvatar.sessionUUID) { - if (self.activated !== true) { - //We were just grabbed, so create a particle system - self.grab(); - } - //Move emitter to where entity is always when its activated - self.sprayStream(); - } else if (self.userData.grabKey && self.userData.grabKey.activated === false && self.activated) { - self.letGo(); - } - } - - this.grab = function() { - this.activated = true; - var animationSettings = JSON.stringify({ - fps: 30, - loop: true, - firstFrame: 1, - lastFrame: 10000, - running: true - }); - var PI = 3.141593; - var DEG_TO_RAD = PI / 180.0; - - this.paintStream = Entities.addEntity({ - type: "ParticleEffect", - animationSettings: animationSettings, - position: this.properties.position, - textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png", - emitSpeed: 0, - speedSpread: 0.02, - polarFinish: 2 * DEG_TO_RAD, - emitAcceleration: ZERO_VEC, - emitRate: 100, - particleRadius: 0.01, - color: { - red: 170, - green: 20, - blue: 150 - }, - lifetime: 50, //probably wont be holding longer than this straight - }); - } - - this.letGo = function() { - this.activated = false; - Entities.deleteEntity(this.paintStream); - this.paintStream = null; - } - - this.reset = function() { - Entities.editEntity(self.entityId, { - position: HOME_POSITION, - rotation: Quat.fromPitchYawRollDegrees(0, 0, 0), - angularVelocity: ZERO_VEC, - velocity: ZERO_VEC - }); - } - - this.sprayStream = function() { - var forwardVec = Quat.getFront(Quat.multiply(self.properties.rotation , Quat.fromPitchYawRollDegrees(0, 90, 0))); - forwardVec = Vec3.normalize(forwardVec); - - var upVec = Quat.getUp(self.properties.rotation); - var position = Vec3.sum(self.properties.position, Vec3.multiply(forwardVec, TIP_OFFSET_Z)); - position = Vec3.sum(position, Vec3.multiply(upVec, TIP_OFFSET_Y)) - Entities.editEntity(self.paintStream, { - position: position, - emitOrientation: forwardVec, - emitSpeed: 5 - }); - - //Now check for an intersection with an entity - //move forward so ray doesnt intersect with gun - var origin = Vec3.sum(position, forwardVec); - var pickRay = { - origin: origin, - direction: Vec3.multiply(forwardVec, 2) - } - - var intersection = Entities.findRayIntersection(pickRay, true); - if (intersection.intersects) { - var normal = Vec3.multiply(-1, Quat.getFront(intersection.properties.rotation)); - this.paint(intersection.intersection, normal); - } - - - } - - this.paint = function(position, normal) { - if (!this.painting) { - - this.newStroke(position); - this.painting = true; - } - - if (this.strokePoints.length > MAX_POINTS_PER_LINE) { - this.painting = false; - return; - } - - var localPoint = Vec3.subtract(position, this.strokeBasePosition); - //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on - localPoint = Vec3.sum(localPoint, Vec3.multiply(normal, .1)); - - if (this.strokePoints.length > 0 && Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]) < MIN_POINT_DISTANCE) { - //need a minimum distance to avoid binormal NANs - return; - } - - this.strokePoints.push(localPoint); - this.strokeNormals.push(normal); - this.strokeWidths.push(STROKE_WIDTH); - Entities.editEntity(this.currentStroke, { - linePoints: this.strokePoints, - normals: this.strokeNormals, - strokeWidths: this.strokeWidths - }); - - - } - - this.newStroke = function(position) { - this.strokeBasePosition = position; - this.currentStroke = Entities.addEntity({ - position: position, - type: "PolyLine", - color: { - red: randInt(160, 250), - green: randInt(10, 20), - blue: randInt(190, 250) - }, - dimensions: { - x: 50, - y: 50, - z: 50 - }, - lifetime: 100 - }); - this.strokePoints = []; - this.strokeNormals = []; - this.strokeWidths = []; - - this.strokes.push(this.currentStroke); - } - - this.preload = function(entityId) { - this.strokes = []; - this.activated = false; - this.entityId = entityId; - this.properties = Entities.getEntityProperties(self.entityId); - this.getUserData(); - - //Only activate for the avatar who is grabbing the can! - if (this.userData.grabKey && this.userData.grabKey.activated) { - this.activated = true; - } - if (!this.userData.grabFrame) { - var data = { - relativePosition: { - x: 0, - y: 0, - z: 0 - }, - relativeRotation: Quat.fromPitchYawRollDegrees(0, 0, 0) - } - setEntityCustomData(GRAB_FRAME_USER_DATA_KEY, this.entityId, data); - } - } - - - this.unload = function() { - Script.update.disconnect(this.update); - if(this.paintStream) { - Entities.deleteEntity(this.paintStream); - } - this.strokes.forEach(function(stroke) { - Entities.deleteEntity(stroke); - }); - } - Script.update.connect(this.update); -}); - - - -function randFloat(min, max) { - return Math.random() * (max - min) + min; -} - -function randInt(min, max) { - return Math.floor(Math.random() * (max - min)) + min; -} \ No newline at end of file diff --git a/examples/sprayPaintSpawner.js b/examples/sprayPaintSpawner.js deleted file mode 100644 index 3b9cee6ef4..0000000000 --- a/examples/sprayPaintSpawner.js +++ /dev/null @@ -1,41 +0,0 @@ -// sprayPaintSpawner.js -// -// Created by Eric Levin on 9/3/15 -// Copyright 2015 High Fidelity, Inc. -// -// This is script spwans a spreay paint can model with the sprayPaintCan.js entity script attached -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - -//Just temporarily using my own bucket here so others can test the entity. Once PR is tested and merged, then the entity script will appear in its proper place in S3, and I wil switch it -// var scriptURL = "https://hifi-public.s3.amazonaws.com/eric/scripts/sprayPaintCan.js?=v6 "; -var scriptURL = Script.resolvePath("entityScripts/sprayPaintCan.js?v2"); -var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; - -var sprayCan = Entities.addEntity({ - type: "Model", - name: "spraycan", - modelURL: modelURL, - position: {x: 549.12, y:495.55, z:503.77}, - rotation: {x: 0, y: 0, z: 0, w: 1}, - dimensions: { - x: 0.07, - y: 0.17, - z: 0.07 - }, - collisionsWillMove: true, - shapeType: 'box', - script: scriptURL, - gravity: {x: 0, y: -0.5, z: 0}, - velocity: {x: 0, y: -1, z: 0} -}); - -function cleanup() { - - // Uncomment the below line to delete sprayCan on script reload- for faster iteration during development - // Entities.deleteEntity(sprayCan); -} - -Script.scriptEnding.connect(cleanup); - From 3592b78b2b1ea4e2c646a8f6385a8bafe4cfc022 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 30 Sep 2015 16:35:43 -0700 Subject: [PATCH 153/212] less points per line --- examples/closePaint.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index dc3e567823..fdd7d7cac6 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -26,7 +26,7 @@ var TRIGGER_ON_VALUE = 0.3; var MAX_DISTANCE = 10; var STROKE_WIDTH = 0.02 -var MAX_POINTS_PER_LINE = 60; +var MAX_POINTS_PER_LINE = 40; var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); @@ -221,6 +221,10 @@ function MyController(hand, triggerAction) { var rightController = new MyController(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); var leftController = new MyController(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); +Controller.actionEvent.connect(function(action, state) { + print("ACTION " + action) +}); + function update() { rightController.update(); leftController.update(); From 2899962d43f61990b36e78ed977a8e5443b9e579 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 30 Sep 2015 17:14:17 -0700 Subject: [PATCH 154/212] can now cycle colors with 4 and 2 buttons on hydra --- examples/closePaint.js | 100 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 12 deletions(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index fdd7d7cac6..fba2aa0e80 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -28,6 +28,14 @@ var MAX_DISTANCE = 10; var STROKE_WIDTH = 0.02 var MAX_POINTS_PER_LINE = 40; +var RIGHT_4_ACTION = 18; +var RIGHT_2_ACTION = 16; + +var LEFT_4_ACTION = 17; +var LEFT_2_ACTION = 16; + +var HUE_INCREMENT = 0.01; + var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); @@ -52,9 +60,9 @@ function MyController(hand, triggerAction) { this.strokeColor = { - red: 200, - green: 20, - blue: 40 + h: 0.8, + s: 0.9, + l: 0.4 }; this.laserPointer = Overlays.addOverlay("circle3d", { @@ -62,7 +70,7 @@ function MyController(hand, triggerAction) { x: STROKE_WIDTH / 2, y: STROKE_WIDTH / 2 }, - color: this.strokeColor, + color: hslToRgb(this.strokeColor), solid: true, position: center }) @@ -80,7 +88,6 @@ function MyController(hand, triggerAction) { }; this.paint = function(position, normal) { - // print("POSITION " + position.z) if (this.painting === false) { if (this.oldPosition) { this.newStroke(this.oldPosition); @@ -101,13 +108,17 @@ function MyController(hand, triggerAction) { //need a minimum distance to avoid binormal NANs return; } - if(this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { + if (this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { //Prevents drawing lines accross models this.painting = false; return; } - if(this.strokePoints.length === 0) { - localPoint = {x: 0, y: 0, z: 0}; + if (this.strokePoints.length === 0) { + localPoint = { + x: 0, + y: 0, + z: 0 + }; } this.strokePoints.push(localPoint); @@ -122,8 +133,7 @@ function MyController(hand, triggerAction) { this.painting = false; return; } - this.oldPosition = position - + this.oldPosition = position } this.newStroke = function(position) { @@ -131,7 +141,7 @@ function MyController(hand, triggerAction) { this.currentStroke = Entities.addEntity({ position: position, type: "PolyLine", - color: this.strokeColor, + color: hslToRgb(this.strokeColor), dimensions: { x: 50, y: 50, @@ -216,13 +226,39 @@ function MyController(hand, triggerAction) { Entities.deleteEntity(stroke); }); } + + this.cycleColorDown = function() { + this.strokeColor.h -= HUE_INCREMENT; + if (this.strokeColor.h < 0) { + this.strokeColor = 1; + } + } + + this.cycleColorUp = function() { + this.strokeColor.h += HUE_INCREMENT; + if (this.strokeColor.h > 1) { + this.strokeColor.h = 0; + } + } } var rightController = new MyController(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); var leftController = new MyController(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); Controller.actionEvent.connect(function(action, state) { - print("ACTION " + action) + if (state === 0) { + return; + } + if (action === RIGHT_4_ACTION) { + rightController.cycleColorUp(); + } else if (action === RIGHT_2_ACTION) { + rightController.cycleColorDown(); + } + if (action === LEFT_4_ACTION) { + leftController.cycleColorUp(); + } else if (action === LEFT_2_ACTION) { + leftController.cycleColorDown(); + } }); function update() { @@ -259,4 +295,44 @@ function orientationOf(vector) { yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); return Quat.multiply(yaw, pitch); +} + +/** + * Converts an HSL color value to RGB. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes h, s, and l are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @param Number h The hue + * @param Number s The saturation + * @param Number l The lightness + * @return Array The RGB representation + */ +function hslToRgb(hsl) { + var r, g, b; + + if (hsl.s == 0) { + r = g = b = hsl.l; // achromatic + } else { + var hue2rgb = function hue2rgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + } + + var q = hsl.l < 0.5 ? hsl.l * (1 + hsl.s) : hsl.l + hsl.s - hsl.l * hsl.s; + var p = 2 * hsl.l - q; + r = hue2rgb(p, q, hsl.h + 1 / 3); + g = hue2rgb(p, q, hsl.h); + b = hue2rgb(p, q, hsl.h - 1 / 3); + } + + return { + red: Math.round(r * 255), + green: Math.round(g * 255), + blue: Math.round(b * 255) + }; } \ No newline at end of file From be9b244779a6b4e34156a22d43004f2fde06d18d Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 17:21:52 -0700 Subject: [PATCH 155/212] Fix the skybox color issue with background rendering when no texture is there --- libraries/model/src/model/Skybox.cpp | 113 +++++++++++++++------------ libraries/model/src/model/Skybox.slf | 10 ++- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 944d16a6dd..4d49492c39 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -45,11 +45,18 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { + const int VERTICES_SLOT = 0; + const int COLOR_SLOT = 1; + + // Create the static shared elements used to render the skybox static gpu::BufferPointer theBuffer; static gpu::Stream::FormatPointer theFormat; - - if (skybox.getCubemap()) { - if (!theBuffer) { + static gpu::BufferPointer theConstants; + static gpu::PipelinePointer thePipeline; + static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader + static std::once_flag once; + std::call_once(once, [&] { + { const float CLIP = 1.0f; const glm::vec2 vertices[4] = { { -CLIP, -CLIP }, { CLIP, -CLIP }, { -CLIP, CLIP }, { CLIP, CLIP } }; theBuffer = std::make_shared(sizeof(vertices), (const gpu::Byte*) vertices); @@ -57,63 +64,65 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky theFormat->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::XYZ)); } - glm::mat4 projMat; - viewFrustum.evalProjectionMatrix(projMat); + { + auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert))); + auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag))); + auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); - Transform viewTransform; - viewFrustum.evalViewTransform(viewTransform); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewTransform); - batch.setModelTransform(Transform()); // only for Mac - batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8); - batch.setInputFormat(theFormat); + gpu::Shader::BindingSet bindings; + bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); + if (!gpu::Shader::makeProgram(*skyShader, bindings)) { - if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { - static gpu::BufferPointer theConstants; - static gpu::PipelinePointer thePipeline; - static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader - if (!thePipeline) { - auto skyVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(Skybox_vert))); - auto skyFS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(Skybox_frag))); - auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); - - gpu::Shader::BindingSet bindings; - bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); - if (!gpu::Shader::makeProgram(*skyShader, bindings)) { - - } - - SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer"); - if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) { - SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer"); - } - - auto skyState = std::make_shared(); - skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); - - thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); - - auto color = glm::vec4(1.0f); - theConstants = std::make_shared(sizeof(color), (const gpu::Byte*) &color); } - if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) { - auto color = glm::vec4(1.0f); - theConstants->setSubData(0, sizeof(color), (const gpu::Byte*) &color); - } else { - theConstants->setSubData(0, sizeof(Color), (const gpu::Byte*) &skybox.getColor()); + SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer"); + if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) { + SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer"); } - batch.setPipeline(thePipeline); - batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize()); - batch.setResourceTexture(0, skybox.getCubemap()); - batch.draw(gpu::TRIANGLE_STRIP, 4); + auto skyState = std::make_shared(); + skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); + + thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); + + auto color = glm::vec4(1.0f); + theConstants = std::make_shared(sizeof(color), (const gpu::Byte*) &color); } + }); - } else { - // skybox has no cubemap, just clear the color buffer - auto color = skybox.getColor(); - batch.clearFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(color, 0.0f), 0.0f, 0, true); + // Render + glm::mat4 projMat; + viewFrustum.evalProjectionMatrix(projMat); + + Transform viewTransform; + viewFrustum.evalViewTransform(viewTransform); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewTransform); + batch.setModelTransform(Transform()); // only for Mac + batch.setInputBuffer(gpu::Stream::POSITION, theBuffer, 0, 8); + batch.setInputFormat(theFormat); + + gpu::TexturePointer skymap; + auto color = glm::vec4(skybox.getColor(), 0.0f); + if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { + skymap = skybox.getCubemap(); + + if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) { + color = glm::vec4(1.0f); + } else { + color.w = 1.0f; + } } + // Update the constant color. + theConstants->setSubData(0, sizeof(glm::vec4), (const gpu::Byte*) &color); + + batch.setPipeline(thePipeline); + batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize()); + batch.setResourceTexture(0, skymap); + + batch.draw(gpu::TRIANGLE_STRIP, 4); + + batch.setResourceTexture(0, nullptr); + } diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index 382801f52d..66abee8948 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -40,8 +40,14 @@ void main(void) { #else vec3 coord = normalize(_normal); - vec3 texel = texture(cubeMap, coord).rgb; - vec3 color = texel * _skybox._color.rgb; + + // Skybox color or blend with skymap + vec3 color = _skybox._color.rgb; + if (_skybox._color.a > 0.0) { + vec3 texel = texture(cubeMap, coord).rgb; + color *= texel; + } + vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction _fragColor = vec4(pixel, 0.0); From d3d47752327dd0a90fee77e30993d5c16bcb0193 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 17:54:20 -0700 Subject: [PATCH 156/212] THe dataBuffer contining the properties of the skybox is now per instace and not static and shared so it's static from frames to frames --- libraries/model/src/model/Skybox.cpp | 55 ++++++++++--------- libraries/model/src/model/Skybox.h | 18 ++++-- .../src/procedural/ProceduralSkybox.cpp | 1 + 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 4d49492c39..7c22d7a062 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -21,6 +21,8 @@ using namespace model; Skybox::Skybox() { + Data data; + _dataBuffer = gpu::BufferView(std::make_shared(sizeof(Data), (const gpu::Byte*) &data)); /* // PLease create a default engineer skybox _cubemap.reset( gpu::Texture::createCube(gpu::Element::COLOR_RGBA_32, 1)); @@ -36,7 +38,7 @@ Skybox::Skybox() { } void Skybox::setColor(const Color& color) { - _color = color; + _dataBuffer.edit()._color = color; } void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { @@ -44,16 +46,33 @@ void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { } -void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { - const int VERTICES_SLOT = 0; - const int COLOR_SLOT = 1; +void Skybox::updateDataBuffer() const { + auto blend = 0.0f; + if (getCubemap() && getCubemap()->isDefined()) { + blend = 1.0f; + } + if (blend != _dataBuffer.get()._blend) { + _dataBuffer.edit()._blend = blend; + } +} + + + +void Skybox::render(gpu::Batch& batch, const ViewFrustum& frustum) const { + updateDataBuffer(); + Skybox::render(batch, frustum, (*this)); +} + + +void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { // Create the static shared elements used to render the skybox static gpu::BufferPointer theBuffer; static gpu::Stream::FormatPointer theFormat; static gpu::BufferPointer theConstants; static gpu::PipelinePointer thePipeline; - static int SKYBOX_CONSTANTS_SLOT = 0; // need to be defined by the compilation of the shader + const int SKYBOX_SKYMAP_SLOT = 0; + const int SKYBOX_CONSTANTS_SLOT = 0; static std::once_flag once; std::call_once(once, [&] { { @@ -70,23 +89,16 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyVS, skyFS)); gpu::Shader::BindingSet bindings; - bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), 0)); + bindings.insert(gpu::Shader::Binding(std::string("cubeMap"), SKYBOX_SKYMAP_SLOT)); + bindings.insert(gpu::Shader::Binding(std::string("skyboxBuffer"), SKYBOX_CONSTANTS_SLOT)); if (!gpu::Shader::makeProgram(*skyShader, bindings)) { } - SKYBOX_CONSTANTS_SLOT = skyShader->getBuffers().findLocation("skyboxBuffer"); - if (SKYBOX_CONSTANTS_SLOT == gpu::Shader::INVALID_LOCATION) { - SKYBOX_CONSTANTS_SLOT = skyShader->getUniforms().findLocation("skyboxBuffer"); - } - auto skyState = std::make_shared(); skyState->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); thePipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); - - auto color = glm::vec4(1.0f); - theConstants = std::make_shared(sizeof(color), (const gpu::Byte*) &color); } }); @@ -103,26 +115,17 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.setInputFormat(theFormat); gpu::TexturePointer skymap; - auto color = glm::vec4(skybox.getColor(), 0.0f); if (skybox.getCubemap() && skybox.getCubemap()->isDefined()) { skymap = skybox.getCubemap(); - - if (glm::all(glm::equal(skybox.getColor(), glm::vec3(0.0f)))) { - color = glm::vec4(1.0f); - } else { - color.w = 1.0f; - } } - // Update the constant color. - theConstants->setSubData(0, sizeof(glm::vec4), (const gpu::Byte*) &color); batch.setPipeline(thePipeline); - batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, theConstants, 0, theConstants->getSize()); - batch.setResourceTexture(0, skymap); + batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, skybox._dataBuffer); + batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, skymap); batch.draw(gpu::TRIANGLE_STRIP, 4); - batch.setResourceTexture(0, nullptr); + batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); } diff --git a/libraries/model/src/model/Skybox.h b/libraries/model/src/model/Skybox.h index e9f95afa16..14ba9fa005 100755 --- a/libraries/model/src/model/Skybox.h +++ b/libraries/model/src/model/Skybox.h @@ -30,20 +30,28 @@ public: virtual ~Skybox() {}; void setColor(const Color& color); - const Color& getColor() const { return _color; } + const Color getColor() const { return _dataBuffer.get()._color; } void setCubemap(const gpu::TexturePointer& cubemap); const gpu::TexturePointer& getCubemap() const { return _cubemap; } - virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const { - render(batch, frustum, (*this)); - } + virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const; + static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox); protected: gpu::TexturePointer _cubemap; - Color _color{1.0f, 1.0f, 1.0f}; + + class Data { + public: + glm::vec3 _color{ 1.0f, 1.0f, 1.0f }; + float _blend = 1.0f; + }; + + mutable gpu::BufferView _dataBuffer; + + void updateDataBuffer() const; }; typedef std::shared_ptr< Skybox > SkyboxPointer; diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index f69e0575de..1c7e7e457c 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -43,6 +43,7 @@ void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& frustum) con void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const ProceduralSkybox& skybox) { if (!(skybox._procedural)) { + skybox.updateDataBuffer(); Skybox::render(batch, viewFrustum, skybox); } From 69c40754390f7e70dcfcd16f79bf14f278e5286f Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 18:08:01 -0700 Subject: [PATCH 157/212] Fix the behavior when skybox color is black and skymap is available --- libraries/model/src/model/Skybox.cpp | 4 ++++ libraries/model/src/model/Skybox.slf | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 7c22d7a062..21b40a54c8 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -50,6 +50,10 @@ void Skybox::updateDataBuffer() const { auto blend = 0.0f; if (getCubemap() && getCubemap()->isDefined()) { blend = 1.0f; + // If pitch black neutralize the color + if (glm::all(glm::equal(getColor(), glm::vec3(0.0f)))) { + blend = 2.0f; + } } if (blend != _dataBuffer.get()._blend) { diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index 66abee8948..a6283055d3 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -45,7 +45,9 @@ void main(void) { vec3 color = _skybox._color.rgb; if (_skybox._color.a > 0.0) { vec3 texel = texture(cubeMap, coord).rgb; - color *= texel; + if (_skybox._color.a < 2.0) { + color *= texel; + } } vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction From 0398f9429e9d7d21f181167664b52eb0799aecd7 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 30 Sep 2015 18:39:13 -0700 Subject: [PATCH 158/212] fix the coo/texel blender mode for the case when color is black and the stereo issue --- libraries/model/src/model/Skybox.cpp | 2 +- libraries/model/src/model/Skybox.slf | 2 ++ libraries/render-utils/src/RenderDeferredTask.cpp | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 21b40a54c8..e516fae583 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -129,7 +129,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.draw(gpu::TRIANGLE_STRIP, 4); - batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); + // batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); } diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index a6283055d3..6246bbd9d3 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -47,6 +47,8 @@ void main(void) { vec3 texel = texture(cubeMap, coord).rgb; if (_skybox._color.a < 2.0) { color *= texel; + } else { + color = texel; } } diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index e16544f5cd..504070963d 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -335,9 +335,10 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren batch.enableStereo(false); batch.setFramebuffer(primaryFboColorDepthStencil); - batch.clearStencilFramebuffer(0, true); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); + batch.clearStencilFramebuffer(0, true); + Transform modelMat; batch.setModelTransform(modelMat); From 4e29d8382dc4a026b60fccd81c050776c34d17bc Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 1 Oct 2015 03:24:10 -0700 Subject: [PATCH 159/212] SSE2 optimization of new resampler. 3.5x faster for all modes. Dither is always enabled. --- libraries/audio/src/AudioSRC.cpp | 400 ++++++++++++++++++++++++++----- 1 file changed, 343 insertions(+), 57 deletions(-) diff --git a/libraries/audio/src/AudioSRC.cpp b/libraries/audio/src/AudioSRC.cpp index 736b098def..e33d399213 100644 --- a/libraries/audio/src/AudioSRC.cpp +++ b/libraries/audio/src/AudioSRC.cpp @@ -558,30 +558,8 @@ static const float Q32_TO_FLOAT = 1.0f / (1ULL << 32); // blocking size in frames, chosen so block processing fits in L1 cache static const int SRC_BLOCK = 1024; -//#define SRC_DITHER -#define RAND16(r) (((r) = (r) * 69069u + 1u) >> 16) - -// these are performance sensitive -#define lo32(a) (((uint32_t* )&(a))[0]) -#define hi32(a) (((int32_t* )&(a))[1]) - -//#define lo32(a) ((uint32_t)(a)) -//#define hi32(a) ((int32_t)((a) >> 32)) - -//static inline uint32_t lo32(int64_t a) { -// union { -// int64_t val; -// struct { uint32_t lo; int32_t hi; } reg; -// } b = { a }; -// return b.reg.lo; -//} -//static inline int32_t hi32(int64_t a) { -// union { -// int64_t val; -// struct { uint32_t lo; int32_t hi; } reg; -// } b = { a }; -// return b.reg.hi; -//} +#define lo32(a) ((uint32_t)(a)) +#define hi32(a) ((int32_t)((a) >> 32)) // // Portable aligned malloc/free @@ -671,6 +649,7 @@ int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain) { numTaps = (numCoefs + upFactor - 1) / upFactor; gain *= (float)oldCoefs / numCoefs; } + numTaps = (numTaps + 3) & ~3; // SIMD4 // interpolate the coefficients of the prototype filter float* tempFilter = new float[numTaps * numPhases]; @@ -679,7 +658,7 @@ int AudioSRC::createRationalFilter(int upFactor, int downFactor, float gain) { cubicInterpolation(prototypeFilter, tempFilter, prototypeCoefs, numCoefs, gain); // create the polyphase filter - _polyphaseFilter = (float*)aligned_malloc(numTaps * numPhases * sizeof(float), 32); + _polyphaseFilter = (float*)aligned_malloc(numTaps * numPhases * sizeof(float), 16); // SIMD4 // rearrange into polyphase form, ordered by use for (int i = 0; i < numPhases; i++) { @@ -720,6 +699,7 @@ int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) { numTaps = (numCoefs + upFactor - 1) / upFactor; gain *= (float)oldCoefs / numCoefs; } + numTaps = (numTaps + 3) & ~3; // SIMD4 // interpolate the coefficients of the prototype filter float* tempFilter = new float[numTaps * numPhases]; @@ -728,7 +708,7 @@ int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) { cubicInterpolation(prototypeFilter, tempFilter, prototypeCoefs, numCoefs, gain); // create the polyphase filter, with extra phase at the end to simplify coef interpolation - _polyphaseFilter = (float*)aligned_malloc(numTaps * (numPhases + 1) * sizeof(float), 32); + _polyphaseFilter = (float*)aligned_malloc(numTaps * (numPhases + 1) * sizeof(float), 16); // SIMD4 // rearrange into polyphase form, ordered by fractional delay for (int phase = 0; phase < numPhases; phase++) { @@ -754,6 +734,284 @@ int AudioSRC::createIrrationalFilter(int upFactor, int downFactor, float gain) { return numTaps; } +// +// on x86 architecture, assume that SSE2 is present +// +#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__) + +#include + +int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFrames) { + int outputFrames = 0; + + assert((_numTaps & 0x3) == 0); // SIMD4 + + if (_step == 0) { // rational + + int32_t i = hi32(_offset); + + while (i < inputFrames) { + + const float* c0 = &_polyphaseFilter[_numTaps * _phase]; + + __m128 acc0 = _mm_setzero_ps(); + + for (int j = 0; j < _numTaps; j += 4) { + + //float coef = c0[j]; + __m128 coef0 = _mm_loadu_ps(&c0[j]); + + //acc0 += input0[i + j] * coef; + acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0); + } + + // horizontal sum + acc0 = _mm_add_ps(acc0, _mm_movehl_ps(acc0, acc0)); + acc0 = _mm_add_ss(acc0, _mm_shuffle_ps(acc0, acc0, _MM_SHUFFLE(0,0,0,1))); + + _mm_store_ss(&output0[outputFrames], acc0); + outputFrames += 1; + + i += _stepTable[_phase]; + if (++_phase == _upFactor) { + _phase = 0; + } + } + _offset = (int64_t)(i - inputFrames) << 32; + + } else { // irrational + + while (hi32(_offset) < inputFrames) { + + int32_t i = hi32(_offset); + uint32_t f = lo32(_offset); + + uint32_t phase = f >> SRC_FRACBITS; + __m128 frac = _mm_set1_ps((f & SRC_FRACMASK) * QFRAC_TO_FLOAT); + + const float* c0 = &_polyphaseFilter[_numTaps * (phase + 0)]; + const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)]; + + __m128 acc0 = _mm_setzero_ps(); + + for (int j = 0; j < _numTaps; j += 4) { + + //float coef = c0[j] + frac * (c1[j] - c0[j]); + __m128 coef0 = _mm_loadu_ps(&c0[j]); + __m128 coef1 = _mm_loadu_ps(&c1[j]); + coef1 = _mm_sub_ps(coef1, coef0); + coef0 = _mm_add_ps(_mm_mul_ps(coef1, frac), coef0); + + //acc0 += input0[i + j] * coef; + acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0); + } + + // horizontal sum + acc0 = _mm_add_ps(acc0, _mm_movehl_ps(acc0, acc0)); + acc0 = _mm_add_ss(acc0, _mm_shuffle_ps(acc0, acc0, _MM_SHUFFLE(0,0,0,1))); + + _mm_store_ss(&output0[outputFrames], acc0); + outputFrames += 1; + + _offset += _step; + } + _offset -= (int64_t)inputFrames << 32; + } + + return outputFrames; +} + +int AudioSRC::multirateFilter2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames) { + int outputFrames = 0; + + assert((_numTaps & 0x3) == 0); // SIMD4 + + if (_step == 0) { // rational + + int32_t i = hi32(_offset); + + while (i < inputFrames) { + + const float* c0 = &_polyphaseFilter[_numTaps * _phase]; + + __m128 acc0 = _mm_setzero_ps(); + __m128 acc1 = _mm_setzero_ps(); + + for (int j = 0; j < _numTaps; j += 4) { + + //float coef = c0[j]; + __m128 coef0 = _mm_loadu_ps(&c0[j]); + + //acc0 += input0[i + j] * coef; + acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0); + acc1 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input1[i + j]), coef0), acc1); + } + + // horizontal sum + acc0 = _mm_add_ps(acc0, _mm_movehl_ps(acc0, acc0)); + acc1 = _mm_add_ps(acc1, _mm_movehl_ps(acc1, acc1)); + acc0 = _mm_add_ss(acc0, _mm_shuffle_ps(acc0, acc0, _MM_SHUFFLE(0,0,0,1))); + acc1 = _mm_add_ss(acc1, _mm_shuffle_ps(acc1, acc1, _MM_SHUFFLE(0,0,0,1))); + + _mm_store_ss(&output0[outputFrames], acc0); + _mm_store_ss(&output1[outputFrames], acc1); + outputFrames += 1; + + i += _stepTable[_phase]; + if (++_phase == _upFactor) { + _phase = 0; + } + } + _offset = (int64_t)(i - inputFrames) << 32; + + } else { // irrational + + while (hi32(_offset) < inputFrames) { + + int32_t i = hi32(_offset); + uint32_t f = lo32(_offset); + + uint32_t phase = f >> SRC_FRACBITS; + __m128 frac = _mm_set1_ps((f & SRC_FRACMASK) * QFRAC_TO_FLOAT); + + const float* c0 = &_polyphaseFilter[_numTaps * (phase + 0)]; + const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)]; + + __m128 acc0 = _mm_setzero_ps(); + __m128 acc1 = _mm_setzero_ps(); + + for (int j = 0; j < _numTaps; j += 4) { + + //float coef = c0[j] + frac * (c1[j] - c0[j]); + __m128 coef0 = _mm_loadu_ps(&c0[j]); + __m128 coef1 = _mm_loadu_ps(&c1[j]); + coef1 = _mm_sub_ps(coef1, coef0); + coef0 = _mm_add_ps(_mm_mul_ps(coef1, frac), coef0); + + //acc0 += input0[i + j] * coef; + acc0 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input0[i + j]), coef0), acc0); + acc1 = _mm_add_ps(_mm_mul_ps(_mm_loadu_ps(&input1[i + j]), coef0), acc1); + } + + // horizontal sum + acc0 = _mm_add_ps(acc0, _mm_movehl_ps(acc0, acc0)); + acc1 = _mm_add_ps(acc1, _mm_movehl_ps(acc1, acc1)); + acc0 = _mm_add_ss(acc0, _mm_shuffle_ps(acc0, acc0, _MM_SHUFFLE(0,0,0,1))); + acc1 = _mm_add_ss(acc1, _mm_shuffle_ps(acc1, acc1, _MM_SHUFFLE(0,0,0,1))); + + _mm_store_ss(&output0[outputFrames], acc0); + _mm_store_ss(&output1[outputFrames], acc1); + outputFrames += 1; + + _offset += _step; + } + _offset -= (int64_t)inputFrames << 32; + } + + return outputFrames; +} + +// convert int16_t to float, deinterleave stereo +void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int numFrames) { + __m128 scale = _mm_set1_ps(1/32768.0f); + + numFrames = (numFrames + 3) & ~3; // SIMD4 can overcompute + assert(numFrames <= SRC_BLOCK); + + if (_numChannels == 1) { + for (int i = 0; i < numFrames; i += 4) { + + __m128i a0 = _mm_loadl_epi64((__m128i*)&input[i]); + + // sign-extend + a0 = _mm_srai_epi32(_mm_unpacklo_epi16(a0, a0), 16); + + __m128 f0 = _mm_mul_ps(_mm_cvtepi32_ps(a0), scale); + + _mm_storeu_ps(&outputs[0][i], f0); + } + } else if (_numChannels == 2) { + for (int i = 0; i < numFrames; i += 4) { + + __m128i a0 = _mm_loadu_si128((__m128i*)&input[2*i]); + __m128i a1 = a0; + + // deinterleave and sign-extend + a0 = _mm_madd_epi16(a0, _mm_set1_epi32(0x00000001)); + a1 = _mm_madd_epi16(a1, _mm_set1_epi32(0x00010000)); + + __m128 f0 = _mm_mul_ps(_mm_cvtepi32_ps(a0), scale); + __m128 f1 = _mm_mul_ps(_mm_cvtepi32_ps(a1), scale); + + _mm_storeu_ps(&outputs[0][i], f0); + _mm_storeu_ps(&outputs[1][i], f1); + } + } +} + +// fast TPDF dither in [-1.0f, 1.0f] +static inline __m128 dither4() { + static __m128i rz = _mm_set_epi16(0, -12285, 8251, 22985, -4297, 14758, -19785, -26093); + + // update the parallel LCGs + rz = _mm_mullo_epi16(rz, _mm_set1_epi16(25173)); + rz = _mm_add_epi16(rz, _mm_set1_epi16(13849)); + + // promote to 32-bit + __m128i r0 = _mm_unpacklo_epi16(rz, _mm_setzero_si128()); + __m128i r1 = _mm_unpackhi_epi16(rz, _mm_setzero_si128()); + + // return (r0 - r1) * (1/65536.0f); + __m128 d0 = _mm_cvtepi32_ps(_mm_sub_epi32(r0, r1)); + return _mm_mul_ps(d0, _mm_set1_ps(1/65536.0f)); +} + +// convert float to int16_t, interleave stereo +void AudioSRC::convertOutputToInt16(float** inputs, int16_t* output, int numFrames) { + __m128 scale = _mm_set1_ps(32768.0f); + + numFrames = (numFrames + 3) & ~3; // SIMD4 can overcompute + assert(numFrames <= SRC_BLOCK); + + if (_numChannels == 1) { + for (int i = 0; i < numFrames; i += 4) { + + __m128 f0 = _mm_mul_ps(_mm_loadu_ps(&inputs[0][i]), scale); + + f0 = _mm_add_ps(f0, dither4()); + + // round and saturate + __m128i a0 = _mm_cvtps_epi32(f0); + a0 = _mm_packs_epi32(a0, a0); + + _mm_storel_epi64((__m128i*)&output[i], a0); + } + } else if (_numChannels == 2) { + for (int i = 0; i < numFrames; i += 4) { + + __m128 f0 = _mm_mul_ps(_mm_loadu_ps(&inputs[0][i]), scale); + __m128 f1 = _mm_mul_ps(_mm_loadu_ps(&inputs[1][i]), scale); + + __m128 d0 = dither4(); + f0 = _mm_add_ps(f0, d0); + f1 = _mm_add_ps(f1, d0); + + // round and saturate + __m128i a0 = _mm_cvtps_epi32(f0); + __m128i a1 = _mm_cvtps_epi32(f1); + a0 = _mm_packs_epi32(a0, a0); + a1 = _mm_packs_epi32(a1, a1); + + // interleave + a0 = _mm_unpacklo_epi16(a0, a1); + + _mm_storeu_si128((__m128i*)&output[2*i], a0); + } + } +} + +#else + int AudioSRC::multirateFilter1(const float* input0, float* output0, int inputFrames) { int outputFrames = 0; @@ -886,45 +1144,73 @@ int AudioSRC::multirateFilter2(const float* input0, const float* input1, float* return outputFrames; } -// convert int16_t to float -// deinterleave stereo samples +// convert int16_t to float, deinterleave stereo void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int numFrames) { - for (int i = 0; i < numFrames; i++) { - for (int j = 0; j < _numChannels; j++) { + const float scale = 1/32768.0f; - float f = (float)input[_numChannels*i + j]; - outputs[j][i] = f * (1.0f/32768.0f); + if (_numChannels == 1) { + for (int i = 0; i < numFrames; i++) { + outputs[0][i] = (float)input[i] * scale; + } + } else if (_numChannels == 2) { + for (int i = 0; i < numFrames; i++) { + outputs[0][i] = (float)input[2*i + 0] * scale; + outputs[1][i] = (float)input[2*i + 1] * scale; } } } -// convert float to int16_t -// interleave stereo samples +// fast TPDF dither in [-1.0f, 1.0f] +static inline float dither() { + static uint32_t rz = 0; + rz = rz * 69069 + 1; + int32_t r0 = rz & 0xffff; + int32_t r1 = rz >> 16; + return (r0 - r1) * (1/65536.0f); +} + +// convert float to int16_t, interleave stereo void AudioSRC::convertOutputToInt16(float** inputs, int16_t* output, int numFrames) { - for (int i = 0; i < numFrames; i++) { - for (int j = 0; j < _numChannels; j++) { + const float scale = 32768.0f; - float f = inputs[j][i] * 32768.0f; + if (_numChannels == 1) { + for (int i = 0; i < numFrames; i++) { -#ifdef SRC_DITHER - // TPDF dither in [-1.0f, 1.0f] - static uint32_t rz = 1; - int r0 = RAND16(rz); - int r1 = RAND16(rz); - f += (r0 - r1) * (1.0f/65536.0f); + float f = inputs[0][i] * scale; - // round + f += dither(); + + // round and saturate f += (f < 0.0f ? -0.5f : +0.5f); -#endif - // saturate - f = std::min(f, 32767.0f); - f = std::max(f, -32768.0f); + f = std::max(std::min(f, 32767.0f), -32768.0f); - output[_numChannels * i + j] = (int16_t)f; + output[i] = (int16_t)f; + } + } else if (_numChannels == 2) { + for (int i = 0; i < numFrames; i++) { + + float f0 = inputs[0][i] * scale; + float f1 = inputs[1][i] * scale; + + float d = dither(); + f0 += d; + f1 += d; + + // round and saturate + f0 += (f0 < 0.0f ? -0.5f : +0.5f); + f1 += (f1 < 0.0f ? -0.5f : +0.5f); + f0 = std::max(std::min(f0, 32767.0f), -32768.0f); + f1 = std::max(std::min(f1, 32767.0f), -32768.0f); + + // interleave + output[2*i + 0] = (int16_t)f0; + output[2*i + 1] = (int16_t)f1; } } } +#endif + int AudioSRC::processFloat(float** inputs, float** outputs, int inputFrames) { int outputFrames = 0; @@ -1019,10 +1305,10 @@ AudioSRC::AudioSRC(int inputSampleRate, int outputSampleRate, int numChannels) { _history[1] = new float[2 * _numHistory]; // format conversion buffers - _inputs[0] = new float[SRC_BLOCK]; - _inputs[1] = new float[SRC_BLOCK]; - _outputs[0] = new float[SRC_BLOCK]; - _outputs[1] = new float[SRC_BLOCK]; + _inputs[0] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16); // SIMD4 + _inputs[1] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16); + _outputs[0] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16); + _outputs[1] = (float*)aligned_malloc(SRC_BLOCK * sizeof(float), 16); // input blocking size, such that input and output are both guaranteed not to exceed SRC_BLOCK frames _inputBlock = std::min(SRC_BLOCK, getMaxInput(SRC_BLOCK)); @@ -1041,10 +1327,10 @@ AudioSRC::~AudioSRC() { delete[] _history[0]; delete[] _history[1]; - delete[] _inputs[0]; - delete[] _inputs[1]; - delete[] _outputs[0]; - delete[] _outputs[1]; + aligned_free(_inputs[0]); + aligned_free(_inputs[1]); + aligned_free(_outputs[0]); + aligned_free(_outputs[1]); } // From ef7e908675e7fdaebc6e73d8aec2f1468e217f6e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 30 Sep 2015 18:03:15 -0700 Subject: [PATCH 160/212] allow dynamic objects to be set collisionless --- libraries/entities/src/BoxEntityItem.h | 1 + libraries/entities/src/EntityItem.h | 2 +- libraries/entities/src/SphereEntityItem.h | 1 + libraries/physics/src/EntityMotionState.cpp | 6 ++++++ libraries/physics/src/ObjectMotionState.h | 8 ++++---- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/libraries/entities/src/BoxEntityItem.h b/libraries/entities/src/BoxEntityItem.h index fdc66dd3e5..cc3bba4823 100644 --- a/libraries/entities/src/BoxEntityItem.h +++ b/libraries/entities/src/BoxEntityItem.h @@ -52,6 +52,7 @@ public: } virtual ShapeType getShapeType() const { return SHAPE_TYPE_BOX; } + virtual bool shouldBePhysical() const { return true; } virtual void debugDump() const; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 62b436b498..f070e2c1e4 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -334,7 +334,7 @@ public: bool getCollisionsWillMove() const { return _collisionsWillMove; } void setCollisionsWillMove(bool value) { _collisionsWillMove = value; } - virtual bool shouldBePhysical() const { return !_ignoreForCollisions; } + virtual bool shouldBePhysical() const { return false; } bool getLocked() const { return _locked; } void setLocked(bool value) { _locked = value; } diff --git a/libraries/entities/src/SphereEntityItem.h b/libraries/entities/src/SphereEntityItem.h index 19ea5d06f9..81a6cf704c 100644 --- a/libraries/entities/src/SphereEntityItem.h +++ b/libraries/entities/src/SphereEntityItem.h @@ -51,6 +51,7 @@ public: } virtual ShapeType getShapeType() const { return SHAPE_TYPE_SPHERE; } + virtual bool shouldBePhysical() const { return true; } virtual bool supportsDetailedRayIntersection() const { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index ff546dbb0b..9cbe89dda6 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -596,6 +596,12 @@ QString EntityMotionState::getName() { // virtual int16_t EntityMotionState::computeCollisionGroup() { + if (!_entity) { + return COLLISION_GROUP_STATIC; + } + if (_entity->getIgnoreForCollisions()) { + return COLLISION_GROUP_COLLISIONLESS; + } switch (computeObjectMotionType()){ case MOTION_TYPE_STATIC: return COLLISION_GROUP_STATIC; diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 1bdf8b6372..61254e49bd 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -37,11 +37,11 @@ enum MotionStateType { // The update flags trigger two varieties of updates: "hard" which require the body to be pulled // and re-added to the physics engine and "easy" which just updates the body properties. -const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_MOTION_TYPE | EntityItem::DIRTY_SHAPE); +const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_MOTION_TYPE | EntityItem::DIRTY_SHAPE | + EntityItem::DIRTY_COLLISION_GROUP); const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_TRANSFORM | EntityItem::DIRTY_VELOCITIES | - EntityItem::DIRTY_MASS | EntityItem::DIRTY_COLLISION_GROUP | - EntityItem::DIRTY_MATERIAL | EntityItem::DIRTY_SIMULATOR_ID | - EntityItem::DIRTY_SIMULATOR_OWNERSHIP); + EntityItem::DIRTY_MASS | EntityItem::DIRTY_MATERIAL | + EntityItem::DIRTY_SIMULATOR_ID | EntityItem::DIRTY_SIMULATOR_OWNERSHIP); // These are the set of incoming flags that the PhysicsEngine needs to hear about: const uint32_t DIRTY_PHYSICS_FLAGS = (uint32_t)(HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSICS_FLAGS | From 22b66077604e699d1725cc4c44e1a9594993b080 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 30 Sep 2015 18:15:34 -0700 Subject: [PATCH 161/212] add polyvox entities to physics engine --- libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index e1e042f3d0..ef44ba5ab0 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -79,6 +79,7 @@ public: glm::mat4 localToVoxelMatrix() const; virtual ShapeType getShapeType() const; + virtual bool shouldBePhysical() const { return true; } virtual bool isReadyToComputeShape(); virtual void computeShapeInfo(ShapeInfo& info); From 381c98c4fa268b09ec81c85d38ad4a8676a58db0 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 30 Sep 2015 18:32:08 -0700 Subject: [PATCH 162/212] fix for ModelEntityItem::shouldBePhysical() --- libraries/entities/src/ModelEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 70747937d8..cd9e3cd3e1 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -457,5 +457,5 @@ QString ModelEntityItem::getAnimationSettings() const { // virtual bool ModelEntityItem::shouldBePhysical() const { - return EntityItem::shouldBePhysical() && getShapeType() != SHAPE_TYPE_NONE; + return getShapeType() != SHAPE_TYPE_NONE; } From 191a4740a392905e148238aa60198749ea2b11fb Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 09:50:58 -0700 Subject: [PATCH 163/212] laser color matches paint color --- examples/acScripts/rain.js | 6 ++++-- examples/closePaint.js | 17 +++++++++++------ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/examples/acScripts/rain.js b/examples/acScripts/rain.js index 3f38b8d36a..fc02b7163f 100644 --- a/examples/acScripts/rain.js +++ b/examples/acScripts/rain.js @@ -18,7 +18,7 @@ var RainSquall = function (properties) { dropFallSpeed = 1, // m/s dropLifetime = 60, // Seconds dropSpinMax = 0, // Maximum angular velocity per axis; deg/s - debug = false, // Display origin circle; don't use running on Stack Manager + debug = true, // Display origin circle; don't use running on Stack Manager // Other squallCircle, SQUALL_CIRCLE_COLOR = { red: 255, green: 0, blue: 0 }, @@ -151,8 +151,10 @@ var RainSquall = function (properties) { }; }; +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); +center.y += 10; var rainSquall1 = new RainSquall({ - origin: { x: 1195, y: 1223, z: 1020 }, + origin:center, radius: 25, dropsPerMinute: 120, dropSize: { x: 0.1, y: 0.1, z: 0.1 }, diff --git a/examples/closePaint.js b/examples/closePaint.js index fba2aa0e80..c17402857b 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -34,7 +34,7 @@ var RIGHT_2_ACTION = 16; var LEFT_4_ACTION = 17; var LEFT_2_ACTION = 16; -var HUE_INCREMENT = 0.01; +var HUE_INCREMENT = 0.02; var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); @@ -61,16 +61,17 @@ function MyController(hand, triggerAction) { this.strokeColor = { h: 0.8, - s: 0.9, + s: 0.8, l: 0.4 }; + this.laserPointer = Overlays.addOverlay("circle3d", { size: { x: STROKE_WIDTH / 2, y: STROKE_WIDTH / 2 }, - color: hslToRgb(this.strokeColor), + color: hslToRgb(this.strokeColor ), solid: true, position: center }) @@ -78,7 +79,6 @@ function MyController(hand, triggerAction) { this.prevTriggerValue = 0; var _this = this; - this.update = function() { this.updateControllerState() this.search(); @@ -232,6 +232,9 @@ function MyController(hand, triggerAction) { if (this.strokeColor.h < 0) { this.strokeColor = 1; } + Overlays.editOverlay(this.laserPointer, { + color: hslToRgb(this.strokeColor) + }); } this.cycleColorUp = function() { @@ -239,6 +242,9 @@ function MyController(hand, triggerAction) { if (this.strokeColor.h > 1) { this.strokeColor.h = 0; } + Overlays.editOverlay(this.laserPointer, { + color: hslToRgb(this.strokeColor) + }); } } @@ -308,9 +314,8 @@ function orientationOf(vector) { * @param Number l The lightness * @return Array The RGB representation */ -function hslToRgb(hsl) { +function hslToRgb(hsl, hueOffset) { var r, g, b; - if (hsl.s == 0) { r = g = b = hsl.l; // achromatic } else { From ef5ad9eeb3eea43592872ec6a139898f00e32749 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 11:02:22 -0700 Subject: [PATCH 164/212] Laser stays visible when further away from surfaces --- examples/closePaint.js | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index c17402857b..fa692e0bbc 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -21,11 +21,10 @@ var MAX_POINT_DISTANCE = 0.5; var SPATIAL_CONTROLLERS_PER_PALM = 2; var TIP_CONTROLLER_OFFSET = 1; -var TRIGGER_ON_VALUE = 0.3; +var TRIGGER_ON_VALUE = 0.1; var MAX_DISTANCE = 10; -var STROKE_WIDTH = 0.02 var MAX_POINTS_PER_LINE = 40; var RIGHT_4_ACTION = 18; @@ -36,6 +35,9 @@ var LEFT_2_ACTION = 16; var HUE_INCREMENT = 0.02; +var MIN_STROKE_WIDTH = 0.005; +var MAX_STROKE_WIDTH = 0.03; + var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); @@ -45,6 +47,7 @@ function MyController(hand, triggerAction) { this.hand = hand; this.strokes = []; this.painting = false; + this.currentStrokeWidth = MIN_STROKE_WIDTH; if (this.hand === RIGHT_HAND) { this.getHandPosition = MyAvatar.getRightPalmPosition; @@ -67,11 +70,7 @@ function MyController(hand, triggerAction) { this.laserPointer = Overlays.addOverlay("circle3d", { - size: { - x: STROKE_WIDTH / 2, - y: STROKE_WIDTH / 2 - }, - color: hslToRgb(this.strokeColor ), + color: hslToRgb(this.strokeColor), solid: true, position: center }) @@ -123,7 +122,7 @@ function MyController(hand, triggerAction) { this.strokePoints.push(localPoint); this.strokeNormals.push(normal); - this.strokeWidths.push(STROKE_WIDTH); + this.strokeWidths.push(this.currentStrokeWidth); Entities.editEntity(this.currentStroke, { linePoints: this.strokePoints, normals: this.strokeNormals, @@ -158,14 +157,14 @@ function MyController(hand, triggerAction) { } this.updateControllerState = function() { - var triggerValue = Controller.getActionValue(this.triggerAction); - if (triggerValue > TRIGGER_ON_VALUE && this.prevTriggerValue <= TRIGGER_ON_VALUE) { + this.triggerValue = Controller.getActionValue(this.triggerAction); + if (this.triggerValue > TRIGGER_ON_VALUE && this.prevTriggerValue <= TRIGGER_ON_VALUE) { this.squeeze(); - } else if (triggerValue < TRIGGER_ON_VALUE && this.prevTriggerValue >= TRIGGER_ON_VALUE) { + } else if (this.triggerValue < TRIGGER_ON_VALUE && this.prevTriggerValue >= TRIGGER_ON_VALUE) { this.release() } - this.prevTriggerValue = triggerValue; + this.prevTriggerValue = this.triggerValue; } this.squeeze = function() { @@ -193,14 +192,21 @@ function MyController(hand, triggerAction) { var distance = Vec3.distance(handPosition, this.intersection.intersection); if (distance < MAX_DISTANCE) { var displayPoint = this.intersection.intersection; - displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, .001)); + displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, .01)); if (this.tryPainting) { this.canPaint = true; } + this.currentStrokeWidth = map(this.triggerValue, 0, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); + var laserSize = map(distance, 1, MAX_DISTANCE, 0.001, 0.1); + laserSize += this.currentStrokeWidth/2; Overlays.editOverlay(this.laserPointer, { visible: true, position: displayPoint, - rotation: orientationOf(this.intersection.surfaceNormal) + rotation: orientationOf(this.intersection.surfaceNormal), + size: { + x: laserSize, + y: laserSize + } }); } else { @@ -340,4 +346,8 @@ function hslToRgb(hsl, hueOffset) { green: Math.round(g * 255), blue: Math.round(b * 255) }; +} + +function map(value, min1, max1, min2, max2) { + return min2 + (max2 - min2) * ((value - min1) / (max1 - min1)); } \ No newline at end of file From a4105eb321a30581ad5673f0dfa3af6a5dedbd88 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 1 Oct 2015 11:34:02 -0700 Subject: [PATCH 165/212] add color pickers --- examples/particle_explorer/main.js | 75 +++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 12 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 9ac556f961..6c9d812280 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -10,7 +10,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -/*global window, EventBridge, dat, convertBinaryToBoolean, listenForSettingsUpdates,createVec3Folder,createQuatFolder,writeVec3ToInterface,writeDataToInterface*/ +/*global window, alert, EventBridge, dat, convertBinaryToBoolean, listenForSettingsUpdates,createVec3Folder,createQuatFolder,writeVec3ToInterface,writeDataToInterface*/ var Settings = function() { this.exportSettings = function() { @@ -19,15 +19,15 @@ var Settings = function() { this.importSettings = function() { importSettings(); } - - return; }; var controllers = []; +var colorControllers = []; var folders = []; var gui; var settings = new Settings(); var updateInterval; +var AUTO_UPDATE = false; var UPDATE_ALL_FREQUENCY = 1000; var keysToIgnore = [ @@ -113,6 +113,7 @@ function loadGUI() { if (shouldIgnore) { return; } + var subKeys = _.keys(settings[key]); var hasX = _.contains(subKeys, 'x'); var hasY = _.contains(subKeys, 'y'); @@ -148,7 +149,9 @@ function loadGUI() { gui.add(settings, 'exportSettings'); addIndividualKeys(); addFolders(); - setInterval(manuallyUpdateDisplay, UPDATE_ALL_FREQUENCY); + if(AUTO_UPDATE){ + setInterval(manuallyUpdateDisplay, UPDATE_ALL_FREQUENCY); + } } @@ -171,15 +174,43 @@ function addIndividualKeys() { } function addFolders() { + _.each(colorKeys, function(key) { + console.log('COLOR KEY IS' + key) + // createColorFolder(key); + createColorPicker(key); + }); _.each(vec3Keys, function(key) { createVec3Folder(key); }); _.each(quatKeys, function(key) { createQuatFolder(key); }); - _.each(colorKeys, function(key) { - createColorFolder(key); + +} + +function createColorPicker(key) { + console.log('CREATE COLOR PICKER') + var colorObject = settings[key]; + var colorArray = convertColorObjectToArray(colorObject); + settings[key] = colorArray; + var controller = gui.addColor(settings, key); + controller.onChange(function(value) { + console.log('COLOR VALUE' + value) + var obj = {}; + obj[key] = convertColorArrayToObject(value); + console.log('AFTER CONVERSION'); + writeVec3ToInterface(obj); }); + return; + + // conroller.onChange(function(colorArray) { + // var colorObject = convertColorArrayToObject(colorArray); + // var obj = {}; + // obj[key] = colorObject + // writeVec3ToInterface(obj) + // console.log('color changed, write this to interface' + JSON.stringify(obj)) + // }); + // controllers.push(controller); } function createVec3Folder(category) { @@ -211,7 +242,6 @@ function createVec3Folder(category) { obj[category][this.property] = value; writeVec3ToInterface(obj); }); - folder.open(); folders.push(folder); } @@ -257,7 +287,6 @@ function createQuatFolder(category) { obj[category][this.property] = value; writeVec3ToInterface(obj); }); - folder.open(); folders.push(folder); } @@ -293,10 +322,27 @@ function createColorFolder(category) { obj[category][this.property] = value; writeVec3ToInterface(obj); }); - folder.open(); folders.push(folder); } + +function convertColorObjectToArray(colorObject) { + var colorArray = []; + _.each(colorObject, function(singleColor) { + colorArray.push(singleColor); + }) + return colorArray +} + +function convertColorArrayToObject(colorArray) { + var colorObject = { + red: colorArray[0], + green: colorArray[1], + blue: colorArray[2] + } + return colorObject +} + function writeDataToInterface(property, value) { var data = {}; data[property] = value; @@ -354,7 +400,7 @@ function listenForSettingsUpdates() { if (data.messageType === 'object_update') { _.each(data.objectSettings, function(value, key) { - settings[key] = value; + // settings[key] = value; }); } @@ -409,6 +455,11 @@ function prepareSettingsForExport() { return; } + if(key.indexOf('color')>-1){ + var colorObject = convertColorArrayToObject(settings[key]); + settings[key]=colorObject + } + exportSettings[key] = settings[key]; }) return JSON.stringify(exportSettings); @@ -418,8 +469,8 @@ function importSettings() { var importInput = document.getElementById('importer-input'); console.log('import value' + importInput.value) try { - var importedSettings = JSON.parse(importInput.value); - // importedSettings = importInput.value; + var importedSettings = JSON.parse(importInput.value); + // importedSettings = importInput.value; var keys = _.keys(importedSettings); _.each(keys, function(key) { var shouldIgnore = _.contains(keysToIgnore, key); From 290659b9f6650c01e04721e19b16f4f66989b1bf Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 11:46:37 -0700 Subject: [PATCH 166/212] increased lifetime --- examples/closePaint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index fa692e0bbc..136237d4b7 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -146,7 +146,7 @@ function MyController(hand, triggerAction) { y: 50, z: 50 }, - lifetime: 100 + lifetime: 200 }); this.strokePoints = []; this.strokeNormals = []; From d2f4b6e9f0e9b882a47ab839bc2bfde273660620 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 1 Oct 2015 12:21:56 -0700 Subject: [PATCH 167/212] add / remove controller listener methods --- examples/particle_explorer/main.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 6c9d812280..71caf4cafb 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -21,15 +21,19 @@ var Settings = function() { } }; + +var AUTO_UPDATE = false; +var UPDATE_ALL_FREQUENCY = 1000; + var controllers = []; var colorControllers = []; var folders = []; var gui; var settings = new Settings(); var updateInterval; -var AUTO_UPDATE = false; -var UPDATE_ALL_FREQUENCY = 1000; +var currentInputField; +var storedController; var keysToIgnore = [ 'importSettings', 'exportSettings', @@ -465,6 +469,16 @@ function prepareSettingsForExport() { return JSON.stringify(exportSettings); } +function removeListener(key){ + _.each(gui.__listening,function(controller,index){ + if(controller.property===key){ + console.log('CONTROLLER KEY MATCHES REMOVELISTENER KEY') + storedController = controller; + gui.__listening.splice(index,1); + } + }); +} + function importSettings() { var importInput = document.getElementById('importer-input'); console.log('import value' + importInput.value) From 2fbb436bc55b50ee3d12d2ccebab01912f0446fd Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 1 Oct 2015 12:42:23 -0700 Subject: [PATCH 168/212] Fix Reload Content menu item --- interface/src/Application.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2a8f7cf8b5..e386cd3a81 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2741,12 +2741,19 @@ void Application::cameraMenuChanged() { } void Application::reloadResourceCaches() { + // Clear entities out of view frustum + _viewFrustum.setPosition(glm::vec3(0.0f, 0.0f, TREE_SCALE)); + _viewFrustum.setOrientation(glm::quat()); + queryOctree(NodeType::EntityServer, PacketType::EntityQuery, _entityServerJurisdictions); + emptyLocalCache(); - + DependencyManager::get()->refreshAll(); DependencyManager::get()->refreshAll(); DependencyManager::get()->refreshAll(); DependencyManager::get()->refreshAll(); + + DependencyManager::get()->reset(); // Force redownload of .fst models } void Application::rotationModeChanged() { From 8453043038fbdd3d7bc1e650fde4e60da334456f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 1 Oct 2015 13:23:51 -0700 Subject: [PATCH 169/212] remove unused variable --- libraries/animation/src/Rig.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 9918b09b8c..a3c48fca5f 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -625,7 +625,6 @@ void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) { setJointRotationInConstrainedFrame((int)i, glm::inverse(_animSkeleton->getRelativeBindPose(i).rot) * poses[i].rot, PRIORITY, false, 1.0f); - JointState& state = _jointStates[i]; setJointTranslation((int)i, true, poses[i].trans, PRIORITY); } From 8bfd38ce7c6ce216a52acfc0b27fe9cb2a403251 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 1 Oct 2015 14:12:32 -0700 Subject: [PATCH 170/212] FBXReader: When the animation has no animation curve use the joint's default position. --- libraries/fbx/src/FBXReader.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 297502d7a1..0c738c5a5b 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1306,17 +1306,18 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS AnimationCurve yPosCurve = animationCurves.value(yComponents.value(translationID)); AnimationCurve zPosCurve = animationCurves.value(zComponents.value(translationID)); - glm::vec3 defaultValues = glm::degrees(safeEulerAngles(joint.rotation)); + glm::vec3 defaultRotValues = glm::degrees(safeEulerAngles(joint.rotation)); + glm::vec3 defaultPosValues = joint.translation; for (int i = 0; i < frameCount; i++) { geometry.animationFrames[i].rotations[jointIndex] = glm::quat(glm::radians(glm::vec3( - xRotCurve.values.isEmpty() ? defaultValues.x : xRotCurve.values.at(i % xRotCurve.values.size()), - yRotCurve.values.isEmpty() ? defaultValues.y : yRotCurve.values.at(i % yRotCurve.values.size()), - zRotCurve.values.isEmpty() ? defaultValues.z : zRotCurve.values.at(i % zRotCurve.values.size())))); + xRotCurve.values.isEmpty() ? defaultRotValues.x : xRotCurve.values.at(i % xRotCurve.values.size()), + yRotCurve.values.isEmpty() ? defaultRotValues.y : yRotCurve.values.at(i % yRotCurve.values.size()), + zRotCurve.values.isEmpty() ? defaultRotValues.z : zRotCurve.values.at(i % zRotCurve.values.size())))); geometry.animationFrames[i].translations[jointIndex] = glm::vec3( - xPosCurve.values.isEmpty() ? defaultValues.x : xPosCurve.values.at(i % xPosCurve.values.size()), - yPosCurve.values.isEmpty() ? defaultValues.y : yPosCurve.values.at(i % yPosCurve.values.size()), - zPosCurve.values.isEmpty() ? defaultValues.z : zPosCurve.values.at(i % zPosCurve.values.size())); + xPosCurve.values.isEmpty() ? defaultPosValues.x : xPosCurve.values.at(i % xPosCurve.values.size()), + yPosCurve.values.isEmpty() ? defaultPosValues.y : yPosCurve.values.at(i % yPosCurve.values.size()), + zPosCurve.values.isEmpty() ? defaultPosValues.z : zPosCurve.values.at(i % zPosCurve.values.size())); } } From 7ee26c5d4a8366b2f3399b2bcbe1e40108ce0176 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 14:26:22 -0700 Subject: [PATCH 171/212] tweaked settings --- examples/closePaint.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index 136237d4b7..6590d7e14e 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -15,13 +15,13 @@ var RIGHT_HAND = 1; var LEFT_HAND = 0; -var MIN_POINT_DISTANCE = 0.01; +var MIN_POINT_DISTANCE = 0.02; var MAX_POINT_DISTANCE = 0.5; var SPATIAL_CONTROLLERS_PER_PALM = 2; var TIP_CONTROLLER_OFFSET = 1; -var TRIGGER_ON_VALUE = 0.1; +var TRIGGER_ON_VALUE = 0.3; var MAX_DISTANCE = 10; @@ -35,8 +35,8 @@ var LEFT_2_ACTION = 16; var HUE_INCREMENT = 0.02; -var MIN_STROKE_WIDTH = 0.005; -var MAX_STROKE_WIDTH = 0.03; +var MIN_STROKE_WIDTH = 0.002; +var MAX_STROKE_WIDTH = 0.04; var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.getOrientation()))); @@ -196,7 +196,7 @@ function MyController(hand, triggerAction) { if (this.tryPainting) { this.canPaint = true; } - this.currentStrokeWidth = map(this.triggerValue, 0, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); + this.currentStrokeWidth = map(this.triggerValue, TRIGGER_ON_VALUE, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); var laserSize = map(distance, 1, MAX_DISTANCE, 0.001, 0.1); laserSize += this.currentStrokeWidth/2; Overlays.editOverlay(this.laserPointer, { From 5aef7475d6c2f8d2ad6d107b7083ce24a19da320 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 14:42:51 -0700 Subject: [PATCH 172/212] Sound position updates every frame based on new position of can --- examples/toys/sprayPaintCan.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 18063474a0..dec6a8976a 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -99,7 +99,6 @@ } this.disableStream = function() { - print("DEKETE STEREAAAM") Entities.deleteEntity(this.paintStream); this.paintStream = null; this.sprayInjector.stop(); @@ -125,6 +124,8 @@ position: position, emitOrientation: forwardQuat, }); + this.sprayInjector.setOptions({position: position}); + } From 55c6b9d9c45b59a2279cb37d75d7c15a05e16ca6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 14:57:03 -0700 Subject: [PATCH 173/212] Added collision sound to blocks --- examples/toys/masterResetEntity.js | 2 ++ examples/toys/sprayPaintCan.js | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index f087d77929..4750b5657b 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -743,6 +743,7 @@ function createPillow(position) { function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; + var collisionSoundURL = "https://hifi-public.s3.amazonaws.com/sounds/Collisions-otherorganic/ToyWoodBlock.L.wav"; var NUM_BLOCKS_PER_COLOR = 4; var i, j; @@ -799,6 +800,7 @@ function createBlocks(position) { name: "block", dimensions: blockTypes[i].dimensions, collisionsWillMove: true, + collisionSoundURL: collisionSoundURL, gravity: { x: 0, y: -2.5, diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index dec6a8976a..4716885ac3 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -129,9 +129,6 @@ } - - - this.preload = function(entityId) { this.spraying = false; this.entityId = entityId; From e1b720d338b9acd15862340dd4ea2ef193e58a68 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 15:18:44 -0700 Subject: [PATCH 174/212] Moved some functions to utils, fixed formatting --- examples/closePaint.js | 490 ++++++++++++++++-------------------- examples/libraries/utils.js | 66 +++++ 2 files changed, 279 insertions(+), 277 deletions(-) diff --git a/examples/closePaint.js b/examples/closePaint.js index 6590d7e14e..d9f70aab3c 100644 --- a/examples/closePaint.js +++ b/examples/closePaint.js @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +Script.include("libraries/utils.js"); + var RIGHT_HAND = 1; var LEFT_HAND = 0; @@ -44,310 +46,244 @@ var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(Camera.g function MyController(hand, triggerAction) { - this.hand = hand; - this.strokes = []; - this.painting = false; - this.currentStrokeWidth = MIN_STROKE_WIDTH; - - if (this.hand === RIGHT_HAND) { - this.getHandPosition = MyAvatar.getRightPalmPosition; - this.getHandRotation = MyAvatar.getRightPalmRotation; - } else { - this.getHandPosition = MyAvatar.getLeftPalmPosition; - this.getHandRotation = MyAvatar.getLeftPalmRotation; - } - - this.triggerAction = triggerAction; - this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand; - this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET; - - - this.strokeColor = { - h: 0.8, - s: 0.8, - l: 0.4 - }; - - - this.laserPointer = Overlays.addOverlay("circle3d", { - color: hslToRgb(this.strokeColor), - solid: true, - position: center - }) - this.triggerValue = 0; - this.prevTriggerValue = 0; - var _this = this; - - this.update = function() { - this.updateControllerState() - this.search(); - if (this.canPaint === true) { - this.paint(this.intersection.intersection, this.intersection.surfaceNormal); - } - }; - - this.paint = function(position, normal) { - if (this.painting === false) { - if (this.oldPosition) { - this.newStroke(this.oldPosition); - } else { - this.newStroke(position); - } - this.painting = true; - } - - - - var localPoint = Vec3.subtract(position, this.strokeBasePosition); - //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on - localPoint = Vec3.sum(localPoint, Vec3.multiply(normal, 0.001 + Math.random() * .001)); //rand avoid z fighting - - var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]); - if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) { - //need a minimum distance to avoid binormal NANs - return; - } - if (this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { - //Prevents drawing lines accross models - this.painting = false; - return; - } - if (this.strokePoints.length === 0) { - localPoint = { - x: 0, - y: 0, - z: 0 - }; - } - - this.strokePoints.push(localPoint); - this.strokeNormals.push(normal); - this.strokeWidths.push(this.currentStrokeWidth); - Entities.editEntity(this.currentStroke, { - linePoints: this.strokePoints, - normals: this.strokeNormals, - strokeWidths: this.strokeWidths - }); - if (this.strokePoints.length === MAX_POINTS_PER_LINE) { - this.painting = false; - return; - } - this.oldPosition = position - } - - this.newStroke = function(position) { - this.strokeBasePosition = position; - this.currentStroke = Entities.addEntity({ - position: position, - type: "PolyLine", - color: hslToRgb(this.strokeColor), - dimensions: { - x: 50, - y: 50, - z: 50 - }, - lifetime: 200 - }); - this.strokePoints = []; - this.strokeNormals = []; - this.strokeWidths = []; - - this.strokes.push(this.currentStroke); - - } - - this.updateControllerState = function() { - this.triggerValue = Controller.getActionValue(this.triggerAction); - if (this.triggerValue > TRIGGER_ON_VALUE && this.prevTriggerValue <= TRIGGER_ON_VALUE) { - this.squeeze(); - } else if (this.triggerValue < TRIGGER_ON_VALUE && this.prevTriggerValue >= TRIGGER_ON_VALUE) { - this.release() - } - - this.prevTriggerValue = this.triggerValue; - } - - this.squeeze = function() { - this.tryPainting = true; - - } - this.release = function() { + this.hand = hand; + this.strokes = []; this.painting = false; - this.tryPainting = false; - this.canPaint = false; - this.oldPosition = null; - } - this.search = function() { + this.currentStrokeWidth = MIN_STROKE_WIDTH; - // the trigger is being pressed, do a ray test - var handPosition = this.getHandPosition(); - var pickRay = { - origin: handPosition, - direction: Quat.getUp(this.getHandRotation()) + if (this.hand === RIGHT_HAND) { + this.getHandPosition = MyAvatar.getRightPalmPosition; + this.getHandRotation = MyAvatar.getRightPalmRotation; + } else { + this.getHandPosition = MyAvatar.getLeftPalmPosition; + this.getHandRotation = MyAvatar.getLeftPalmRotation; + } + + this.triggerAction = triggerAction; + this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand; + this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET; + + + this.strokeColor = { + h: 0.8, + s: 0.8, + l: 0.4 }; - this.intersection = Entities.findRayIntersection(pickRay, true); - if (this.intersection.intersects) { - var distance = Vec3.distance(handPosition, this.intersection.intersection); - if (distance < MAX_DISTANCE) { - var displayPoint = this.intersection.intersection; - displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, .01)); - if (this.tryPainting) { - this.canPaint = true; + this.laserPointer = Overlays.addOverlay("circle3d", { + color: hslToRgb(this.strokeColor), + solid: true, + position: center + }); + this.triggerValue = 0; + this.prevTriggerValue = 0; + var _this = this; + + this.update = function() { + this.updateControllerState(); + this.search(); + if (this.canPaint === true) { + this.paint(this.intersection.intersection, this.intersection.surfaceNormal); } - this.currentStrokeWidth = map(this.triggerValue, TRIGGER_ON_VALUE, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); - var laserSize = map(distance, 1, MAX_DISTANCE, 0.001, 0.1); - laserSize += this.currentStrokeWidth/2; + }; + + this.paint = function(position, normal) { + if (this.painting === false) { + if (this.oldPosition) { + this.newStroke(this.oldPosition); + } else { + this.newStroke(position); + } + this.painting = true; + } + + + + var localPoint = Vec3.subtract(position, this.strokeBasePosition); + //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on + localPoint = Vec3.sum(localPoint, Vec3.multiply(normal, 0.001 + Math.random() * .001)); //rand avoid z fighting + + var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]); + if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) { + //need a minimum distance to avoid binormal NANs + return; + } + if (this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { + //Prevents drawing lines accross models + this.painting = false; + return; + } + if (this.strokePoints.length === 0) { + localPoint = { + x: 0, + y: 0, + z: 0 + }; + } + + this.strokePoints.push(localPoint); + this.strokeNormals.push(normal); + this.strokeWidths.push(this.currentStrokeWidth); + Entities.editEntity(this.currentStroke, { + linePoints: this.strokePoints, + normals: this.strokeNormals, + strokeWidths: this.strokeWidths + }); + if (this.strokePoints.length === MAX_POINTS_PER_LINE) { + this.painting = false; + return; + } + this.oldPosition = position; + } + + this.newStroke = function(position) { + this.strokeBasePosition = position; + this.currentStroke = Entities.addEntity({ + position: position, + type: "PolyLine", + color: hslToRgb(this.strokeColor), + dimensions: { + x: 50, + y: 50, + z: 50 + }, + lifetime: 200 + }); + this.strokePoints = []; + this.strokeNormals = []; + this.strokeWidths = []; + + this.strokes.push(this.currentStroke); + + } + + this.updateControllerState = function() { + this.triggerValue = Controller.getActionValue(this.triggerAction); + if (this.triggerValue > TRIGGER_ON_VALUE && this.prevTriggerValue <= TRIGGER_ON_VALUE) { + this.squeeze(); + } else if (this.triggerValue < TRIGGER_ON_VALUE && this.prevTriggerValue >= TRIGGER_ON_VALUE) { + this.release(); + } + + this.prevTriggerValue = this.triggerValue; + } + + this.squeeze = function() { + this.tryPainting = true; + + } + this.release = function() { + this.painting = false; + this.tryPainting = false; + this.canPaint = false; + this.oldPosition = null; + } + this.search = function() { + + // the trigger is being pressed, do a ray test + var handPosition = this.getHandPosition(); + var pickRay = { + origin: handPosition, + direction: Quat.getUp(this.getHandRotation()) + }; + + + this.intersection = Entities.findRayIntersection(pickRay, true); + if (this.intersection.intersects) { + var distance = Vec3.distance(handPosition, this.intersection.intersection); + if (distance < MAX_DISTANCE) { + var displayPoint = this.intersection.intersection; + displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, .01)); + if (this.tryPainting) { + this.canPaint = true; + } + this.currentStrokeWidth = map(this.triggerValue, TRIGGER_ON_VALUE, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); + var laserSize = map(distance, 1, MAX_DISTANCE, 0.01, 0.1); + laserSize += this.currentStrokeWidth / 2; + Overlays.editOverlay(this.laserPointer, { + visible: true, + position: displayPoint, + rotation: orientationOf(this.intersection.surfaceNormal), + size: { + x: laserSize, + y: laserSize + } + }); + + } else { + this.hitFail(); + } + } else { + this.hitFail(); + } + }; + + this.hitFail = function() { + this.canPaint = false; + Overlays.editOverlay(this.laserPointer, { - visible: true, - position: displayPoint, - rotation: orientationOf(this.intersection.surfaceNormal), - size: { - x: laserSize, - y: laserSize - } + visible: false }); - } else { - this.hitFail(); - } - } else { - this.hitFail(); } - }; - this.hitFail = function() { - this.canPaint = false; - - Overlays.editOverlay(this.laserPointer, { - visible: false - }); - - } - - this.cleanup = function() { - Overlays.deleteOverlay(this.laserPointer); - this.strokes.forEach(function(stroke) { - Entities.deleteEntity(stroke); - }); - } - - this.cycleColorDown = function() { - this.strokeColor.h -= HUE_INCREMENT; - if (this.strokeColor.h < 0) { - this.strokeColor = 1; + this.cleanup = function() { + Overlays.deleteOverlay(this.laserPointer); + this.strokes.forEach(function(stroke) { + Entities.deleteEntity(stroke); + }); } - Overlays.editOverlay(this.laserPointer, { - color: hslToRgb(this.strokeColor) - }); - } - this.cycleColorUp = function() { - this.strokeColor.h += HUE_INCREMENT; - if (this.strokeColor.h > 1) { - this.strokeColor.h = 0; + this.cycleColorDown = function() { + this.strokeColor.h -= HUE_INCREMENT; + if (this.strokeColor.h < 0) { + this.strokeColor = 1; + } + Overlays.editOverlay(this.laserPointer, { + color: hslToRgb(this.strokeColor) + }); + } + + this.cycleColorUp = function() { + this.strokeColor.h += HUE_INCREMENT; + if (this.strokeColor.h > 1) { + this.strokeColor.h = 0; + } + Overlays.editOverlay(this.laserPointer, { + color: hslToRgb(this.strokeColor) + }); } - Overlays.editOverlay(this.laserPointer, { - color: hslToRgb(this.strokeColor) - }); - } } var rightController = new MyController(RIGHT_HAND, Controller.findAction("RIGHT_HAND_CLICK")); var leftController = new MyController(LEFT_HAND, Controller.findAction("LEFT_HAND_CLICK")); Controller.actionEvent.connect(function(action, state) { - if (state === 0) { - return; - } - if (action === RIGHT_4_ACTION) { - rightController.cycleColorUp(); - } else if (action === RIGHT_2_ACTION) { - rightController.cycleColorDown(); - } - if (action === LEFT_4_ACTION) { - leftController.cycleColorUp(); - } else if (action === LEFT_2_ACTION) { - leftController.cycleColorDown(); - } + if (state === 0) { + return; + } + if (action === RIGHT_4_ACTION) { + rightController.cycleColorUp(); + } else if (action === RIGHT_2_ACTION) { + rightController.cycleColorDown(); + } + if (action === LEFT_4_ACTION) { + leftController.cycleColorUp(); + } else if (action === LEFT_2_ACTION) { + leftController.cycleColorDown(); + } }); function update() { - rightController.update(); - leftController.update(); + rightController.update(); + leftController.update(); } function cleanup() { - rightController.cleanup(); - leftController.cleanup(); + rightController.cleanup(); + leftController.cleanup(); } Script.scriptEnding.connect(cleanup); Script.update.connect(update); - - -function orientationOf(vector) { - var Y_AXIS = { - x: 0, - y: 1, - z: 0 - }; - var X_AXIS = { - x: 1, - y: 0, - z: 0 - }; - - var theta = 0.0; - - var RAD_TO_DEG = 180.0 / Math.PI; - var direction, yaw, pitch; - direction = Vec3.normalize(vector); - yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); - pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); - return Quat.multiply(yaw, pitch); -} - -/** - * Converts an HSL color value to RGB. Conversion formula - * adapted from http://en.wikipedia.org/wiki/HSL_color_space. - * Assumes h, s, and l are contained in the set [0, 1] and - * returns r, g, and b in the set [0, 255]. - * - * @param Number h The hue - * @param Number s The saturation - * @param Number l The lightness - * @return Array The RGB representation - */ -function hslToRgb(hsl, hueOffset) { - var r, g, b; - if (hsl.s == 0) { - r = g = b = hsl.l; // achromatic - } else { - var hue2rgb = function hue2rgb(p, q, t) { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; - return p; - } - - var q = hsl.l < 0.5 ? hsl.l * (1 + hsl.s) : hsl.l + hsl.s - hsl.l * hsl.s; - var p = 2 * hsl.l - q; - r = hue2rgb(p, q, hsl.h + 1 / 3); - g = hue2rgb(p, q, hsl.h); - b = hue2rgb(p, q, hsl.h - 1 / 3); - } - - return { - red: Math.round(r * 255), - green: Math.round(g * 255), - blue: Math.round(b * 255) - }; -} - -function map(value, min1, max1, min2, max2) { - return min2 + (max2 - min2) * ((value - min1) / (max1 - min1)); -} \ No newline at end of file diff --git a/examples/libraries/utils.js b/examples/libraries/utils.js index f6f635c73a..fa0f36cbb1 100644 --- a/examples/libraries/utils.js +++ b/examples/libraries/utils.js @@ -179,3 +179,69 @@ pointInExtents = function(point, minPoint, maxPoint) { (point.y >= minPoint.y && point.y <= maxPoint.y) && (point.z >= minPoint.z && point.z <= maxPoint.z); } + +/** + * Converts an HSL color value to RGB. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes h, s, and l are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @param Number h The hue + * @param Number s The saturation + * @param Number l The lightness + * @return Array The RGB representation + */ +hslToRgb = function(hsl, hueOffset) { + var r, g, b; + if (hsl.s == 0) { + r = g = b = hsl.l; // achromatic + } else { + var hue2rgb = function hue2rgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + } + + var q = hsl.l < 0.5 ? hsl.l * (1 + hsl.s) : hsl.l + hsl.s - hsl.l * hsl.s; + var p = 2 * hsl.l - q; + r = hue2rgb(p, q, hsl.h + 1 / 3); + g = hue2rgb(p, q, hsl.h); + b = hue2rgb(p, q, hsl.h - 1 / 3); + } + + return { + red: Math.round(r * 255), + green: Math.round(g * 255), + blue: Math.round(b * 255) + }; +} + +map = function(value, min1, max1, min2, max2) { + return min2 + (max2 - min2) * ((value - min1) / (max1 - min1)); +} + +orientationOf = function(vector) { + var Y_AXIS = { + x: 0, + y: 1, + z: 0 + }; + var X_AXIS = { + x: 1, + y: 0, + z: 0 + }; + + var theta = 0.0; + + var RAD_TO_DEG = 180.0 / Math.PI; + var direction, yaw, pitch; + direction = Vec3.normalize(vector); + yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); + pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); + return Quat.multiply(yaw, pitch); +} + From 8e2c1a6b170a518923238a9456bc78952644e5bd Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 1 Oct 2015 15:22:45 -0700 Subject: [PATCH 175/212] Add ping pong ball gun, add basketball hoop, reduce gate gravity, lint code --- examples/toys/masterResetEntity.js | 190 ++++++++++++++--------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 4750b5657b..501e59fc5b 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -8,7 +8,7 @@ /*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ //per script -/*global deleteAllToys, createAllToys, createGates, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches */ +/*global deleteAllToys, createAllToys, createGates, createPingPongBallGun, createFire, createPottedPlant, createCombinedArmChair, createBasketballHoop, createBasketBall, createSprayCan, createDoll, createWand, createDice, createCat, deleteAllToys, createFlashlight, createBlocks, createMagballs, createLightSwitches */ var utilitiesScript = Script.resolvePath("../libraries/utils.js"); Script.include(utilitiesScript); @@ -71,13 +71,11 @@ function createAllToys() { // //Handles toggling of all sconce lights createLightSwitches(); - - createCombinedArmChair({ x: 549.29, y: 495.05, z: 508.22 - }) + }); createPottedPlant({ x: 554.26, @@ -85,6 +83,9 @@ function createAllToys() { z: 504.53 }); + createPingPongBallGun(); + + createBasketballHoop(); createGates(); @@ -106,7 +107,7 @@ function deleteAllToys() { function createFire() { - myOrientation = Quat.fromPitchYawRollDegrees(-90, 0, 0.0); + var myOrientation = Quat.fromPitchYawRollDegrees(-90, 0, 0.0); var animationSettings = JSON.stringify({ fps: 30, @@ -143,13 +144,13 @@ function createFire() { green: 99, blue: 32 }, - radiusSpread: .01, - radiusStart: .02, + radiusSpread: 0.01, + radiusStart: 0.02, radiusEnd: 0.001, - particleRadius: .05, + particleRadius: 0.05, radiusFinish: 0.0, emitOrientation: myOrientation, - emitSpeed: .3, + emitSpeed: 0.3, speedSpread: 0.1, alphaStart: 0.05, alpha: 0.1, @@ -157,7 +158,7 @@ function createFire() { emitDimensions: { x: 1, y: 1, - z: .1 + z: 0.1 }, polarFinish: 0.1, emitAcceleration: { @@ -383,7 +384,7 @@ function createGates() { collisionsWillMove: true, gravity: { x: 0, - y: -100, + y: -50, z: 0 }, linearDamping: 1, @@ -437,6 +438,86 @@ function createGates() { }); } +function createPingPongBallGun() { + var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun.fbx'; + var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/ping_pong_gun_collision_hull.obj'; + var scriptURL = Script.resolvePath('ping_pong_gun/pingPongGun.js'); + + var position = { + x: 548.6, + y: 495.4, + z: 503.39 + }; + + var rotation = Quat.fromPitchYawRollDegrees(0, 36, 0); + + var pingPongGun = Entities.addEntity({ + type: "Model", + modelURL: MODEL_URL, + shapeType: 'compound', + compoundShapeURL: COLLISION_HULL_URL, + script: scriptURL, + position: position, + rotation: rotation, + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + dimensions: { + x: 0.67, + y: 0.14, + z: 0.09 + }, + collisionsWillMove: true, + }); + + setEntityCustomData(resetKey, pingPongGun, { + resetMe: true + }); + + +} + +function createBasketballHoop() { + var position = { + x: 539.23, + y: 496.13, + z: 475.89 + }; + var rotation = Quat.fromPitchYawRollDegrees(0, 58.49, 0); + + var hoopURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop.fbx"; + var hoopCollisionHullURL = "http://hifi-public.s3.amazonaws.com/models/basketball_hoop/basketball_hoop_collision_hull.obj"; + + var hoop = Entities.addEntity({ + type: "Model", + modelURL: hoopURL, + position: position, + rotation: rotation, + shapeType: 'compound', + gravity: { + x: 0, + y: -9.8, + z: 0 + }, + dimensions: { + x: 1.89, + y: 3.99, + z: 3.79 + }, + compoundShapeURL: hoopCollisionHullURL + }); + + setEntityCustomData(resetKey, hoop, { + resetMe: true + }); + + setEntityCustomData(GRABBABLE_DATA_KEY, hoop, { + grabbable: false + }); +} + function createWand(position) { var WAND_MODEL = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/wand.fbx'; var WAND_COLLISION_SHAPE = 'http://hifi-public.s3.amazonaws.com/james/bubblewand/models/wand/actual_no_top_collision_hull.obj'; @@ -579,12 +660,9 @@ function createSprayCan(position) { } -//createPottedPlant,createArmChair,createPillow function createPottedPlant(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/potted_plant/potted_plant.fbx"; - var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); - var entity = Entities.addEntity({ type: "Model", name: "Potted Plant", @@ -618,12 +696,12 @@ function createPottedPlant(position) { setEntityCustomData(GRABBABLE_DATA_KEY, entity, { grabbable: false }); -}; +} function createCombinedArmChair(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/combined_chair.fbx"; - var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj" + var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_collision_hull.obj"; var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); @@ -661,85 +739,7 @@ function createCombinedArmChair(position) { setEntityCustomData(GRABBABLE_DATA_KEY, entity, { grabbable: false }); -}; - -function createArmChair(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/new_red_arm_chair.fbx"; - var RED_ARM_CHAIR_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/new_red_arm_chair_collision_hull.obj" - - var rotation = Quat.fromPitchYawRollDegrees(0, -143, 0); - - var entity = Entities.addEntity({ - type: "Model", - name: "Red Arm Chair", - modelURL: modelURL, - shapeType: 'compound', - compoundShapeURL: RED_ARM_CHAIR_COLLISION_HULL, - position: position, - rotation: rotation, - dimensions: { - x: 1.26, - y: 1.56, - z: 1.35 - }, - collisionsWillMove: true, - gravity: { - x: 0, - y: -0.5, - z: 0 - }, - velocity: { - x: 0, - y: 0, - z: 0 - }, - linearDamping: 0.3 - }); - - setEntityCustomData(resetKey, entity, { - resetMe: true - }); -}; - -function createPillow(position) { - var modelURL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow.fbx"; - var RED_ARM_CHAIR_PILLOW_COLLISION_HULL = "http://hifi-public.s3.amazonaws.com/models/red_arm_chair/red_arm_chair_pillow_collision_hull.obj" - - var rotation = Quat.fromPitchYawRollDegrees(-0.29, -143.05, 0.32); - - var entity = Entities.addEntity({ - type: "Model", - name: "Red Arm Chair Pillow", - modelURL: modelURL, - shapeType: 'compound', - compoundShapeURL: RED_ARM_CHAIR_PILLOW_COLLISION_HULL, - position: position, - rotation: rotation, - dimensions: { - x: 0.4, - y: 0.4, - z: 0.4 - }, - collisionsWillMove: true, - ignoreForCollisions: false, - gravity: { - x: 0, - y: -10.1, - z: 0 - }, - restitution: 0, - velocity: { - x: 0, - y: -0.1, - z: 0 - }, - linearDamping: 1 - }); - - setEntityCustomData(resetKey, entity, { - resetMe: true - }); -}; +} function createBlocks(position) { var baseURL = HIFI_PUBLIC_BUCKET + "models/content/planky/"; From 25e25726d59d09c719234ea7694f376336fcd856 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 15:43:25 -0700 Subject: [PATCH 176/212] only lights --- examples/toys/masterResetEntity.js | 116 ++++++++++++++++------------- 1 file changed, 65 insertions(+), 51 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 4750b5657b..0382e569bb 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -20,75 +20,89 @@ var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var shouldDeleteOnEndScript = false; //Before creating anything, first search a radius and delete all the things that should be deleted -deleteAllToys(); +// deleteAllToys(); +deleteLights(); createAllToys(); function createAllToys() { - createBlocks({ - x: 548.3, - y: 495.55, - z: 504.4 - }); + // createBlocks({ + // x: 548.3, + // y: 495.55, + // z: 504.4 + // }); - createSprayCan({ - x: 549.7, - y: 495.6, - z: 503.91 - }); + // createSprayCan({ + // x: 549.7, + // y: 495.6, + // z: 503.91 + // }); - createBasketBall({ - x: 547.73, - y: 495.5, - z: 505.47 - }); + // createBasketBall({ + // x: 547.73, + // y: 495.5, + // z: 505.47 + // }); - createDoll({ - x: 546.67, - y: 495.41, - z: 505.09 - }); + // createDoll({ + // x: 546.67, + // y: 495.41, + // z: 505.09 + // }); - createWand({ - x: 546.71, - y: 495.55, - z: 506.15 - }); + // createWand({ + // x: 546.71, + // y: 495.55, + // z: 506.15 + // }); - createDice(); + // createDice(); - createFlashlight({ - x: 545.72, - y: 495.41, - z: 505.78 - }); + // createFlashlight({ + // x: 545.72, + // y: 495.41, + // z: 505.78 + // }); - createCat({ - x: 551.09, - y: 494.98, - z: 503.49 - }); + // createCat({ + // x: 551.09, + // y: 494.98, + // z: 503.49 + // }); + // createCombinedArmChair({ + // x: 549.29, + // y: 495.05, + // z: 508.22 + // }) + + // createPottedPlant({ + // x: 554.26, + // y: 495.23, + // z: 504.53 + // }); + + + // createGates(); + + // createFire(); // //Handles toggling of all sconce lights createLightSwitches(); - createCombinedArmChair({ - x: 549.29, - y: 495.05, - z: 508.22 - }) +} - createPottedPlant({ - x: 554.26, - y: 495.23, - z: 504.53 +function deleteLights() { + var entities = Entities.findEntities(MyAvatar.position, 100); + + entities.forEach(function(entity) { + //params: customKey, id, defaultValue + var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; + var lightType = getEntityCustomData(resetKey, entity, {}).lightType; + if (shouldReset === true && (lightType === "Sconce Light Garage" || lightType === "Sconce Light Hall")) { + Entities.deleteEntity(entity); + } }); - - - createGates(); - - createFire(); } function deleteAllToys() { From cdb249c6ff1add3932d1759429c3f0de8efd8363 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 15:53:28 -0700 Subject: [PATCH 177/212] original master script --- examples/toys/masterResetEntity.js | 100 ++++++++++++++--------------- 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index 0382e569bb..ef7990b942 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -20,71 +20,71 @@ var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var shouldDeleteOnEndScript = false; //Before creating anything, first search a radius and delete all the things that should be deleted -// deleteAllToys(); -deleteLights(); +deleteAllToys(); +// deleteLights(); createAllToys(); function createAllToys() { - // createBlocks({ - // x: 548.3, - // y: 495.55, - // z: 504.4 - // }); + createBlocks({ + x: 548.3, + y: 495.55, + z: 504.4 + }); - // createSprayCan({ - // x: 549.7, - // y: 495.6, - // z: 503.91 - // }); + createSprayCan({ + x: 549.7, + y: 495.6, + z: 503.91 + }); - // createBasketBall({ - // x: 547.73, - // y: 495.5, - // z: 505.47 - // }); + createBasketBall({ + x: 547.73, + y: 495.5, + z: 505.47 + }); - // createDoll({ - // x: 546.67, - // y: 495.41, - // z: 505.09 - // }); + createDoll({ + x: 546.67, + y: 495.41, + z: 505.09 + }); - // createWand({ - // x: 546.71, - // y: 495.55, - // z: 506.15 - // }); + createWand({ + x: 546.71, + y: 495.55, + z: 506.15 + }); - // createDice(); + createDice(); - // createFlashlight({ - // x: 545.72, - // y: 495.41, - // z: 505.78 - // }); + createFlashlight({ + x: 545.72, + y: 495.41, + z: 505.78 + }); - // createCat({ - // x: 551.09, - // y: 494.98, - // z: 503.49 - // }); + createCat({ + x: 551.09, + y: 494.98, + z: 503.49 + }); - // createCombinedArmChair({ - // x: 549.29, - // y: 495.05, - // z: 508.22 - // }) + createCombinedArmChair({ + x: 549.29, + y: 495.05, + z: 508.22 + }) - // createPottedPlant({ - // x: 554.26, - // y: 495.23, - // z: 504.53 - // }); + createPottedPlant({ + x: 554.26, + y: 495.23, + z: 504.53 + }); - // createGates(); + createGates(); - // createFire(); + createFire(); // //Handles toggling of all sconce lights createLightSwitches(); From 0fb51a67778bc6bfe902aabe2bd2162127bf9b12 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 15:56:16 -0700 Subject: [PATCH 178/212] got rid of unneeded light test code --- examples/toys/masterResetEntity.js | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterResetEntity.js index ef7990b942..966acc19b2 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterResetEntity.js @@ -21,7 +21,6 @@ var shouldDeleteOnEndScript = false; //Before creating anything, first search a radius and delete all the things that should be deleted deleteAllToys(); -// deleteLights(); createAllToys(); function createAllToys() { @@ -92,19 +91,6 @@ function createAllToys() { } -function deleteLights() { - var entities = Entities.findEntities(MyAvatar.position, 100); - - entities.forEach(function(entity) { - //params: customKey, id, defaultValue - var shouldReset = getEntityCustomData(resetKey, entity, {}).resetMe; - var lightType = getEntityCustomData(resetKey, entity, {}).lightType; - if (shouldReset === true && (lightType === "Sconce Light Garage" || lightType === "Sconce Light Hall")) { - Entities.deleteEntity(entity); - } - }); -} - function deleteAllToys() { var entities = Entities.findEntities(MyAvatar.position, 100); From 407b6b8158b34dc1a729cb15e2f2bc90f78ae5f3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 1 Oct 2015 16:10:29 -0700 Subject: [PATCH 179/212] Fixed bug in spray paint where sometimes would not spray --- examples/toys/sprayPaintCan.js | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 4716885ac3..0de95f5d93 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -101,6 +101,7 @@ this.disableStream = function() { Entities.deleteEntity(this.paintStream); this.paintStream = null; + this.spraying = false; this.sprayInjector.stop(); } @@ -145,35 +146,3 @@ }); } }); - - - -function randFloat(min, max) { - return Math.random() * (max - min) + min; -} - -function randInt(min, max) { - return Math.floor(Math.random() * (max - min)) + min; -} - -function orientationOf(vector) { - var Y_AXIS = { - x: 0, - y: 1, - z: 0 - }; - var X_AXIS = { - x: 1, - y: 0, - z: 0 - }; - - var theta = 0.0; - - var RAD_TO_DEG = 180.0 / Math.PI; - var direction, yaw, pitch; - direction = Vec3.normalize(vector); - yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); - pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); - return Quat.multiply(yaw, pitch); -} \ No newline at end of file From fe5ea471a1bd6faefe6ff90c5f80388ae89a10b7 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 1 Oct 2015 16:10:33 -0700 Subject: [PATCH 180/212] AnimClip: read in translations from fbx file and pre-process them Do the following things to the translations 1. scale by the model offset, this should move the translations into the correct units (meters). 2. compute the ratio between the bone length in the animation and the skeleton. 3. subtract the anim translation from the first translation frame in the animation effectively turning it into a bind pose delta translation. 4. apply bone length ratio to the resulting delta. 5. set the final translation to be the skeleton rel bind pose + this scaled delta translation --- libraries/animation/src/AnimClip.cpp | 47 +++++++++++++++++++--------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/libraries/animation/src/AnimClip.cpp b/libraries/animation/src/AnimClip.cpp index f33c958fa8..c432b3b9ac 100644 --- a/libraries/animation/src/AnimClip.cpp +++ b/libraries/animation/src/AnimClip.cpp @@ -135,29 +135,46 @@ void AnimClip::copyFromNetworkAnim() { const int frameCount = geom.animationFrames.size(); const int skeletonJointCount = _skeleton->getNumJoints(); _anim.resize(frameCount); - for (int i = 0; i < frameCount; i++) { + + const glm::vec3 offsetScale = extractScale(geom.offset); + + for (int frame = 0; frame < frameCount; frame++) { // init all joints in animation to bind pose - _anim[i].reserve(skeletonJointCount); - for (int j = 0; j < skeletonJointCount; j++) { - _anim[i].push_back(_skeleton->getRelativeBindPose(j)); + // this will give us a resonable result for bones in the skeleton but not in the animation. + _anim[frame].reserve(skeletonJointCount); + for (int skeletonJoint = 0; skeletonJoint < skeletonJointCount; skeletonJoint++) { + _anim[frame].push_back(_skeleton->getRelativeBindPose(skeletonJoint)); } - // init over all joint animations - for (int j = 0; j < animJointCount; j++) { - int k = jointMap[j]; - if (k >= 0 && k < skeletonJointCount) { - _anim[i][k].rot = _skeleton->getRelativeBindPose(k).rot * geom.animationFrames[i].rotations[j]; + for (int animJoint = 0; animJoint < animJointCount; animJoint++) { - // TODO -- why does applying all the joint translations make a mutant? - if (animJoints[j].parentIndex == -1) { - _anim[i][k].trans = geom.animationFrames[i].translations[j] * extractScale(geom.offset); - } else { - _anim[i][k].trans = _skeleton->getRelativeBindPose(k).trans; - } + int skeletonJoint = jointMap[animJoint]; + + // skip joints that are in the animation but not in the skeleton. + if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) { + + const glm::vec3& fbxZeroTrans = geom.animationFrames[0].translations[animJoint] * offsetScale; + const AnimPose& relBindPose = _skeleton->getRelativeBindPose(skeletonJoint); + + // used to adjust translation offsets, so large translation animatons on the reference skeleton + // will be adjusted when played on a skeleton with short limbs. + float limbLengthScale = fabs(glm::length(fbxZeroTrans)) <= 0.0001f ? 1.0f : (glm::length(relBindPose.trans) / glm::length(fbxZeroTrans)); + + AnimPose& pose = _anim[frame][skeletonJoint]; + const FBXAnimationFrame& fbxAnimFrame = geom.animationFrames[frame]; + + // rotation in fbxAnimationFrame is a delta from a reference skeleton bind pose. + pose.rot = relBindPose.rot * fbxAnimFrame.rotations[animJoint]; + + // translation in fbxAnimationFrame is not a delta. + // convert it into a delta by subtracting from the first frame. + const glm::vec3& fbxTrans = fbxAnimFrame.translations[animJoint] * offsetScale; + pose.trans = relBindPose.trans + limbLengthScale * (fbxTrans - fbxZeroTrans); } } } + _poses.resize(skeletonJointCount); } From b352ab473632a4c1bbecb73cc28ab8b233866772 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:04:37 -0700 Subject: [PATCH 181/212] Update lightSwitchGarage.js fix header and spacing issues --- examples/toys/lightSwitchGarage.js | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/examples/toys/lightSwitchGarage.js b/examples/toys/lightSwitchGarage.js index 5f302ff47e..19d33117df 100644 --- a/examples/toys/lightSwitchGarage.js +++ b/examples/toys/lightSwitchGarage.js @@ -1,11 +1,10 @@ // -// detectGrabExample.js +// lightSwitchGarage.js.js // examples/entityScripts // // Created by Eric Levin on 9/21/15. // Copyright 2015 High Fidelity, Inc. // -// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -15,7 +14,6 @@ var _this; - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) LightSwitchGarage = function() { @@ -78,7 +76,6 @@ createLights: function() { - var sconceLight3 = Entities.addEntity({ type: "Light", position: { @@ -113,7 +110,6 @@ y: 496.24026489257812, z: 507.90237426757812 }, - name: "Sconce 4 Light", dimensions: { x: 2.545, @@ -159,12 +155,9 @@ lightType: "Sconce Light Garage" }); - - setEntityCustomData(this.lightStateKey, this.entityID, { on: true }); - }, flipLights: function() { @@ -185,9 +178,6 @@ }, - - // preload() will be called when the entity has become visible (or known) to the interface - // it gives us a chance to set our local JavaScript object up. In this case it means: preload: function(entityID) { this.entityID = entityID; @@ -209,4 +199,4 @@ // entity scripts always need to return a newly constructed object of our type return new LightSwitchGarage(); -}) \ No newline at end of file +}) From 9098585e2fa975abef2a5694713bb9eaee3c740d Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:14:08 -0700 Subject: [PATCH 182/212] Update cat.js remove a lot of unused code and add flag for whether cat is already meowing so that it doesn't start another one until its done. unfortunately i dont know how to read the audio isplaying state so we have to use a lame timeout --- examples/toys/cat.js | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index a71cec95c2..156765ed00 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -1,12 +1,11 @@ // -// doll.js +// cat.js // examples/toybox/entityScripts // // Created by Eric Levin on 9/21/15. // Copyright 2015 High Fidelity, Inc. // -// This entity script breathes movement and sound- one might even say life- into a doll. -// + // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // @@ -15,20 +14,23 @@ var _this; - // this is the "constructor" for the entity as a JS object we don't do much here, but we do want to remember - // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) Cat = function() { _this = this; this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); - this.distanceThreshold = 1; - this.canMeow = true; - this.meowBreakTime = 3000; }; Cat.prototype = { - + isMeowing:false, startTouch: function() { - this.meow(); + var _ t=this; + if(this.isMeowing!==true){ + this.meow(); + this.isMeowing=true; + Script.setTimeout(function(){ + _t.isMeowing=false; + },2000) + } + }, meow: function() { @@ -38,14 +40,10 @@ volume: .1 }); }, - // preload() will be called when the entity has become visible (or known) to the interface - // it gives us a chance to set our local JavaScript object up. In this case it means: - // * remembering our entityID, so we can access it in cases where we're called without an entityID - // * connecting to the update signal so we can check our grabbed state + preload: function(entityID) { this.entityID = entityID; this.position = Entities.getEntityProperties(this.entityID, "position").position; - Script.update.connect(this.update); }, unload: function() { @@ -55,4 +53,4 @@ // entity scripts always need to return a newly constructed object of our type return new Cat(); -}); \ No newline at end of file +}); From cfb9728fdb8d4478d0cc2d9e3be4b8dd394bc697 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:17:35 -0700 Subject: [PATCH 183/212] Update doll.js remove some unused code --- examples/toys/doll/doll.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/examples/toys/doll/doll.js b/examples/toys/doll/doll.js index eeb4f8ee8a..79e8a28fb5 100644 --- a/examples/toys/doll/doll.js +++ b/examples/toys/doll/doll.js @@ -56,12 +56,11 @@ }, continueNearGrab: function() { - var props = Entities.getEntityProperties(this.entityID, ["position", "animationFrameIndex"]); + var props = Entities.getEntityProperties(this.entityID, ["position"]); var audioOptions = { position: props.position }; this.audioInjector.options = audioOptions; - }, releaseGrab: function() { @@ -84,12 +83,9 @@ }, preload: function(entityID) { - // preload() will be called when the entity has become visible (or known) to the interface - // it gives us a chance to set our local JavaScript object up. In this case it means: - // * remembering our entityID, so we can access it in cases where we're called without an entityID this.entityID = entityID; }, }; // entity scripts always need to return a newly constructed object of our type return new Doll(); -}); \ No newline at end of file +}); From 6523a057a866418d77dfead1efde6175bc56f442 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:18:27 -0700 Subject: [PATCH 184/212] Update lightSwitchHall.js fix header file --- examples/toys/lightSwitchHall.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/examples/toys/lightSwitchHall.js b/examples/toys/lightSwitchHall.js index 4dd1a867de..e1093311f9 100644 --- a/examples/toys/lightSwitchHall.js +++ b/examples/toys/lightSwitchHall.js @@ -1,11 +1,10 @@ // -// detectGrabExample.js +// lightSwitchHall.js // examples/entityScripts // // Created by Eric Levin on 9/21/15. // Copyright 2015 High Fidelity, Inc. // -// This is an example of an entity script which when assigned to an entity, will detect when the entity is being grabbed by the hydraGrab script // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -25,7 +24,6 @@ this.resetKey = "resetMe"; this.switchSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav"); - }; LightSwitchHall.prototype = { @@ -178,4 +176,4 @@ // entity scripts always need to return a newly constructed object of our type return new LightSwitchHall(); -}) \ No newline at end of file +}) From 54a51e6b8b11a210bbf2939e774d5ceba63fac4e Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:19:36 -0700 Subject: [PATCH 185/212] Update and rename masterResetEntity.js to masterReset.js remove reference to 'entities' in the file name since this script does more than that. also update the header file. --- examples/toys/{masterResetEntity.js => masterReset.js} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename examples/toys/{masterResetEntity.js => masterReset.js} (99%) diff --git a/examples/toys/masterResetEntity.js b/examples/toys/masterReset.js similarity index 99% rename from examples/toys/masterResetEntity.js rename to examples/toys/masterReset.js index f9471611be..8137f27f70 100644 --- a/examples/toys/masterResetEntity.js +++ b/examples/toys/masterReset.js @@ -1,4 +1,4 @@ -// +// masterReset.js // Created by Eric Levin on 9/23/2015 // Copyright 2015 High Fidelity, Inc. // @@ -842,4 +842,4 @@ function randFloat(low, high) { function randInt(low, high) { return Math.floor(randFloat(low, high)); -} \ No newline at end of file +} From 3565d96ffb19b225798e161cc492e85d860c3240 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:21:15 -0700 Subject: [PATCH 186/212] Update sprayPaintCan.js add a header, cleanup --- examples/toys/sprayPaintCan.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/examples/toys/sprayPaintCan.js b/examples/toys/sprayPaintCan.js index 0de95f5d93..5c524a38bc 100644 --- a/examples/toys/sprayPaintCan.js +++ b/examples/toys/sprayPaintCan.js @@ -1,3 +1,14 @@ +// +// sprayPaintCan.js +// examples/entityScripts +// +// Created by Eric Levin on 9/21/15. +// 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 +// + + (function() { // Script.include("../libraries/utils.js"); //Need absolute path for now, for testing before PR merge and s3 cloning. Will change post-merge @@ -13,7 +24,7 @@ x: 0, y: 0, z: 0 - } + }; // if the trigger value goes below this while held, the can will stop spraying. if it goes above, it will spray var DISABLE_SPRAY_THRESHOLD = 0.5; @@ -129,14 +140,12 @@ } - this.preload = function(entityId) { this.spraying = false; this.entityId = entityId; this.resetKey = "resetMe"; } - this.unload = function() { if (this.paintStream) { Entities.deleteEntity(this.paintStream); From 6cc2df90524511a57e491f9c90b0850a914e5c84 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:34:22 -0700 Subject: [PATCH 187/212] Update cat.js hook into isPlaying for sounds --- examples/toys/cat.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 156765ed00..34dea1fb80 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -21,29 +21,36 @@ Cat.prototype = { isMeowing:false, + this.injector:null, startTouch: function() { var _ t=this; if(this.isMeowing!==true){ this.meow(); this.isMeowing=true; - Script.setTimeout(function(){ - _t.isMeowing=false; - },2000) } }, - + + update:function(){ + if(this.injector!==null){ + this.isMeowing = this.injector.isPlaying; + } + if(this.isMeowing===false){ + this.injector=null + } + } + meow: function() { - - Audio.playSound(this.meowSound, { + this.injector = Audio.playSound(this.meowSound, { position: this.position, - volume: .1 + volume: 0.1 }); }, preload: function(entityID) { this.entityID = entityID; this.position = Entities.getEntityProperties(this.entityID, "position").position; + Script.update.connect(this.update); }, unload: function() { From f200fcdfa2704a9fc0edcfc1e5078ed92e284dc4 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:35:34 -0700 Subject: [PATCH 188/212] Update cat.js --- examples/toys/cat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 34dea1fb80..bde0a5a2c4 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -21,7 +21,7 @@ Cat.prototype = { isMeowing:false, - this.injector:null, + injector:null, startTouch: function() { var _ t=this; if(this.isMeowing!==true){ From 59c1c7ee6a6502dc14340a598ebae718d4a0e607 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:40:12 -0700 Subject: [PATCH 189/212] Update masterReset.js remove file versioning --- examples/toys/masterReset.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/toys/masterReset.js b/examples/toys/masterReset.js index 8137f27f70..029f7f1ba6 100644 --- a/examples/toys/masterReset.js +++ b/examples/toys/masterReset.js @@ -188,7 +188,7 @@ function createFire() { function createCat(position) { - var scriptURL = Script.resolvePath("cat.js?v1"); + var scriptURL = Script.resolvePath("cat.js"); var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/Dark_Cat.fbx"; var animationURL = "http://hifi-public.s3.amazonaws.com/ryan/sleeping.fbx"; var animationSettings = JSON.stringify({ @@ -256,8 +256,8 @@ function createFlashlight(position) { } function createLightSwitches() { - var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx?v1"; - var scriptURL = Script.resolvePath("lightSwitchHall.js?v1"); + var modelURL = "http://hifi-public.s3.amazonaws.com/ryan/lightswitch.fbx"; + var scriptURL = Script.resolvePath("lightSwitchHall.js"); var lightSwitchHall = Entities.addEntity({ type: "Model", @@ -286,7 +286,7 @@ function createLightSwitches() { resetMe: true }); - scriptURL = Script.resolvePath("lightSwitchGarage.js?v1"); + scriptURL = Script.resolvePath("lightSwitchGarage.js"); var lightSwitchGarage = Entities.addEntity({ type: "Model", @@ -597,7 +597,7 @@ function createBasketBall(position) { function createDoll(position) { var modelURL = "http://hifi-public.s3.amazonaws.com/models/Bboys/bboy2/bboy2.fbx"; - var scriptURL = Script.resolvePath("doll/doll.js?v2"); + var scriptURL = Script.resolvePath("doll/doll.js"); var naturalDimensions = { x: 1.63, @@ -632,7 +632,7 @@ function createDoll(position) { } function createSprayCan(position) { - var scriptURL = Script.resolvePath("sprayPaintCan.js?v1" + Math.random()); + var scriptURL = Script.resolvePath("sprayPaintCan.js") ; var modelURL = "https://hifi-public.s3.amazonaws.com/eric/models/paintcan.fbx"; var entity = Entities.addEntity({ From 55d20e9d4cd30b9f10a8405ad1e710f90207241e Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:41:24 -0700 Subject: [PATCH 190/212] Update cat.js --- examples/toys/cat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index bde0a5a2c4..44991dd9bd 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -23,7 +23,7 @@ isMeowing:false, injector:null, startTouch: function() { - var _ t=this; + var _t=this; if(this.isMeowing!==true){ this.meow(); this.isMeowing=true; From 3490e08521360bde1d0f0266f64ddacbab48a410 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Oct 2015 18:42:09 -0700 Subject: [PATCH 191/212] Little improvments on the performance side to get the Stencil pass and the masking of the background under reasonable performances --- .../gpu/src/gpu/DrawUnitQuadTexcoord.slv | 28 +++++++++++++ libraries/gpu/src/gpu/GLBackend.cpp | 39 ++++++++++++------- libraries/gpu/src/gpu/GLBackendState.cpp | 23 +++++++---- libraries/gpu/src/gpu/GLBackendTransform.cpp | 30 ++++++++------ libraries/gpu/src/gpu/StandardShaderLib.cpp | 8 ++++ libraries/gpu/src/gpu/StandardShaderLib.h | 4 ++ .../render-utils/src/RenderDeferredTask.cpp | 21 ++++------ 7 files changed, 108 insertions(+), 45 deletions(-) create mode 100644 libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv diff --git a/libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv b/libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv new file mode 100644 index 0000000000..60ab0bd7dd --- /dev/null +++ b/libraries/gpu/src/gpu/DrawUnitQuadTexcoord.slv @@ -0,0 +1,28 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw the unit quad [-1,-1 -> 1,1] amd pass along the unit texcoords [0, 0 -> 1, 1]. Not transform used. +// Simply draw a Triangle_strip of 2 triangles, no input buffers or index buffer needed +// +// Created by Sam Gateau on 6/22/2015 +// 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 +// +out vec2 varTexCoord0; + +void main(void) { + const vec4 UNIT_QUAD[4] = vec4[4]( + vec4(-1.0, -1.0, 0.0, 1.0), + vec4(1.0, -1.0, 0.0, 1.0), + vec4(-1.0, 1.0, 0.0, 1.0), + vec4(1.0, 1.0, 0.0, 1.0) + ); + vec4 pos = UNIT_QUAD[gl_VertexID]; + + varTexCoord0 = (pos.xy + 1) * 0.5; + + gl_Position = pos; +} diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 250fc4aaac..b1e63a18bd 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -132,20 +132,26 @@ void GLBackend::renderPassTransfer(Batch& batch) { const size_t numCommands = batch.getCommands().size(); const Batch::Commands::value_type* command = batch.getCommands().data(); const Batch::CommandOffsets::value_type* offset = batch.getCommandOffsets().data(); - - for (auto& cached : batch._buffers._items) { - if (cached._data) { - syncGPUObject(*cached._data); + + { // Sync all the buffers + PROFILE_RANGE("syncGPUBuffer"); + + for (auto& cached : batch._buffers._items) { + if (cached._data) { + syncGPUObject(*cached._data); + } } } - // Reset the transform buffers - _transform._cameras.resize(0); - _transform._cameraOffsets.clear(); - _transform._objects.resize(0); - _transform._objectOffsets.clear(); - for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { - switch (*command) { + { // Sync all the buffers + PROFILE_RANGE("syncCPUTransform"); + _transform._cameras.resize(0); + _transform._cameraOffsets.clear(); + _transform._objects.resize(0); + _transform._objectOffsets.clear(); + + for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { + switch (*command) { case Batch::COMMAND_draw: case Batch::COMMAND_drawIndexed: case Batch::COMMAND_drawInstanced: @@ -164,11 +170,16 @@ void GLBackend::renderPassTransfer(Batch& batch) { default: break; + } + command++; + offset++; } - command++; - offset++; } - _transform.transfer(); + + { // Sync the transform buffers + PROFILE_RANGE("syncGPUTransform"); + _transform.transfer(); + } } void GLBackend::renderPassDraw(Batch& batch) { diff --git a/libraries/gpu/src/gpu/GLBackendState.cpp b/libraries/gpu/src/gpu/GLBackendState.cpp index feba6e6853..895d0a0027 100644 --- a/libraries/gpu/src/gpu/GLBackendState.cpp +++ b/libraries/gpu/src/gpu/GLBackendState.cpp @@ -642,8 +642,13 @@ void GLBackend::do_setStateStencil(State::StencilActivation activation, State::S if (activation.isEnabled()) { glEnable(GL_STENCIL_TEST); - glStencilMaskSeparate(GL_FRONT, activation.getWriteMaskFront()); - glStencilMaskSeparate(GL_BACK, activation.getWriteMaskBack()); + + if (activation.getWriteMaskFront() != activation.getWriteMaskBack()) { + glStencilMaskSeparate(GL_FRONT, activation.getWriteMaskFront()); + glStencilMaskSeparate(GL_BACK, activation.getWriteMaskBack()); + } else { + glStencilMask(activation.getWriteMaskFront()); + } static GLenum STENCIL_OPS[] = { GL_KEEP, @@ -655,12 +660,16 @@ void GLBackend::do_setStateStencil(State::StencilActivation activation, State::S GL_INCR, GL_DECR }; - glStencilOpSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); - glStencilFuncSeparate(GL_FRONT, GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); - - glStencilOpSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); - glStencilFuncSeparate(GL_BACK, GL_COMPARISON_FUNCTIONS[backTest.getFunction()], backTest.getReference(), backTest.getReadMask()); + if (frontTest != backTest) { + glStencilOpSeparate(GL_FRONT, STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); + glStencilFuncSeparate(GL_FRONT, GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); + glStencilOpSeparate(GL_BACK, STENCIL_OPS[backTest.getFailOp()], STENCIL_OPS[backTest.getPassOp()], STENCIL_OPS[backTest.getDepthFailOp()]); + glStencilFuncSeparate(GL_BACK, GL_COMPARISON_FUNCTIONS[backTest.getFunction()], backTest.getReference(), backTest.getReadMask()); + } else { + glStencilOp(STENCIL_OPS[frontTest.getFailOp()], STENCIL_OPS[frontTest.getPassOp()], STENCIL_OPS[frontTest.getDepthFailOp()]); + glStencilFunc(GL_COMPARISON_FUNCTIONS[frontTest.getFunction()], frontTest.getReference(), frontTest.getReadMask()); + } } else { glDisable(GL_STENCIL_TEST); } diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 4a55155a86..5e16421c6a 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -130,19 +130,27 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo void GLBackend::TransformStageState::transfer() const { static QByteArray bufferData; - glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer); - bufferData.resize(_cameraUboSize * _cameras.size()); - for (size_t i = 0; i < _cameras.size(); ++i) { - memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera)); + if (!_cameras.empty()) { + glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer); + bufferData.resize(_cameraUboSize * _cameras.size()); + for (size_t i = 0; i < _cameras.size(); ++i) { + memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera)); + } + glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); } - glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer); - bufferData.resize(_objectUboSize * _objects.size()); - for (size_t i = 0; i < _objects.size(); ++i) { - memcpy(bufferData.data() + (_objectUboSize * i), &_objects[i], sizeof(TransformObject)); + + if (!_objects.empty()) { + glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer); + bufferData.resize(_objectUboSize * _objects.size()); + for (size_t i = 0; i < _objects.size(); ++i) { + memcpy(bufferData.data() + (_objectUboSize * i), &_objects[i], sizeof(TransformObject)); + } + glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); + } + + if (!_cameras.empty() || !_objects.empty()) { + glBindBuffer(GL_UNIFORM_BUFFER, 0); } - glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index 3f27a7fc35..864bff08c9 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -12,6 +12,7 @@ // #include "StandardShaderLib.h" +#include "DrawUnitQuadTexcoord_vert.h" #include "DrawTransformUnitQuad_vert.h" #include "DrawTexcoordRectTransformUnitQuad_vert.h" #include "DrawViewportQuadTransformTexcoord_vert.h" @@ -21,6 +22,7 @@ using namespace gpu; +ShaderPointer StandardShaderLib::_drawUnitQuadTexcoordVS; ShaderPointer StandardShaderLib::_drawTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawTexcoordRectTransformUnitQuadVS; ShaderPointer StandardShaderLib::_drawViewportQuadTransformTexcoordVS; @@ -55,6 +57,12 @@ ShaderPointer StandardShaderLib::getProgram(GetShader getVS, GetShader getPS) { } +ShaderPointer StandardShaderLib::getDrawUnitQuadTexcoordVS() { + if (!_drawUnitQuadTexcoordVS) { + _drawUnitQuadTexcoordVS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(DrawUnitQuadTexcoord_vert))); + } + return _drawUnitQuadTexcoordVS; +} ShaderPointer StandardShaderLib::getDrawTransformUnitQuadVS() { if (!_drawTransformUnitQuadVS) { diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index 2d9c168473..12ea9045c2 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -23,6 +23,9 @@ namespace gpu { class StandardShaderLib { public: + // Shader draws the unit quad in the full viewport clipPos = ([(-1,-1),(1,1)]) and the unit texcoord = [(0,0),(1,1)]. + static ShaderPointer getDrawUnitQuadTexcoordVS(); + // Shader draw the unit quad objectPos = ([(-1,-1),(1,1)]) and transform it by the full model transform stack (Model, View, Proj). // A texcoord attribute is also generated texcoord = [(0,0),(1,1)] static ShaderPointer getDrawTransformUnitQuadVS(); @@ -44,6 +47,7 @@ public: protected: + static ShaderPointer _drawUnitQuadTexcoordVS; static ShaderPointer _drawTransformUnitQuadVS; static ShaderPointer _drawTexcoordRectTransformUnitQuadVS; static ShaderPointer _drawViewportQuadTransformTexcoordVS; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 504070963d..983c2d44ba 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -37,15 +37,19 @@ void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderCon RenderArgs* args = renderContext->args; gpu::doInBatch(args->_context, [=](gpu::Batch& batch) { + auto primaryFboStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); auto primaryFbo = DependencyManager::get()->getPrimaryFramebufferDepthColor(); batch.enableStereo(false); - batch.setFramebuffer(nullptr); - batch.setFramebuffer(primaryFbo); - batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); + batch.setFramebuffer(primaryFboStencil); + batch.clearFramebuffer( + gpu::Framebuffer::BUFFER_STENCIL, + vec4(vec3(0), 1), 1.0, 0.0, true); + + batch.setFramebuffer(primaryFbo); batch.clearFramebuffer( gpu::Framebuffer::BUFFER_COLOR0 | gpu::Framebuffer::BUFFER_DEPTH, @@ -68,7 +72,6 @@ void ResolveDeferred::run(const SceneContextPointer& sceneContext, const RenderC RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(new SetupDeferred::JobModel("SetupFramebuffer"))); - // _jobs.push_back(Job(new DrawBackground::JobModel("DrawBackground"))); _jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred"))); _jobs.push_back(Job(new FetchItems::JobModel("FetchOpaque", @@ -302,7 +305,7 @@ gpu::PipelinePointer DrawStencilDeferred::_opaquePipeline; const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { if (!_opaquePipeline) { const gpu::int8 STENCIL_OPAQUE = 1; - auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS(); + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(drawOpaqueStencil_frag))); auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); @@ -329,7 +332,6 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren args->_batch = &batch; auto primaryFboColorDepthStencil = DependencyManager::get()->getPrimaryFramebufferStencilColor(); - auto primaryFboFull = DependencyManager::get()->getPrimaryFramebuffer(); auto primaryDepth = DependencyManager::get()->getPrimaryDepthTexture(); batch.enableStereo(false); @@ -337,11 +339,6 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren batch.setFramebuffer(primaryFboColorDepthStencil); batch.setViewportTransform(args->_viewport); batch.setStateScissorRect(args->_viewport); - batch.clearStencilFramebuffer(0, true); - - - Transform modelMat; - batch.setModelTransform(modelMat); batch.setPipeline(getOpaquePipeline()); batch.setResourceTexture(0, primaryDepth); @@ -349,8 +346,6 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(0, nullptr); - batch.setFramebuffer(primaryFboFull); - }); args->_batch = nullptr; } From d0e079ee9dd48e82c74e2d36b86701cb50377cf5 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:46:32 -0700 Subject: [PATCH 192/212] Update cat.js add globals, lint the code --- examples/toys/cat.js | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 44991dd9bd..537e0c21b4 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -8,45 +8,42 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// +/*global Cat, print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ + (function() { - var _this; - Cat = function() { - _this = this; this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); }; Cat.prototype = { - isMeowing:false, - injector:null, + isMeowing: false, + injector: null, startTouch: function() { - var _t=this; - if(this.isMeowing!==true){ + if (this.isMeowing !== true) { this.meow(); - this.isMeowing=true; + this.isMeowing = true; } }, - - update:function(){ - if(this.injector!==null){ - this.isMeowing = this.injector.isPlaying; + + update: function() { + if (this.injector !== null) { + this.isMeowing = this.injector.isPlaying; } - if(this.isMeowing===false){ - this.injector=null + if (this.isMeowing === false) { + this.injector = null; } - } - + }, + meow: function() { this.injector = Audio.playSound(this.meowSound, { position: this.position, volume: 0.1 }); }, - + preload: function(entityID) { this.entityID = entityID; this.position = Entities.getEntityProperties(this.entityID, "position").position; From 0ce6a305bdb200fa85949eda66f4e918fd9642f6 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:52:08 -0700 Subject: [PATCH 193/212] Update cat.js --- examples/toys/cat.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 537e0c21b4..63a8a351d4 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -13,7 +13,9 @@ (function() { +var _this; Cat = function() { + _this=this; this.meowSound = SoundCache.getSound("https://s3.amazonaws.com/hifi-public/sounds/Animals/cat_meow.wav"); }; @@ -29,11 +31,11 @@ }, update: function() { - if (this.injector !== null) { - this.isMeowing = this.injector.isPlaying; + if (_this.injector !== null) { + _this.isMeowing = this.injector.isPlaying; } - if (this.isMeowing === false) { - this.injector = null; + if (_this.isMeowing === false) { + _this.injector = null; } }, From a3c91b12b9c8d1fa7cb83739adc95cd482279b78 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 18:56:38 -0700 Subject: [PATCH 194/212] Update cat.js --- examples/toys/cat.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/toys/cat.js b/examples/toys/cat.js index 63a8a351d4..beca627539 100644 --- a/examples/toys/cat.js +++ b/examples/toys/cat.js @@ -33,10 +33,11 @@ var _this; update: function() { if (_this.injector !== null) { _this.isMeowing = this.injector.isPlaying; + if (_this.isMeowing === false) { + _this.injector = null; + } } - if (_this.isMeowing === false) { - _this.injector = null; - } + }, meow: function() { From 4b1b53e18943ffce6276292ddd6ff941955d40b0 Mon Sep 17 00:00:00 2001 From: James Pollack Date: Thu, 1 Oct 2015 19:01:10 -0700 Subject: [PATCH 195/212] end of dat --- examples/particle_explorer/main.js | 74 ++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js index 71caf4cafb..b25d54ea8f 100644 --- a/examples/particle_explorer/main.js +++ b/examples/particle_explorer/main.js @@ -23,7 +23,7 @@ var Settings = function() { var AUTO_UPDATE = false; -var UPDATE_ALL_FREQUENCY = 1000; +var UPDATE_ALL_FREQUENCY = 100; var controllers = []; var colorControllers = []; @@ -153,16 +153,17 @@ function loadGUI() { gui.add(settings, 'exportSettings'); addIndividualKeys(); addFolders(); - if(AUTO_UPDATE){ + if (AUTO_UPDATE) { setInterval(manuallyUpdateDisplay, UPDATE_ALL_FREQUENCY); } + registerDOMElementsForListenerBlocking(); } function addIndividualKeys() { _.each(individualKeys, function(key) { - var controller = gui.add(settings, key); + var controller = gui.add(settings, key).listen(); //need to fix not being able to input values if constantly listening //.listen(); @@ -179,8 +180,7 @@ function addIndividualKeys() { function addFolders() { _.each(colorKeys, function(key) { - console.log('COLOR KEY IS' + key) - // createColorFolder(key); + // createColorFolder(key); createColorPicker(key); }); _.each(vec3Keys, function(key) { @@ -193,16 +193,13 @@ function addFolders() { } function createColorPicker(key) { - console.log('CREATE COLOR PICKER') var colorObject = settings[key]; var colorArray = convertColorObjectToArray(colorObject); settings[key] = colorArray; var controller = gui.addColor(settings, key); controller.onChange(function(value) { - console.log('COLOR VALUE' + value) var obj = {}; obj[key] = convertColorArrayToObject(value); - console.log('AFTER CONVERSION'); writeVec3ToInterface(obj); }); return; @@ -380,6 +377,7 @@ function writeVec3ToInterface(obj) { } window.onload = function() { + console.log('WINDOW ONLOAD'); if (typeof EventBridge !== 'undefined') { var stringifiedData = JSON.stringify({ @@ -392,7 +390,7 @@ window.onload = function() { listenForSettingsUpdates(); } else { - // console.log('No event bridge, probably not in interface.'); + console.log('No event bridge, probably not in interface.'); } }; @@ -459,9 +457,9 @@ function prepareSettingsForExport() { return; } - if(key.indexOf('color')>-1){ + if (key.indexOf('color') > -1) { var colorObject = convertColorArrayToObject(settings[key]); - settings[key]=colorObject + settings[key] = colorObject } exportSettings[key] = settings[key]; @@ -469,16 +467,56 @@ function prepareSettingsForExport() { return JSON.stringify(exportSettings); } -function removeListener(key){ - _.each(gui.__listening,function(controller,index){ - if(controller.property===key){ - console.log('CONTROLLER KEY MATCHES REMOVELISTENER KEY') - storedController = controller; - gui.__listening.splice(index,1); - } + +function removeListenerFromGUI(key) { + console.log('REMOVE ' + key ) + _.each(gui.__listening, function(controller, index) { + console.log('CONTROLLER AT REMOVE' + controller) + // if (controller.property === key) { + // storedController = controller; + // gui.__listening.splice(index, 1); + // } }); } +function addListenersBackToGUI(event) { + gui.__listening.push(storedController); + storedController = null; +} + +function registerDOMElementsForListenerBlocking() { + console.log('gui.__controllers length::: '+gui.__controllers.length) + + + + _.each(gui.__controllers, function(controller) { + var input = controller.domElement.childNodes[0]; + input.addEventListener('focus', function(event) { + console.log('INPUT ELEMENT GOT FOCUS!' + controller.property); + removeListenerFromGUI(controller.property); + }); + }) + + _.each(gui.__controllers, function(controller) { + var input = controller.domElement.childNodes[0]; + input.addEventListener('blur', function(event) { + console.log('INPUT ELEMENT GOT BLUR!' + controller.property); + addListenersBackToGUI(); + }); + }) + + // _.each(gui.__folders, function(folder) { + // _.each(folder.__controllers, function(controller) { + // var input = controller.__input; + // input.addEventListener('focus', function(event) { + // console.log('FOLDER ELEMENT GOT FOCUS!' + controller.property); + // }); + // }) + // }); +} + +// gui.__folders['Flow Field'].__controllers[0].__input + function importSettings() { var importInput = document.getElementById('importer-input'); console.log('import value' + importInput.value) From 690620d74d7889f831a078f18c26f81b7958d935 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 1 Oct 2015 19:23:32 -0700 Subject: [PATCH 196/212] Cleaning code --- libraries/gpu/src/gpu/GLBackendTexture.cpp | 7 ++----- libraries/model/src/model/Skybox.cpp | 2 +- libraries/render-utils/src/Environment.cpp | 2 -- libraries/render-utils/src/RenderDeferredTask.cpp | 1 - libraries/render-utils/src/drawOpaqueStencil.slf | 10 ++-------- 5 files changed, 5 insertions(+), 17 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendTexture.cpp b/libraries/gpu/src/gpu/GLBackendTexture.cpp index 044204934c..ee5e1d3bc6 100755 --- a/libraries/gpu/src/gpu/GLBackendTexture.cpp +++ b/libraries/gpu/src/gpu/GLBackendTexture.cpp @@ -360,11 +360,8 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) { if (bytes && texture.isAutogenerateMips()) { glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - }/* else { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - }*/ - + } + object->_target = GL_TEXTURE_2D; syncSampler(texture.getSampler(), texture.getType(), object); diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index e516fae583..21b40a54c8 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -129,7 +129,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.draw(gpu::TRIANGLE_STRIP, 4); - // batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); + batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); } diff --git a/libraries/render-utils/src/Environment.cpp b/libraries/render-utils/src/Environment.cpp index acb149a3cc..b26d402fa3 100644 --- a/libraries/render-utils/src/Environment.cpp +++ b/libraries/render-utils/src/Environment.cpp @@ -62,8 +62,6 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra auto state = std::make_shared(); state->setCullMode(gpu::State::CULL_NONE); - // state->setDepthTest(false); - // state->setDepthTest(true, false, gpu::LESS_EQUAL); state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 983c2d44ba..0f79dc8b8d 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -314,7 +314,6 @@ const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() { auto state = std::make_shared(); state->setStencilTest(true, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE, gpu::State::STENCIL_OP_REPLACE)); - // state->setStencilTest(false, 0xFF, gpu::State::StencilTest(STENCIL_OPAQUE, 0xFF, gpu::ALWAYS, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR, gpu::State::STENCIL_OP_INCR)); state->setColorWriteMask(0); _opaquePipeline.reset(gpu::Pipeline::create(program, state)); diff --git a/libraries/render-utils/src/drawOpaqueStencil.slf b/libraries/render-utils/src/drawOpaqueStencil.slf index 883154c624..14feda21e9 100644 --- a/libraries/render-utils/src/drawOpaqueStencil.slf +++ b/libraries/render-utils/src/drawOpaqueStencil.slf @@ -13,18 +13,12 @@ // in vec2 varTexCoord0; -out vec4 outFragColor; uniform sampler2D depthTexture; void main(void) { - // outFragColor = vec4(varTexCoord0, 0.0, 1.0); - - float depth = texture(depthTexture, varTexCoord0.xy).r; - outFragColor = vec4(1.0, 0.0, 0.0, 1.0); - if (depth < 1.0) { - outFragColor = vec4(0.0, 1.0, 0.0, 1.0); - } else { + float depth = texture(depthTexture, varTexCoord0.xy).r; + if (depth >= 1.0) { discard; } } From e1e34b2ce5cbd20a972947977ca4e79a02e912da Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 1 Oct 2015 20:17:04 -0700 Subject: [PATCH 197/212] Fix to allow arbitrary input/output buffers from caller. SIMD padding is no longer required. --- libraries/audio/src/AudioSRC.cpp | 78 ++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/libraries/audio/src/AudioSRC.cpp b/libraries/audio/src/AudioSRC.cpp index e33d399213..99760fc42f 100644 --- a/libraries/audio/src/AudioSRC.cpp +++ b/libraries/audio/src/AudioSRC.cpp @@ -915,12 +915,10 @@ int AudioSRC::multirateFilter2(const float* input0, const float* input1, float* void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int numFrames) { __m128 scale = _mm_set1_ps(1/32768.0f); - numFrames = (numFrames + 3) & ~3; // SIMD4 can overcompute - assert(numFrames <= SRC_BLOCK); - if (_numChannels == 1) { - for (int i = 0; i < numFrames; i += 4) { + int i = 0; + for (; i < numFrames - 3; i += 4) { __m128i a0 = _mm_loadl_epi64((__m128i*)&input[i]); // sign-extend @@ -930,9 +928,21 @@ void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int _mm_storeu_ps(&outputs[0][i], f0); } - } else if (_numChannels == 2) { - for (int i = 0; i < numFrames; i += 4) { + for (; i < numFrames; i++) { + __m128i a0 = _mm_insert_epi16(_mm_setzero_si128(), input[i], 0); + // sign-extend + a0 = _mm_srai_epi32(_mm_unpacklo_epi16(a0, a0), 16); + + __m128 f0 = _mm_mul_ps(_mm_cvtepi32_ps(a0), scale); + + _mm_store_ss(&outputs[0][i], f0); + } + + } else if (_numChannels == 2) { + + int i = 0; + for (; i < numFrames - 3; i += 4) { __m128i a0 = _mm_loadu_si128((__m128i*)&input[2*i]); __m128i a1 = a0; @@ -946,6 +956,20 @@ void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int _mm_storeu_ps(&outputs[0][i], f0); _mm_storeu_ps(&outputs[1][i], f1); } + for (; i < numFrames; i++) { + __m128i a0 = _mm_cvtsi32_si128(*(int32_t*)&input[2*i]); + __m128i a1 = a0; + + // deinterleave and sign-extend + a0 = _mm_madd_epi16(a0, _mm_set1_epi32(0x00000001)); + a1 = _mm_madd_epi16(a1, _mm_set1_epi32(0x00010000)); + + __m128 f0 = _mm_mul_ps(_mm_cvtepi32_ps(a0), scale); + __m128 f1 = _mm_mul_ps(_mm_cvtepi32_ps(a1), scale); + + _mm_store_ss(&outputs[0][i], f0); + _mm_store_ss(&outputs[1][i], f1); + } } } @@ -970,12 +994,10 @@ static inline __m128 dither4() { void AudioSRC::convertOutputToInt16(float** inputs, int16_t* output, int numFrames) { __m128 scale = _mm_set1_ps(32768.0f); - numFrames = (numFrames + 3) & ~3; // SIMD4 can overcompute - assert(numFrames <= SRC_BLOCK); - if (_numChannels == 1) { - for (int i = 0; i < numFrames; i += 4) { + int i = 0; + for (; i < numFrames - 3; i += 4) { __m128 f0 = _mm_mul_ps(_mm_loadu_ps(&inputs[0][i]), scale); f0 = _mm_add_ps(f0, dither4()); @@ -986,9 +1008,22 @@ void AudioSRC::convertOutputToInt16(float** inputs, int16_t* output, int numFram _mm_storel_epi64((__m128i*)&output[i], a0); } - } else if (_numChannels == 2) { - for (int i = 0; i < numFrames; i += 4) { + for (; i < numFrames; i++) { + __m128 f0 = _mm_mul_ps(_mm_load_ss(&inputs[0][i]), scale); + f0 = _mm_add_ps(f0, dither4()); + + // round and saturate + __m128i a0 = _mm_cvtps_epi32(f0); + a0 = _mm_packs_epi32(a0, a0); + + output[i] = (int16_t)_mm_extract_epi16(a0, 0); + } + + } else if (_numChannels == 2) { + + int i = 0; + for (; i < numFrames - 3; i += 4) { __m128 f0 = _mm_mul_ps(_mm_loadu_ps(&inputs[0][i]), scale); __m128 f1 = _mm_mul_ps(_mm_loadu_ps(&inputs[1][i]), scale); @@ -1004,9 +1039,26 @@ void AudioSRC::convertOutputToInt16(float** inputs, int16_t* output, int numFram // interleave a0 = _mm_unpacklo_epi16(a0, a1); - _mm_storeu_si128((__m128i*)&output[2*i], a0); } + for (; i < numFrames; i++) { + __m128 f0 = _mm_mul_ps(_mm_load_ss(&inputs[0][i]), scale); + __m128 f1 = _mm_mul_ps(_mm_load_ss(&inputs[1][i]), scale); + + __m128 d0 = dither4(); + f0 = _mm_add_ps(f0, d0); + f1 = _mm_add_ps(f1, d0); + + // round and saturate + __m128i a0 = _mm_cvtps_epi32(f0); + __m128i a1 = _mm_cvtps_epi32(f1); + a0 = _mm_packs_epi32(a0, a0); + a1 = _mm_packs_epi32(a1, a1); + + // interleave + a0 = _mm_unpacklo_epi16(a0, a1); + *(int32_t*)&output[2*i] = _mm_cvtsi128_si32(a0); + } } } From 3555e90cf60360273f3fac159c05009b9528c223 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 1 Oct 2015 20:32:48 -0700 Subject: [PATCH 198/212] Improved random generator for SIMD dither --- libraries/audio/src/AudioSRC.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/audio/src/AudioSRC.cpp b/libraries/audio/src/AudioSRC.cpp index 99760fc42f..59fe29df36 100644 --- a/libraries/audio/src/AudioSRC.cpp +++ b/libraries/audio/src/AudioSRC.cpp @@ -975,11 +975,11 @@ void AudioSRC::convertInputFromInt16(const int16_t* input, float** outputs, int // fast TPDF dither in [-1.0f, 1.0f] static inline __m128 dither4() { - static __m128i rz = _mm_set_epi16(0, -12285, 8251, 22985, -4297, 14758, -19785, -26093); + static __m128i rz; - // update the parallel LCGs - rz = _mm_mullo_epi16(rz, _mm_set1_epi16(25173)); - rz = _mm_add_epi16(rz, _mm_set1_epi16(13849)); + // update the 8 different maximum-length LCGs + rz = _mm_mullo_epi16(rz, _mm_set_epi16(25173, -25511, -5975, -23279, 19445, -27591, 30185, -3495)); + rz = _mm_add_epi16(rz, _mm_set_epi16(13849, -32767, 105, -19675, -7701, -32679, -13225, 28013)); // promote to 32-bit __m128i r0 = _mm_unpacklo_epi16(rz, _mm_setzero_si128()); From 7c9d7ffefd4c8f065ac7d6a81dbeca56fe917b44 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 1 Oct 2015 23:49:33 -0700 Subject: [PATCH 199/212] single sysytem particle explorer with one way bindings is feature complete --- examples/particle_explorer/index.html | 25 +- examples/particle_explorer/main.js | 256 ++++++++---------- .../particle_explorer/particleExplorer.js | 16 +- 3 files changed, 132 insertions(+), 165 deletions(-) diff --git a/examples/particle_explorer/index.html b/examples/particle_explorer/index.html index 06ffc0390b..4b9e2a9d36 100644 --- a/examples/particle_explorer/index.html +++ b/examples/particle_explorer/index.html @@ -6,34 +6,37 @@ // Copyright 2015 High Fidelity, Inc. // // Loads dat.gui, underscore, and the app -// Quickly edit the aesthetics of a particle system. This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. +// Quickly edit the aesthetics of a particle system. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// +// --> - +