void Triangle::prepare() { Vector3D n = getFaceNormal(); for (int i = 0; i < 3; i++) { const Point3D& p0 = getVtxPosition(i); const Point3D& p1 = getVtxPosition((i + 1) % 3); const Point3D& p2 = getVtxPosition((i + 2) % 3); Vector3D e = p2 - p1; Vector3D np = n % e; float a = np.dot(p1); float b = np.dot(p0); float f = 1.0f / (b - a); float d = 1.0f - f*b; mPlanes[i] = f * np; mPlaneOffsets(i) = d; } }
void Mesh::recalculateNormals() { for (int i = 0; i < getNumVertices(); i++) { normal(i) = Vec3(0, 0, 0); } for (int i = 0; i < getNumFaces(); i++) { int size; int *verts = face(i, size); Vec3 n = getFaceNormal(i); for (int v = 0; v < size; v++) { normal(verts[v]) += n; } } for (int i = 0; i < getNumVertices(); i++) { normal(i) = normalize(normal(i)); } }
void SilhouetteEdges::getFaceNormals(ID3DXMesh* mesh, ID3DXBuffer* adjBuffer, D3DXVECTOR3* currentFaceNormal, D3DXVECTOR3 adjFaceNormals[3], DWORD faceIndex) { MeshVertex* vertices = 0; mesh->LockVertexBuffer(0, (void**)&vertices); WORD* indices = 0; mesh->LockIndexBuffer(0, (void**)&indices); DWORD* adj = (DWORD*)adjBuffer->GetBufferPointer(); // // Get the face normal. getFaceNormal(mesh, faceIndex, currentFaceNormal); // // Get adjacent face indices WORD faceIndex0 = adj[faceIndex * 3]; WORD faceIndex1 = adj[faceIndex * 3 + 1]; WORD faceIndex2 = adj[faceIndex * 3 + 2]; // // Get adjacent face normals, if there is no adjacent face, // then set the adjacent face normal to the opposite of the // "currentFaceNormal". Recall we do this because edges that // don't have an adjacent triangle are automatically considered // silhouette edges. And in order to make that happen, we need // the current face normal and adjacent face normal to point // in the opposite direction. Also, recall that an entry // in the adjacency buffer equal to -1 denotes that the edge // doesn't have an adjacent triangle. D3DXVECTOR3 faceNormal0, faceNormal1, faceNormal2; if( faceIndex0 != USHRT_MAX ) // is there an adjacent triangle? { WORD i0 = indices[faceIndex0 * 3]; WORD i1 = indices[faceIndex0 * 3 + 1]; WORD i2 = indices[faceIndex0 * 3 + 2]; D3DXVECTOR3 v0 = vertices[i0].position; D3DXVECTOR3 v1 = vertices[i1].position; D3DXVECTOR3 v2 = vertices[i2].position; D3DXVECTOR3 edge0 = v1 - v0; D3DXVECTOR3 edge1 = v2 - v0; D3DXVec3Cross(&faceNormal0, &edge0, &edge1); D3DXVec3Normalize(&faceNormal0, &faceNormal0); } else { faceNormal0 = -(*currentFaceNormal); } if( faceIndex1 != USHRT_MAX ) // is there an adjacent triangle? { WORD i0 = indices[faceIndex1 * 3]; WORD i1 = indices[faceIndex1 * 3 + 1]; WORD i2 = indices[faceIndex1 * 3 + 2]; D3DXVECTOR3 v0 = vertices[i0].position; D3DXVECTOR3 v1 = vertices[i1].position; D3DXVECTOR3 v2 = vertices[i2].position; D3DXVECTOR3 edge0 = v1 - v0; D3DXVECTOR3 edge1 = v2 - v0; D3DXVec3Cross(&faceNormal1, &edge0, &edge1); D3DXVec3Normalize(&faceNormal1, &faceNormal1); } else { faceNormal1 = -(*currentFaceNormal); } if( faceIndex2 != USHRT_MAX ) // is there an adjacent triangle? { WORD i0 = indices[faceIndex2 * 3]; WORD i1 = indices[faceIndex2 * 3 + 1]; WORD i2 = indices[faceIndex2 * 3 + 2]; D3DXVECTOR3 v0 = vertices[i0].position; D3DXVECTOR3 v1 = vertices[i1].position; D3DXVECTOR3 v2 = vertices[i2].position; D3DXVECTOR3 edge0 = v1 - v0; D3DXVECTOR3 edge1 = v2 - v0; D3DXVec3Cross(&faceNormal2, &edge0, &edge1); D3DXVec3Normalize(&faceNormal2, &faceNormal2); } else { faceNormal2 = -(*currentFaceNormal); } // save adjacent face normals adjFaceNormals[0] = faceNormal0; adjFaceNormals[1] = faceNormal1; adjFaceNormals[2] = faceNormal2; mesh->UnlockVertexBuffer(); mesh->UnlockIndexBuffer(); }