#!/bin/node let g_y_rotation = Math.PI/4; let g_x_rotation = Math.PI/4; let vertexcount = 0; class Axis { static x = new Axis('x'); static y = new Axis('y'); static z = new Axis('z'); constructor(name) { this.name = name; } } class Rotation { static x1 = new Rotation('x1'); static x1i = new Rotation('x1i'); static x2 = new Rotation('x2'); static x2i = new Rotation('x2i'); static x3 = new Rotation('x3'); static x3i = new Rotation('x3i'); static y1 = new Rotation('y1'); static y1i = new Rotation('y1i'); static y2 = new Rotation('y2'); static y2i = new Rotation('y2i'); static y3 = new Rotation('y3'); static y3i = new Rotation('y3i'); static z1 = new Rotation('z1'); static z1i = new Rotation('z1i'); static z2 = new Rotation('z2'); static z2i = new Rotation('z2i'); static z3 = new Rotation('z3'); static z3i = new Rotation('z3i'); constructor(name) { this.name = name; } } const turn = (vertices, axis, angle) => { let coord1_offset = ''; let coord2_offset = ''; switch(axis) { case Axis.x: coord1_offset = 0; coord2_offset = 1; break; case Axis.y: coord1_offset = 2; coord2_offset = 0; break; case Axis.z: coord1_offset = 1; coord2_offset = 2; break; } for(let i = 0; i*3 < vertices.length; ++i ) { let coord1 = vertices[3 * i + coord1_offset] * Math.cos(angle) + vertices[3 * i + coord2_offset] * Math.sin(angle); let coord2 = vertices[3 * i + coord2_offset] * Math.cos(angle) - vertices[3 * i + coord1_offset] * Math.sin(angle); vertices[3 * i + coord1_offset] = coord1; vertices[3 * i + coord2_offset] = coord2; } return vertices; } let Colors = { blue: [0.0, 0.27, 0.68, 1.0], green: [0.0, 0.61, 0.28, 1.0], white: [1.0, 1.0, 1.0, 1.0], yellow: [1.0, 0.84, 0.0, 1.0], red: [0.73, 0.0, 0.0, 1.0], orange: [1.0, 0.35, 0.0, 1.0], black: [0.0, 0.0, 0.0, 1.0], }; class Cube { static jjj constructor(center_pos, width, starting_indices, front_color, back_color, bottom_color, top_color, right_color, left_color) { const half_width = width / 2; this.positions = [ // front face -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, // back face -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, // bottom face -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, // top face -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, // right face 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, // left face -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, ]; for (let i = 0; i < this.positions.length; ++i) { this.positions[i] *= half_width; this.positions[i] += center_pos[i%3]; } this.indices = [ 0, 1, 2, 0, 2, 3, // front 4, 5, 6, 4, 6, 7, // back 8, 9, 10, 8, 10, 11, // bottom 12, 13, 14, 12, 14, 15, // top 16, 17, 18, 16, 18, 19, // right 20, 21, 22, 20, 22, 23, // left ]; for ( let i = 0; i < this.indices.length; ++i ) { this.indices[i] += starting_indices; } this.colors = []; this.colors = this.colors.concat( front_color, front_color, front_color, front_color ); this.colors = this.colors.concat( back_color, back_color, back_color, back_color ); this.colors = this.colors.concat( bottom_color, bottom_color, bottom_color, bottom_color ); this.colors = this.colors.concat( top_color, top_color, top_color, top_color ); this.colors = this.colors.concat( right_color, right_color, right_color, right_color ); this.colors = this.colors.concat( left_color, left_color, left_color, left_color ); } rotate(axis, angle) { this.positions = turn( this.positions, axis, angle ); } get_positions() { return this.positions; } get_trig_indices() { return this.indices; } get_colors() { return this.colors; } get_vertices_count() { return this.positions.length / 3; } } let rubik = ((width) => { let positions = []; let colors = []; let indices = []; const createCube = (pos, cols) => { let cube = new Cube(pos, width, vertexcount, cols[0], cols[1], cols[2], cols[3], cols[4], cols[5]); vertexcount += cube.get_vertices_count(); positions = positions.concat(cube.get_positions()); colors = colors.concat(cube.get_colors()); indices = indices.concat(cube.get_trig_indices()); return cube; } // ----------------------- front face ---------------------------------------------------------- let front_top_left_cube = createCube([-1.0, 1.0, 1.0], [ Colors.blue, Colors.black, Colors.black, Colors.yellow, Colors.black, Colors.orange]); let front_top_cube = createCube([0.0, 1.0, 1.0], [ Colors.blue, Colors.black, Colors.black, Colors.yellow, Colors.black, Colors.black]); let front_top_right_cube = createCube([1.0, 1.0, 1.0], [ Colors.blue, Colors.black, Colors.black, Colors.yellow, Colors.red, Colors.black]); // ----------------------- next row ------------------------------------------------------------ let front_left_cube = createCube([-1.0, 0.0, 1.0], [ Colors.blue, Colors.black, Colors.black, Colors.black, Colors.black, Colors.orange]); let front_cube = createCube([0.0, 0.0, 1.0], [ Colors.blue, Colors.black, Colors.black, Colors.black, Colors.black, Colors.black]); let front_right_cube = createCube([1.0, 0.0, 1.0], [ Colors.blue, Colors.black, Colors.black, Colors.black, Colors.red, Colors.black]); // ----------------------- next row ------------------------------------------------------------ let front_bottom_left_cube = createCube([-1.0, -1.0, 1.0], [ Colors.blue, Colors.black, Colors.white, Colors.black, Colors.black, Colors.orange]); let front_bottom_cube = createCube([0.0, -1.0, 1.0], [ Colors.blue, Colors.black, Colors.white, Colors.black, Colors.black, Colors.black]); let front_bottom_right_cube = createCube([1.0, -1.0, 1.0], [ Colors.blue, Colors.black, Colors.white, Colors.black, Colors.red, Colors.black]); // ----------------------- middle layer -------------------------------------------------------- let top_left_cube = createCube([-1.0, 1.0, 0.0], [ Colors.black, Colors.black, Colors.black, Colors.yellow, Colors.black, Colors.orange]); let top_cube = createCube([0.0, 1.0, 0.0], [ Colors.black, Colors.black, Colors.black, Colors.yellow, Colors.black, Colors.black]); let top_right_cube = createCube([1.0, 1.0, 0.0], [ Colors.black, Colors.black, Colors.black, Colors.yellow, Colors.red, Colors.black]); // ----------------------- next row ------------------------------------------------------------ let left_cube = createCube([-1.0, 0.0, 0.0], [ Colors.black, Colors.black, Colors.black, Colors.black, Colors.black, Colors.orange]); let center_cube = createCube([0.0, 0.0, 0.0], [ Colors.black, Colors.black, Colors.black, Colors.black, Colors.black, Colors.black]); let right_cube = createCube([1.0, 0.0, 0.0], [ Colors.black, Colors.black, Colors.black, Colors.black, Colors.red, Colors.black]); // ----------------------- next row ------------------------------------------------------------ let bottom_left_cube = createCube([-1.0, -1.0, 0.0], [ Colors.black, Colors.black, Colors.white, Colors.black, Colors.black, Colors.orange]); let bottom_cube = createCube([0.0, -1.0, 0.0], [ Colors.black, Colors.black, Colors.white, Colors.black, Colors.black, Colors.black]); let bottom_right_cube = createCube([1.0, -1.0, 0.0], [ Colors.black, Colors.black, Colors.white, Colors.black, Colors.red, Colors.black]); // ----------------------- back face ----------------------------------------------------------- let back_top_left_cube = createCube([-1.0, 1.0, -1.0], [ Colors.black, Colors.green, Colors.black, Colors.yellow, Colors.black, Colors.orange]); let back_top_cube = createCube([0.0, 1.0, -1.0], [ Colors.black, Colors.green, Colors.black, Colors.yellow, Colors.black, Colors.black]); let back_top_right_cube = createCube([1.0, 1.0, -1.0], [ Colors.black, Colors.green, Colors.black, Colors.yellow, Colors.red, Colors.black]); // ----------------------- next row ------------------------------------------------------------ let back_left_cube = createCube([-1.0, 0.0, -1.0], [ Colors.black, Colors.green, Colors.black, Colors.black, Colors.black, Colors.orange]); let back_cube = createCube([0.0, 0.0, -1.0], [ Colors.black, Colors.green, Colors.black, Colors.black, Colors.black, Colors.black]); let back_right_cube = createCube([1.0, 0.0, -1.0], [ Colors.black, Colors.green, Colors.black, Colors.black, Colors.red, Colors.black]); // ----------------------- next row ------------------------------------------------------------ let back_bottom_left_cube = createCube([-1.0, -1.0, -1.0], [ Colors.black, Colors.green, Colors.white, Colors.black, Colors.black, Colors.orange]); let back_bottom_cube = createCube([0.0, -1.0, -1.0], [ Colors.black, Colors.green, Colors.white, Colors.black, Colors.black, Colors.black]); let back_bottom_right_cube = createCube([1.0, -1.0, -1.0], [ Colors.black, Colors.green, Colors.white, Colors.black, Colors.red, Colors.black]); return { cubes: { front_top_left: front_top_left_cube, front_top: front_top_cube, front_top_right: front_top_right_cube, front_left: front_left_cube, front: front_cube, front_right: front_right_cube, front_bottom_left: front_bottom_left_cube, front_bottom: front_bottom_cube, front_bottom_right: front_bottom_right_cube, top_left: top_left_cube, top: top_cube, top_right: top_right_cube, left: left_cube, center : center_cube, right: right_cube, bottom_left: bottom_left_cube, bottom: bottom_cube, bottom_right: bottom_right_cube, back_top_left: back_top_left_cube, back_top: back_top_cube, back_top_right: back_top_right_cube, back_left: back_left_cube, back: back_cube, back_right: back_right_cube, back_bottom_left: back_bottom_left_cube, back_bottom: back_bottom_cube, back_bottom_right: back_bottom_right_cube, }, rendering_order: [...Array(27).keys()], positions: positions, colors: colors, indices: indices, indices_length: indices.length, updateColors() { this.colors = []; this.colors = this.colors.concat(this.cubes.front_top_left.get_colors()); this.colors = this.colors.concat(this.cubes.front_top.get_colors()); this.colors = this.colors.concat(this.cubes.front_top_right.get_colors()); this.colors = this.colors.concat(this.cubes.front_left.get_colors()); this.colors = this.colors.concat(this.cubes.front.get_colors()); this.colors = this.colors.concat(this.cubes.front_right.get_colors()); this.colors = this.colors.concat(this.cubes.front_bottom_left.get_colors()); this.colors = this.colors.concat(this.cubes.front_bottom.get_colors()); this.colors = this.colors.concat(this.cubes.front_bottom_right.get_colors()); this.colors = this.colors.concat(this.cubes.top_left.get_colors()); this.colors = this.colors.concat(this.cubes.top.get_colors()); this.colors = this.colors.concat(this.cubes.top_right.get_colors()); this.colors = this.colors.concat(this.cubes.left.get_colors()); this.colors = this.colors.concat(this.cubes.center .get_colors()); this.colors = this.colors.concat(this.cubes.right.get_colors()); this.colors = this.colors.concat(this.cubes.bottom_left.get_colors()); this.colors = this.colors.concat(this.cubes.bottom.get_colors()); this.colors = this.colors.concat(this.cubes.bottom_right.get_colors()); this.colors = this.colors.concat(this.cubes.back_top_left.get_colors()); this.colors = this.colors.concat(this.cubes.back_top.get_colors()); this.colors = this.colors.concat(this.cubes.back_top_right.get_colors()); this.colors = this.colors.concat(this.cubes.back_left.get_colors()); this.colors = this.colors.concat(this.cubes.back.get_colors()); this.colors = this.colors.concat(this.cubes.back_right.get_colors()); this.colors = this.colors.concat(this.cubes.back_bottom_left.get_colors()); this.colors = this.colors.concat(this.cubes.back_bottom.get_colors()); this.colors = this.colors.concat(this.cubes.back_bottom_right.get_colors()); }, updatepos() { this.positions = []; this.positions = this.positions.concat(this.cubes.front_top_left.get_positions()); this.positions = this.positions.concat(this.cubes.front_top.get_positions()); this.positions = this.positions.concat(this.cubes.front_top_right.get_positions()); this.positions = this.positions.concat(this.cubes.front_left.get_positions()); this.positions = this.positions.concat(this.cubes.front.get_positions()); this.positions = this.positions.concat(this.cubes.front_right.get_positions()); this.positions = this.positions.concat(this.cubes.front_bottom_left.get_positions()); this.positions = this.positions.concat(this.cubes.front_bottom.get_positions()); this.positions = this.positions.concat(this.cubes.front_bottom_right.get_positions()); this.positions = this.positions.concat(this.cubes.top_left.get_positions()); this.positions = this.positions.concat(this.cubes.top.get_positions()); this.positions = this.positions.concat(this.cubes.top_right.get_positions()); this.positions = this.positions.concat(this.cubes.left.get_positions()); this.positions = this.positions.concat(this.cubes.center .get_positions()); this.positions = this.positions.concat(this.cubes.right.get_positions()); this.positions = this.positions.concat(this.cubes.bottom_left.get_positions()); this.positions = this.positions.concat(this.cubes.bottom.get_positions()); this.positions = this.positions.concat(this.cubes.bottom_right.get_positions()); this.positions = this.positions.concat(this.cubes.back_top_left.get_positions()); this.positions = this.positions.concat(this.cubes.back_top.get_positions()); this.positions = this.positions.concat(this.cubes.back_top_right.get_positions()); this.positions = this.positions.concat(this.cubes.back_left.get_positions()); this.positions = this.positions.concat(this.cubes.back.get_positions()); this.positions = this.positions.concat(this.cubes.back_right.get_positions()); this.positions = this.positions.concat(this.cubes.back_bottom_left.get_positions()); this.positions = this.positions.concat(this.cubes.back_bottom.get_positions()); this.positions = this.positions.concat(this.cubes.back_bottom_right.get_positions()); }, rotate_only(dir) { switch(dir) { case Rotation.x1: this.cubes.front_top_left.rotate(Axis.x, Math.PI / 2); this.cubes.front_top.rotate(Axis.x, Math.PI / 2); this.cubes.front_top_right.rotate(Axis.x, Math.PI / 2); this.cubes.front_left.rotate(Axis.x, Math.PI / 2); this.cubes.front.rotate(Axis.x, Math.PI / 2); this.cubes.front_right.rotate(Axis.x, Math.PI / 2); this.cubes.front_bottom_left.rotate(Axis.x, Math.PI / 2); this.cubes.front_bottom.rotate(Axis.x, Math.PI / 2); this.cubes.front_bottom_right.rotate(Axis.x, Math.PI / 2); [this.cubes.front_top_right, this.cubes.front_bottom_right, this.cubes.front_bottom_left, this.cubes.front_top_left,] = [this.cubes.front_top_left, this.cubes.front_top_right, this.cubes.front_bottom_right, this.cubes.front_bottom_left]; [this.cubes.front_top, this.cubes.front_left, this.cubes.front_bottom, this.cubes.front_right] = [this.cubes.front_left, this.cubes.front_bottom, this.cubes.front_right, this.cubes.front_top]; [this.rendering_order[2], this.rendering_order[8], this.rendering_order[6], this.rendering_order[0],] = [this.rendering_order[0], this.rendering_order[2], this.rendering_order[8], this.rendering_order[6]]; [this.rendering_order[1], this.rendering_order[3], this.rendering_order[7], this.rendering_order[6]] = [this.rendering_order[3], this.rendering_order[7], this.rendering_order[6], this.rendering_order[1]]; break; case Rotation.x1i: this.cubes.front_top_left.rotate(Axis.x, -Math.PI / 2); this.cubes.front_top.rotate(Axis.x, -Math.PI / 2); this.cubes.front_top_right.rotate(Axis.x, -Math.PI / 2); this.cubes.front_left.rotate(Axis.x, -Math.PI / 2); this.cubes.front.rotate(Axis.x, -Math.PI / 2); this.cubes.front_right.rotate(Axis.x, -Math.PI / 2); this.cubes.front_bottom_left.rotate(Axis.x, -Math.PI / 2); this.cubes.front_bottom.rotate(Axis.x, -Math.PI / 2); this.cubes.front_bottom_right.rotate(Axis.x, -Math.PI / 2); [this.cubes.front_top_right, this.cubes.front_bottom_right, this.cubes.front_bottom_left, this.cubes.front_top_left,] = [this.cubes.front_bottom_right, this.cubes.front_bottom_left, this.cubes.front_top_left, this.cubes.front_top_right]; [this.cubes.front_top, this.cubes.front_left, this.cubes.front_bottom, this.cubes.front_right] = [this.cubes.front_right, this.cubes.front_top, this.cubes.front_left, this.cubes.front_bottom]; [this.rendering_order[2], this.rendering_order[8], this.rendering_order[6], this.rendering_order[0],] = [this.rendering_order[8], this.rendering_order[6], this.rendering_order[0], this.rendering_order[2]]; [this.rendering_order[1], this.rendering_order[3], this.rendering_order[7], this.rendering_order[5]] = [this.rendering_order[5], this.rendering_order[1], this.rendering_order[3], this.rendering_order[7]]; break; case Rotation.x2: this.cubes.top_left.rotate(Axis.x, Math.PI / 2); this.cubes.top.rotate(Axis.x, Math.PI / 2); this.cubes.top_right.rotate(Axis.x, Math.PI / 2); this.cubes.left.rotate(Axis.x, Math.PI / 2); this.cubes.center.rotate(Axis.x, Math.PI / 2); this.cubes.right.rotate(Axis.x, Math.PI / 2); this.cubes.bottom_left.rotate(Axis.x, Math.PI / 2); this.cubes.bottom.rotate(Axis.x, Math.PI / 2); this.cubes.bottom_right.rotate(Axis.x, Math.PI / 2); [this.cubes.top_right, this.cubes.bottom_right, this.cubes.bottom_left, this.cubes.top_left,] = [this.cubes.top_left, this.cubes.top_right, this.cubes.bottom_right, this.cubes.bottom_left]; [this.cubes.top, this.cubes.left, this.cubes.bottom, this.cubes.right] = [this.cubes.left, this.cubes.bottom, this.cubes.right, this.cubes.top]; [this.rendering_order[11], this.rendering_order[17], this.rendering_order[15], this.rendering_order[9],] = [this.rendering_order[9], this.rendering_order[11], this.rendering_order[17], this.rendering_order[15]]; [this.rendering_order[10], this.rendering_order[12], this.rendering_order[16], this.rendering_order[14]] = [this.rendering_order[12], this.rendering_order[16], this.rendering_order[14], this.rendering_order[10]]; break; case Rotation.x2i: this.cubes.top_left.rotate(Axis.x, -Math.PI / 2); this.cubes.top.rotate(Axis.x, -Math.PI / 2); this.cubes.top_right.rotate(Axis.x, -Math.PI / 2); this.cubes.left.rotate(Axis.x, -Math.PI / 2); this.cubes.center.rotate(Axis.x, -Math.PI / 2); this.cubes.right.rotate(Axis.x, -Math.PI / 2); this.cubes.bottom_left.rotate(Axis.x, -Math.PI / 2); this.cubes.bottom.rotate(Axis.x, -Math.PI / 2); this.cubes.bottom_right.rotate(Axis.x, -Math.PI / 2); [this.cubes.top_right, this.cubes.bottom_right, this.cubes.bottom_left, this.cubes.top_left,] = [this.cubes.bottom_right, this.cubes.bottom_left, this.cubes.top_left, this.cubes.top_right]; [this.cubes.top, this.cubes.left, this.cubes.bottom, this.cubes.right] = [this.cubes.right, this.cubes.top, this.cubes.left, this.cubes.bottom]; [this.rendering_order[11], this.rendering_order[17], this.rendering_order[15], this.rendering_order[9],] = [this.rendering_order[9], this.rendering_order[11], this.rendering_order[17], this.rendering_order[15]]; [this.rendering_order[10], this.rendering_order[12], this.rendering_order[16], this.rendering_order[14]] = [this.rendering_order[12], this.rendering_order[16], this.rendering_order[14], this.rendering_order[10]]; break; case Rotation.x3: this.cubes.back_top_left.rotate(Axis.x, Math.PI / 2); this.cubes.back_top.rotate(Axis.x, Math.PI / 2); this.cubes.back_top_right.rotate(Axis.x, Math.PI / 2); this.cubes.back_left.rotate(Axis.x, Math.PI / 2); this.cubes.back.rotate(Axis.x, Math.PI / 2); this.cubes.back_right.rotate(Axis.x, Math.PI / 2); this.cubes.back_bottom_left.rotate(Axis.x, Math.PI / 2); this.cubes.back_bottom.rotate(Axis.x, Math.PI / 2); this.cubes.back_bottom_right.rotate(Axis.x, Math.PI / 2); [this.cubes.back_top_right, this.cubes.back_bottom_right, this.cubes.back_bottom_left, this.cubes.back_top_left,] = [this.cubes.back_top_left, this.cubes.back_top_right, this.cubes.back_bottom_right, this.cubes.back_bottom_left]; [this.cubes.back_top, this.cubes.back_left, this.cubes.back_bottom, this.cubes.back_right] = [this.cubes.back_left, this.cubes.back_bottom, this.cubes.back_right, this.cubes.back_top]; [this.rendering_order[20], this.rendering_order[26], this.rendering_order[24], this.rendering_order[18],] = [this.rendering_order[18], this.rendering_order[20], this.rendering_order[26], this.rendering_order[24]]; [this.rendering_order[19], this.rendering_order[21], this.rendering_order[25], this.rendering_order[23]] = [this.rendering_order[21], this.rendering_order[25], this.rendering_order[23], this.rendering_order[19]]; break; case Rotation.x3i: this.cubes.back_top_left.rotate(Axis.x, -Math.PI / 2); this.cubes.back_top.rotate(Axis.x, -Math.PI / 2); this.cubes.back_top_right.rotate(Axis.x, -Math.PI / 2); this.cubes.back_left.rotate(Axis.x, -Math.PI / 2); this.cubes.back.rotate(Axis.x, -Math.PI / 2); this.cubes.back_right.rotate(Axis.x, -Math.PI / 2); this.cubes.back_bottom_left.rotate(Axis.x, -Math.PI / 2); this.cubes.back_bottom.rotate(Axis.x, -Math.PI / 2); this.cubes.back_bottom_right.rotate(Axis.x, -Math.PI / 2); [this.cubes.back_top_right, this.cubes.back_bottom_right, this.cubes.back_bottom_left, this.cubes.back_top_left,] = [this.cubes.back_bottom_right, this.cubes.back_bottom_left, this.cubes.back_top_left, this.cubes.back_top_right]; [this.cubes.back_top, this.cubes.back_left, this.cubes.back_bottom, this.cubes.back_right] = [this.cubes.back_right, this.cubes.back_top, this.cubes.back_left, this.cubes.back_bottom]; [this.rendering_order[20], this.rendering_order[26], this.rendering_order[24], this.rendering_order[18],] = [this.rendering_order[18], this.rendering_order[20], this.rendering_order[26], this.rendering_order[24]]; [this.rendering_order[19], this.rendering_order[21], this.rendering_order[25], this.rendering_order[23]] = [this.rendering_order[21], this.rendering_order[25], this.rendering_order[23], this.rendering_order[19]]; break; case Rotation.y1: this.cubes.back_top_right.rotate(Axis.y, Math.PI / 2); this.cubes.back_top.rotate(Axis.y, Math.PI / 2); this.cubes.back_top_left.rotate(Axis.y, Math.PI / 2); this.cubes.top_right.rotate(Axis.y, Math.PI / 2); this.cubes.top.rotate(Axis.y, Math.PI / 2); this.cubes.top_left.rotate(Axis.y, Math.PI / 2); this.cubes.front_top_right.rotate(Axis.y, Math.PI / 2); this.cubes.front_top.rotate(Axis.y, Math.PI / 2); this.cubes.front_top_left.rotate(Axis.y, Math.PI / 2); [this.cubes.back_top_right, this.cubes.front_top_right, this.cubes.front_top_left, this.cubes.back_top_left] = [this.cubes.back_top_left, this.cubes.back_top_right, this.cubes.front_top_right, this.cubes.front_top_left]; [this.cubes.back_top, this.cubes.top_left, this.cubes.front_top, this.cubes.top_right] = [this.cubes.top_left, this.cubes.front_top, this.cubes.top_right, this.cubes.back_top]; [this.rendering_order[20], this.rendering_order[2], this.rendering_order[0], this.rendering_order[18]] = [this.rendering_order[18], this.rendering_order[20], this.rendering_order[2], this.rendering_order[0]]; [this.rendering_order[19], this.rendering_order[9], this.rendering_order[1], this.rendering_order[11]] = [this.rendering_order[9], this.rendering_order[1], this.rendering_order[11], this.rendering_order[19]]; break; case Rotation.y1i: this.cubes.back_top_right.rotate(Axis.y, -Math.PI / 2); this.cubes.back_top.rotate(Axis.y, -Math.PI / 2); this.cubes.back_top_left.rotate(Axis.y, -Math.PI / 2); this.cubes.top_right.rotate(Axis.y, -Math.PI / 2); this.cubes.top.rotate(Axis.y, -Math.PI / 2); this.cubes.top_left.rotate(Axis.y, -Math.PI / 2); this.cubes.front_top_right.rotate(Axis.y, -Math.PI / 2); this.cubes.front_top.rotate(Axis.y, -Math.PI / 2); this.cubes.front_top_left.rotate(Axis.y, -Math.PI / 2); [this.cubes.back_top_right, this.cubes.front_top_right, this.cubes.front_top_left, this.cubes.back_top_left] = [this.cubes.front_top_right, this.cubes.front_top_left, this.cubes.back_top_left, this.cubes.back_top_right]; [this.cubes.back_top, this.cubes.top_left, this.cubes.front_top, this.cubes.top_right] = [this.cubes.top_right, this.cubes.back_top, this.cubes.top_left, this.cubes.front_top]; [this.rendering_order[20], this.rendering_order[2], this.rendering_order[0], this.rendering_order[18]] = [this.rendering_order[2], this.rendering_order[0], this.rendering_order[18], this.rendering_order[20]]; [this.rendering_order[19], this.rendering_order[9], this.rendering_order[1], this.rendering_order[11]] = [this.rendering_order[11], this.rendering_order[19], this.rendering_order[9], this.rendering_order[1]]; break; case Rotation.y2: this.cubes.back_right.rotate(Axis.y, Math.PI / 2); this.cubes.back.rotate(Axis.y, Math.PI / 2); this.cubes.back_left.rotate(Axis.y, Math.PI / 2); this.cubes.right.rotate(Axis.y, Math.PI / 2); this.cubes.center.rotate(Axis.y, Math.PI / 2); this.cubes.left.rotate(Axis.y, Math.PI / 2); this.cubes.front_right.rotate(Axis.y, Math.PI / 2); this.cubes.front.rotate(Axis.y, Math.PI / 2); this.cubes.front_left.rotate(Axis.y, Math.PI / 2); [this.cubes.back_right, this.cubes.front_right, this.cubes.front_left, this.cubes.back_left] = [this.cubes.back_left, this.cubes.back_right, this.cubes.front_right, this.cubes.front_left]; [this.cubes.back, this.cubes.left, this.cubes.front, this.cubes.right] = [this.cubes.left, this.cubes.front, this.cubes.right, this.cubes.back]; [this.rendering_order[23], this.rendering_order[5], this.rendering_order[3], this.rendering_order[21]] = [this.rendering_order[21], this.rendering_order[23], this.rendering_order[5], this.rendering_order[3]]; [this.rendering_order[22], this.rendering_order[12], this.rendering_order[4], this.rendering_order[14]] = [this.rendering_order[12], this.rendering_order[4], this.rendering_order[14], this.rendering_order[22]]; break; case Rotation.y2i: this.cubes.back_right.rotate(Axis.y, -Math.PI / 2); this.cubes.back.rotate(Axis.y, -Math.PI / 2); this.cubes.back_left.rotate(Axis.y, -Math.PI / 2); this.cubes.right.rotate(Axis.y, -Math.PI / 2); this.cubes.center.rotate(Axis.y, -Math.PI / 2); this.cubes.left.rotate(Axis.y, -Math.PI / 2); this.cubes.front_right.rotate(Axis.y, -Math.PI / 2); this.cubes.front.rotate(Axis.y, -Math.PI / 2); this.cubes.front_left.rotate(Axis.y, -Math.PI / 2); [this.cubes.back_right, this.cubes.front_right, this.cubes.front_left, this.cubes.back_left] = [this.cubes.front_right, this.cubes.front_left, this.cubes.back_left, this.cubes.back_right]; [this.cubes.back, this.cubes.left, this.cubes.front, this.cubes.right] = [this.cubes.right, this.cubes.back, this.cubes.left, this.cubes.front]; [this.rendering_order[23], this.rendering_order[5], this.rendering_order[3], this.rendering_order[21]] = [this.rendering_order[5], this.rendering_order[3], this.rendering_order[21], this.rendering_order[23]]; [this.rendering_order[22], this.rendering_order[12], this.rendering_order[4], this.rendering_order[14]] = [this.rendering_order[14], this.rendering_order[22], this.rendering_order[12], this.rendering_order[4]]; break; case Rotation.y3: this.cubes.back_bottom_right.rotate(Axis.y, Math.PI / 2); this.cubes.back_bottom.rotate(Axis.y, Math.PI / 2); this.cubes.back_bottom_left.rotate(Axis.y, Math.PI / 2); this.cubes.bottom_right.rotate(Axis.y, Math.PI / 2); this.cubes.bottom.rotate(Axis.y, Math.PI / 2); this.cubes.bottom_left.rotate(Axis.y, Math.PI / 2); this.cubes.front_bottom_right.rotate(Axis.y, Math.PI / 2); this.cubes.front_bottom.rotate(Axis.y, Math.PI / 2); this.cubes.front_bottom_left.rotate(Axis.y, Math.PI / 2); [this.cubes.back_bottom_right, this.cubes.front_bottom_right, this.cubes.front_bottom_left, this.cubes.back_bottom_left] = [this.cubes.back_bottom_left, this.cubes.back_bottom_right, this.cubes.front_bottom_right, this.cubes.front_bottom_left]; [this.cubes.back_bottom, this.cubes.bottom_left, this.cubes.front_bottom, this.cubes.bottom_right] = [this.cubes.bottom_left, this.cubes.front_bottom, this.cubes.bottom_right, this.cubes.back_bottom]; [this.rendering_order[26], this.rendering_order[8], this.rendering_order[6], this.rendering_order[24]] = [this.rendering_order[24], this.rendering_order[26], this.rendering_order[8], this.rendering_order[6]]; [this.rendering_order[25], this.rendering_order[15], this.rendering_order[7], this.rendering_order[17]] = [this.rendering_order[15], this.rendering_order[7], this.rendering_order[17], this.rendering_order[25]]; break; case Rotation.y3i: this.cubes.back_bottom_right.rotate(Axis.y, -Math.PI / 2); this.cubes.back_bottom.rotate(Axis.y, -Math.PI / 2); this.cubes.back_bottom_left.rotate(Axis.y, -Math.PI / 2); this.cubes.bottom_right.rotate(Axis.y, -Math.PI / 2); this.cubes.bottom.rotate(Axis.y, -Math.PI / 2); this.cubes.bottom_left.rotate(Axis.y, -Math.PI / 2); this.cubes.front_bottom_right.rotate(Axis.y, -Math.PI / 2); this.cubes.front_bottom.rotate(Axis.y, -Math.PI / 2); this.cubes.front_bottom_left.rotate(Axis.y, -Math.PI / 2); [this.cubes.back_bottom_right, this.cubes.front_bottom_right, this.cubes.front_bottom_left, this.cubes.back_bottom_left] = [this.cubes.front_bottom_right, this.cubes.front_bottom_left, this.cubes.back_bottom_left, this.cubes.back_bottom_right]; [this.cubes.back_bottom, this.cubes.bottom_left, this.cubes.front_bottom, this.cubes.bottom_right] = [this.cubes.bottom_right, this.cubes.back_bottom, this.cubes.bottom_left, this.cubes.front_bottom]; [this.rendering_order[26], this.rendering_order[8], this.rendering_order[6], this.rendering_order[24]] = [this.rendering_order[8], this.rendering_order[6], this.rendering_order[24], this.rendering_order[26]]; [this.rendering_order[25], this.rendering_order[15], this.rendering_order[7], this.rendering_order[17]] = [this.rendering_order[17], this.rendering_order[25], this.rendering_order[15], this.rendering_order[7]]; break; case Rotation.z1: this.cubes.back_top_left.rotate(Axis.z, -Math.PI / 2); this.cubes.top_left.rotate(Axis.z, -Math.PI / 2); this.cubes.front_top_left.rotate(Axis.z, -Math.PI / 2); this.cubes.back_left.rotate(Axis.z, -Math.PI / 2); this.cubes.left.rotate(Axis.z, -Math.PI / 2); this.cubes.front_left.rotate(Axis.z, -Math.PI / 2); this.cubes.back_bottom_left.rotate(Axis.z, -Math.PI / 2); this.cubes.bottom_left.rotate(Axis.z, -Math.PI / 2); this.cubes.front_bottom_left.rotate(Axis.z, -Math.PI / 2); [this.cubes.back_top_left, this.cubes.front_top_left, this.cubes.front_bottom_left, this.cubes.back_bottom_left] = [this.cubes.back_bottom_left, this.cubes.back_top_left, this.cubes.front_top_left, this.cubes.front_bottom_left]; [this.cubes.top_left, this.cubes.back_left, this.cubes.bottom_left, this.cubes.front_left] = [this.cubes.back_left, this.cubes.bottom_left, this.cubes.front_left, this.cubes.top_left]; [this.rendering_order[18], this.rendering_order[0], this.rendering_order[6], this.rendering_order[24]] = [this.rendering_order[24], this.rendering_order[18], this.rendering_order[0], this.rendering_order[6]]; [this.rendering_order[9], this.rendering_order[21], this.rendering_order[15], this.rendering_order[3]] = [this.rendering_order[21], this.rendering_order[15], this.rendering_order[3], this.rendering_order[9]]; break; case Rotation.z1i: this.cubes.back_top_left.rotate(Axis.z, Math.PI / 2); this.cubes.top_left.rotate(Axis.z, Math.PI / 2); this.cubes.front_top_left.rotate(Axis.z, Math.PI / 2); this.cubes.back_left.rotate(Axis.z, Math.PI / 2); this.cubes.left.rotate(Axis.z, Math.PI / 2); this.cubes.front_left.rotate(Axis.z, Math.PI / 2); this.cubes.back_bottom_left.rotate(Axis.z, Math.PI / 2); this.cubes.bottom_left.rotate(Axis.z, Math.PI / 2); this.cubes.front_bottom_left.rotate(Axis.z, Math.PI / 2); [this.cubes.back_top_left, this.cubes.front_top_left, this.cubes.front_bottom_left, this.cubes.back_bottom_left] = [this.cubes.front_top_left, this.cubes.front_bottom_left, this.cubes.back_bottom_left, this.cubes.back_top_left]; [this.cubes.top_left, this.cubes.back_left, this.cubes.bottom_left, this.cubes.front_left] = [this.cubes.front_left, this.cubes.top_left, this.cubes.back_left, this.cubes.bottom_left]; [this.rendering_order[18], this.rendering_order[0], this.rendering_order[6], this.rendering_order[24]] = [this.rendering_order[0], this.rendering_order[6], this.rendering_order[24], this.rendering_order[18]]; [this.rendering_order[9], this.rendering_order[21], this.rendering_order[15], this.rendering_order[3]] = [this.rendering_order[3], this.rendering_order[9], this.rendering_order[21], this.rendering_order[15]]; break; case Rotation.z2: this.cubes.back_top.rotate(Axis.z, -Math.PI / 2); this.cubes.top.rotate(Axis.z, -Math.PI / 2); this.cubes.front_top.rotate(Axis.z, -Math.PI / 2); this.cubes.back.rotate(Axis.z, -Math.PI / 2); this.cubes.center.rotate(Axis.z, -Math.PI / 2); this.cubes.front.rotate(Axis.z, -Math.PI / 2); this.cubes.back_bottom.rotate(Axis.z, -Math.PI / 2); this.cubes.bottom.rotate(Axis.z, -Math.PI / 2); this.cubes.front_bottom.rotate(Axis.z, -Math.PI / 2); [this.cubes.back_top, this.cubes.front_top, this.cubes.front_bottom, this.cubes.back_bottom] = [this.cubes.back_bottom, this.cubes.back_top, this.cubes.front_top, this.cubes.front_bottom]; [this.cubes.top, this.cubes.back, this.cubes.bottom, this.cubes.front] = [this.cubes.back, this.cubes.bottom, this.cubes.front, this.cubes.top]; [this.rendering_order[19], this.rendering_order[1], this.rendering_order[7], this.rendering_order[25]] = [this.rendering_order[25], this.rendering_order[19], this.rendering_order[1], this.rendering_order[7]]; [this.rendering_order[10], this.rendering_order[22], this.rendering_order[16], this.rendering_order[4]] = [this.rendering_order[22], this.rendering_order[16], this.rendering_order[4], this.rendering_order[10]]; break; case Rotation.z2i: this.cubes.back_top.rotate(Axis.z, Math.PI / 2); this.cubes.top.rotate(Axis.z, Math.PI / 2); this.cubes.front_top.rotate(Axis.z, Math.PI / 2); this.cubes.back.rotate(Axis.z, Math.PI / 2); this.cubes.center.rotate(Axis.z, Math.PI / 2); this.cubes.front.rotate(Axis.z, Math.PI / 2); this.cubes.back_bottom.rotate(Axis.z, Math.PI / 2); this.cubes.bottom.rotate(Axis.z, Math.PI / 2); this.cubes.front_bottom.rotate(Axis.z, Math.PI / 2); [this.cubes.back_top, this.cubes.front_top, this.cubes.front_bottom, this.cubes.back_bottom] = [this.cubes.front_top, this.cubes.front_bottom, this.cubes.back_bottom, this.cubes.back_top]; [this.cubes.top, this.cubes.back, this.cubes.bottom, this.cubes.front] = [this.cubes.front, this.cubes.top, this.cubes.back, this.cubes.bottom]; [this.rendering_order[19], this.rendering_order[1], this.rendering_order[7], this.rendering_order[25]] = [this.rendering_order[1], this.rendering_order[7], this.rendering_order[25], this.rendering_order[19]]; [this.rendering_order[10], this.rendering_order[22], this.rendering_order[16], this.rendering_order[4]] = [this.rendering_order[4], this.rendering_order[10], this.rendering_order[22], this.rendering_order[16]]; break; case Rotation.z3: this.cubes.back_top_right.rotate(Axis.z, -Math.PI / 2); this.cubes.top_right.rotate(Axis.z, -Math.PI / 2); this.cubes.front_top_right.rotate(Axis.z, -Math.PI / 2); this.cubes.back_right.rotate(Axis.z, -Math.PI / 2); this.cubes.right.rotate(Axis.z, -Math.PI / 2); this.cubes.front_right.rotate(Axis.z, -Math.PI / 2); this.cubes.back_bottom_right.rotate(Axis.z, -Math.PI / 2); this.cubes.bottom_right.rotate(Axis.z, -Math.PI / 2); this.cubes.front_bottom_right.rotate(Axis.z, -Math.PI / 2); [this.cubes.back_top_right, this.cubes.front_top_right, this.cubes.front_bottom_right, this.cubes.back_bottom_right] = [this.cubes.back_bottom_right, this.cubes.back_top_right, this.cubes.front_top_right, this.cubes.front_bottom_right]; [this.cubes.top_right, this.cubes.back_right, this.cubes.bottom_right, this.cubes.front_right] = [this.cubes.back_right, this.cubes.bottom_right, this.cubes.front_right, this.cubes.top_right]; [this.rendering_order[20], this.rendering_order[2], this.rendering_order[8], this.rendering_order[26]] = [this.rendering_order[26], this.rendering_order[20], this.rendering_order[2], this.rendering_order[8]]; [this.rendering_order[11], this.rendering_order[23], this.rendering_order[17], this.rendering_order[5]] = [this.rendering_order[23], this.rendering_order[17], this.rendering_order[5], this.rendering_order[11]]; break; case Rotation.z3i: this.cubes.back_top_right.rotate(Axis.z, Math.PI / 2); this.cubes.top_right.rotate(Axis.z, Math.PI / 2); this.cubes.front_top_right.rotate(Axis.z, Math.PI / 2); this.cubes.back_right.rotate(Axis.z, Math.PI / 2); this.cubes.right.rotate(Axis.z, Math.PI / 2); this.cubes.front_right.rotate(Axis.z, Math.PI / 2); this.cubes.back_bottom_right.rotate(Axis.z, Math.PI / 2); this.cubes.bottom_right.rotate(Axis.z, Math.PI / 2); this.cubes.front_bottom_right.rotate(Axis.z, Math.PI / 2); [this.cubes.back_top_right, this.cubes.front_top_right, this.cubes.front_bottom_right, this.cubes.back_bottom_right] = [this.cubes.front_top_right, this.cubes.front_bottom_right, this.cubes.back_bottom_right, this.cubes.back_top_right]; [this.cubes.top_right, this.cubes.back_right, this.cubes.bottom_right, this.cubes.front_right] = [this.cubes.front_right, this.cubes.top_right, this.cubes.back_right, this.cubes.bottom_right]; [this.rendering_order[20], this.rendering_order[2], this.rendering_order[8], this.rendering_order[26]] = [this.rendering_order[2], this.rendering_order[8], this.rendering_order[26], this.rendering_order[20]]; [this.rendering_order[11], this.rendering_order[23], this.rendering_order[17], this.rendering_order[5]] = [this.rendering_order[5], this.rendering_order[11], this.rendering_order[23], this.rendering_order[17]]; break; } this.updatepos(); this.updateColors(); }, rotate(dir) { this.rotate_only(dir); this.updateColors(); this.updatepos(); if ( this.is_solved() ) { console.log("is_solved"); } }, shuffle(nb_shuffle) { for(let i = 0; i < nb_shuffle; ++i) { switch (Math.floor( Math.random() * 18 )) { case 0: this.rotate_only( Rotation.x1); break; case 1: this.rotate_only( Rotation.x1i); break; case 2: this.rotate_only( Rotation.x2); break; case 3: this.rotate_only( Rotation.x2i); break; case 4: this.rotate_only( Rotation.x3); break; case 5: this.rotate_only( Rotation.x3i); break; case 6: this.rotate_only( Rotation.y1); break; case 7: this.rotate_only( Rotation.y1i); break; case 8: this.rotate_only( Rotation.y2); break; case 9: this.rotate_only( Rotation.y2i); break; case 10: this.rotate_only( Rotation.y3); break; case 11: this.rotate_only( Rotation.y3i); break; case 12: this.rotate_only( Rotation.z1); break; case 13: this.rotate_only( Rotation.z1i); break; case 14: this.rotate_only( Rotation.z2); break; case 15: this.rotate_only( Rotation.z2i); break; case 16: this.rotate_only( Rotation.z3); break; case 17: this.rotate_only( Rotation.z3i); break; } } this.updateColors(); this.updatepos(); }, is_solved() { for ( let i = 0; i < this.rendering_order.length; ++i ) { if ( this.rendering_order[i] != i ) { return false; } } return true; }, } })(0.85); function loadShader( gl, type, source ) { const shader = gl.createShader( type ); gl.shaderSource( shader, source ); gl.compileShader( shader ); if ( !gl.getShaderParameter( shader, gl.COMPILE_STATUS ) ) { alert( "An error has occured while compiling the shader: " + gl.getShaderInfoLog(shader) ); gl.deleteShader(shader); return null; } return shader; } function initShaderProgram(gl, vsSource, fsSource) { const vertexShader = loadShader( gl, gl.VERTEX_SHADER, vsSource ); const fragmentShader = loadShader( gl, gl.FRAGMENT_SHADER, fsSource ); const shaderProgram = gl.createProgram(); gl.attachShader( shaderProgram, vertexShader ); gl.attachShader( shaderProgram, fragmentShader ); gl.linkProgram( shaderProgram ); if ( !gl.getProgramParameter(shaderProgram, gl.LINK_STATUS) ) { alert( `Unable to initialize the shader program: ${gl.getProgramInfoLog(shaderProgram)}` ); return null; } return shaderProgram; } function initBuffers(gl) { const positionBuffer = gl.createBuffer(); gl.bindBuffer( gl.ARRAY_BUFFER, positionBuffer ); const positions = rubik.positions; gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(positions), gl.DYNAMIC_DRAW); const colors = rubik.colors; const colorBuffer = gl.createBuffer(); gl.bindBuffer( gl.ARRAY_BUFFER, colorBuffer ); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(colors), gl.DYNAMIC_DRAW); const indexBuffer = gl.createBuffer(); gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, indexBuffer ); const indices = rubik.indices; gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW); return { position : positionBuffer, // textureCoord: textureCoordBuffer, color: colorBuffer, indices: indexBuffer, }; } function drawScene( gl, programInfo, buffers, cubeRotation ) { gl.clearColor(0.0, 0.0, 0.0, 1.0); gl.clearDepth(1.0); gl.enable( gl.DEPTH_TEST ); gl.depthFunc( gl.LEQUAL ); gl.clear(gl.COLOR_BUFFER_BIT, gl.DEPTH_BUFFER_BIT); gl.bindBuffer( gl.ARRAY_BUFFER, buffers.position ); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(rubik.positions), gl.DYNAMIC_DRAW); gl.bindBuffer( gl.ARRAY_BUFFER, buffers.color ); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(rubik.colors), gl.DYNAMIC_DRAW); const fieldOfView = Math.PI / 4; const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight; const zNear = 0.1; const zFar = 100.0; const projectionMatrix = mat4.create(); mat4.perspective( projectionMatrix, fieldOfView, aspect, zNear, zFar ); const modelViewMatrix = mat4.create(); mat4.translate( modelViewMatrix, modelViewMatrix, [ 0.0, 0.0, -9.0 ]); mat4.rotate( modelViewMatrix, modelViewMatrix, g_x_rotation, [1, 0, 0]); mat4.rotate( modelViewMatrix, modelViewMatrix, g_y_rotation, [0, 1, 0]); { const numComponents = 3; const type = gl.FLOAT; const normalize = false; const stride = 0; const offset = 0; gl.bindBuffer( gl.ARRAY_BUFFER, buffers.position ); gl.vertexAttribPointer( programInfo.attribLocations.vertexPosition, numComponents, type, normalize, stride, offset ); gl.enableVertexAttribArray( programInfo.attribLocations.vertexPosition ); } { const numComponents = 4; const type = gl.FLOAT; const normalize = false; const stride = 0; const offset = 0; gl.bindBuffer( gl.ARRAY_BUFFER, buffers.color ); gl.vertexAttribPointer( programInfo.attribLocations.vertexColor, numComponents, type, normalize, stride, offset); gl.enableVertexAttribArray( programInfo.attribLocations.vertexColor ); } gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices); gl.useProgram( programInfo.program ); gl.uniformMatrix4fv( programInfo.uniformLocations.projectionMatrix, false, projectionMatrix); gl.uniformMatrix4fv( programInfo.uniformLocations.modelViewMatrix, false, modelViewMatrix); { const type = gl.UNSIGNED_SHORT; const offset = 0; gl.drawElements( gl.TRIANGLES, rubik.indices.length, type, offset ); } } function main() { let slider_y = document.getElementById("y_rotation"); slider_y.oninput = () => { g_y_rotation = slider_y.value * Math.PI / 180; }; let slider_x = document.getElementById("x_rotation"); slider_x.oninput = () => { g_x_rotation = slider_x.value * Math.PI / 180; }; const canvas = document.querySelector('#glCanvas'); const gl = canvas.getContext("webgl"); if ( !gl ) { alert("Unable to initialize WebGl. Your browser or your machine may not support it."); return; } const vsSource = ` attribute vec4 aVertexPosition; attribute vec4 aVertexColor; uniform mat4 uModelViewMatrix; uniform mat4 uProjectionMatrix; varying lowp vec4 vColor; void main() { gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; vColor = aVertexColor; } ` const fsSource = ` varying lowp vec4 vColor; void main() { gl_FragColor = vColor; } ` const shaderProgram = initShaderProgram(gl, vsSource, fsSource); const programInfo = { program: shaderProgram, attribLocations: { vertexPosition: gl.getAttribLocation( shaderProgram, "aVertexPosition" ), vertexColor: gl.getAttribLocation( shaderProgram, "aVertexColor" ), }, uniformLocations: { projectionMatrix: gl.getUniformLocation( shaderProgram, "uProjectionMatrix" ), modelViewMatrix: gl.getUniformLocation( shaderProgram, "uModelViewMatrix" ), }, }; const buffers = initBuffers(gl); document.getElementById("rotate_x1").onclick = () => { rubik.rotate(Rotation.x1); } document.getElementById("rotate_x1i").onclick = () => { rubik.rotate(Rotation.x1i); } document.getElementById("rotate_x2").onclick = () => { rubik.rotate(Rotation.x2); } document.getElementById("rotate_x2i").onclick = () => { rubik.rotate(Rotation.x2i); } document.getElementById("rotate_x3").onclick = () => { rubik.rotate(Rotation.x3); } document.getElementById("rotate_x3i").onclick = () => { rubik.rotate(Rotation.x3i); } document.getElementById("rotate_y1").onclick = () => { rubik.rotate(Rotation.y1); } document.getElementById("rotate_y1i").onclick = () => { rubik.rotate(Rotation.y1i); } document.getElementById("rotate_y2").onclick = () => { rubik.rotate(Rotation.y2); } document.getElementById("rotate_y2i").onclick = () => { rubik.rotate(Rotation.y2i); } document.getElementById("rotate_y3").onclick = () => { rubik.rotate(Rotation.y3); } document.getElementById("rotate_y3i").onclick = () => { rubik.rotate(Rotation.y3i); } document.getElementById("rotate_z1").onclick = () => { rubik.rotate(Rotation.z1); } document.getElementById("rotate_z1i").onclick = () => { rubik.rotate(Rotation.z1i); } document.getElementById("rotate_z2").onclick = () => { rubik.rotate(Rotation.z2); } document.getElementById("rotate_z2i").onclick = () => { rubik.rotate(Rotation.z2i); } document.getElementById("rotate_z3").onclick = () => { rubik.rotate(Rotation.z3); } document.getElementById("rotate_z3i").onclick = () => { rubik.rotate(Rotation.z3i); } document.getElementById("shuffle").onclick = () => { rubik.shuffle(4); } const render = (now) => { drawScene( gl, programInfo, buffers, now * 0.001 ); requestAnimationFrame(render); } requestAnimationFrame(render); } window.onload = main;