Skip to content

Commit

Permalink
Merge pull request #21 from Algorush/rotate-or-replace-tiles
Browse files Browse the repository at this point in the history
Rotate or replace tiles
  • Loading branch information
kfarr authored Jan 7, 2024
2 parents 2fded02 + 809b285 commit d82610d
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 79 deletions.
4 changes: 3 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@
<a-entity scale="0.125 0.125 0.125"
geometry="primitive: box; height: 0.25; width: 0.25; depth: 0.25" material="shader: standard"
snap="offset: 0.125; snap: 0.25"
add-model="name: {{ model }}; gridCoord: {{ coord }}"
bind-item__grid-rotation="rotation: item.rotation"
bind-item__grid-model="model: item.model"
bind-item__grid-coord="gridCoord: item.coord"
></a-entity>
</template>
</a-entity>
Expand Down
48 changes: 48 additions & 0 deletions src/app/grid-coord.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* global AFRAME */
/**
* change position of element by it's grid coordinates
*
*/
AFRAME.registerComponent('grid-coord', {
schema: {
gridCoord: {type: 'string', default: ''},
gridSize: {type: 'number', default: 5},
gridDivisions: {type: 'number', default: 20}
},
init: function () {
const data = this.data;
const el = this.el;

if (!data.gridCoord) { return; }

[this.lon, this.lat] = data.gridCoord.split(',');

const gridPos = this.stateToLocalGrid(data.gridSize, data.gridDivisions);

el.setAttribute('position', gridPos);

},
// Convert long / lat state grid coordinates to local grid position
stateToLocalGrid: function (gridSize, gridDivisions) {
// grid divisions (# of cells) ie 20 divisions
// grid size (meter) ie 5 meters
// cellsPerMeter: gridDivisions / gridSize = 4 cells per meter
const cellsPerMeter = gridDivisions / gridSize;
const snap = this.el.getAttribute('snap');
let snapOffset = (snap) ? snap['offset'] : 0.01;

const [posLong, posLat] =
[this.lon, this.lat].map((strVal) => {
const numVal = Number(strVal);
// add - or + snap offset is used to snap element to the desired grid cell
return (numVal + (numVal >= 0 ? -snapOffset : snapOffset )) / cellsPerMeter;
});
// console.log(`Lat Y: ${posLat}, Long X: ${posLong}`);

const localPos = {
x: posLong,
z: posLat * -1
};
return localPos;
}
});
25 changes: 25 additions & 0 deletions src/app/grid-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* global AFRAME */
/**
* change gltf-model of element by model name
*
*/
AFRAME.registerComponent('grid-model', {
schema: {
model: {type: 'string', default: ''}
},
addGltfModel: function (modelName) {
const el = this.el;
const sceneEl = el.sceneEl;

if (sceneEl.catalogIsloaded) {
el.setAttribute('gltf-model', './' + sceneEl.systems.state.state.model.list[modelName].dist);
} else {
sceneEl.addEventListener('catalogIsLoaded', () => {
el.setAttribute('gltf-model', './' + sceneEl.systems.state.state.model.list[modelName].dist);
})
}
},
update: function(oldData) {
this.addGltfModel(this.data.model);
}
});
16 changes: 16 additions & 0 deletions src/app/grid-rotation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* global AFRAME */
/**
* change rotation of element by rotation value of y-axis
*
*/
AFRAME.registerComponent('grid-rotation', {
schema: {
rotation: {type: 'number', default: 0}
},
update: function(oldData) {
const data = this.data;
const el = this.el;

el.setAttribute('rotation', {x:0, y: data.rotation, z: 0});
}
});
1 change: 0 additions & 1 deletion src/app/intersection-spawn.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ AFRAME.registerComponent('intersection-spawn', {
const localPos = _worldToLocal(evt.detail.intersection.point, targetEl); // convert world intersection position to local position

const gridPos = this.localToStateGrid(localPos, data.gridSize, data.gridDivisions);
// console.log('Grid Position:', gridPos);

AFRAME.scenes[0].emit('addGridObject', {
lon: gridPos.x,
Expand Down
60 changes: 0 additions & 60 deletions src/app/load-model.js

This file was deleted.

61 changes: 45 additions & 16 deletions src/app/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,14 @@ const GRID_SIZE = 10; // Example grid size (10x10)

// Initial grid state setup with City Hall at the center
const INITIAL_GRID_STATE = [];

const INIT_GRID_COORDS = [[-1, -1], [-1, 1], [1, -1], [1, 1]];

INIT_GRID_COORDS.forEach(lon_lat_values => {
INIT_GRID_COORDS.forEach(coord => {
const lon = coord[0];
const lat = coord[1];
INITIAL_GRID_STATE.push(
{coord: lon_lat_values, model: 'park_base', rotation: 0, elevation: 0}
{coord: coord.join(','), model: 'park_base', rotation: 0, elevation: 0}
);
});

Expand Down Expand Up @@ -103,7 +106,10 @@ AFRAME.registerState({

let { lon, lat, model, rotation, elevation } = payload;

if (isCityHall(lon, lat)) return;
if (isCityHall(lon, lat)) {
console.log('Cannot place object on city hall');
return;
}

if (!model) {
model = getModelNameFromState(state);
Expand All @@ -117,39 +123,56 @@ AFRAME.registerState({
console.log('model', model);
const keyCell = findGridIndex(state.grid, lon, lat);

// Prevent modification of City Hall cells and exists cells
if (!keyCell) {
// If the cell is free add selected model to the spawned cell
state.grid.push(
{ coord: [lon, lat], model: model, rotation: rotation, elevation: elevation }
{ coord: [lon, lat].join(','), model: model, rotation: rotation, elevation: elevation }
);
} else {
console.log('Cannot place object on city hall');

if (state.grid[keyCell].model === model) {
// if the cell model is the same as the selected model
this.rotateOrElevateGridObject(state, {keyCell, addRotation: 90});
} else {
// change the current model of element to selected model
// Setting the __dirty flag is needed to track changes
// in the value of individual elements, but not the entire array
state.grid.__dirty = true;
state.grid[keyCell].model = model;
state.grid[keyCell].rotation = 0;
}
}
console.log('Updated Grid State:', state.grid);
},
// Handler to rotate or elevate an object
// Note: City Hall cells cannot be rotated or elevated
rotateOrElevateGridObject: function (state, payload) {
const { lon, lat, rotation, elevation } = payload;
let { lon, lat, addRotation, addElevation, keyCell } = payload;

if (isCityHall(lon, lat)) return;

const keyCell = findGridIndex(state.grid, lon, lat);
keyCell = keyCell ?? findGridIndex(state.grid, lon, lat);

if (keyCell) {

state.grid[keyCell].rotation += rotation;
state.grid[keyCell].elevation += elevation;
if (addRotation) {
// Setting the __dirty flag is needed to track changes
// in the value of individual elements, but not the entire array
state.grid.__dirty = true;
const currentRot = state.grid[keyCell].rotation;
// prevent big rotation values
state.grid[keyCell].rotation = (currentRot + addRotation) % 360;
}

if (addElevation) state.grid[keyCell].elevation += addElevation;

},
// Handler to clear a cell
// Note: City Hall cells cannot be cleared
clearGridCell: function (state, payload) {
const { lon, lat } = payload;
const { lon, lat, keyCell } = payload;

if (isCityHall(lon, lat)) return;

const keyCell = findGridIndex(state.grid, lon, lat);
keyCell = keyCell ?? findGridIndex(state.grid, lon, lat);

if (keyCell) {
state.grid.splice(keyCell, 1);
Expand All @@ -168,16 +191,21 @@ AFRAME.registerState({

// check for City Hall cells
function isCityHall(lon, lat) {
if (! lon && lat) return false;

const cityHallCell = INIT_GRID_COORDS.findIndex(
(elData) => elData[0] == lon && elData[1] == lat
(coord) => coord[0] == lon && coord[1] == lat
);
return (cityHallCell == -1) ? false: true;
}

// find index of grid array element by grid coordinates
function findGridIndex(gridArray, lon, lat) {
if (! lon && lat) return;
const strCoord = [lon, lat].join(',');

const gridArrayIndex = gridArray.findIndex(
(elData) => elData.coord[0] == lon && elData.coord[1] == lat
(elData) => elData.coord == strCoord
);
return gridArrayIndex === -1 ? null : gridArrayIndex;
}
Expand Down Expand Up @@ -225,6 +253,7 @@ AFRAME.registerComponent('load-catalog', {
}
this.el.catalogIsloaded = true;
this.el.emit('catalogIsLoaded');

}
});

Expand Down
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ require('./app/intersection-spawn.js');
require('./app/snap.js');
require('./app/set-rotation-from-anchor.js');
require('./app/state.js');
require('./app/load-model.js');
require('./app/grid-coord.js');
require('./app/grid-model.js');
require('./app/grid-rotation.js');

0 comments on commit d82610d

Please sign in to comment.