Just want to follow up and say wow, I have had my ass kicked so much on this project. It has been refreshing, yet frustrating, to have something that I have no idea how to approach for the first time since the beginning of my career almost a decade ago.
I actually opted out of maintaining a 3D array of gridSize x gridSize x gridSize
length and went for a much more simplistic approach with less overhead, that I refer to as “index projection” but its basically just “this hurts my brain less”.
Index projection: Knowing the gridSize, which in my application defines the width, depth, and height of the 3d voxel canvas, I can determine the position of a voxel based on its index.
const gridSize = 4
const indexes = [3, 27]
// [{x: 3, y: 0, z: 0}, {x: 3, y: 1, z: 2 }]
Likewise, I can convert an x/y/z position to an index with index = (z * gridSize) + (y * (gridSize * gridSize)) + x
.
I have a gridSize x gridSize
square grid of tiles on the bottom of my voxel grid and each one is responsive to pointerOver
and click
to add the initial voxels to the grid, from which point I intend to make voxels’ sides reactive to pointerOver
and click
, but haven’t got that far yet. (I have gotten far enouigh to try and fail, but not enough to show anything lmao.)
The hardest part has been the algorithm for clicking and dragging from one floorTile to another and having a “ghost” path of voxels appear that will be committed to and applied to the voxel grid on pointerUp. (See gist 0.)
I have had to do sketchy stuff that I don’t trust very well for transferring pointerOver
from a floorTile to a voxel for highlighting, but it works for the time being.
Although refreshing, I believe I may be in over my head, and may be trying a less intensive 3D application for what is basically my first use of 3D in JS. This high-cognitive-load logic mixed with the mutable, non-reactive patterns I have to use that split from my years of thinking immutably / reactively is just a lot to handle all at once.
Pretty happy with what I accomplished here, though!
Gist 0: getGridPath
Gist 1: grid.store