5. GRID 3D

Overview

In this exercise, we will create a three-dimensional grid of objects using nested loops. We’ll be extending this exercise further by adding animation to the objects. If you are unfamiliar with the basics, please go through the Grid 1D and Grid 2D exercises first.

Grid 3D Codepen: https://codepen.io/xrclub/full/gOvweVr

Getting Started: https://xr.club/exercise/getting-started/

Level I – Grid 3D

The scene, camera, lighting, and renderer need to be set up beforehand, as in the Getting Started exercise. If you need help remembering how it all works, check that exercise out before starting. Here, we will just focus on creating the Grid 3D scene.

Here are the instructions:

  1. define grid dimensions and cube counts
  2. calculate spacing between cubes
  3. set up cube geometry and material  
  4. create an empty cubes array 
  5. generate cubes using a nested for loop 
  6. set new X, Y & Z positions and store cube into array

Step 1: define grid dimensions and cube counts 

A 3D grid uses the x, y and z axes. Set columns, rows and layers as dimensions X, Y and Z. Determine the cube counts along these axes.

// Set the grid dimensions for each axis
this.gridDimensionX = 20;
this.gridDimensionZ = 20;
this.gridDimensionY = 10;
// Set the number of cubes along each axis
this.numCubesX = 4;
this.numCubesZ = 4;
this.numCubesY = 4;

Step 2: calculate spacing between cubes

Determine the spacing between each cube. This will be used later to calculate the X, Y and Z positions. Divide the grid dimension size by the number of objects minus one, along each axis to achieve this result. This is because there are “grid objects – 1” separations on a line.

// Calculate spacing between cubes in each dimension
this.spaceBetweenCubesX = this.gridDimensionX / (this.numCubesX - 1);
this.spaceBetweenCubesZ = this.gridDimensionZ / (this.numCubesZ - 1);
this.spaceBetweenCubesY = this.gridDimensionY / (this.numCubesY - 1);

Step 3: set up cube geometry and material  

Create geometry and material for the cube.

// Create cube geometry and material
const cubeGeometry = new THREE.BoxGeometry( 0.5, 0.5, 0.5 );
const cubeMaterial = new THREE.MeshStandardMaterial({ color: 0xffffff });

Step 4: create an empty cubes array 

Create an empty array to store cubes.

// Create an empty array to store cubes
this.cubesArray = [];

Step 5: generate cubes using a nested for loop  

A nested loop is a loop within another loop. Create a nested loop that iterates through the grid objects along the Y-axis, then the Z-axis and finally create cubes within the innermost loop. Add cube to the scene.

// Loop through rows (Y-axis)
for (let rowIndex = 0; rowIndex < this.numCubesY; rowIndex++) {

  // Loop through layers (Z-axis)
  for (let zIndex = 0; zIndex < this.numCubesZ; zIndex++) {
        
    // Loop through columns (X-axis)
    for (let colIndex = 0; colIndex < this.numCubesX; colIndex++) {
          
      let cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
      this.scene.add(cube);
    }
  }
}

Step 6: set new X, Y & Z positions and store cube into array  

Along each axis, multiply the index of each X, Y and Z dimension by the spaceBetweenCubes to create the separations. Realign the cube’s position symmetrically according to the grid’s centre by subtracting half the grid’s X, Y and Z dimensions respectively. Set the new positions for the cube and push it into the empty cubes array.

// Calculate cube's X & Y position by multiplying the index with the space between each cube. Centre the grid of cubes by subtracting half the grid's dimension size 
cube.position.x = colIndex * this.spaceBetweenCubesX - this.gridDimensionX / 2;
cube.position.y = rowIndex * this.spaceBetweenCubesY - this.gridDimensionY / 2;
cube.position.z = zIndex * this.spaceBetweenCubesZ - this.gridDimensionZ / 2;

this.cubesArray.push(cube);

Result

See the Pen Loops – 3D Matrix by XR Club (@xrclub) on CodePen.

Level II – Grid 3D – Animated

Next we’ll animate the Grid 3D scene.

Add a new time variable

Create a new time variable to store the animation elapsed time.

// Set time to zero
this.time = 0;

Store time elapsed

In the update loop, continuously add dt to time. The accumulated total represents the elapsed time.

update(dt){
    this.time += dt;
    this.renderer.render(this.scene, this.camera);
  }
}

Add animation logic

Obtain the current cube by looping through the cubes array. Calculate the scale factor based on the sine function of time and the cube’s Z position. Then set the object’s scale based on this scale factor. The Grid 3D should now be animated.

for(let cubeIndex = 0; cubeIndex < this.objects.length; cubeIndex++){
  // Get current cube
  let cube = this.objects[cubeIndex];

  // Calculate scale factor using sine function of the time and the cube's Z position
  let scale = Math.sin( this.time + cube.position.z );

  // Set new scale factors for the cube
  cube.scale.set(scale,scale,scale);
}

Result

See the Pen Loops -3D Matrix – Ani by XR Club (@xrclub) on CodePen.

Leave a Reply

Your email address will not be published.