Example #1
0
/*
=============
Tess_SurfaceMDV
=============
*/
static void Tess_SurfaceMDV( mdvSurface_t *srf )
{
	int           i, j;
	int           numIndexes = 0;
	int           numVertexes;
	mdvXyz_t      *oldVert, *newVert;
	mdvNormal_t   *oldNormal, *newNormal;
	mdvSt_t       *st;
	srfTriangle_t *tri;
	float         backlerp;
	float         oldXyzScale, newXyzScale;

	GLimp_LogComment( "--- Tess_SurfaceMDV ---\n" );

	if ( backEnd.currentEntity->e.oldframe == backEnd.currentEntity->e.frame )
	{
		backlerp = 0;
	}
	else
	{
		backlerp = backEnd.currentEntity->e.backlerp;
	}

	newXyzScale = ( 1.0f - backlerp );
	oldXyzScale = backlerp;

	Tess_CheckOverflow( srf->numVerts, srf->numTriangles * 3 );

	numIndexes = srf->numTriangles * 3;

	for ( i = 0, tri = srf->triangles; i < srf->numTriangles; i++, tri++ )
	{
		tess.indexes[ tess.numIndexes + i * 3 + 0 ] = tess.numVertexes + tri->indexes[ 0 ];
		tess.indexes[ tess.numIndexes + i * 3 + 1 ] = tess.numVertexes + tri->indexes[ 1 ];
		tess.indexes[ tess.numIndexes + i * 3 + 2 ] = tess.numVertexes + tri->indexes[ 2 ];
	}

	newVert = srf->verts + ( backEnd.currentEntity->e.frame * srf->numVerts );
	oldVert = srf->verts + ( backEnd.currentEntity->e.oldframe * srf->numVerts );
	newNormal = srf->normals + ( backEnd.currentEntity->e.frame * srf->numVerts );
	oldNormal = srf->normals + ( backEnd.currentEntity->e.oldframe * srf->numVerts );
	st = srf->st;

	numVertexes = srf->numVerts;

	for ( j = 0; j < numVertexes; j++, newVert++, oldVert++, st++ )
	{
		vec3_t tmpVert;

		if ( backlerp == 0 )
		{
			// just copy
			VectorCopy( newVert->xyz, tmpVert );
		}
		else
		{
			// interpolate the xyz
			VectorScale( oldVert->xyz, oldXyzScale, tmpVert );
			VectorMA( tmpVert, newXyzScale, newVert->xyz, tmpVert );
		}

		tess.verts[ tess.numVertexes + j ].xyz[ 0 ] = tmpVert[ 0 ];
		tess.verts[ tess.numVertexes + j ].xyz[ 1 ] = tmpVert[ 1 ];
		tess.verts[ tess.numVertexes + j ].xyz[ 2 ] = tmpVert[ 2 ];

		tess.verts[ tess.numVertexes + j ].texCoords[ 0 ] = floatToHalf( st->st[ 0 ] );
		tess.verts[ tess.numVertexes + j ].texCoords[ 1 ] = floatToHalf( st->st[ 1 ] );
	}

	tess.attribsSet |= ATTR_POSITION | ATTR_TEXCOORD;

	// calc tangent spaces
	if ( !tess.skipTangentSpaces )
	{
		int         i;
		float       *v;
		const float *v0, *v1, *v2;
		const int16_t *t0, *t1, *t2;
		vec3_t      tangent, *tangents;
		vec3_t      binormal, *binormals;
		vec3_t      *normals;
		glIndex_t   *indices;

		tess.attribsSet |= ATTR_QTANGENT;

		tangents = (vec3_t *)ri.Hunk_AllocateTempMemory( numVertexes * sizeof( vec3_t ) );
		binormals = (vec3_t *)ri.Hunk_AllocateTempMemory( numVertexes * sizeof( vec3_t ) );
		normals = (vec3_t *)ri.Hunk_AllocateTempMemory( numVertexes * sizeof( vec3_t ) );

		for ( i = 0; i < numVertexes; i++ )
		{
			VectorClear( tangents[ i ] );
			VectorClear( binormals[ i ] );

			if ( backlerp == 0 )
			{
				// just copy
				VectorCopy( newNormal->normal, normals[ i ] );
			}
			else
			{
				// interpolate the xyz
				VectorScale( oldNormal->normal, oldXyzScale, normals[ i ] );
				VectorMA( normals[ i ], newXyzScale, newNormal->normal, normals[ i ] );
				VectorNormalizeFast( normals[ i ] );
			}
		}

		for ( i = 0, indices = tess.indexes + tess.numIndexes; i < numIndexes; i += 3, indices += 3 )
		{
			v0 = tess.verts[ indices[ 0 ] ].xyz;
			v1 = tess.verts[ indices[ 1 ] ].xyz;
			v2 = tess.verts[ indices[ 2 ] ].xyz;

			t0 = tess.verts[ indices[ 0 ] ].texCoords;
			t1 = tess.verts[ indices[ 1 ] ].texCoords;
			t2 = tess.verts[ indices[ 2 ] ].texCoords;

			R_CalcTangents( tangent, binormal, v0, v1, v2, t0, t1, t2 );

			for ( j = 0; j < 3; j++ )
			{
				v = tangents[ indices[ j ] - tess.numVertexes ];
				VectorAdd( v, tangent, v );

				v = binormals[ indices[ j ] - tess.numVertexes ];
				VectorAdd( v, binormal, v );
			}
		}

		for ( i = 0; i < numVertexes; i++ )
		{
			R_TBNtoQtangents( tangents[ i ], binormals[ i ],
					  normals[ i ], tess.verts[ numVertexes + i ].qtangents );
		}

		ri.Hunk_FreeTempMemory( normals );
		ri.Hunk_FreeTempMemory( binormals );
		ri.Hunk_FreeTempMemory( tangents );
	}

	tess.numIndexes += numIndexes;
	tess.numVertexes += numVertexes;
}
Example #2
0
/*
==============
Tess_AddQuadStampExt2
==============
*/
void Tess_AddQuadStampExt2( vec4_t quadVerts[ 4 ], const vec4_t color, float s1, float t1, float s2, float t2 )
{
	int    i;
	vec3_t normal, tangent, binormal;
	int    ndx;

	GLimp_LogComment( "--- Tess_AddQuadStampExt2 ---\n" );

	Tess_CheckOverflow( 4, 6 );

	ndx = tess.numVertexes;

	// triangle indexes for a simple quad
	tess.indexes[ tess.numIndexes ] = ndx;
	tess.indexes[ tess.numIndexes + 1 ] = ndx + 1;
	tess.indexes[ tess.numIndexes + 2 ] = ndx + 3;

	tess.indexes[ tess.numIndexes + 3 ] = ndx + 3;
	tess.indexes[ tess.numIndexes + 4 ] = ndx + 1;
	tess.indexes[ tess.numIndexes + 5 ] = ndx + 2;

	VectorCopy( quadVerts[ 0 ], tess.verts[ ndx + 0 ].xyz );
	VectorCopy( quadVerts[ 1 ], tess.verts[ ndx + 1 ].xyz );
	VectorCopy( quadVerts[ 2 ], tess.verts[ ndx + 2 ].xyz );
	VectorCopy( quadVerts[ 3 ], tess.verts[ ndx + 3 ].xyz );

	tess.attribsSet |= ATTR_POSITION | ATTR_COLOR | ATTR_TEXCOORD | ATTR_QTANGENT;

	// constant normal all the way around
	vec2_t st[ 3 ] = { { s1, t1 }, { s2, t1 }, { s2, t2 } };
	R_CalcFaceNormal( normal, quadVerts[ 0 ], quadVerts[ 1 ], quadVerts[ 2 ] );
	R_CalcTangents( tangent, binormal,
			quadVerts[ 0 ], quadVerts[ 1 ], quadVerts[ 2 ],
			st[ 0 ], st[ 1 ], st[ 2 ] );
	//if ( !calcNormals )
	//{
	//	VectorNegate( backEnd.viewParms.orientation.axis[ 0 ], normal );
	//}

	R_TBNtoQtangents( tangent, binormal, normal, tess.verts[ ndx ].qtangents );
	Vector4Copy( tess.verts[ ndx ].qtangents, tess.verts[ ndx + 1 ].qtangents );
	Vector4Copy( tess.verts[ ndx ].qtangents, tess.verts[ ndx + 2 ].qtangents );
	Vector4Copy( tess.verts[ ndx ].qtangents, tess.verts[ ndx + 3 ].qtangents );

	// standard square texture coordinates
	tess.verts[ ndx ].texCoords[ 0 ] = floatToHalf( s1 );
	tess.verts[ ndx ].texCoords[ 1 ] = floatToHalf( t1 );

	tess.verts[ ndx + 1 ].texCoords[ 0 ] = floatToHalf( s2 );
	tess.verts[ ndx + 1 ].texCoords[ 1 ] = floatToHalf( t1 );

	tess.verts[ ndx + 2 ].texCoords[ 0 ] = floatToHalf( s2 );
	tess.verts[ ndx + 2 ].texCoords[ 1 ] = floatToHalf( t2 );

	tess.verts[ ndx + 3 ].texCoords[ 0 ] = floatToHalf( s1 );
	tess.verts[ ndx + 3 ].texCoords[ 1 ] = floatToHalf( t2 );

	// constant color all the way around
	// should this be identity and let the shader specify from entity?

	u8vec4_t iColor;
	floatToUnorm8( color, iColor );
	for ( i = 0; i < 4; i++ )
	{
		Vector4Copy( iColor, tess.verts[ ndx + i ].color );
	}

	tess.numVertexes += 4;
	tess.numIndexes += 6;
}
Example #3
0
/*
=============
Tess_SurfacePolychain
=============
*/
static void Tess_SurfacePolychain( srfPoly_t *p )
{
	int i, j;
	int numVertexes;
	int numIndexes;

	GLimp_LogComment( "--- Tess_SurfacePolychain ---\n" );

	Tess_CheckOverflow( p->numVerts, 3 * ( p->numVerts - 2 ) );

	// fan triangles into the tess array
	numVertexes = 0;

	for ( i = 0; i < p->numVerts; i++ )
	{
		VectorCopy( p->verts[ i ].xyz, tess.verts[ tess.numVertexes + i ].xyz );

		tess.verts[ tess.numVertexes + i ].texCoords[ 0 ] = floatToHalf( p->verts[ i ].st[ 0 ] );
		tess.verts[ tess.numVertexes + i ].texCoords[ 1 ] = floatToHalf( p->verts[ i ].st[ 1 ] );

		Vector4Copy( p->verts[ i ].modulate, tess.verts[ tess.numVertexes + i ].color );

		numVertexes++;
	}

	// generate fan indexes into the tess array
	numIndexes = 0;

	for ( i = 0; i < p->numVerts - 2; i++ )
	{
		tess.indexes[ tess.numIndexes + i * 3 + 0 ] = tess.numVertexes;
		tess.indexes[ tess.numIndexes + i * 3 + 1 ] = tess.numVertexes + i + 1;
		tess.indexes[ tess.numIndexes + i * 3 + 2 ] = tess.numVertexes + i + 2;
		numIndexes += 3;
	}

	tess.attribsSet |= ATTR_POSITION | ATTR_TEXCOORD | ATTR_COLOR;

	// calc tangent spaces
	if ( tess.surfaceShader->interactLight && !tess.skipTangentSpaces )
	{
		int         i;
		float       *v;
		const float *v0, *v1, *v2;
		const int16_t *t0, *t1, *t2;
		vec3_t      tangent, *tangents;
		vec3_t      binormal, *binormals;
		vec3_t      normal, *normals;
		glIndex_t   *indices;

		tangents = (vec3_t *)ri.Hunk_AllocateTempMemory( numVertexes * sizeof( vec3_t ) );
		binormals = (vec3_t *)ri.Hunk_AllocateTempMemory( numVertexes * sizeof( vec3_t ) );
		normals = (vec3_t *)ri.Hunk_AllocateTempMemory( numVertexes * sizeof( vec3_t ) );

		for ( i = 0; i < numVertexes; i++ )
		{
			VectorClear( tangents[ i ] );
			VectorClear( binormals[ i ] );
			VectorClear( normals[ i ] );
		}

		for ( i = 0, indices = tess.indexes + tess.numIndexes; i < numIndexes; i += 3, indices += 3 )
		{
			v0 = tess.verts[ indices[ 0 ] ].xyz;
			v1 = tess.verts[ indices[ 1 ] ].xyz;
			v2 = tess.verts[ indices[ 2 ] ].xyz;

			t0 = tess.verts[ indices[ 0 ] ].texCoords;
			t1 = tess.verts[ indices[ 1 ] ].texCoords;
			t2 = tess.verts[ indices[ 2 ] ].texCoords;

			R_CalcFaceNormal( normal, v0, v1, v2 );
			R_CalcTangents( tangent, binormal, v0, v1, v2, t0, t1, t2 );

			for ( j = 0; j < 3; j++ )
			{
				v = tangents[ indices[ j ] - tess.numVertexes ];
				VectorAdd( v, tangent, v );
				v = binormals[ indices[ j ] - tess.numVertexes ];
				VectorAdd( v, binormal, v );
				v = normals[ indices[ j ] - tess.numVertexes ];
				VectorAdd( v, normal, v );
			}
		}

		for ( i = 0; i < numVertexes; i++ )
		{
			VectorNormalizeFast( normals[ i ] );
			R_TBNtoQtangents( tangents[ i ], binormals[ i ],
					  normals[ i ], tess.verts[ tess.numVertexes + i ].qtangents );
		}

		ri.Hunk_FreeTempMemory( normals );
		ri.Hunk_FreeTempMemory( binormals );
		ri.Hunk_FreeTempMemory( tangents );

		tess.attribsSet |= ATTR_QTANGENT;
	}

	tess.numIndexes += numIndexes;
	tess.numVertexes += numVertexes;
}
Example #4
0
/*
=================
MakeMeshNormals

Handles all the complicated wrapping and degenerate cases
=================
*/
static void MakeMeshNormals( int width, int height, srfVert_t ctrl[ MAX_GRID_SIZE ][ MAX_GRID_SIZE ] )
{
	int        i, j, k, dist;
	vec3_t     tangent, binormal, normal;
	vec3_t     sum, sumTangents, sumBinormals;
	int        count;
	vec3_t     base;
	vec3_t     delta;
	int        x, y;
	srfVert_t  *dv;
	vec3_t     around[ 8 ], temp;
	bool   good[ 8 ];
	vec2_t     st[8];
	bool   wrapWidth, wrapHeight;
	float      len;
	static int neighbors[ 8 ][ 2 ] =
	{
		{ 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 }, { -1, 1 }
	};

	wrapWidth = false;

	for ( i = 0; i < height; i++ )
	{
		VectorSubtract( ctrl[ i ][ 0 ].xyz, ctrl[ i ][ width - 1 ].xyz, delta );
		len = VectorLengthSquared( delta );

		if ( len > 1.0 )
		{
			break;
		}
	}

	if ( i == height )
	{
		wrapWidth = true;
	}

	wrapHeight = false;

	for ( i = 0; i < width; i++ )
	{
		VectorSubtract( ctrl[ 0 ][ i ].xyz, ctrl[ height - 1 ][ i ].xyz, delta );
		len = VectorLengthSquared( delta );

		if ( len > 1.0 )
		{
			break;
		}
	}

	if ( i == width )
	{
		wrapHeight = true;
	}

	for ( i = 0; i < width; i++ )
	{
		for ( j = 0; j < height; j++ )
		{
			count = 0;
			dv = &ctrl[ j ][ i ];
			VectorCopy( dv->xyz, base );

			for ( k = 0; k < 8; k++ )
			{
				VectorClear( around[ k ] );
				good[ k ] = false;

				for ( dist = 1; dist <= 3; dist++ )
				{
					x = i + neighbors[ k ][ 0 ] * dist;
					y = j + neighbors[ k ][ 1 ] * dist;

					if ( wrapWidth )
					{
						if ( x < 0 )
						{
							x = width - 1 + x;
						}
						else if ( x >= width )
						{
							x = 1 + x - width;
						}
					}

					if ( wrapHeight )
					{
						if ( y < 0 )
						{
							y = height - 1 + y;
						}
						else if ( y >= height )
						{
							y = 1 + y - height;
						}
					}

					if ( x < 0 || x >= width || y < 0 || y >= height )
					{
						break; // edge of patch
					}

					VectorSubtract( ctrl[ y ][ x ].xyz, base, temp );

					if ( VectorNormalize2( temp, temp ) == 0 )
					{
						continue; // degenerate edge, get more dist
					}
					else
					{
						good[ k ] = true;
						VectorCopy( temp, around[ k ] );
						Vector2Copy( ctrl[ y ][ x ].st, st[ k ] );
						break; // good edge
					}
				}
			}

			VectorClear( sum );
			VectorClear( sumTangents );
			VectorClear( sumBinormals );

			for ( k = 0; k < 8; k++ )
			{
				if ( !good[ k ] || !good[( k + 1 ) & 7 ] )
				{
					continue; // didn't get two points
				}

				CrossProduct( around[( k + 1 ) & 7 ], around[ k ], normal );

				if ( VectorNormalize2( normal, normal ) == 0 )
				{
					continue;
				}

				R_CalcTangents( tangent, binormal,
						vec3_origin, around[ k ], around[ ( k + 1 ) & 7 ],
						dv->st, st[ k ], st[ ( k + 1 ) & 7 ] );

				VectorAdd( normal, sum, sum );
				VectorAdd( tangent, sumTangents, sumTangents );
				VectorAdd( binormal, sumBinormals, sumBinormals );
				count++;
			}

			if ( count == 0 )
			{
				VectorSet( dv->normal, 0.0f, 0.0f, 1.0f );
			} else {
				VectorNormalize2( sum, dv->normal );
			}

			R_TBNtoQtangents( sumTangents, sumBinormals, dv->normal,
					  dv->qtangent );
		}
	}
}