mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-13 23:46:29 +02:00
Merge pull request #3230 from Barnold1953/rockPaperScissors
Rock Paper Scissors CA script
This commit is contained in:
commit
321b8de898
5 changed files with 292 additions and 1 deletions
272
examples/rockPaperScissorsCells.js
Normal file
272
examples/rockPaperScissorsCells.js
Normal file
|
@ -0,0 +1,272 @@
|
|||
// 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/
|
||||
// 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 = 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 = [];
|
||||
|
||||
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;
|
||||
|
||||
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 };
|
||||
|
||||
|
||||
//Check for free region for AC
|
||||
var regionMarkerX = -1;
|
||||
var regionMarkerY = -1;
|
||||
var regionMarkerI = -1;
|
||||
var regionMarkerJ = -1;
|
||||
|
||||
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() {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//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);
|
||||
|
||||
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 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() {
|
||||
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].type = currentCells[y][x].type;
|
||||
nextCells[i][j].changed = true;
|
||||
} else {
|
||||
//indicate no update
|
||||
nextCells[i][j].changed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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].type = nextCells[i][j].type;
|
||||
currentCells[i][j].changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
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;
|
||||
init();
|
||||
}
|
||||
|
||||
if (isLocal == false) {
|
||||
VoxelViewer.queryOctree();
|
||||
}
|
||||
sendNextCells();
|
||||
}
|
||||
|
||||
function scriptEnding() {
|
||||
Voxels.eraseVoxel(regionMarkerX, regionMarkerY, position.z, cellScale);
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(scriptEnding);
|
||||
|
||||
Script.update.connect(step);
|
||||
Voxels.setPacketsPerSecond(2000);
|
||||
|
||||
// test for local...
|
||||
Menu.isOptionChecked("Voxels");
|
||||
isLocal = true; // will only get here on local client
|
|
@ -40,6 +40,15 @@ void ResourceCache::refresh(const QUrl& url) {
|
|||
}
|
||||
|
||||
QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl& fallback, bool delayLoad, void* extra) {
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QSharedPointer<Resource> result;
|
||||
QMetaObject::invokeMethod(this, "getResource", Qt::BlockingQueuedConnection,
|
||||
Q_RETURN_ARG(QSharedPointer<Resource>, 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);
|
||||
}
|
||||
|
|
|
@ -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<Resource> getResource(const QUrl& url, const QUrl& fallback = QUrl(),
|
||||
Q_INVOKABLE QSharedPointer<Resource> getResource(const QUrl& url, const QUrl& fallback = QUrl(),
|
||||
bool delayLoad = false, void* extra = NULL);
|
||||
|
||||
/// Creates a new resource.
|
||||
|
|
|
@ -80,11 +80,16 @@ void VoxelsScriptingInterface::setVoxel(float x, float y, float z, float scale,
|
|||
DeleteVoxelCommand* deleteCommand = new DeleteVoxelCommand(_tree,
|
||||
addVoxelDetail,
|
||||
getVoxelPacketSender());
|
||||
_undoStackMutex.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
|
||||
_undoStackMutex.unlock();
|
||||
} else {
|
||||
// queue the destructive add
|
||||
queueVoxelAdd(PacketTypeVoxelSetDestructive, addVoxelDetail);
|
||||
|
@ -109,11 +114,15 @@ void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale
|
|||
}
|
||||
|
||||
if (_undoStack) {
|
||||
|
||||
DeleteVoxelCommand* command = new DeleteVoxelCommand(_tree,
|
||||
deleteVoxelDetail,
|
||||
getVoxelPacketSender());
|
||||
|
||||
_undoStackMutex.lock();
|
||||
// As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves.
|
||||
_undoStack->push(command);
|
||||
_undoStackMutex.unlock();
|
||||
} else {
|
||||
getVoxelPacketSender()->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &deleteVoxelDetail);
|
||||
_tree->deleteVoxelAt(deleteVoxelDetail.x, deleteVoxelDetail.y, deleteVoxelDetail.z, deleteVoxelDetail.s);
|
||||
|
|
|
@ -102,6 +102,7 @@ private:
|
|||
void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails);
|
||||
VoxelTree* _tree;
|
||||
QUndoStack* _undoStack;
|
||||
QMutex _undoStackMutex;
|
||||
};
|
||||
|
||||
#endif // hifi_VoxelsScriptingInterface_h
|
||||
|
|
Loading…
Reference in a new issue