THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 24/01/2009 at 12:59, xxxxxxxx wrote:
Here you go... some quick-n-dirty code to generate Vertex Normals from a mesh object. Returns the same type of memory chunk that CreatePhongNormals() does (I call this when no Phong Tag exists)...
// helper struct
struct NormalStruct
{
NormalStruct(_DONTCONSTRUCT dc) : a(DC), b(DC), c(DC), d(DC) { }
NormalStruct(void) {}
NormalStruct(const Vector &t_a, const Vector &t_b, const Vector &t_c, const Vector &t_d) { a=t_a; b=t_b; c=t_c; d=t_d; }
NormalStruct(const Vector &t_a, const Vector &t_b, const Vector &t_c) { a=t_a; b=t_b; c=t_c; }
Vector a,b,c,d;
};
//------------------------------------------------------------------------------------------------------
//******************************************************************************************************
// ComputeVertexNormals()
//******************************************************************************************************
//------------------------------------------------------------------------------------------------------
NormalStruct *ogreMesh::ComputeVertexNormals(void)
{
CPolygon *pMeshPoly, *pNeighborPoly;
LONG j, faceCnt, *pFaces = NULL;
DWORD i;
Vector v1, v2, vNorm, *pNorm, *pNorms;
Neighbor neighbor;
// initialize neighbor class
if( !neighbor.Init(m_numVerts, m_pPolys, m_numFaces, NULL) )
return NULL;
// this array needs to be large enough for a unique Normal per quad-face vertex
pNorms = (Vector * )GeAlloc((4 * m_numFaces) * sizeof(Vector));
if( !pNorms )
return NULL;
pNorm = &pNorms[0];
pMeshPoly = &m_pPolys[0];
for(i=0; i<m_numFaces; i++)
{
//====================== Mesh Poly Point A ========================
vNorm = Vector(); // (re)intitialize
neighbor.GetPointPolys(pMeshPoly->a, &pFaces, &faceCnt);
for(j=0; j<faceCnt; j++)
{
pNeighborPoly = &m_pPolys[pFaces[j]];
// Compute face normal
v1 = m_pPoints[pNeighborPoly->b] - m_pPoints[pNeighborPoly->a];
v2 = m_pPoints[pNeighborPoly->c] - m_pPoints[pNeighborPoly->a];
vNorm += v1 % v2; // get cross-product
}
vNorm /= faceCnt; // average the normal(s)
*pNorm = !vNorm; // normalize and store
pNorm++;
//====================== Mesh Poly Point B ========================
vNorm = Vector(); // (re)intitialize
neighbor.GetPointPolys(pMeshPoly->b, &pFaces, &faceCnt);
for(j=0; j<faceCnt; j++)
{
pNeighborPoly = &m_pPolys[pFaces[j]];
// Compute face normal
v1 = m_pPoints[pNeighborPoly->b] - m_pPoints[pNeighborPoly->a];
v2 = m_pPoints[pNeighborPoly->c] - m_pPoints[pNeighborPoly->a];
vNorm += v1 % v2; // get cross-product
}
vNorm /= faceCnt; // average the normal(s)
*pNorm = !vNorm; // normalize and store
pNorm++;
//====================== Mesh Poly Point C ========================
vNorm = Vector(); // (re)intitialize
neighbor.GetPointPolys(pMeshPoly->c, &pFaces, &faceCnt);
for(j=0; j<faceCnt; j++)
{
pNeighborPoly = &m_pPolys[pFaces[j]];
// Compute face normal
v1 = m_pPoints[pNeighborPoly->b] - m_pPoints[pNeighborPoly->a];
v2 = m_pPoints[pNeighborPoly->c] - m_pPoints[pNeighborPoly->a];
vNorm += v1 % v2; // get cross-product
}
vNorm /= faceCnt; // average the normal(s)
*pNorm = !vNorm; // normalize and store
pNorm++;
if( pMeshPoly->c != pMeshPoly->d )
{
//====================== Mesh Poly Point D ========================
vNorm = Vector(); // (re)intitialize
neighbor.GetPointPolys(pMeshPoly->d, &pFaces, &faceCnt);
for(j=0; j<faceCnt; j++)
{
pNeighborPoly = &m_pPolys[pFaces[j]];
// Compute face normal
v1 = m_pPoints[pNeighborPoly->b] - m_pPoints[pNeighborPoly->a];
v2 = m_pPoints[pNeighborPoly->c] - m_pPoints[pNeighborPoly->a];
vNorm += v1 % v2; // get cross-product
}
vNorm /= faceCnt; // average the normal(s)
*pNorm = !vNorm; // normalize and store
pNorm++;
}
else
{
// if this is a triangle, just re-use C normal, computed above
*pNorm = !vNorm; // normalize and store
pNorm++;
}
pMeshPoly++;
}
return (NormalStruct * )pNorms;
}
I think there are only a few member variables being used in that (mostly just values you can get from the PolyObject, which you could pass into that routine). You might also want to throw some if( faceCnt ) checks in there to avoid divide-by-zero (though I've never seen it happen).
Cheers,
Keith