0
I have the following statements:
#define SCALE 4
#define PADDING 1.1
#define CUBES 27
#define CUBE_VERTICES 8
#define CUBE_FACES 6
#define FACE_VERTICES 4
typedef struct {
float angle;
float x;
float y;
float z;
} Rotate;
typedef struct {
float x;
float y;
float z;
} Vertice;
typedef struct {
int vertices[4];
float red;
float green;
float blue;
} Face;
typedef struct {
Vertice vertices[8];
Face faces[6];
Rotate rotate;
} Cube;
float rotate_y = 0;
float rotate_x = 0;
int mode = 1;
float rotate_angle = 5;
Cube cubes[27];
Where I define some variables where the most important ones are the structs
and the array of Cube
.
I will quickly describe what I am doing so it becomes easier for everyone to understand, (Cube
) consists of 8 vertices or points (Vertice
), six-sided(Face
) and a rotation(Rotate
), in turn, each Vertice
has coordinates (x,y,z), each Face
has a coloring and a set of vertex indicators, which will show which vertices of the Cube
forms that face, and each Rotate
has the rotation angle and which axis will rotate.
Having this cube information I can pass this structure to the openGL draw it on the screen. My project is to make a Rubik’s Cube, so it would have 27 cubes, so the array
cube.
So I thought I’d just create the first cube, and then clone the rest by just changing the coordinates of its vertices. Let’s go through the process of creating the first cube:
Cube createCube(Cube c) {
// criando vertices de cima
// vertice cria X Y Z
c.vertices[0] = createVertice(-0.5, 0.5, 0.5);
c.vertices[1] = createVertice(0.5, 0.5, 0.5);
c.vertices[2] = createVertice(0.5, 0.5, -0.5);
c.vertices[3] = createVertice(-0.5, 0.5, -0.5);
// criando vertices de baixo
// vertice cria X Y Z
c.vertices[4] = createVertice(-0.5, -0.5, 0.5);
c.vertices[5] = createVertice(0.5, -0.5, 0.5);
c.vertices[6] = createVertice(0.5, -0.5, -0.5);
c.vertices[7] = createVertice(-0.5, -0.5, -0.5);
// cima e baixo
// face cria determina vertices R G B
c.faces[0] = createFace(verticesFromFace(1, 2, 3, 4), 0.9, 0.9, 0.9);
c.faces[1] = createFace(verticesFromFace(5, 6, 7, 8), 0.8, 1.0, 0.2);
// direita e esquerda
// face cria determina vertices R G B
c.faces[2] = createFace(verticesFromFace(1, 4, 8, 5), 0.2, 0.4, 0.8);
c.faces[3] = createFace(verticesFromFace(2, 3, 7, 6), 0.2, 0.8, 0.4);
// fundo e frente
// face cria determina vertices R G B
c.faces[4] = createFace(verticesFromFace(1, 2, 6, 5), 0.9, 0.0, 0.2);
c.faces[5] = createFace(verticesFromFace(4, 3, 7, 8), 1.0, 0.3, 0.1);
c.rotate = createRotate(0.0f, 0.0f, 0.0f, 0.0f);
return c;
}
In this method I just create a cube, passing data of each vertex, each face and its rotation. The methods called inside these are:
Vertice createVertice(float x, float y, float z) {
Vertice v;
v.x = x;
v.y = y;
v.z = z;
return v;
}
Face createFace(int vertices[4], float red, float green, float blue) {
Face f;
f.vertices[0] = vertices[0];
f.vertices[1] = vertices[1];
f.vertices[2] = vertices[2];
f.vertices[3] = vertices[3];
free(vertices);
f.red = red;
f.green = green;
f.blue = blue;
return f;
}
Rotate createRotate(float angle, float x, float y, float z) {
Rotate r;
r.angle = angle;
r.x = x;
r.y = y;
r.z = z;
return r;
}
They create a certain struct
, passing the data to it and returning it.
With the first cube created, I will clone the others:
void createAndCloneCubes() {
cubes[0] = createCube(cubes[0]);
cubes[1] = cloneCube(cubes[0], PADDING, 0, 0);
cubes[2] = cloneCube(cubes[0], -PADDING, 0, 0);
cubes[9] = cloneCube(cubes[0], 0, 0, -PADDING);
cubes[10] = cloneCube(cubes[1], 0, 0, -PADDING);
cubes[11] = cloneCube(cubes[2], 0, 0, -PADDING);
cubes[18] = cloneCube(cubes[0], 0, 0, PADDING);
cubes[19] = cloneCube(cubes[1], 0, 0, PADDING);
cubes[20] = cloneCube(cubes[2], 0, 0, PADDING);
cubes[3] = cloneCube(cubes[0], 0, PADDING, 0);
cubes[4] = cloneCube(cubes[1], 0, PADDING, 0);
cubes[5] = cloneCube(cubes[2], 0, PADDING, 0);
cubes[12] = cloneCube(cubes[3], 0, 0, -PADDING);
cubes[13] = cloneCube(cubes[4], 0, 0, -PADDING);
cubes[14] = cloneCube(cubes[5], 0, 0, -PADDING);
cubes[21] = cloneCube(cubes[3], 0, 0, PADDING);
cubes[22] = cloneCube(cubes[4], 0, 0, PADDING);
cubes[23] = cloneCube(cubes[5], 0, 0, PADDING);
cubes[6] = cloneCube(cubes[0], 0, -PADDING, 0);
cubes[7] = cloneCube(cubes[1], 0, -PADDING, 0);
cubes[8] = cloneCube(cubes[2], 0, -PADDING, 0);
cubes[15] = cloneCube(cubes[6], 0, 0, -PADDING);
cubes[16] = cloneCube(cubes[7], 0, 0, -PADDING);
cubes[17] = cloneCube(cubes[8], 0, 0, -PADDING);
cubes[24] = cloneCube(cubes[6], 0, 0, PADDING);
cubes[25] = cloneCube(cubes[7], 0, 0, PADDING);
cubes[26] = cloneCube(cubes[8], 0, 0, PADDING);
}
The first I create, and the other I clone, pass by parameter the cube to be cloned, and then the distance between one and the other on each axis(x,y,z).
The method for cloning the cube is as follows:
Cube cloneCube(Cube input, float appX, float appY, float appZ) {
int i;
Cube output;
for (i = 0; i < CUBE_VERTICES; i++)
output.vertices[i] =
createVertice(input.vertices[i].x + appX, input.vertices[i].y + appY,
input.vertices[i].z + appZ);
for (i = 0; i < CUBE_FACES; i++) {
output.faces[i] = createFace(
verticesFromFace(input.faces[i].vertices[0], input.faces[i].vertices[1],
input.faces[i].vertices[2],
input.faces[i].vertices[3]),
input.faces[i].red, input.faces[i].green, input.faces[i].blue);
}
output.rotate = createRotate(input.rotate.angle, input.rotate.x,
input.rotate.y, input.rotate.z);
return output;
}
Where I create a new cube, parrying the information from the old one to it, with observation that in the vertices I add the spacing between a cube and another.
Well, finally, after explaining all my program flow, I’ll tell you the real problem, after all this code, I draw the cubes with openGL, so far so good, the cube is generated, but at certain times I need to change the rotation of a cube, so try the following code:
if (key == '9' && mode == 2) {
Rotate r;
r.angle = -90;
r.x = 0;
r.y = 0;
r.z = 1;
cubes[16].rotate = r;
} else if (key == '0' && mode == 2) {
cubes[16].rotate = createRotate(90, 0, 0, 1);
}
Above, I have two equivalent attempts to change the rotation of cube number 16, but when changing the rotation of the cube, all cloned cubes of this or that has been cloned(7) are also changing the value of their rotation. For example, cube 16 was created like this:
cubes[16] = cloneCube(cubes[7], 0, 0, -PADDING);
So by changing its rotation, the rotation of the Ubes[7], Ubes[25], Ubes[1] (because the 7 was cloned from it) and others are also changing. Probably the rotation of all cloned cubes are at the same address as their parent cube. But I’m not finding the error, as I do so that each cube has its own rotation, even if it has been cloned from another cube?
P.S.: I’m sorry the question is huge, but I tried to do my best so you can understand everything and help me.
I noticed one thing: why
free(vertices)
? You made somemalloc()
before? If not, risk causing problems in your program.– Emoon
Yes, in the method
verticesFromFace()
that I forgot to put I’m allocating a vector of 4 positions with themalloc
– Leonardo
The @Emoon asked this because it’s not normal, as I said in the previous answer, notice how weird it is to do it this way. I think I’m missing a [mcve] for me to be interested in the question.
– Maniero