Exemplo n.º 1
0
//-------------------------------------------------------------
//- 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); 
	}
}
Exemplo n.º 2
0
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;
}