From 2fea3c58cdc99249dee7cfbd0eacbc6a9a64555e Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 17 Jul 2014 15:25:54 -0700 Subject: [PATCH 1/7] Added working rockPaperScissors.js that works for multiple ACs --- examples/rockPaperScissorsCells.js | 225 +++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100644 examples/rockPaperScissorsCells.js diff --git a/examples/rockPaperScissorsCells.js b/examples/rockPaperScissorsCells.js new file mode 100644 index 0000000000..9227278455 --- /dev/null +++ b/examples/rockPaperScissorsCells.js @@ -0,0 +1,225 @@ +// rockPaperScissorsCells.js +// examples +// +// Created by Ben Arnold on 7/16/14. +// Copyright 2014 High Fidelity, Inc. +// +// This sample script creates a voxel wall that simulates the Rock Paper Scissors cellular +// automata. http://www.gamedev.net/blog/844/entry-2249737-another-cellular-automaton-video/ +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var NUMBER_OF_CELLS_EACH_DIMENSION = 64; +var NUMBER_OF_CELLS_REGION_EACH_DIMESION = 16; +var REGIONS_EACH_DIMENSION = NUMBER_OF_CELLS_EACH_DIMENSION / NUMBER_OF_CELLS_REGION_EACH_DIMESION; + +var currentCells = []; +var nextCells = []; + +var cornerPosition = {x: 100, y: 0, z: 0 } +var position = {x: 0, y: 0, z: 0 }; + +var METER_LENGTH = 1; +var cellScale = (NUMBER_OF_CELLS_EACH_DIMENSION * METER_LENGTH) / NUMBER_OF_CELLS_EACH_DIMENSION; + +//Feel free to add new cell types here. It can be more than three. +var cellTypes = []; +cellTypes[0] = { r: 255, g: 0, b: 0 }; +cellTypes[1] = { r: 0, g: 255, b: 0 }; +cellTypes[2] = { r: 0, g:0, b: 255 }; +cellTypes[3] = { r: 255, g: 255, b: 255 }; +cellTypes[4] = { r: 255, g: 0, b: 255 }; +cellTypes[5] = { r: 0, g: 255, b: 255 }; + +//Check for free region for AC +var regionMarkerX = -1; +var regionMarkerY = -1; +var regionMarkerI = -1; +var regionMarkerJ = -1; + +var regionMarkerColor = {r: 255, g: 0, b: 255}; + +for (var i = 0; i < REGIONS_EACH_DIMENSION; i++) { + for (var j = 0; j < REGIONS_EACH_DIMENSION; j++) { + var x = cornerPosition.x + (j) * cellScale; + var y = cornerPosition.y + (i + NUMBER_OF_CELLS_EACH_DIMENSION) * cellScale; + var z = cornerPosition.z; + var voxel = Voxels.getVoxelAt(x, y, z, cellScale); + if (voxel.x != x || voxel.y != y || voxel.z != z || voxel.s != cellScale || + voxel.red != regionMarkerColor.r || voxel.green != regionMarkerColor.g || voxel.blue != regionMarkerColor.b) { + regionMarkerX = x; + regionMarkerY = y; + regionMarkerI = i; + regionMarkerJ = j; + i = REGIONS_EACH_DIMENSION; //force quit loop + break; + } + } +} + +if (regionMarkerX == -1) { + print("No available Cellular Automata regions found!") + Script.stop(); +} + +position.x = cornerPosition.x + regionMarkerJ * NUMBER_OF_CELLS_REGION_EACH_DIMESION * cellScale; +position.y = cornerPosition.y + regionMarkerI * NUMBER_OF_CELLS_REGION_EACH_DIMESION * cellScale; +position.z = cornerPosition.z; + +Voxels.setVoxel(regionMarkerX, regionMarkerY, position.z, cellScale, regionMarkerColor.r, regionMarkerColor.g, regionMarkerColor.b); + +// randomly populate the cell start values +for (var i = 0; i < NUMBER_OF_CELLS_REGION_EACH_DIMESION; i++) { + // create the array to hold this row + currentCells[i] = []; + + // create the array to hold this row in the nextCells array + nextCells[i] = []; + + for (var j = 0; j < NUMBER_OF_CELLS_REGION_EACH_DIMESION; j++) { + currentCells[i][j] = { changed: true, type: Math.floor(Math.random() * cellTypes.length) }; + + // put the same value in the nextCells array for first board draw + nextCells[i][j] = currentCells[i][j]; + } +} + +function updateCells() { + var i = 0; + var j = 0; + var cell; + var y = 0; + var x = 0; + + for (i = 0; i < NUMBER_OF_CELLS_REGION_EACH_DIMESION; i++) { + for (j = 0; j < NUMBER_OF_CELLS_REGION_EACH_DIMESION; j++) { + + cell = currentCells[i][j]; + + var r = Math.floor(Math.random() * 8); + + switch (r){ + case 0: + y = i - 1; + x = j - 1; + break; + case 1: + y = i; + x = j-1; + break; + case 2: + y = i + 1; + x = j - 1; + break; + case 3: + y = i + 1; + x = j; + break; + case 4: + y = i + 1; + x = j + 1; + break; + case 5: + y = i; + x = j + 1; + break; + case 6: + y = i - 1; + x = j + 1; + break; + case 7: + y = i - 1; + x = j; + break; + default: + continue; + + } + + //check the voxel grid instead of local array when on the edge + if (x == -1 || x == NUMBER_OF_CELLS_REGION_EACH_DIMESION || + y == -1 || y == NUMBER_OF_CELLS_REGION_EACH_DIMESION) { + + var voxel = Voxels.getVoxelAt(position.x + x * cellScale, position.y + y * cellScale, position.z, cellScale); + var predatorCellType = ((cell.type + 1) % cellTypes.length); + var predatorCellColor = cellTypes[predatorCellType]; + if (voxel.red == predatorCellColor.r && voxel.green == predatorCellColor.g && voxel.blue == predatorCellColor.b) { + nextCells[i][j].type = predatorCellType; + nextCells[i][j].changed = true; + } + } else { + + if (currentCells[y][x].type == ((cell.type + 1) % cellTypes.length)) { + nextCells[i][j] = currentCells[y][x]; + nextCells[i][j].changed = true; + } else { + //indicate no update + nextCells[i][j].changed = true; + } + } + } + } + + for (i = 0; i < NUMBER_OF_CELLS_REGION_EACH_DIMESION; i++) { + for (j = 0; j < NUMBER_OF_CELLS_REGION_EACH_DIMESION; j++) { + if (nextCells[i][j].changed == true) { + // there has been a change to this cell, change the value in the currentCells array + currentCells[i][j] = nextCells[i][j]; + } + } + } +} + +function sendNextCells() { + for (var i = 0; i < NUMBER_OF_CELLS_REGION_EACH_DIMESION; i++) { + for (var j = 0; j < NUMBER_OF_CELLS_REGION_EACH_DIMESION; j++) { + if (nextCells[i][j].changed == true) { + // there has been a change to the state of this cell, send it + + // find the x and y position for this voxel, z = 0 + var x = j * cellScale; + var y = i * cellScale; + var type = nextCells[i][j].type; + + // queue a packet to add a voxel for the new cell + Voxels.setVoxel(position.x + x, position.y + y, position.z, cellScale, cellTypes[type].r, cellTypes[type].g, cellTypes[type].b); + } + } + } +} + +var sentFirstBoard = false; + +var UPDATES_PER_SECOND = 3.0; +var frameIndex = 1.0; +var oldFrameIndex = 0; + +function step(deltaTime) { + frameIndex += deltaTime * UPDATES_PER_SECOND; + if (Math.floor(frameIndex) == oldFrameIndex) { + return; + } + oldFrameIndex++; + + if (sentFirstBoard) { + // we've already sent the first full board, perform a step in time + updateCells(); + } else { + // this will be our first board send + sentFirstBoard = true; + } + + sendNextCells(); +} + +function scriptEnding() { + Voxels.eraseVoxel(regionMarkerX, regionMarkerY, position.z, cellScale); +} + +Script.scriptEnding.connect(scriptEnding); + +Script.update.connect(step); +//Voxels.setMaxPacketSize(1); //this is needed or a bug occurs :( +Voxels.setPacketsPerSecond(2000); From 592c571fcb6d3c9d71916dd4fd3d82c3c2fdc8a2 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 17 Jul 2014 18:15:34 -0700 Subject: [PATCH 2/7] Fixed crash bug in voxelScriptingInterface --- examples/rockPaperScissorsCells.js | 10 ++++------ libraries/voxels/src/VoxelsScriptingInterface.cpp | 6 ++++++ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/examples/rockPaperScissorsCells.js b/examples/rockPaperScissorsCells.js index 9227278455..4f6de888a1 100644 --- a/examples/rockPaperScissorsCells.js +++ b/examples/rockPaperScissorsCells.js @@ -29,9 +29,7 @@ var cellTypes = []; cellTypes[0] = { r: 255, g: 0, b: 0 }; cellTypes[1] = { r: 0, g: 255, b: 0 }; cellTypes[2] = { r: 0, g:0, b: 255 }; -cellTypes[3] = { r: 255, g: 255, b: 255 }; -cellTypes[4] = { r: 255, g: 0, b: 255 }; -cellTypes[5] = { r: 0, g: 255, b: 255 }; + //Check for free region for AC var regionMarkerX = -1; @@ -152,11 +150,11 @@ function updateCells() { } else { if (currentCells[y][x].type == ((cell.type + 1) % cellTypes.length)) { - nextCells[i][j] = currentCells[y][x]; + nextCells[i][j].type = currentCells[y][x].type; nextCells[i][j].changed = true; } else { //indicate no update - nextCells[i][j].changed = true; + nextCells[i][j].changed = false; } } } @@ -192,7 +190,7 @@ function sendNextCells() { var sentFirstBoard = false; -var UPDATES_PER_SECOND = 3.0; +var UPDATES_PER_SECOND = 6.0; var frameIndex = 1.0; var oldFrameIndex = 0; diff --git a/libraries/voxels/src/VoxelsScriptingInterface.cpp b/libraries/voxels/src/VoxelsScriptingInterface.cpp index e877f99760..ba1c3d72de 100644 --- a/libraries/voxels/src/VoxelsScriptingInterface.cpp +++ b/libraries/voxels/src/VoxelsScriptingInterface.cpp @@ -81,11 +81,17 @@ void VoxelsScriptingInterface::setVoxel(float x, float y, float z, float scale, DeleteVoxelCommand* deleteCommand = new DeleteVoxelCommand(_tree, addVoxelDetail, getVoxelPacketSender()); + static QMutex mutex; + mutex.lock(); + _undoStack->beginMacro(addCommand->text()); // As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves. _undoStack->push(deleteCommand); _undoStack->push(addCommand); _undoStack->endMacro(); + + //Unlock the mutex + mutex.unlock(); } else { // queue the destructive add queueVoxelAdd(PacketTypeVoxelSetDestructive, addVoxelDetail); From 814dd0fcb6408ed9b07fdf4be9ea5d22c5a1fcbb Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Fri, 18 Jul 2014 11:37:13 -0700 Subject: [PATCH 3/7] Fixed another crash relating to undo stack. Made script support the VoxelViewer --- examples/rockPaperScissorsCells.js | 31 +++++++++++++++++++--- libraries/networking/src/ResourceCache.cpp | 9 +++++++ libraries/networking/src/ResourceCache.h | 2 +- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/examples/rockPaperScissorsCells.js b/examples/rockPaperScissorsCells.js index 4f6de888a1..aa7d4ef040 100644 --- a/examples/rockPaperScissorsCells.js +++ b/examples/rockPaperScissorsCells.js @@ -11,10 +11,12 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var NUMBER_OF_CELLS_EACH_DIMENSION = 64; +var NUMBER_OF_CELLS_EACH_DIMENSION = 48; var NUMBER_OF_CELLS_REGION_EACH_DIMESION = 16; var REGIONS_EACH_DIMENSION = NUMBER_OF_CELLS_EACH_DIMENSION / NUMBER_OF_CELLS_REGION_EACH_DIMESION; +var isLocal = false; + var currentCells = []; var nextCells = []; @@ -24,11 +26,20 @@ var position = {x: 0, y: 0, z: 0 }; var METER_LENGTH = 1; var cellScale = (NUMBER_OF_CELLS_EACH_DIMENSION * METER_LENGTH) / NUMBER_OF_CELLS_EACH_DIMENSION; +var viewerPosition = {x: cornerPosition.x + (NUMBER_OF_CELLS_EACH_DIMENSION / 2) * cellScale, y: cornerPosition.y + (NUMBER_OF_CELLS_EACH_DIMENSION / 2) * cellScale, z: cornerPosition.z }; + +viewerPosition.z += 50; +var yaw = 0; +var orientation = Quat.fromPitchYawRollDegrees(0, yaw, 0); + //Feel free to add new cell types here. It can be more than three. var cellTypes = []; cellTypes[0] = { r: 255, g: 0, b: 0 }; cellTypes[1] = { r: 0, g: 255, b: 0 }; cellTypes[2] = { r: 0, g:0, b: 255 }; +cellTypes[3] = { r: 0, g:255, b: 255 }; +cellTypes[4] = { r: 255, g:0, b: 255 }; +//cellTypes[5] = { r: 255, g:255, b: 255 }; //Check for free region for AC @@ -76,8 +87,10 @@ for (var i = 0; i < NUMBER_OF_CELLS_REGION_EACH_DIMESION; i++) { // create the array to hold this row in the nextCells array nextCells[i] = []; + var randomColor = Math.floor(Math.random() * cellTypes.length); + for (var j = 0; j < NUMBER_OF_CELLS_REGION_EACH_DIMESION; j++) { - currentCells[i][j] = { changed: true, type: Math.floor(Math.random() * cellTypes.length) }; + currentCells[i][j] = { changed: true, type: randomColor }; // put the same value in the nextCells array for first board draw nextCells[i][j] = currentCells[i][j]; @@ -207,6 +220,15 @@ function step(deltaTime) { } else { // this will be our first board send sentFirstBoard = true; + + print("AHHHH"); + print(viewerPosition.x + " " + viewerPosition.y + " " + viewerPosition.z); + + if (isLocal == false) { + VoxelViewer.setPosition(viewerPosition); + VoxelViewer.setOrientation(orientation); + VoxelViewer.queryOctree(); + } } sendNextCells(); @@ -219,5 +241,8 @@ function scriptEnding() { Script.scriptEnding.connect(scriptEnding); Script.update.connect(step); -//Voxels.setMaxPacketSize(1); //this is needed or a bug occurs :( Voxels.setPacketsPerSecond(2000); + +// test for local... +Menu.isOptionChecked("Voxels"); +isLocal = true; // will only get here on local client \ No newline at end of file diff --git a/libraries/networking/src/ResourceCache.cpp b/libraries/networking/src/ResourceCache.cpp index a183e2f9a1..73c01ef582 100644 --- a/libraries/networking/src/ResourceCache.cpp +++ b/libraries/networking/src/ResourceCache.cpp @@ -40,6 +40,15 @@ void ResourceCache::refresh(const QUrl& url) { } QSharedPointer ResourceCache::getResource(const QUrl& url, const QUrl& fallback, bool delayLoad, void* extra) { + + if (QThread::currentThread() != thread()) { + QSharedPointer result; + QMetaObject::invokeMethod(this, "getResource", Qt::BlockingQueuedConnection, + Q_RETURN_ARG(QSharedPointer, result), Q_ARG(const QUrl&, url), Q_ARG(const QUrl&, fallback), + Q_ARG(bool, delayLoad), Q_ARG(void*, extra)); + return result; + } + if (!url.isValid() && !url.isEmpty() && fallback.isValid()) { return getResource(fallback, QUrl(), delayLoad); } diff --git a/libraries/networking/src/ResourceCache.h b/libraries/networking/src/ResourceCache.h index 1593ad45fc..c3a5974da7 100644 --- a/libraries/networking/src/ResourceCache.h +++ b/libraries/networking/src/ResourceCache.h @@ -52,7 +52,7 @@ protected: /// \param fallback a fallback URL to load if the desired one is unavailable /// \param delayLoad if true, don't load the resource immediately; wait until load is first requested /// \param extra extra data to pass to the creator, if appropriate - QSharedPointer getResource(const QUrl& url, const QUrl& fallback = QUrl(), + Q_INVOKABLE QSharedPointer getResource(const QUrl& url, const QUrl& fallback = QUrl(), bool delayLoad = false, void* extra = NULL); /// Creates a new resource. From 4410411d9d4c2f32eeaafca369e572a1c37e8d86 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Fri, 18 Jul 2014 14:51:53 -0700 Subject: [PATCH 4/7] Script improvements for AC --- examples/rockPaperScissorsCells.js | 118 ++++++++++-------- .../voxels/src/VoxelsScriptingInterface.cpp | 5 + 2 files changed, 68 insertions(+), 55 deletions(-) diff --git a/examples/rockPaperScissorsCells.js b/examples/rockPaperScissorsCells.js index aa7d4ef040..d7101ce4c7 100644 --- a/examples/rockPaperScissorsCells.js +++ b/examples/rockPaperScissorsCells.js @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var NUMBER_OF_CELLS_EACH_DIMENSION = 48; +var NUMBER_OF_CELLS_EACH_DIMENSION = 64; var NUMBER_OF_CELLS_REGION_EACH_DIMESION = 16; var REGIONS_EACH_DIMENSION = NUMBER_OF_CELLS_EACH_DIMENSION / NUMBER_OF_CELLS_REGION_EACH_DIMESION; @@ -37,8 +37,8 @@ var cellTypes = []; cellTypes[0] = { r: 255, g: 0, b: 0 }; cellTypes[1] = { r: 0, g: 255, b: 0 }; cellTypes[2] = { r: 0, g:0, b: 255 }; -cellTypes[3] = { r: 0, g:255, b: 255 }; -cellTypes[4] = { r: 255, g:0, b: 255 }; +cellTypes[3] = { r: 0, g: 255, b: 255 }; +//cellTypes[4] = { r: 255, g:0, b: 255 }; //cellTypes[5] = { r: 255, g:255, b: 255 }; @@ -50,51 +50,45 @@ var regionMarkerJ = -1; var regionMarkerColor = {r: 255, g: 0, b: 255}; -for (var i = 0; i < REGIONS_EACH_DIMENSION; i++) { - for (var j = 0; j < REGIONS_EACH_DIMENSION; j++) { - var x = cornerPosition.x + (j) * cellScale; - var y = cornerPosition.y + (i + NUMBER_OF_CELLS_EACH_DIMENSION) * cellScale; - var z = cornerPosition.z; - var voxel = Voxels.getVoxelAt(x, y, z, cellScale); - if (voxel.x != x || voxel.y != y || voxel.z != z || voxel.s != cellScale || - voxel.red != regionMarkerColor.r || voxel.green != regionMarkerColor.g || voxel.blue != regionMarkerColor.b) { - regionMarkerX = x; - regionMarkerY = y; - regionMarkerI = i; - regionMarkerJ = j; - i = REGIONS_EACH_DIMENSION; //force quit loop - break; + +function init() { + + for (var i = 0; i < REGIONS_EACH_DIMENSION; i++) { + for (var j = 0; j < REGIONS_EACH_DIMENSION; j++) { + var x = cornerPosition.x + (j) * cellScale; + var y = cornerPosition.y + (i + NUMBER_OF_CELLS_EACH_DIMENSION) * cellScale; + var z = cornerPosition.z; + var voxel = Voxels.getVoxelAt(x, y, z, cellScale); + if (voxel.x != x || voxel.y != y || voxel.z != z || voxel.s != cellScale || + voxel.red != regionMarkerColor.r || voxel.green != regionMarkerColor.g || voxel.blue != regionMarkerColor.b) { + regionMarkerX = x; + regionMarkerY = y; + regionMarkerI = i; + regionMarkerJ = j; + i = REGIONS_EACH_DIMENSION; //force quit loop + break; + } } } -} + + Voxels.setVoxel(regionMarkerX, regionMarkerY, position.z, cellScale, regionMarkerColor.r, regionMarkerColor.g, regionMarkerColor.b); -if (regionMarkerX == -1) { - print("No available Cellular Automata regions found!") - Script.stop(); -} - -position.x = cornerPosition.x + regionMarkerJ * NUMBER_OF_CELLS_REGION_EACH_DIMESION * cellScale; -position.y = cornerPosition.y + regionMarkerI * NUMBER_OF_CELLS_REGION_EACH_DIMESION * cellScale; -position.z = cornerPosition.z; - -Voxels.setVoxel(regionMarkerX, regionMarkerY, position.z, cellScale, regionMarkerColor.r, regionMarkerColor.g, regionMarkerColor.b); - -// randomly populate the cell start values -for (var i = 0; i < NUMBER_OF_CELLS_REGION_EACH_DIMESION; i++) { - // create the array to hold this row - currentCells[i] = []; - - // create the array to hold this row in the nextCells array - nextCells[i] = []; - - var randomColor = Math.floor(Math.random() * cellTypes.length); - - for (var j = 0; j < NUMBER_OF_CELLS_REGION_EACH_DIMESION; j++) { - currentCells[i][j] = { changed: true, type: randomColor }; - - // put the same value in the nextCells array for first board draw - nextCells[i][j] = currentCells[i][j]; - } + // randomly populate the cell start values + var randomColor = Math.floor(Math.random() * cellTypes.length); + for (var i = 0; i < NUMBER_OF_CELLS_REGION_EACH_DIMESION; i++) { + // create the array to hold this row + currentCells[i] = []; + + // create the array to hold this row in the nextCells array + nextCells[i] = []; + + for (var j = 0; j < NUMBER_OF_CELLS_REGION_EACH_DIMESION; j++) { + currentCells[i][j] = { changed: true, type: randomColor }; + + // put the same value in the nextCells array for first board draw + nextCells[i][j] = currentCells[i][j]; + } + } } function updateCells() { @@ -202,35 +196,49 @@ function sendNextCells() { } var sentFirstBoard = false; +var voxelViewerInit = false; var UPDATES_PER_SECOND = 6.0; var frameIndex = 1.0; var oldFrameIndex = 0; +var framesToWait = UPDATES_PER_SECOND; + function step(deltaTime) { + + if (isLocal == false) { + if (voxelViewerInit == false) { + VoxelViewer.setPosition(viewerPosition); + VoxelViewer.setOrientation(orientation); + voxelViewerInit = true; + } + VoxelViewer.queryOctree(); + } + frameIndex += deltaTime * UPDATES_PER_SECOND; if (Math.floor(frameIndex) == oldFrameIndex) { return; } oldFrameIndex++; + + if (frameIndex <= framesToWait) { + return; + } + print("UPDATE"); + if (sentFirstBoard) { // we've already sent the first full board, perform a step in time updateCells(); } else { // this will be our first board send sentFirstBoard = true; - - print("AHHHH"); - print(viewerPosition.x + " " + viewerPosition.y + " " + viewerPosition.z); - - if (isLocal == false) { - VoxelViewer.setPosition(viewerPosition); - VoxelViewer.setOrientation(orientation); - VoxelViewer.queryOctree(); - } + init(); + } + + if (isLocal == false) { + VoxelViewer.queryOctree(); } - sendNextCells(); } diff --git a/libraries/voxels/src/VoxelsScriptingInterface.cpp b/libraries/voxels/src/VoxelsScriptingInterface.cpp index ba1c3d72de..093d736720 100644 --- a/libraries/voxels/src/VoxelsScriptingInterface.cpp +++ b/libraries/voxels/src/VoxelsScriptingInterface.cpp @@ -116,11 +116,16 @@ void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale } if (_undoStack) { + DeleteVoxelCommand* command = new DeleteVoxelCommand(_tree, deleteVoxelDetail, getVoxelPacketSender()); + + static QMutex mutex; + mutex.lock(); // As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves. _undoStack->push(command); + mutex.unlock(); } else { getVoxelPacketSender()->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &deleteVoxelDetail); _tree->deleteVoxelAt(deleteVoxelDetail.x, deleteVoxelDetail.y, deleteVoxelDetail.z, deleteVoxelDetail.s); From ab52f384b7fddc64da65f762ba2f4cf01f3a3aff Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Thu, 31 Jul 2014 11:15:20 -0700 Subject: [PATCH 5/7] Improvements on RPS script --- examples/rockPaperScissorsCells.js | 50 ++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/examples/rockPaperScissorsCells.js b/examples/rockPaperScissorsCells.js index d7101ce4c7..2a9cb00a0b 100644 --- a/examples/rockPaperScissorsCells.js +++ b/examples/rockPaperScissorsCells.js @@ -6,12 +6,14 @@ // // This sample script creates a voxel wall that simulates the Rock Paper Scissors cellular // automata. http://www.gamedev.net/blog/844/entry-2249737-another-cellular-automaton-video/ +// If multiple instances of this script are run, they will combine into a larger wall. +// NOTE: You must run each instance one at a time. If they all start at once there are race conditions. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var NUMBER_OF_CELLS_EACH_DIMENSION = 64; +var NUMBER_OF_CELLS_EACH_DIMENSION = 48; var NUMBER_OF_CELLS_REGION_EACH_DIMESION = 16; var REGIONS_EACH_DIMENSION = NUMBER_OF_CELLS_EACH_DIMENSION / NUMBER_OF_CELLS_REGION_EACH_DIMESION; @@ -38,8 +40,6 @@ cellTypes[0] = { r: 255, g: 0, b: 0 }; cellTypes[1] = { r: 0, g: 255, b: 0 }; cellTypes[2] = { r: 0, g:0, b: 255 }; cellTypes[3] = { r: 0, g: 255, b: 255 }; -//cellTypes[4] = { r: 255, g:0, b: 255 }; -//cellTypes[5] = { r: 255, g:255, b: 255 }; //Check for free region for AC @@ -48,8 +48,19 @@ var regionMarkerY = -1; var regionMarkerI = -1; var regionMarkerJ = -1; -var regionMarkerColor = {r: 255, g: 0, b: 255}; +var regionMarkerColor = {r: 254, g: 0, b: 253}; +function setRegionToColor(startX, startY, width, height, color) { + for (var i = startY; i < startY + height; i++) { + for (var j = startX; j < startX + width; j++) { + + currentCells[i][j] = { changed: true, type: color }; + + // put the same value in the nextCells array for first board draw + nextCells[i][j] = { changed: true, type: color }; + } + } +} function init() { @@ -71,24 +82,30 @@ function init() { } } - Voxels.setVoxel(regionMarkerX, regionMarkerY, position.z, cellScale, regionMarkerColor.r, regionMarkerColor.g, regionMarkerColor.b); + //Didnt find an open spot, end script + if (regionMarkerX == -1) { + Script.stop(); + } + + position.x = cornerPosition.x + regionMarkerJ * NUMBER_OF_CELLS_REGION_EACH_DIMESION; + position.y = cornerPosition.y + regionMarkerI * NUMBER_OF_CELLS_REGION_EACH_DIMESION; + position.z = cornerPosition.z; + + Voxels.setVoxel(regionMarkerX, regionMarkerY, cornerPosition.z, cellScale, regionMarkerColor.r, regionMarkerColor.g, regionMarkerColor.b); - // randomly populate the cell start values - var randomColor = Math.floor(Math.random() * cellTypes.length); for (var i = 0; i < NUMBER_OF_CELLS_REGION_EACH_DIMESION; i++) { // create the array to hold this row currentCells[i] = []; // create the array to hold this row in the nextCells array nextCells[i] = []; - - for (var j = 0; j < NUMBER_OF_CELLS_REGION_EACH_DIMESION; j++) { - currentCells[i][j] = { changed: true, type: randomColor }; - - // put the same value in the nextCells array for first board draw - nextCells[i][j] = currentCells[i][j]; - } } + + var width = NUMBER_OF_CELLS_REGION_EACH_DIMESION / 2; + setRegionToColor(0, 0, width, width, 0); + setRegionToColor(0, width, width, width, 1); + setRegionToColor(width, width, width, width, 2); + setRegionToColor(width, 0, width, width, 3); } function updateCells() { @@ -171,7 +188,8 @@ function updateCells() { for (j = 0; j < NUMBER_OF_CELLS_REGION_EACH_DIMESION; j++) { if (nextCells[i][j].changed == true) { // there has been a change to this cell, change the value in the currentCells array - currentCells[i][j] = nextCells[i][j]; + currentCells[i][j].type = nextCells[i][j].type; + currentCells[i][j].changed = true; } } } @@ -224,8 +242,6 @@ function step(deltaTime) { if (frameIndex <= framesToWait) { return; } - - print("UPDATE"); if (sentFirstBoard) { // we've already sent the first full board, perform a step in time From bd1fbaaf762a25635674d23ff73f24a965efc220 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Sat, 2 Aug 2014 16:02:08 -0700 Subject: [PATCH 6/7] Made static mutex into member variable --- libraries/voxels/src/VoxelsScriptingInterface.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libraries/voxels/src/VoxelsScriptingInterface.cpp b/libraries/voxels/src/VoxelsScriptingInterface.cpp index 093d736720..1b2df471f4 100644 --- a/libraries/voxels/src/VoxelsScriptingInterface.cpp +++ b/libraries/voxels/src/VoxelsScriptingInterface.cpp @@ -81,8 +81,7 @@ void VoxelsScriptingInterface::setVoxel(float x, float y, float z, float scale, DeleteVoxelCommand* deleteCommand = new DeleteVoxelCommand(_tree, addVoxelDetail, getVoxelPacketSender()); - static QMutex mutex; - mutex.lock(); + _undoStackMutex.lock(); _undoStack->beginMacro(addCommand->text()); // As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves. @@ -91,7 +90,7 @@ void VoxelsScriptingInterface::setVoxel(float x, float y, float z, float scale, _undoStack->endMacro(); //Unlock the mutex - mutex.unlock(); + _undoStackMutex.unlock(); } else { // queue the destructive add queueVoxelAdd(PacketTypeVoxelSetDestructive, addVoxelDetail); @@ -121,11 +120,10 @@ void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale deleteVoxelDetail, getVoxelPacketSender()); - static QMutex mutex; - mutex.lock(); + _undoStackMutex.lock(); // As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves. _undoStack->push(command); - mutex.unlock(); + _undoStackMutex.unlock(); } else { getVoxelPacketSender()->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &deleteVoxelDetail); _tree->deleteVoxelAt(deleteVoxelDetail.x, deleteVoxelDetail.y, deleteVoxelDetail.z, deleteVoxelDetail.s); From 5829e3ad1ede5aa80abee796509928d4991c6bb1 Mon Sep 17 00:00:00 2001 From: barnold1953 Date: Sat, 2 Aug 2014 16:03:13 -0700 Subject: [PATCH 7/7] Forgot to save header --- libraries/voxels/src/VoxelsScriptingInterface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/voxels/src/VoxelsScriptingInterface.h b/libraries/voxels/src/VoxelsScriptingInterface.h index 787c37fb20..2e1fc2a8d5 100644 --- a/libraries/voxels/src/VoxelsScriptingInterface.h +++ b/libraries/voxels/src/VoxelsScriptingInterface.h @@ -102,6 +102,7 @@ private: void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails); VoxelTree* _tree; QUndoStack* _undoStack; + QMutex _undoStackMutex; }; #endif // hifi_VoxelsScriptingInterface_h