//------------------------------------------------------------- //- CalcNorms //- Calculate the vertex and face normals //------------------------------------------------------------- void CalcNorms() { //Calculate face normals first for(int x = 0; x < 10; x++) { CVector3 vTmp = CalcFaceNormal(CVector3(verts[Tris[x][2]]), CVector3(verts[Tris[x][1]]), CVector3(verts[Tris[x][0]])); memcpy(facenormals[x], vTmp.Get(), 12); } //Calculate the vertex normals for(x = 0; x < 10; x++) { int iShared[10]; //Indices of shared faces int iNumShared = 0; //Number of faces that share vertex //first find out which faces share the vertex for(int y = 0; y < 10; y++) { for(int z = 0; z < 3; z++) { if(Tris[y][z] == x) { iShared[iNumShared] = y; iNumShared ++; } } } //Calculate a normal by averaging the face normals of the shared faces CVector3 finalNorm; for(y = 0; y < iNumShared; y++) { finalNorm += facenormals[iShared[y]]; } finalNorm /= (float)iNumShared; memcpy(&vertnormals[x], finalNorm.Get(), 12); } }
static bool Quadable(EERIEPOLY * ep, EERIEPOLY * ep2, float tolerance) { long count=0; long ep_notcommon=-1; long ep2_notcommon=-1; if(ep2->type & POLY_QUAD) return false; if(ep->tex != ep2->tex) return false; long typ1=ep->type&(~POLY_QUAD); long typ2=ep2->type&(~POLY_QUAD); if(typ1!=typ2) return false; if((ep->type & POLY_TRANS) && ep->transval != ep2->transval) return false; ep->norm = CalcFaceNormal(ep->v); if(glm::abs(glm::dot(ep->norm, ep2->norm)) < 1.f - tolerance) return false; for (long i=0;i<3;i++) { long common=-1; long common2=-1; for (long j=0;j<3;j++) { if ( ( NearlyEqual(ep->v[i].p.x,ep2->v[j].p.x) ) && ( NearlyEqual(ep->v[i].p.y,ep2->v[j].p.y) ) && ( NearlyEqual(ep->v[i].p.z,ep2->v[j].p.z) ) && ( NearlyEqual(ep->v[i].uv.x,ep2->v[j].uv.x) ) && ( NearlyEqual(ep->v[i].uv.y,ep2->v[j].uv.y) ) ) { count++; common=j; } if ( ( NearlyEqual(ep->v[j].p.x,ep2->v[i].p.x) ) && ( NearlyEqual(ep->v[j].p.y,ep2->v[i].p.y) ) && ( NearlyEqual(ep->v[j].p.z,ep2->v[i].p.z) ) && ( NearlyEqual(ep->v[j].uv.x,ep2->v[i].uv.x) ) && ( NearlyEqual(ep->v[j].uv.y,ep2->v[i].uv.y) ) ) { common2=j; } } if (common2==-1) ep2_notcommon=i; if (common==-1) ep_notcommon=i; } if ((count>=2) && (ep_notcommon!=-1) && (ep2_notcommon!=-1)) { ep2->type |= POLY_QUAD; switch (ep2_notcommon) { case 1: CopyVertices(ep2,3,0); CopyVertices(ep2,0,1); CopyVertices(ep2,1,2); CopyVertices(ep2,2,3); break; case 2: CopyVertices(ep2,3,0); CopyVertices(ep2,0,2); CopyVertices(ep2,2,1); CopyVertices(ep2,1,3); break; } CopyVertices(ep2,3,0); ep2->v[3].p = ep->v[ep_notcommon].p; ep2->tv[3].uv = ep2->v[3].uv = ep->v[ep_notcommon].uv; ep2->tv[3].color = ep2->v[3].color = Color::white.toRGB(); ep2->tv[3].rhw = ep2->v[3].rhw = 1.f; ep2->center = (ep2->v[0].p + ep2->v[1].p + ep2->v[2].p + ep2->v[3].p) * 0.25f; ep2->max = glm::max(ep2->max, ep2->v[3].p); ep2->min = glm::min(ep2->min, ep2->v[3].p); ep2->norm2 = ep->norm; ep2->area += fdist((ep2->v[1].p + ep2->v[2].p) * .5f, ep2->v[3].p) * fdist(ep2->v[3].p, ep2->v[1].p)*.5f; // should this be v[2] instead of v[3]? return true; } return false; }