Updating mesh position not working

Trying to make this Rubik’s cube with Babylonjs and for more than 24 hrs, i can’t get to change the cube’s position using cube.position.
The entire Rubik’s cube is made up of 27 smaller cubes(you know what way i’m headed already).
i can’t get to rotate some of these smaller cubes that make a face.

see how i’m trying to make this update:

updateCubePositions(cubes: Cube[], rotatedMeshes: BABYLON.Mesh[]) {
    // Loop through each cube and update its position
    for (let i = 0; i < cubes.length; i++) {
      let cube = cubes[i].mesh;
      let rotatedMesh = rotatedMeshes[i];

      let newPosition = rotatedMesh.position;

      // Update the position of the cube
      cube.updatePosition(newPosition);
    }

    console.log(
      "Final Cube Positions:",
      cubes.map((cube) => cube.position)
    );
    console.log(
      "Final Rotated Mesh Positions:",
      rotatedMeshes.map((mesh) => mesh.position)
    );
  }

and this is my Cube class:

import * as BABYLON from "@babylonjs/core";

export class Cube {
  position: BABYLON.Vector3;
  mesh: BABYLON.Mesh;
  materials: BABYLON.MultiMaterial;

  constructor(position: BABYLON.Vector3, scene: BABYLON.Scene) {
    this.position = position;
    this.mesh = this.createCubeMesh(scene);
    this.materials = this.createCubeMaterials(scene);
    this.applyMaterials();
  }

  // Create cube mesh
  createCubeMesh(scene: BABYLON.Scene): BABYLON.Mesh {
    const cube = BABYLON.MeshBuilder.CreateBox("cube", { size: 0.5 }, scene);
    cube.position = this.position;
    cube.enableEdgesRendering();
    cube.edgesColor = new BABYLON.Color4(0, 0, 0, 1);
    cube.edgesWidth = 2;

    // Apply different materials to each face of the box
    cube.subMeshes = []; // Reset any default subMeshes
    const vertices: BABYLON.Nullable<BABYLON.FloatArray> = cube.getVerticesData(
      BABYLON.VertexBuffer.PositionKind
    );

    // Create sub-meshes for each face
    for (let i = 0; i < 6; i++) {
      new BABYLON.SubMesh(i, 0, vertices?.length! / 3, i * 6, 6, cube);
    }

    return cube;
  }

  // Create cube materials
  createCubeMaterials(scene: BABYLON.Scene): BABYLON.MultiMaterial {
    const redMaterial = new BABYLON.StandardMaterial("redMaterial", scene);
    redMaterial.diffuseColor = BABYLON.Color3.Red();
    const greenMaterial = new BABYLON.StandardMaterial("greenMaterial", scene);
    greenMaterial.diffuseColor = BABYLON.Color3.Green();
    const blueMaterial = new BABYLON.StandardMaterial("blueMaterial", scene);
    blueMaterial.diffuseColor = BABYLON.Color3.Blue();
    const yellowMaterial = new BABYLON.StandardMaterial(
      "yellowMaterial",
      scene
    );
    yellowMaterial.diffuseColor = BABYLON.Color3.Yellow();
    const whiteMaterial = new BABYLON.StandardMaterial("whiteMaterial", scene);
    whiteMaterial.diffuseColor = BABYLON.Color3.White();
    const orangeMaterial = new BABYLON.StandardMaterial(
      "orangeMaterial",
      scene
    );
    orangeMaterial.diffuseColor = new BABYLON.Color3(1, 0.647, 0); // Orange

    // Apply the materials to the faces of the cube
    const multiMaterial = new BABYLON.MultiMaterial("multiMat", scene);
    multiMaterial.subMaterials = [
      blueMaterial, // Front face
      greenMaterial, // Back face
      redMaterial, // Left face
      orangeMaterial, // Right face
      whiteMaterial, // Top face
      yellowMaterial, // Bottom face
    ];

    return multiMaterial;
  }

  // Apply the materials to the cube's mesh
  applyMaterials() {
    this.mesh.material = this.materials;
  }

  // Update the cube's position
  updatePosition(newPosition: BABYLON.Vector3) {
    this.mesh.position = newPosition;
  }

  // Update materials based on new cube position (after rotating the face)
  updateCubeMaterial(newMaterials: BABYLON.MultiMaterial) {
    this.mesh.material = newMaterials;
  }
}

Please what am i doing wrong, i’m not happy with myself i can’t get this to work, and i need help
PLAYGROUND: Babylon.js Playground

Please, just say something, what you think, that might help me

I don’t see where you’re rotating sides. Or how updatePosition is called. It’s best to provide a playground that shows the issue youre running imto.

There is a lot that BABYLON can do for you automatically.

Here, I’m using a few of those features. I think I’m doing it right, but you’ll have to doublecheck. And likely tweak if you move the cubes to a different world position. If you want one monolithic cube (moved around using a single position), there’s some tweaking to do creating the cubelettes as children to a transformNode, and you’ll want to rotate around that transformNode’s local space.

  • CreateBox() allows assigning colors to sides.
  • CreateInstance() creates a copy with the same VertexBuffer
  • mesh.rotate() allows specifying local or world space.

Edit: it’s not quite right.
Edit2: after a lot of debugging, I think I’ve fixed it. (updated playground link above)

2 Likes

Hey @HiGreg ,
This is what i have been doing so farr

Hey

fixed positioning and PARTLY rotation(only to see that it works). use U button to see that it is correctly rotating.
I updated updateCubePositions only function

Your problem was that your cubes and rotatedCubes params contains the same objects and when you update cubes[i].position you also update rotatedCubes param (so you break rotated cubes param). so before this “for” you should remember positions which i did.( actually i don’t think it’s a good practice to have 2 params in function with the same values)
also i added rotation line to see that it correctly rotatin because i couldnt make your rotation func work. but this line is just to see that it rotating by U button correctly. it will not rotating correctly by other buttons because of hardcode angle but i think you can do this yourself

1 Like

Hi @TooCalm
I updated the code and i ran into 2 more issues:

  1. At first rotation of any face when animation is applied, the face make a double rotation at once, but is rotating as expected subsequently.
  2. I am still unable to rotate other faces properly after the first rotation is successfull(not minding the face)

Please can you help me figure out what i’m doing wrong?