Pergunta

I'm struggling calculating the normals for each of the 8 vertices for my cube in c++. I thought it should be going like this: - calculate the normals for each of the 6 faces of the cube - each vertex touches 3 faces, so calculating the normalized vector for all the 3 faces

m_iNoVerts=8;
Vertex verts[8];
verts[0].position = XMFLOAT3(-1.0f, -1.0f,  1.0f);
verts[1].position = XMFLOAT3(-1.0f,  1.0f,  1.0f);
verts[2].position = XMFLOAT3( 1.0f, -1.0f,  1.0f);
verts[3].position = XMFLOAT3( 1.0f,  1.0f,  1.0f);
verts[4].position = XMFLOAT3(-1.0f, -1.0f, -1.0f);
verts[5].position = XMFLOAT3(-1.0f,  1.0f, -1.0f);
verts[6].position = XMFLOAT3( 1.0f, -1.0f, -1.0f);
verts[7].position = XMFLOAT3( 1.0f,  1.0f, -1.0f);

m_iNoIndices = 36;
int indices[36] = {0, 1, 2, // front face   0
                  1, 2, 3,

                  4, 5, 6,  // back face    1
                  5, 6, 7,

                  4, 5, 0,  // left face    2
                  5, 0, 1,

                  2, 3, 6,  // right face   3
                  3, 6, 7,

                  1, 5, 3,  // top face     4
                  5, 3, 7,

                  0, 4, 2,  // bottom face  5
                  4, 2, 6};

// Calculate the normals for each face
XMVECTOR result[6]; // cross product of vec1 and vec2 represents the normal of the face
XMVECTOR vec1;      // vec1 = B - A example first calc: B = verts[1] and A = verts[0]
XMVECTOR vec2;      // vec2 = C - B
int ii = 0;
for(int i = 0; i < 6; ++i)
{
    vec1.x = verts[indices[ii+1]].position.x - verts[indices[ii]].position.x;
    vec1.y = verts[indices[ii+1]].position.y - verts[indices[ii]].position.y;
    vec1.z = verts[indices[ii+1]].position.z - verts[indices[ii]].position.z;

    vec2.x = verts[indices[ii+2]].position.x - verts[indices[ii+1]].position.x;
    vec2.y = verts[indices[ii+2]].position.y - verts[indices[ii+1]].position.y;
    vec2.z = verts[indices[ii+2]].position.z - verts[indices[ii+1]].position.z;

    // calculate the cross product
    //result[i].x = (vec1.y * vec2.z) - (vec1.z * vec2.y);
    //result[i].y = (vec1.z * vec2.x) - (vec1.x * vec2.z);
    //result[i].z = (vec1.x * vec2.y) - (vec1.y * vec2.x);
    //result[i].w = 0;
    result[i] = XMVector3Cross(vec1, vec2);

    ii += 6;    // increasing the counter for the indices to jump to the next face 
}

// calculating the normals of each vertex
XMVECTOR normal[8];
// building the resulting vector of the 3 sites on each vertex
normal[0] = result[0] + result[2] + result[5];
normal[1] = result[0] + result[2] + result[4];
normal[2] = result[0] + result[3] + result[5];
normal[3] = result[0] + result[3] + result[4];
normal[4] = result[1] + result[2] + result[5];
normal[5] = result[1] + result[2] + result[4];
normal[6] = result[1] + result[3] + result[5];
normal[7] = result[1] + result[3] + result[4];

for(int i = 0; i < m_iNoVerts; ++i)
{
    normal[i] = XMVector3Normalize(normal[i]);  // normalization of the vector
    verts[i].normal.x = normal[i].x;
    verts[i].normal.y = normal[i].y;
    verts[i].normal.z = normal[i].z;
}

when I check the normals in the debugger, the values are +-0.577.. The given values from my teacher are

0.0  0.5  0.5
0.0  0.5  0.5
0.0 -0.5  0.5
0.0 -0.5  0.5
0.0  0.5 -0.5
0.0  0.5 -0.5
0.0 -0.5 -0.5
0.0 -0.5 -0.5

Whats the thing I'm doing wrong? Thanks!

Foi útil?

Solução

The normals of faces of a cube are simply

[+-1, 0, 0],   [0,+-1,0],    [0,0,+-1]
(Left/Right), (Top/Bottom), (Front/Back)

The 8 normals for the vertices, if such a concept is meaningful, are even more simply vertex - center or vertex it self in this case, since center is at origin.

That can be of course calculated by adding the 8 linear combinations of the face normals and normalizing, giving

[+-1, +-1, +-1] / sqrt(3)

But in essence, there's not that much to calculate...

Outras dicas

  1. Each face can be defined by just 3 vertices. You have a list of 6, why?

  2. If you do this: vec1 = B - A; vec2 = C - A then in the case of a cube they will be orthogonal :)

  3. The normals can be scaled by any constant, they will still be normal. It is probably convention to scale them to be unit vectors. To do that, just divide each by its norm (vector length). 0.577 is sqrt(1/3), probably. (+-0.577, +-0.577, +-0.577) are unit vectors.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top