myRubixCube::myRubixCube(double length)
{
    len = length;
    plane.push_back(2);
    axis.push_back(0);
    solving, rotating = false;
    theta = 0;
    direction = 0;
    int p = 0, i, j, k;
    for (i = 0; i<27; i++)
        c[i].set_length(len);

    for (i = 0; i<9; i++)
    {
        c[i].color[2] = 3; c[i + 18].color[5] = 6;
    }
    for (i = 0; i<27; i += 9)
    {
        c[i + 5].color[0] = 1; c[i + 8].color[0] = 1; c[i + 2].color[0] = 1;
        c[i + 2].color[1] = 2; c[i + 1].color[1] = 2; c[i].color[1] = 2;
        c[i].color[3] = 4; c[i + 3].color[3] = 4; c[i + 6].color[3] = 4;
        c[i + 6].color[4] = 5; c[i + 7].color[4] = 5; c[i + 8].color[4] = 5;
    }
    for (i = 0; i<3; i++)
        for (j = 0; j<3; j++)
            for (k = 0; k<3; k++)
                cubepos[i][j][k] = p++;
    set_centre();
}
void myRubixCube::rotate_cube_plane()
{
    if (!rotating)
    {
        int i, j, k;
        if (plane.back() != 0 && plane.back() != 1 && plane.back() != 2)
            exit(2);
        switch (axis.back())
        {
        case 0:
            differposition(direction, cubepos[plane.back()][0][0], cubepos[plane.back()][0][1], cubepos[plane.back()][0][2], cubepos[plane.back()][1][0], cubepos[plane.back()][1][1], cubepos[plane.back()][1][2], cubepos[plane.back()][2][0], cubepos[plane.back()][2][1], cubepos[plane.back()][2][2]);
            break;
        case 1:
            differposition(direction, cubepos[2][plane.back()][0], cubepos[2][plane.back()][1], cubepos[2][plane.back()][2], cubepos[1][plane.back()][0], cubepos[1][plane.back()][1], cubepos[1][plane.back()][2], cubepos[0][plane.back()][0], cubepos[0][plane.back()][1], cubepos[0][plane.back()][2]);
            break;
        case 2:
            differposition(direction, cubepos[0][0][plane.back()], cubepos[1][0][plane.back()], cubepos[2][0][plane.back()], cubepos[0][1][plane.back()], cubepos[1][1][plane.back()], cubepos[2][1][plane.back()], cubepos[0][2][plane.back()], cubepos[1][2][plane.back()], cubepos[2][2][plane.back()]);
            break;
        default:
            exit(2);
        }
        set_centre();

        switch (axis.back())
        {
        case 0:
            for (j = 0; j < 3; j++)
                for (k = 0; k < 3; k++)
                    c[cubepos[plane.back()][j][k]].rotate(0, direction);
            break;
        case 1:
            for (i = 0; i < 3; i++)
                for (k = 0; k < 3; k++)
                    c[cubepos[i][plane.back()][k]].rotate(1, direction);
            break;
        case 2:
            for (i = 0; i < 3; i++)
                for (j = 0; j < 3; j++)
                    c[cubepos[i][j][plane.back()]].rotate(2, direction);
            break;
        }

    }
    else
        glutIdleFunc(idle);
        ;
}
void GLViewController::set_view_param(const Vec3f& e, const Vec3f& c, const Vec3f& u)
{
    // native viewing direction is the negative z-axis
    // while right is the x-axis and up is the y-axis
    Vec3f view = c - e;
    float eye_dist = length(view);
    view /= eye_dist;
    Vec3f right = normalize(cross(view, u));
    Vec3f up = cross(right, view);
    Mat3x3f rot(right, up, -view);
    rot = transpose(rot); // since matrix is row-major

    // convert the change-of-basis matrix to a quaternion
    Quatf qrot;
    qrot.make_rot(rot);
    set_rotation(qrot);
    set_centre(c);
    set_eye_dist(eye_dist);
}