Esempio n. 1
0
/*
================
ParseSurface
================
*/
static void ParseSurface( const idMapPatch *patch, const idSurface *surface, const idMaterial *material ) {
	int				i;
	mapTri_t		*tri;
	primitive_t		*prim;

	prim = (primitive_t *)Mem_Alloc( sizeof( *prim ) );
	memset( prim, 0, sizeof( *prim ) );
	prim->next = uEntity->primitives;
	uEntity->primitives = prim;

	for ( i = 0; i < surface->GetNumIndexes(); i += 3 ) {
		tri = AllocTri();
		tri->v[2] = (*surface)[surface->GetIndexes()[i+0]];
		tri->v[1] = (*surface)[surface->GetIndexes()[i+2]];
		tri->v[0] = (*surface)[surface->GetIndexes()[i+1]];
		tri->material = material;
		tri->next = prim->tris;
		prim->tris = tri;
	}

	// set merge groups if needed, to prevent multiple sides from being
	// merged into a single surface in the case of gui shaders, mirrors, and autosprites
	if ( material->IsDiscrete() ) {
		for ( tri = prim->tris ; tri ; tri = tri->next ) {
			tri->mergeGroup = (void *)patch;
		}
	}
}
/*
====================
RegenerateTriangles

Add new triangles to the group's regeneratedTris
====================
*/
static	void	RegenerateTriangles( optIsland_t* island )
{
	optTri_t*		optTri;
	mapTri_t*		tri;
	int				c_out;
	
	c_out = 0;
	
	for( optTri = island->tris ; optTri ; optTri = optTri->next )
	{
		if( !optTri->filled )
		{
			continue;
		}
		
		// create a new mapTri_t
		tri = AllocTri();
		
		tri->material = island->group->material;
		tri->mergeGroup = island->group->mergeGroup;
		
		tri->v[0] = optTri->v[0]->v;
		tri->v[1] = optTri->v[1]->v;
		tri->v[2] = optTri->v[2]->v;
		
		idPlane plane;
		PlaneForTri( tri, plane );
		if( plane.Normal() * dmapGlobals.mapPlanes[ island->group->planeNum ].Normal() <= 0 )
		{
			// this can happen reasonably when a triangle is nearly degenerate in
			// optimization planar space, and winds up being degenerate in 3D space
			common->Printf( "WARNING: backwards triangle generated!\n" );
			// discard it
			FreeTri( tri );
			continue;
		}
		
		c_out++;
		tri->next = island->group->regeneratedTris;
		island->group->regeneratedTris = tri;
	}
	
	FreeOptTriangles( island );
	
	if( dmapGlobals.verbose )
	{
		common->Printf( "%6i tris out\n", c_out );
	}
}
Esempio n. 3
0
/*
================
WindingToTriList

Generates a new list of triangles with proper texcoords from a winding
created by clipping the originalTri

OriginalTri can be NULL if you don't care about texCoords
================
*/
mapTri_t *WindingToTriList( const idWinding *w, const mapTri_t *originalTri ) {
    mapTri_t	*tri;
    mapTri_t	*triList;
    int			i, j;
    const idVec3	*vec;

    if ( !w ) {
        return NULL;
    }

    triList = NULL;
    for ( i = 2 ; i < w->GetNumPoints() ; i++ ) {
        tri = AllocTri();
        if ( !originalTri ) {
            memset( tri, 0, sizeof( *tri ) );
        } else {
            *tri = *originalTri;
        }
        tri->next = triList;
        triList = tri;

        for ( j = 0 ; j < 3 ; j++ ) {
            if ( j == 0 ) {
                vec = &((*w)[0]).ToVec3();
            } else if ( j == 1 ) {
                vec = &((*w)[i-1]).ToVec3();
            } else {
                vec = &((*w)[i]).ToVec3();
            }

            VectorCopy( *vec, tri->v[j].xyz );
        }
        if ( originalTri ) {
            TriVertsFromOriginal( tri, originalTri );
        }
    }

    return triList;
}
mapTri_t *TriListForSide( const side_t *s, const idWinding *w ) {
	int				i, j;
	idDrawVert		*dv;
	mapTri_t		*tri, *triList;
	const idVec3		*vec;
	const idMaterial	*si;

	si = s->material;

	// skip any generated faces
	if ( !si ) {
		return NULL;
	}

	// don't create faces for non-visible sides
	if ( !si->SurfaceCastsShadow() && !si->IsDrawn() ) {
		return NULL;
	}

	if ( 1 ) {
		// triangle fan using only the outer verts
		// this gives the minimum triangle count,
		// but may have some very distended triangles
		triList = NULL;
		for ( i = 2 ; i < w->GetNumPoints() ; i++ ) {
			tri = AllocTri();
			tri->material = si;
			tri->next = triList;
			triList = tri;

			for ( j = 0 ; j < 3 ; j++ ) {
				if ( j == 0 ) {
					vec = &((*w)[0]).ToVec3();
				} else if ( j == 1 ) {
					vec = &((*w)[i-1]).ToVec3();
				} else {
					vec = &((*w)[i]).ToVec3();
				}

				dv = tri->v + j;
#if 0
				// round the xyz to a given precision
				for ( k = 0 ; k < 3 ; k++ ) {
					dv->xyz[k] = SNAP_INT_TO_FLOAT * floor( vec[k] * SNAP_FLOAT_TO_INT + 0.5 );
				}
#else
				VectorCopy( *vec, dv->xyz );
#endif

				// calculate texture s/t from brush primitive texture matrix
				dv->st[0] = DotProduct( dv->xyz, s->texVec.v[0] ) + s->texVec.v[0][3];
				dv->st[1] = DotProduct( dv->xyz, s->texVec.v[1] ) + s->texVec.v[1][3];

				// copy normal
				dv->normal = dmapGlobals.mapPlanes[s->planenum].Normal();
				if ( dv->normal.Length() < 0.9 || dv->normal.Length() > 1.1 ) {
					common->Error( "Bad normal in TriListForSide" );
				}
			}
		}
	} else {
		// triangle fan from central point, more verts and tris, but less distended
		// I use this when debugging some tjunction problems
		triList = NULL;
		for ( i = 0 ; i < w->GetNumPoints() ; i++ ) {
			idVec3	midPoint;

			tri = AllocTri();
			tri->material = si;
			tri->next = triList;
			triList = tri;

			for ( j = 0 ; j < 3 ; j++ ) {
				if ( j == 0 ) {
					vec = &midPoint;
					midPoint = w->GetCenter();
				} else if ( j == 1 ) {
					vec = &((*w)[i]).ToVec3();
				} else {
					vec = &((*w)[(i+1)%w->GetNumPoints()]).ToVec3();
				}

				dv = tri->v + j;

				VectorCopy( *vec, dv->xyz );

				// calculate texture s/t from brush primitive texture matrix
				dv->st[0] = DotProduct( dv->xyz, s->texVec.v[0] ) + s->texVec.v[0][3];
				dv->st[1] = DotProduct( dv->xyz, s->texVec.v[1] ) + s->texVec.v[1][3];

				// copy normal
				dv->normal = dmapGlobals.mapPlanes[s->planenum].Normal();
				if ( dv->normal.Length() < 0.9f || dv->normal.Length() > 1.1f ) {
					common->Error( "Bad normal in TriListForSide" );
				}
			}
		}
	}

	// set merge groups if needed, to prevent multiple sides from being
	// merged into a single surface in the case of gui shaders, mirrors, and autosprites
	if ( s->material->IsDiscrete() ) {
		for ( tri = triList ; tri ; tri = tri->next ) {
			tri->mergeGroup = (void *)s;
		}
	}

	return triList;
}