Example #1
0
/*
=================
R_MergeSurfaceList

Only deals with vertexes and indexes, not silhouettes, planes, etc.
Does NOT perform a cleanup triangles, so there may be duplicated verts in the result.
=================
*/
srfTriangles_t	*R_MergeSurfaceList( const srfTriangles_t **surfaces, int numSurfaces ) {
	srfTriangles_t	*newTri;
	const srfTriangles_t	*tri;
	int				i, j;
	int				totalVerts;
	int				totalIndexes;

	totalVerts = 0;
	totalIndexes = 0;
	for ( i = 0 ; i < numSurfaces ; i++ ) {
		totalVerts += surfaces[i]->numVerts;
		totalIndexes += surfaces[i]->numIndices;
	}

	newTri = R_AllocStaticTriSurf();
	newTri->numVerts = totalVerts;
	newTri->numIndices = totalIndexes;
	R_AllocStaticTriSurfVerts( newTri, newTri->numVerts );
	R_AllocStaticTriSurfIndices( newTri, newTri->numIndices );

	totalVerts = 0;
	totalIndexes = 0;
	for ( i = 0 ; i < numSurfaces ; i++ ) {
		tri = surfaces[i];
		memcpy( newTri->verts + totalVerts, tri->verts, tri->numVerts * sizeof( *tri->verts ) );
		for ( j = 0 ; j < tri->numIndices ; j++ ) {
			newTri->indices[ totalIndexes + j ] = totalVerts + tri->indices[j];
		}
		totalVerts += tri->numVerts;
		totalIndexes += tri->numIndices;
	}

	return newTri;
}
Example #2
0
void GameLocal::LoadAllModel()
{
	StaticModel* dsmodel = new StaticModel;
	LoadMesh3DS("../Media/Dino.3ds", dsmodel);
	AddStaticModel(dsmodel);

	StaticModel* model = resourceSys->AddMesh("ninja.b3d");
	AddStaticModel(model);

	drawSurf_t* drawSur = R_AllocDrawSurf();
	drawSur->geo = R_AllocStaticTriSurf();
	srfTriangles_t* tri = drawSur->geo;
	tri->numVerts = KnightModel::numVertices;
	tri->numIndexes = KnightModel::numIndices;
	drawSur->view = _camera->GetViewProj();
	R_AllocStaticTriSurfVerts(tri, tri->numVerts);

	for (int i = 0; i < KnightModel::numVertices; i++)
	{
		memcpy(&(tri->verts[i].xyz), KnightModel::vertices[i].position, sizeof(float) * 3);
		memcpy(&(tri->verts[i].uv), KnightModel::vertices[i].uv, sizeof(float) * 3);
		memcpy(&(tri->verts[i].normal), KnightModel::vertices[i].normal, sizeof(float) * 3);
	}
	tri->indexes = new glIndex_t[KnightModel::numIndices];
	memcpy(tri->indexes, KnightModel::indices, tri->numIndexes*sizeof(glIndex_t));

	R_GenerateGeometryVbo(tri);
	renderSys->AddDrawSur(drawSur);
}
Example #3
0
/*
====================
idMD5Mesh::UpdateSurface
====================
*/
void idMD5Mesh::UpdateSurface( const struct renderEntity_s *ent, const idJointMat *entJoints,
								const idJointMat *entJointsInverted, modelSurface_t *surf ) {

	tr.pc.c_deformedSurfaces++;
	tr.pc.c_deformedVerts += deformInfo->numOutputVerts;
	tr.pc.c_deformedIndexes += deformInfo->numIndexes;

	surf->shader = shader;

	if ( surf->geometry != NULL ) {
		// if the number of verts and indexes are the same we can re-use the triangle surface
		if ( surf->geometry->numVerts == deformInfo->numOutputVerts && surf->geometry->numIndexes == deformInfo->numIndexes ) {
			R_FreeStaticTriSurfVertexCaches( surf->geometry );
		} else {
			R_FreeStaticTriSurf( surf->geometry );
			surf->geometry = R_AllocStaticTriSurf();
		}
	} else {
		surf->geometry = R_AllocStaticTriSurf();
	}

	srfTriangles_t * tri = surf->geometry;

	// note that some of the data is referenced, and should not be freed
	tri->referencedIndexes = true;
	tri->numIndexes = deformInfo->numIndexes;
	tri->indexes = deformInfo->indexes;
	tri->silIndexes = deformInfo->silIndexes;
	tri->numMirroredVerts = deformInfo->numMirroredVerts;
	tri->mirroredVerts = deformInfo->mirroredVerts;
	tri->numDupVerts = deformInfo->numDupVerts;
	tri->dupVerts = deformInfo->dupVerts;
	tri->numSilEdges = deformInfo->numSilEdges;
	tri->silEdges = deformInfo->silEdges;

	tri->indexCache = deformInfo->staticIndexCache;

	tri->numVerts = deformInfo->numOutputVerts;
	if ( r_useGPUSkinning.GetBool() ) {
		if ( tri->verts != NULL && tri->verts != deformInfo->verts ) {
			R_FreeStaticTriSurfVerts( tri );
		}
		tri->verts = deformInfo->verts;
		tri->ambientCache = deformInfo->staticAmbientCache;
		tri->shadowCache = deformInfo->staticShadowCache;
		tri->referencedVerts = true;
	} else {
		if ( tri->verts == NULL || tri->verts == deformInfo->verts ) {
			tri->verts = NULL;
			R_AllocStaticTriSurfVerts( tri, deformInfo->numOutputVerts );
			assert( tri->verts != NULL );	// quiet analyze warning
			memcpy( tri->verts, deformInfo->verts, deformInfo->numOutputVerts * sizeof( deformInfo->verts[0] ) );	// copy over the texture coordinates
		}
		TransformVertsAndTangents( tri->verts, deformInfo->numOutputVerts, deformInfo->verts, entJointsInverted );
		tri->referencedVerts = false;
	}
	tri->tangentsCalculated = true;

	CalculateBounds( entJoints, tri->bounds );
}
Example #4
0
/*
====================
idRenderModelLiquid::GenerateSurface
====================
*/
modelSurface_t idRenderModelLiquid::GenerateSurface( float lerp ) {
	srfTriangles_t	*tri;
	int				i, base;
	idDrawVert		*vert;
	modelSurface_t	surf;
	float			inv_lerp;

	inv_lerp = 1.0f - lerp;
	vert = verts.Ptr();
	for( i = 0; i < verts.Num(); i++, vert++ ) {
		vert->xyz.z = page1[ i ] * lerp + page2[ i ] * inv_lerp;
	}

	tr.pc.c_deformedSurfaces++;
	tr.pc.c_deformedVerts += deformInfo->numOutputVerts;
	tr.pc.c_deformedIndexes += deformInfo->numIndexes;

	tri = R_AllocStaticTriSurf();

	// note that some of the data is references, and should not be freed
	tri->deformedSurface = true;

	tri->numIndexes = deformInfo->numIndexes;
	tri->indexes = deformInfo->indexes;
	tri->silIndexes = deformInfo->silIndexes;
	tri->numMirroredVerts = deformInfo->numMirroredVerts;
	tri->mirroredVerts = deformInfo->mirroredVerts;
	tri->numDupVerts = deformInfo->numDupVerts;
	tri->dupVerts = deformInfo->dupVerts;
	tri->numSilEdges = deformInfo->numSilEdges;
	tri->silEdges = deformInfo->silEdges;
	tri->dominantTris = deformInfo->dominantTris;

	tri->numVerts = deformInfo->numOutputVerts;
	R_AllocStaticTriSurfVerts( tri, tri->numVerts );
	SIMDProcessor->Memcpy( tri->verts, verts.Ptr(), deformInfo->numSourceVerts * sizeof(tri->verts[0]) );

	// replicate the mirror seam vertexes
	base = deformInfo->numOutputVerts - deformInfo->numMirroredVerts;
	for ( i = 0 ; i < deformInfo->numMirroredVerts ; i++ ) {
		tri->verts[base + i] = tri->verts[deformInfo->mirroredVerts[i]];
	}

	R_BoundTriSurf( tri );

	// If a surface is going to be have a lighting interaction generated, it will also have to call
	// R_DeriveTangents() to get normals, tangents, and face planes.  If it only
	// needs shadows generated, it will only have to generate face planes.  If it only
	// has ambient drawing, or is culled, no additional work will be necessary
	if ( !r_useDeferredTangents.GetBool() ) {
		// set face planes, vertex normals, tangents
		R_DeriveTangents( tri );
	}

	surf.geometry	= tri;
	surf.shader		= shader;

	return surf;
}
Example #5
0
static int lgeo_newVert(lua_State* L)
{
	srfTriangles_s* obj = lgeo_to(L);
	int num = lua_tonumber(L, -2);
	obj->numVerts = num;
	R_AllocStaticTriSurfVerts(obj, num);
	return 1;
}
/*
=====================
R_PolytopeSurface

Generate vertexes and indexes for a polytope, and optionally returns the polygon windings.
The positive sides of the planes will be visible.
=====================
*/
srfTriangles_t *R_PolytopeSurface( int numPlanes, const idPlane *planes, idWinding **windings ) {
	int i, j;
	srfTriangles_t *tri;
	idFixedWinding planeWindings[MAX_POLYTOPE_PLANES];
	int numVerts, numIndexes;
	if( numPlanes > MAX_POLYTOPE_PLANES ) {
		common->Error( "R_PolytopeSurface: more than %d planes", MAX_POLYTOPE_PLANES );
	}
	numVerts = 0;
	numIndexes = 0;
	for( i = 0; i < numPlanes; i++ ) {
		const idPlane &plane = planes[i];
		idFixedWinding &w = planeWindings[i];
		w.BaseForPlane( plane );
		for( j = 0; j < numPlanes; j++ ) {
			const idPlane &plane2 = planes[j];
			if( j == i ) {
				continue;
			} else if( !w.ClipInPlace( -plane2, ON_EPSILON ) ) {
				break;
			}
		}
		if( w.GetNumPoints() <= 2 ) {
			continue;
		}
		numVerts += w.GetNumPoints();
		numIndexes += ( w.GetNumPoints() - 2 ) * 3;
	}
	// allocate the surface
	tri = R_AllocStaticTriSurf();
	R_AllocStaticTriSurfVerts( tri, numVerts );
	R_AllocStaticTriSurfIndexes( tri, numIndexes );
	// copy the data from the windings
	for( i = 0; i < numPlanes; i++ ) {
		idFixedWinding &w = planeWindings[i];
		if( !w.GetNumPoints() ) {
			continue;
		}
		for( j = 0 ; j < w.GetNumPoints() ; j++ ) {
			tri->verts[tri->numVerts + j ].Clear();
			tri->verts[tri->numVerts + j ].xyz = w[j].ToVec3();
		}
		for( j = 1 ; j < w.GetNumPoints() - 1 ; j++ ) {
			tri->indexes[ tri->numIndexes + 0 ] = tri->numVerts;
			tri->indexes[ tri->numIndexes + 1 ] = tri->numVerts + j;
			tri->indexes[ tri->numIndexes + 2 ] = tri->numVerts + j + 1;
			tri->numIndexes += 3;
		}
		tri->numVerts += w.GetNumPoints();
		// optionally save the winding
		if( windings ) {
			windings[i] = new idWinding( w.GetNumPoints() );
			*windings[i] = w;
		}
	}
	R_BoundTriSurf( tri );
	return tri;
}
Example #7
0
/*
================
CombineModelSurfaces

Frees the model and returns a new model with all triangles combined
into one surface
================
*/
static idRenderModel *CombineModelSurfaces( idRenderModel *model ) {
	int		totalVerts;
	int		totalIndexes;
	int		numIndexes;
	int		numVerts;
	int		i, j;

	totalVerts = 0;
	totalIndexes = 0;

	for ( i = 0 ; i < model->NumSurfaces() ; i++ ) {
		const modelSurface_t	*surf = model->Surface(i);

		totalVerts += surf->geometry->numVerts;
		totalIndexes += surf->geometry->numIndexes;
	}

	srfTriangles_t *newTri = R_AllocStaticTriSurf();
	R_AllocStaticTriSurfVerts( newTri, totalVerts );
	R_AllocStaticTriSurfIndexes( newTri, totalIndexes );

	newTri->numVerts = totalVerts;
	newTri->numIndexes = totalIndexes;

	newTri->bounds.Clear();

	idDrawVert *verts = newTri->verts;
	glIndex_t *indexes = newTri->indexes;
	numIndexes = 0;
	numVerts = 0;
	for ( i = 0 ; i < model->NumSurfaces() ; i++ ) {
		const modelSurface_t *surf = model->Surface(i);
		const srfTriangles_t *tri = surf->geometry;

		memcpy( verts + numVerts, tri->verts, tri->numVerts * sizeof( tri->verts[0] ) );
		for ( j = 0 ; j < tri->numIndexes ; j++ ) {
			indexes[numIndexes+j] = numVerts + tri->indexes[j];
		}
		newTri->bounds.AddBounds( tri->bounds );
		numIndexes += tri->numIndexes;
		numVerts += tri->numVerts;
	}

	modelSurface_t surf;

	surf.id = 0;
	surf.geometry = newTri;
	surf.shader = tr.defaultMaterial;

	idRenderModel *newModel = renderModelManager->AllocModel();
	newModel->AddSurface( surf );

	renderModelManager->FreeModel( model );

	return newModel;
}
Example #8
0
/*
====================
ShareMapTriVerts

Converts independent triangles to shared vertex triangles
====================
*/
srfTriangles_t	*ShareMapTriVerts( const mapTri_t *tris )
{
    const mapTri_t	*step;
    int			count;
    int			i, j;
    int			numVerts;
    int			numIndexes;
    srfTriangles_t	*uTri;

    // unique the vertexes
    count = CountTriList( tris );

    uTri = R_AllocStaticTriSurf();
    R_AllocStaticTriSurfVerts( uTri, count * 3 );
    R_AllocStaticTriSurfIndexes( uTri, count * 3 );

    numVerts = 0;
    numIndexes = 0;

    for ( step = tris ; step ; step = step->next )
    {
        for ( i = 0 ; i < 3 ; i++ )
        {
            const idDrawVert	*dv;

            dv = &step->v[i];

            // search for a match
            for ( j = 0 ; j < numVerts ; j++ )
            {
                if ( MatchVert( &uTri->verts[j], dv ) )
                {
                    break;
                }
            }
            if ( j == numVerts )
            {
                numVerts++;
                uTri->verts[j].xyz = dv->xyz;
                uTri->verts[j].normal = dv->normal;
                uTri->verts[j].st[0] = dv->st[0];
                uTri->verts[j].st[1] = dv->st[1];
            }

            uTri->indexes[numIndexes++] = j;
        }
    }

    uTri->numVerts = numVerts;
    uTri->numIndexes = numIndexes;

    return uTri;
}
/*
====================
idRenderModelLiquid::GenerateSurface
====================
*/
modelSurface_t idRenderModelLiquid::GenerateSurface( float lerp )
{
	srfTriangles_t*	tri;
	int				i, base;
	idDrawVert*		vert;
	modelSurface_t	surf;
	float			inv_lerp;
	
	inv_lerp = 1.0f - lerp;
	vert = verts.Ptr();
	for( i = 0; i < verts.Num(); i++, vert++ )
	{
		vert->xyz.z = page1[ i ] * lerp + page2[ i ] * inv_lerp;
	}
	
	tr.pc.c_deformedSurfaces++;
	tr.pc.c_deformedVerts += deformInfo->numOutputVerts;
	tr.pc.c_deformedIndexes += deformInfo->numIndexes;
	
	tri = R_AllocStaticTriSurf();
	
	// note that some of the data is references, and should not be freed
	tri->referencedIndexes = true;
	
	tri->numIndexes = deformInfo->numIndexes;
	tri->indexes = deformInfo->indexes;
	tri->silIndexes = deformInfo->silIndexes;
	tri->numMirroredVerts = deformInfo->numMirroredVerts;
	tri->mirroredVerts = deformInfo->mirroredVerts;
	tri->numDupVerts = deformInfo->numDupVerts;
	tri->dupVerts = deformInfo->dupVerts;
	tri->numSilEdges = deformInfo->numSilEdges;
	tri->silEdges = deformInfo->silEdges;
	
	tri->numVerts = deformInfo->numOutputVerts;
	R_AllocStaticTriSurfVerts( tri, tri->numVerts );
	SIMDProcessor->Memcpy( tri->verts, verts.Ptr(), deformInfo->numSourceVerts * sizeof( tri->verts[0] ) );
	
	// replicate the mirror seam vertexes
	base = deformInfo->numOutputVerts - deformInfo->numMirroredVerts;
	for( i = 0 ; i < deformInfo->numMirroredVerts ; i++ )
	{
		tri->verts[base + i] = tri->verts[deformInfo->mirroredVerts[i]];
	}
	
	R_BoundTriSurf( tri );
	
	surf.geometry	= tri;
	surf.shader		= shader;
	
	return surf;
}
Example #10
0
/*
========================
idRenderModelMD5::LoadBinaryModel
========================
*/
bool idRenderModelMD5::LoadBinaryModel( idFile* file, const ID_TIME_T sourceTimeStamp )
{

	if( !idRenderModelStatic::LoadBinaryModel( file, sourceTimeStamp ) )
	{
		return false;
	}
	
	unsigned int magic = 0;
	file->ReadBig( magic );
	if( magic != MD5B_MAGIC )
	{
		return false;
	}
	
	int tempNum;
	file->ReadBig( tempNum );
	joints.SetNum( tempNum );
	for( int i = 0; i < joints.Num(); i++ )
	{
		file->ReadString( joints[i].name );
		int offset;
		file->ReadBig( offset );
		if( offset >= 0 )
		{
			joints[i].parent = joints.Ptr() + offset;
		}
		else
		{
			joints[i].parent = NULL;
		}
	}
	
	file->ReadBig( tempNum );
	defaultPose.SetNum( tempNum );
	for( int i = 0; i < defaultPose.Num(); i++ )
	{
		file->ReadBig( defaultPose[i].q.x );
		file->ReadBig( defaultPose[i].q.y );
		file->ReadBig( defaultPose[i].q.z );
		file->ReadBig( defaultPose[i].q.w );
		file->ReadVec3( defaultPose[i].t );
	}
	
	file->ReadBig( tempNum );
	invertedDefaultPose.SetNum( tempNum );
	for( int i = 0; i < invertedDefaultPose.Num(); i++ )
	{
		file->ReadBigArray( invertedDefaultPose[ i ].ToFloatPtr(), JOINTMAT_TYPESIZE );
	}
	SIMD_INIT_LAST_JOINT( invertedDefaultPose.Ptr(), joints.Num() );
	
	file->ReadBig( tempNum );
	meshes.SetNum( tempNum );
	for( int i = 0; i < meshes.Num(); i++ )
	{
	
		idStr materialName;
		file->ReadString( materialName );
		if( materialName.IsEmpty() )
		{
			meshes[i].shader = NULL;
		}
		else
		{
			meshes[i].shader = declManager->FindMaterial( materialName );
		}
		
		file->ReadBig( meshes[i].numVerts );
		file->ReadBig( meshes[i].numTris );
		
		file->ReadBig( meshes[i].numMeshJoints );
		meshes[i].meshJoints = ( byte* ) Mem_Alloc( meshes[i].numMeshJoints * sizeof( meshes[i].meshJoints[0] ), TAG_MODEL );
		file->ReadBigArray( meshes[i].meshJoints, meshes[i].numMeshJoints );
		file->ReadBig( meshes[i].maxJointVertDist );
		
		meshes[i].deformInfo = ( deformInfo_t* )R_ClearedStaticAlloc( sizeof( deformInfo_t ) );
		deformInfo_t& deform = *meshes[i].deformInfo;
		
		file->ReadBig( deform.numSourceVerts );
		file->ReadBig( deform.numOutputVerts );
		file->ReadBig( deform.numIndexes );
		file->ReadBig( deform.numMirroredVerts );
		file->ReadBig( deform.numDupVerts );
		file->ReadBig( deform.numSilEdges );
		
		srfTriangles_t	tri;
		memset( &tri, 0, sizeof( srfTriangles_t ) );
		
		if( deform.numOutputVerts > 0 )
		{
			R_AllocStaticTriSurfVerts( &tri, deform.numOutputVerts );
			deform.verts = tri.verts;
			file->ReadBigArray( deform.verts, deform.numOutputVerts );
		}
		
		if( deform.numIndexes > 0 )
		{
			R_AllocStaticTriSurfIndexes( &tri, deform.numIndexes );
			R_AllocStaticTriSurfSilIndexes( &tri, deform.numIndexes );
			deform.indexes = tri.indexes;
			deform.silIndexes = tri.silIndexes;
			file->ReadBigArray( deform.indexes, deform.numIndexes );
			file->ReadBigArray( deform.silIndexes, deform.numIndexes );
		}
		
		if( deform.numMirroredVerts > 0 )
		{
			R_AllocStaticTriSurfMirroredVerts( &tri, deform.numMirroredVerts );
			deform.mirroredVerts = tri.mirroredVerts;
			file->ReadBigArray( deform.mirroredVerts, deform.numMirroredVerts );
		}
		
		if( deform.numDupVerts > 0 )
		{
			R_AllocStaticTriSurfDupVerts( &tri, deform.numDupVerts );
			deform.dupVerts = tri.dupVerts;
			file->ReadBigArray( deform.dupVerts, deform.numDupVerts * 2 );
		}
		
		if( deform.numSilEdges > 0 )
		{
			R_AllocStaticTriSurfSilEdges( &tri, deform.numSilEdges );
			deform.silEdges = tri.silEdges;
			assert( deform.silEdges != NULL );
			for( int j = 0; j < deform.numSilEdges; j++ )
			{
				file->ReadBig( deform.silEdges[j].p1 );
				file->ReadBig( deform.silEdges[j].p2 );
				file->ReadBig( deform.silEdges[j].v1 );
				file->ReadBig( deform.silEdges[j].v2 );
			}
		}
		
		idShadowVertSkinned* shadowVerts = ( idShadowVertSkinned* ) Mem_Alloc( ALIGN( deform.numOutputVerts * 2 * sizeof( idShadowVertSkinned ), 16 ), TAG_MODEL );
		idShadowVertSkinned::CreateShadowCache( shadowVerts, deform.verts, deform.numOutputVerts );
		
		deform.staticAmbientCache = vertexCache.AllocStaticVertex( deform.verts, ALIGN( deform.numOutputVerts * sizeof( idDrawVert ), VERTEX_CACHE_ALIGN ) );
		deform.staticIndexCache = vertexCache.AllocStaticIndex( deform.indexes, ALIGN( deform.numIndexes * sizeof( triIndex_t ), INDEX_CACHE_ALIGN ) );
		deform.staticShadowCache = vertexCache.AllocStaticVertex( shadowVerts, ALIGN( deform.numOutputVerts * 2 * sizeof( idShadowVertSkinned ), VERTEX_CACHE_ALIGN ) );
		
		Mem_Free( shadowVerts );
		
		file->ReadBig( meshes[i].surfaceNum );
	}
	
	return true;
}
Example #11
0
/*
===============
idRenderModelSprite::InstantiateDynamicModel
===============
*/
idRenderModel *	idRenderModelSprite::InstantiateDynamicModel( const struct renderEntity_s *renderEntity, const struct viewDef_s *viewDef, idRenderModel *cachedModel ) {
	idRenderModelStatic *staticModel;
	srfTriangles_t *tri;
	modelSurface_t surf;

	if ( cachedModel && !r_useCachedDynamicModels.GetBool() ) {
		delete cachedModel;
		cachedModel = NULL;
	}

	if ( renderEntity == NULL || viewDef == NULL ) {
		delete cachedModel;
		return NULL;
	}

	if ( cachedModel != NULL ) {

		assert( dynamic_cast<idRenderModelStatic *>( cachedModel ) != NULL );
		assert( idStr::Icmp( cachedModel->Name(), sprite_SnapshotName ) == 0 );

		staticModel = static_cast<idRenderModelStatic *>( cachedModel );
		surf = *staticModel->Surface( 0 );
		tri = surf.geometry;

	} else {

		staticModel = new idRenderModelStatic;
		staticModel->InitEmpty( sprite_SnapshotName );

		tri = R_AllocStaticTriSurf();
		R_AllocStaticTriSurfVerts( tri, 4 );
		R_AllocStaticTriSurfIndexes( tri, 6 );

		tri->verts[ 0 ].Clear();
		tri->verts[ 0 ].normal.Set( 1.0f, 0.0f, 0.0f );
		tri->verts[ 0 ].tangents[0].Set( 0.0f, 1.0f, 0.0f );
		tri->verts[ 0 ].tangents[1].Set( 0.0f, 0.0f, 1.0f );
		tri->verts[ 0 ].st[ 0 ] = 0.0f;
		tri->verts[ 0 ].st[ 1 ] = 0.0f;

		tri->verts[ 1 ].Clear();
		tri->verts[ 1 ].normal.Set( 1.0f, 0.0f, 0.0f );
		tri->verts[ 1 ].tangents[0].Set( 0.0f, 1.0f, 0.0f );
		tri->verts[ 1 ].tangents[1].Set( 0.0f, 0.0f, 1.0f );
		tri->verts[ 1 ].st[ 0 ] = 1.0f;
		tri->verts[ 1 ].st[ 1 ] = 0.0f;

		tri->verts[ 2 ].Clear();
		tri->verts[ 2 ].normal.Set( 1.0f, 0.0f, 0.0f );
		tri->verts[ 2 ].tangents[0].Set( 0.0f, 1.0f, 0.0f );
		tri->verts[ 2 ].tangents[1].Set( 0.0f, 0.0f, 1.0f );
		tri->verts[ 2 ].st[ 0 ] = 1.0f;
		tri->verts[ 2 ].st[ 1 ] = 1.0f;

		tri->verts[ 3 ].Clear();
		tri->verts[ 3 ].normal.Set( 1.0f, 0.0f, 0.0f );
		tri->verts[ 3 ].tangents[0].Set( 0.0f, 1.0f, 0.0f );
		tri->verts[ 3 ].tangents[1].Set( 0.0f, 0.0f, 1.0f );
		tri->verts[ 3 ].st[ 0 ] = 0.0f;
		tri->verts[ 3 ].st[ 1 ] = 1.0f;

		tri->indexes[ 0 ] = 0;
		tri->indexes[ 1 ] = 1;
		tri->indexes[ 2 ] = 3;
		tri->indexes[ 3 ] = 1;
		tri->indexes[ 4 ] = 2;
		tri->indexes[ 5 ] = 3;

		tri->numVerts = 4;
		tri->numIndexes = 6;

		surf.geometry = tri;
		surf.id = 0;
		surf.shader = tr.defaultMaterial;
		staticModel->AddSurface( surf );
	}

	int	red			= idMath::FtoiFast( renderEntity->shaderParms[ SHADERPARM_RED ] * 255.0f );
	int green		= idMath::FtoiFast( renderEntity->shaderParms[ SHADERPARM_GREEN ] * 255.0f );
	int	blue		= idMath::FtoiFast( renderEntity->shaderParms[ SHADERPARM_BLUE ] * 255.0f );
	int	alpha		= idMath::FtoiFast( renderEntity->shaderParms[ SHADERPARM_ALPHA ] * 255.0f );

	idVec3 right	= idVec3( 0.0f, renderEntity->shaderParms[ SHADERPARM_SPRITE_WIDTH ] * 0.5f, 0.0f );
	idVec3 up		= idVec3( 0.0f, 0.0f, renderEntity->shaderParms[ SHADERPARM_SPRITE_HEIGHT ] * 0.5f );

	tri->verts[ 0 ].xyz = up + right;
	tri->verts[ 0 ].color[ 0 ] = red;
	tri->verts[ 0 ].color[ 1 ] = green;
	tri->verts[ 0 ].color[ 2 ] = blue;
	tri->verts[ 0 ].color[ 3 ] = alpha;

	tri->verts[ 1 ].xyz = up - right;
	tri->verts[ 1 ].color[ 0 ] = red;
	tri->verts[ 1 ].color[ 1 ] = green;
	tri->verts[ 1 ].color[ 2 ] = blue;
	tri->verts[ 1 ].color[ 3 ] = alpha;

	tri->verts[ 2 ].xyz = - right - up;
	tri->verts[ 2 ].color[ 0 ] = red;
	tri->verts[ 2 ].color[ 1 ] = green;
	tri->verts[ 2 ].color[ 2 ] = blue;
	tri->verts[ 2 ].color[ 3 ] = alpha;

	tri->verts[ 3 ].xyz = right - up;
	tri->verts[ 3 ].color[ 0 ] = red;
	tri->verts[ 3 ].color[ 1 ] = green;
	tri->verts[ 3 ].color[ 2 ] = blue;
	tri->verts[ 3 ].color[ 3 ] = alpha;

	R_BoundTriSurf( tri );

	staticModel->bounds = tri->bounds;

	return staticModel;
}
Example #12
0
/*
================
idRenderWorldLocal::ParseModel
================
*/
idRenderModel *idRenderWorldLocal::ParseModel( idLexer *src ) {
	idRenderModel	*model;
	idToken			token;
	int				i, j;
	srfTriangles_t	*tri;
	modelSurface_t	surf;

	src->ExpectTokenString( "{" );

	// parse the name
	src->ExpectAnyToken( &token );

	model = renderModelManager->AllocModel();
	model->InitEmpty( token );

	int numSurfaces = src->ParseInt();
	if ( numSurfaces < 0 ) {
		src->Error( "R_ParseModel: bad numSurfaces" );
	}

	for ( i = 0 ; i < numSurfaces ; i++ ) {
		src->ExpectTokenString( "{" );

		src->ExpectAnyToken( &token );

		surf.shader = declManager->FindMaterial( token );

		((idMaterial*)surf.shader)->AddReference();

		tri = R_AllocStaticTriSurf();
		surf.geometry = tri;

		tri->numVerts = src->ParseInt();
		tri->numIndexes = src->ParseInt();

		R_AllocStaticTriSurfVerts( tri, tri->numVerts );
		for ( j = 0 ; j < tri->numVerts ; j++ ) {
			float	vec[8];

			src->Parse1DMatrix( 8, vec );

			tri->verts[j].xyz[0] = vec[0];
			tri->verts[j].xyz[1] = vec[1];
			tri->verts[j].xyz[2] = vec[2];
			tri->verts[j].st[0] = vec[3];
			tri->verts[j].st[1] = vec[4];
			tri->verts[j].normal[0] = vec[5];
			tri->verts[j].normal[1] = vec[6];
			tri->verts[j].normal[2] = vec[7];
		}

		R_AllocStaticTriSurfIndexes( tri, tri->numIndexes );
		for ( j = 0 ; j < tri->numIndexes ; j++ ) {
			tri->indexes[j] = src->ParseInt();
		}
		src->ExpectTokenString( "}" );

		// add the completed surface to the model
		model->AddSurface( surf );
	}

	src->ExpectTokenString( "}" );

	model->FinishSurfaces();

	return model;
}
/*
====================
idRenderModelPrt::InstantiateDynamicModel
====================
*/
idRenderModel* idRenderModelPrt::InstantiateDynamicModel( const struct renderEntity_s* renderEntity, const viewDef_t* viewDef, idRenderModel* cachedModel )
{
	idRenderModelStatic*	staticModel;
	
	if( cachedModel && !r_useCachedDynamicModels.GetBool() )
	{
		delete cachedModel;
		cachedModel = NULL;
	}
	
	// this may be triggered by a model trace or other non-view related source, to which we should look like an empty model
	if( renderEntity == NULL || viewDef == NULL )
	{
		delete cachedModel;
		return NULL;
	}
	
	if( r_skipParticles.GetBool() )
	{
		delete cachedModel;
		return NULL;
	}
	
	/*
	// if the entire system has faded out
	if ( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] && viewDef->renderView.time * 0.001f >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] ) {
		delete cachedModel;
		return NULL;
	}
	*/
	
	if( cachedModel != NULL )
	{
	
		assert( dynamic_cast<idRenderModelStatic*>( cachedModel ) != NULL );
		assert( idStr::Icmp( cachedModel->Name(), parametricParticle_SnapshotName ) == 0 );
		
		staticModel = static_cast<idRenderModelStatic*>( cachedModel );
		
	}
	else
	{
	
		staticModel = new( TAG_MODEL ) idRenderModelStatic;
		staticModel->InitEmpty( parametricParticle_SnapshotName );
	}
	
	particleGen_t g;
	
	g.renderEnt = renderEntity;
	g.renderView = &viewDef->renderView;
	g.origin.Zero();
	g.axis.Identity();
	
	for( int stageNum = 0; stageNum < particleSystem->stages.Num(); stageNum++ )
	{
		idParticleStage* stage = particleSystem->stages[stageNum];
		
		if( !stage->material )
		{
			continue;
		}
		if( !stage->cycleMsec )
		{
			continue;
		}
		if( stage->hidden )  		// just for gui particle editor use
		{
			staticModel->DeleteSurfaceWithId( stageNum );
			continue;
		}
		
		idRandom steppingRandom, steppingRandom2;
		
		int stageAge = g.renderView->time[renderEntity->timeGroup] + renderEntity->shaderParms[SHADERPARM_TIMEOFFSET] * 1000 - stage->timeOffset * 1000;
		int	stageCycle = stageAge / stage->cycleMsec;
		
		// some particles will be in this cycle, some will be in the previous cycle
		steppingRandom.SetSeed( ( ( stageCycle << 10 ) & idRandom::MAX_RAND ) ^ ( int )( renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND ) );
		steppingRandom2.SetSeed( ( ( ( stageCycle - 1 ) << 10 ) & idRandom::MAX_RAND ) ^ ( int )( renderEntity->shaderParms[SHADERPARM_DIVERSITY] * idRandom::MAX_RAND ) );
		
		int	count = stage->totalParticles * stage->NumQuadsPerParticle();
		
		int surfaceNum;
		modelSurface_t* surf;
		
		if( staticModel->FindSurfaceWithId( stageNum, surfaceNum ) )
		{
			surf = &staticModel->surfaces[surfaceNum];
			R_FreeStaticTriSurfVertexCaches( surf->geometry );
		}
		else
		{
			surf = &staticModel->surfaces.Alloc();
			surf->id = stageNum;
			surf->shader = stage->material;
			surf->geometry = R_AllocStaticTriSurf();
			R_AllocStaticTriSurfVerts( surf->geometry, 4 * count );
			R_AllocStaticTriSurfIndexes( surf->geometry, 6 * count );
		}
		
		int numVerts = 0;
		idDrawVert* verts = surf->geometry->verts;
		
		for( int index = 0; index < stage->totalParticles; index++ )
		{
			g.index = index;
			
			// bump the random
			steppingRandom.RandomInt();
			steppingRandom2.RandomInt();
			
			// calculate local age for this index
			int	bunchOffset = stage->particleLife * 1000 * stage->spawnBunching * index / stage->totalParticles;
			
			int particleAge = stageAge - bunchOffset;
			int	particleCycle = particleAge / stage->cycleMsec;
			if( particleCycle < 0 )
			{
				// before the particleSystem spawned
				continue;
			}
			if( stage->cycles && particleCycle >= stage->cycles )
			{
				// cycled systems will only run cycle times
				continue;
			}
			
			if( particleCycle == stageCycle )
			{
				g.random = steppingRandom;
			}
			else
			{
				g.random = steppingRandom2;
			}
			
			int	inCycleTime = particleAge - particleCycle * stage->cycleMsec;
			
			if( renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] &&
					g.renderView->time[renderEntity->timeGroup] - inCycleTime >= renderEntity->shaderParms[SHADERPARM_PARTICLE_STOPTIME] * 1000 )
			{
				// don't fire any more particles
				continue;
			}
			
			// supress particles before or after the age clamp
			g.frac = ( float )inCycleTime / ( stage->particleLife * 1000 );
			if( g.frac < 0.0f )
			{
				// yet to be spawned
				continue;
			}
			if( g.frac > 1.0f )
			{
				// this particle is in the deadTime band
				continue;
			}
			
			// this is needed so aimed particles can calculate origins at different times
			g.originalRandom = g.random;
			
			g.age = g.frac * stage->particleLife;
			
			// if the particle doesn't get drawn because it is faded out or beyond a kill region, don't increment the verts
			numVerts += stage->CreateParticle( &g, verts + numVerts );
		}
		
		// numVerts must be a multiple of 4
		assert( ( numVerts & 3 ) == 0 && numVerts <= 4 * count );
		
		// build the indexes
		int	numIndexes = 0;
		triIndex_t* indexes = surf->geometry->indexes;
		for( int i = 0; i < numVerts; i += 4 )
		{
			indexes[numIndexes + 0] = i + 0;
			indexes[numIndexes + 1] = i + 2;
			indexes[numIndexes + 2] = i + 3;
			indexes[numIndexes + 3] = i + 0;
			indexes[numIndexes + 4] = i + 3;
			indexes[numIndexes + 5] = i + 1;
			numIndexes += 6;
		}
		
		surf->geometry->tangentsCalculated = false;
		surf->geometry->numVerts = numVerts;
		surf->geometry->numIndexes = numIndexes;
		surf->geometry->bounds = stage->bounds;		// just always draw the particles
	}
	
	return staticModel;
}
Example #14
0
bool MeshLoaderB3D::ReadVrts() {
	const int max_tex_coords = 3;
	int flags, tex_coord_sets, tex_coord_set_size;

	_file->ReadInt(flags);
	_file->ReadInt(tex_coord_sets);
	_file->ReadInt(tex_coord_set_size);

	if (tex_coord_sets >= max_tex_coords || tex_coord_set_size >= 4) // Something is wrong 
	{
		Sys_Printf("tex_coord_sets or tex_coord_set_size too big");
		return false;
	}

	//------ Allocate Memory, for speed -----------//

	int sizeOfVertex = 3;
	bool hasNormal = false;
	bool hasVertexColors = false;
	if (flags & 1) {
		hasNormal = true;
		sizeOfVertex += 3;
	}
	if (flags & 2) {
		sizeOfVertex += 4;
		hasVertexColors=true;
	}

	sizeOfVertex += tex_coord_sets*tex_coord_set_size;
	unsigned int size = _stack[_stackIndex-1] - _file->Tell();
	//106407 16800
	unsigned int numVertex = size / sizeof(float) ;
	numVertex /= sizeOfVertex;

	srfTriangles_t* tri = R_AllocStaticTriSurf();
	R_AllocStaticTriSurfVerts(tri, numVertex);
	tri->numVerts = numVertex;

	int idx = 0;
	while( CheckSize()) {
		float color[4]={1.0f, 1.0f, 1.0f, 1.0f};
		_file->ReadVec3(tri->verts[idx].xyz);

		if (flags & 1) {
			_file->ReadVec3(tri->verts[idx].normal);
		}
		if (flags & 2) {
			_file->ReadFloat(color[0]);
			_file->ReadFloat(color[1]);
			_file->ReadFloat(color[2]);
			_file->ReadFloat(color[3]);
		}
		float u, v;
		for (int i = 0; i < tex_coord_sets; ++i) {
			//for (int j = 0; j < tex_coord_set_size; ++j)
			{
				_file->ReadFloat(u);
				_file->ReadFloat(v);
				//v = 1 - v;
			}
		}

		tri->verts[idx].st = idVec2(u, v);
		idx++;
	}

	modelSurface_t modelSurf;
	modelSurf.id = _surfaces.Size();
	modelSurf.shader = declManager->FindMaterial("textures/ninja/ninja");
	modelSurf.geometry = tri;
	_surfaces.Append(modelSurf);

	return true;
}
Example #15
0
/*
====================
idMD5Mesh::UpdateSurface
====================
*/
void idMD5Mesh::UpdateSurface( const struct renderEntity_s *ent, const idJointMat *entJoints, modelSurface_t *surf ) {
	int i, base;
	srfTriangles_t *tri;

	tr.pc.c_deformedSurfaces++;
	tr.pc.c_deformedVerts += deformInfo->numOutputVerts;
	tr.pc.c_deformedIndexes += deformInfo->numIndexes;

	surf->shader = shader;

	if ( surf->geometry ) {
		// if the number of verts and indexes are the same we can re-use the triangle surface
		// the number of indexes must be the same to assure the correct amount of memory is allocated for the facePlanes
		if ( surf->geometry->numVerts == deformInfo->numOutputVerts && surf->geometry->numIndexes == deformInfo->numIndexes ) {
			R_FreeStaticTriSurfVertexCaches( surf->geometry );
		} else {
			R_FreeStaticTriSurf( surf->geometry );
			surf->geometry = R_AllocStaticTriSurf();
		}
	} else {
		surf->geometry = R_AllocStaticTriSurf();
	}

	tri = surf->geometry;

	// note that some of the data is references, and should not be freed
	tri->deformedSurface = true;
	tri->tangentsCalculated = false;
	tri->facePlanesCalculated = false;

	tri->numIndexes = deformInfo->numIndexes;
	tri->indexes = deformInfo->indexes;
	tri->silIndexes = deformInfo->silIndexes;
	tri->numMirroredVerts = deformInfo->numMirroredVerts;
	tri->mirroredVerts = deformInfo->mirroredVerts;
	tri->numDupVerts = deformInfo->numDupVerts;
	tri->dupVerts = deformInfo->dupVerts;
	tri->numSilEdges = deformInfo->numSilEdges;
	tri->silEdges = deformInfo->silEdges;
	tri->dominantTris = deformInfo->dominantTris;
	tri->numVerts = deformInfo->numOutputVerts;

	if ( tri->verts == NULL ) {
		R_AllocStaticTriSurfVerts( tri, tri->numVerts );
		for ( i = 0; i < deformInfo->numSourceVerts; i++ ) {
			tri->verts[i].Clear();
			tri->verts[i].st = texCoords[i];
		}
	}

	if ( ent->shaderParms[ SHADERPARM_MD5_SKINSCALE ] != 0.0f ) {
		TransformScaledVerts( tri->verts, entJoints, ent->shaderParms[ SHADERPARM_MD5_SKINSCALE ] );
	} else {
		TransformVerts( tri->verts, entJoints );
	}

	// replicate the mirror seam vertexes
	base = deformInfo->numOutputVerts - deformInfo->numMirroredVerts;
	for ( i = 0; i < deformInfo->numMirroredVerts; i++ ) {
		tri->verts[base + i] = tri->verts[deformInfo->mirroredVerts[i]];
	}

	R_BoundTriSurf( tri );

	// If a surface is going to be have a lighting interaction generated, it will also have to call
	// R_DeriveTangents() to get normals, tangents, and face planes.  If it only
	// needs shadows generated, it will only have to generate face planes.  If it only
	// has ambient drawing, or is culled, no additional work will be necessary
	if ( !r_useDeferredTangents.GetBool() ) {
		// set face planes, vertex normals, tangents
		R_DeriveTangents( tri );
	}
}
Example #16
0
/*
====================
idRenderModelOverlay::AddOverlaySurfacesToModel
====================
*/
void idRenderModelOverlay::AddOverlaySurfacesToModel( idRenderModel *baseModel ) {
	int i, j, k, numVerts, numIndexes, surfaceNum;
	const modelSurface_t *baseSurf;
	idRenderModelStatic *staticModel;
	overlaySurface_t *surf;
	srfTriangles_t *newTri;
	modelSurface_t *newSurf;

	if ( baseModel == NULL || baseModel->IsDefaultModel() ) {
		return;
	}

	// md5 models won't have any surfaces when r_showSkel is set
	if ( !baseModel->NumSurfaces() ) {
		return;
	}

	if ( baseModel->IsDynamicModel() != DM_STATIC ) {
		common->Error( "idRenderModelOverlay::AddOverlaySurfacesToModel: baseModel is not a static model" );
	}

	assert( dynamic_cast<idRenderModelStatic *>(baseModel) != NULL );
	staticModel = static_cast<idRenderModelStatic *>(baseModel);

	staticModel->overlaysAdded = 0;

	if ( !materials.Num() ) {
		staticModel->DeleteSurfacesWithNegativeId();
		return;
	}

	for ( k = 0; k < materials.Num(); k++ ) {

		numVerts = numIndexes = 0;
		for ( i = 0; i < materials[k]->surfaces.Num(); i++ ) {
			numVerts += materials[k]->surfaces[i]->numVerts;
			numIndexes += materials[k]->surfaces[i]->numIndexes;
		}

		if ( staticModel->FindSurfaceWithId( -1 - k, surfaceNum ) ) {
			newSurf = &staticModel->surfaces[surfaceNum];
		} else {
			newSurf = &staticModel->surfaces.Alloc();
			newSurf->geometry = NULL;
			newSurf->shader = materials[k]->material;
			newSurf->id = -1 - k;
		}

		if ( newSurf->geometry == NULL || newSurf->geometry->numVerts < numVerts || newSurf->geometry->numIndexes < numIndexes ) {
			R_FreeStaticTriSurf( newSurf->geometry );
			newSurf->geometry = R_AllocStaticTriSurf();
			R_AllocStaticTriSurfVerts( newSurf->geometry, numVerts );
			R_AllocStaticTriSurfIndexes( newSurf->geometry, numIndexes );
			SIMDProcessor->Memset( newSurf->geometry->verts, 0, numVerts * sizeof( newTri->verts[0] ) );
		} else {
			R_FreeStaticTriSurfVertexCaches( newSurf->geometry );
		}

		newTri = newSurf->geometry;
		numVerts = numIndexes = 0;

		for ( i = 0; i < materials[k]->surfaces.Num(); i++ ) {
			surf = materials[k]->surfaces[i];

			// get the model surface for this overlay surface
			if ( surf->surfaceNum < staticModel->NumSurfaces() ) {
				baseSurf = staticModel->Surface( surf->surfaceNum );
			} else {
				baseSurf = NULL;
			}

			// if the surface ids no longer match
			if ( !baseSurf || baseSurf->id != surf->surfaceId ) {
				// find the surface with the correct id
				if ( staticModel->FindSurfaceWithId( surf->surfaceId, surf->surfaceNum ) ) {
					baseSurf = staticModel->Surface( surf->surfaceNum );
				} else {
					// the surface with this id no longer exists
					FreeSurface( surf );
					materials[k]->surfaces.RemoveIndex( i );
					i--;
					continue;
				}
			}

			// copy indexes;
			for ( j = 0; j < surf->numIndexes; j++ ) {
				newTri->indexes[numIndexes + j] = numVerts + surf->indexes[j];
			}
			numIndexes += surf->numIndexes;

			// copy vertices
			for ( j = 0; j < surf->numVerts; j++ ) {
				overlayVertex_t *overlayVert = &surf->verts[j];

				newTri->verts[numVerts].st[0] = overlayVert->st[0];
				newTri->verts[numVerts].st[1] = overlayVert->st[1];

				if ( overlayVert->vertexNum >= baseSurf->geometry->numVerts ) {
					// This can happen when playing a demofile and a model has been changed since it was recorded, so just issue a warning and go on.
					common->Warning( "idRenderModelOverlay::AddOverlaySurfacesToModel: overlay vertex out of range.  Model has probably changed since generating the overlay." );
					FreeSurface( surf );
					materials[k]->surfaces.RemoveIndex( i );
					staticModel->DeleteSurfaceWithId( newSurf->id );
					return;
				}
				newTri->verts[numVerts].xyz = baseSurf->geometry->verts[overlayVert->vertexNum].xyz;
				numVerts++;
			}
		}

		newTri->numVerts = numVerts;
		newTri->numIndexes = numIndexes;
		R_BoundTriSurf( newTri );

		staticModel->overlaysAdded++;	// so we don't create an overlay on an overlay surface
	}
}
Example #17
0
/*
=============
idRenderModelMD3::InstantiateDynamicModel
=============
*/
idRenderModel *idRenderModelMD3::InstantiateDynamicModel( const struct renderEntity_s *ent, const struct viewDef_s *view, idRenderModel *cachedModel ) {
    int				i, j;
    float			backlerp;
    int *			triangles;
    float *			texCoords;
    int				indexes;
    int				numVerts;
    md3Surface_t *	surface;
    int				frame, oldframe;
    idRenderModelStatic	*staticModel;

    if ( cachedModel ) {
        delete cachedModel;
        cachedModel = NULL;
    }

    staticModel = new idRenderModelStatic;
    staticModel->bounds.Clear();

    surface = (md3Surface_t *) ((byte *)md3 + md3->ofsSurfaces);

    // TODO: these need set by an entity
    frame = ent->shaderParms[SHADERPARM_MD3_FRAME];			// probably want to keep frames < 1000 or so
    oldframe = ent->shaderParms[SHADERPARM_MD3_LASTFRAME];
    backlerp = ent->shaderParms[SHADERPARM_MD3_BACKLERP];

    for( i = 0; i < md3->numSurfaces; i++ ) {

        srfTriangles_t *tri = R_AllocStaticTriSurf();
        R_AllocStaticTriSurfVerts( tri, surface->numVerts );
        R_AllocStaticTriSurfIndexes( tri, surface->numTriangles * 3 );
        tri->bounds.Clear();

        modelSurface_t	surf;

        surf.geometry = tri;

        md3Shader_t* shaders = (md3Shader_t *) ((byte *)surface + surface->ofsShaders);
        surf.shader = shaders->shader;

        LerpMeshVertexes( tri, surface, backlerp, frame, oldframe );

        triangles = (int *) ((byte *)surface + surface->ofsTriangles);
        indexes = surface->numTriangles * 3;
        for (j = 0 ; j < indexes ; j++) {
            tri->indexes[j] = triangles[j];
        }
        tri->numIndexes += indexes;

        texCoords = (float *) ((byte *)surface + surface->ofsSt);

        numVerts = surface->numVerts;
        for ( j = 0; j < numVerts; j++ ) {
            idDrawVert *stri = &tri->verts[j];
            stri->st[0] = texCoords[j*2+0];
            stri->st[1] = texCoords[j*2+1];
        }

        R_BoundTriSurf( tri );

        staticModel->AddSurface( surf );
        staticModel->bounds.AddPoint( surf.geometry->bounds[0] );
        staticModel->bounds.AddPoint( surf.geometry->bounds[1] );

        // find the next surface
        surface = (md3Surface_t *)( (byte *)surface + surface->ofsEnd );
    }

    return staticModel;
}
/*
===============
idRenderModelBeam::InstantiateDynamicModel
===============
*/
idRenderModel *idRenderModelBeam::InstantiateDynamicModel(const struct renderEntity_s *renderEntity, const struct viewDef_s *viewDef, idRenderModel *cachedModel)
{
	idRenderModelStatic *staticModel;
	srfTriangles_t *tri;
	modelSurface_t surf;

	if (cachedModel) {
		delete cachedModel;
		cachedModel = NULL;
	}

	if (renderEntity == NULL || viewDef == NULL) {
		delete cachedModel;
		return NULL;
	}

	if (cachedModel != NULL) {

		assert(dynamic_cast<idRenderModelStatic *>(cachedModel) != NULL);
		assert(idStr::Icmp(cachedModel->Name(), beam_SnapshotName) == 0);

		staticModel = static_cast<idRenderModelStatic *>(cachedModel);
		surf = *staticModel->Surface(0);
		tri = surf.geometry;

	} else {

		staticModel = new idRenderModelStatic;
		staticModel->InitEmpty(beam_SnapshotName);

		tri = R_AllocStaticTriSurf();
		R_AllocStaticTriSurfVerts(tri, 4);
		R_AllocStaticTriSurfIndexes(tri, 6);

		tri->verts[0].Clear();
		tri->verts[0].st[0] = 0;
		tri->verts[0].st[1] = 0;

		tri->verts[1].Clear();
		tri->verts[1].st[0] = 0;
		tri->verts[1].st[1] = 1;

		tri->verts[2].Clear();
		tri->verts[2].st[0] = 1;
		tri->verts[2].st[1] = 0;

		tri->verts[3].Clear();
		tri->verts[3].st[0] = 1;
		tri->verts[3].st[1] = 1;

		tri->indexes[0] = 0;
		tri->indexes[1] = 2;
		tri->indexes[2] = 1;
		tri->indexes[3] = 2;
		tri->indexes[4] = 3;
		tri->indexes[5] = 1;

		tri->numVerts = 4;
		tri->numIndexes = 6;

		surf.geometry = tri;
		surf.id = 0;
		surf.shader = tr.defaultMaterial;
		staticModel->AddSurface(surf);
	}

	idVec3	target = *reinterpret_cast<const idVec3 *>(&renderEntity->shaderParms[SHADERPARM_BEAM_END_X]);

	// we need the view direction to project the minor axis of the tube
	// as the view changes
	idVec3	localView, localTarget;
	float	modelMatrix[16];
	R_AxisToModelMatrix(renderEntity->axis, renderEntity->origin, modelMatrix);
	R_GlobalPointToLocal(modelMatrix, viewDef->renderView.vieworg, localView);
	R_GlobalPointToLocal(modelMatrix, target, localTarget);

	idVec3	major = localTarget;
	idVec3	minor;

	idVec3	mid = 0.5f * localTarget;
	idVec3	dir = mid - localView;
	minor.Cross(major, dir);
	minor.Normalize();

	if (renderEntity->shaderParms[SHADERPARM_BEAM_WIDTH] != 0.0f) {
		minor *= renderEntity->shaderParms[SHADERPARM_BEAM_WIDTH] * 0.5f;
	}

	int red		= idMath::FtoiFast(renderEntity->shaderParms[SHADERPARM_RED] * 255.0f);
	int green	= idMath::FtoiFast(renderEntity->shaderParms[SHADERPARM_GREEN] * 255.0f);
	int blue	= idMath::FtoiFast(renderEntity->shaderParms[SHADERPARM_BLUE] * 255.0f);
	int alpha	= idMath::FtoiFast(renderEntity->shaderParms[SHADERPARM_ALPHA] * 255.0f);

	tri->verts[0].xyz = minor;
	tri->verts[0].color[0] = red;
	tri->verts[0].color[1] = green;
	tri->verts[0].color[2] = blue;
	tri->verts[0].color[3] = alpha;

	tri->verts[1].xyz = -minor;
	tri->verts[1].color[0] = red;
	tri->verts[1].color[1] = green;
	tri->verts[1].color[2] = blue;
	tri->verts[1].color[3] = alpha;

	tri->verts[2].xyz = localTarget + minor;
	tri->verts[2].color[0] = red;
	tri->verts[2].color[1] = green;
	tri->verts[2].color[2] = blue;
	tri->verts[2].color[3] = alpha;

	tri->verts[3].xyz = localTarget - minor;
	tri->verts[3].color[0] = red;
	tri->verts[3].color[1] = green;
	tri->verts[3].color[2] = blue;
	tri->verts[3].color[3] = alpha;

	R_BoundTriSurf(tri);

	staticModel->bounds = tri->bounds;

	return staticModel;
}
/*
================
idRenderWorldLocal::ParseModel
================
*/
idRenderModel* idRenderWorldLocal::ParseModel( idLexer* src, const char* mapName, ID_TIME_T mapTimeStamp, idFile* fileOut )
{
	idToken token;
	
	src->ExpectTokenString( "{" );
	
	// parse the name
	src->ExpectAnyToken( &token );
	
	idRenderModel* model = renderModelManager->AllocModel();
	model->InitEmpty( token );
	
	if( fileOut != NULL )
	{
		// write out the type so the binary reader knows what to instantiate
		fileOut->WriteString( "shadowmodel" );
		fileOut->WriteString( token );
	}
	
	int numSurfaces = src->ParseInt();
	if( numSurfaces < 0 )
	{
		src->Error( "R_ParseModel: bad numSurfaces" );
	}
	
	for( int i = 0; i < numSurfaces; i++ )
	{
		src->ExpectTokenString( "{" );
		
		src->ExpectAnyToken( &token );
		
		modelSurface_t surf;
		surf.shader = declManager->FindMaterial( token );
		
		( ( idMaterial* )surf.shader )->AddReference();
		
		srfTriangles_t* tri = R_AllocStaticTriSurf();
		surf.geometry = tri;
		
		tri->numVerts = src->ParseInt();
		tri->numIndexes = src->ParseInt();
		
		// parse the vertices
		idTempArray<float> verts( tri->numVerts * 8 );
		for( int j = 0; j < tri->numVerts; j++ )
		{
			src->Parse1DMatrix( 8, &verts[j * 8] );
		}
		
		// parse the indices
		idTempArray<triIndex_t> indexes( tri->numIndexes );
		for( int j = 0; j < tri->numIndexes; j++ )
		{
			indexes[j] = src->ParseInt();
		}
		
#if 1
		// find the island that each vertex belongs to
		idTempArray<int> vertIslands( tri->numVerts );
		idTempArray<bool> trisVisited( tri->numIndexes );
		vertIslands.Zero();
		trisVisited.Zero();
		int numIslands = 0;
		for( int j = 0; j < tri->numIndexes; j += 3 )
		{
			if( trisVisited[j] )
			{
				continue;
			}
			
			int islandNum = ++numIslands;
			vertIslands[indexes[j + 0]] = islandNum;
			vertIslands[indexes[j + 1]] = islandNum;
			vertIslands[indexes[j + 2]] = islandNum;
			trisVisited[j] = true;
			
			idList<int> queue;
			queue.Append( j );
			for( int n = 0; n < queue.Num(); n++ )
			{
				int t = queue[n];
				for( int k = 0; k < tri->numIndexes; k += 3 )
				{
					if( trisVisited[k] )
					{
						continue;
					}
					bool connected =	indexes[t + 0] == indexes[k + 0] || indexes[t + 0] == indexes[k + 1] || indexes[t + 0] == indexes[k + 2] ||
										indexes[t + 1] == indexes[k + 0] || indexes[t + 1] == indexes[k + 1] || indexes[t + 1] == indexes[k + 2] ||
										indexes[t + 2] == indexes[k + 0] || indexes[t + 2] == indexes[k + 1] || indexes[t + 2] == indexes[k + 2];
					if( connected )
					{
						vertIslands[indexes[k + 0]] = islandNum;
						vertIslands[indexes[k + 1]] = islandNum;
						vertIslands[indexes[k + 2]] = islandNum;
						trisVisited[k] = true;
						queue.Append( k );
					}
				}
			}
		}
		
		// center the texture coordinates for each island for maximum 16-bit precision
		for( int j = 1; j <= numIslands; j++ )
		{
			float minS = idMath::INFINITY;
			float minT = idMath::INFINITY;
			float maxS = -idMath::INFINITY;
			float maxT = -idMath::INFINITY;
			for( int k = 0; k < tri->numVerts; k++ )
			{
				if( vertIslands[k] == j )
				{
					minS = Min( minS, verts[k * 8 + 3] );
					maxS = Max( maxS, verts[k * 8 + 3] );
					minT = Min( minT, verts[k * 8 + 4] );
					maxT = Max( maxT, verts[k * 8 + 4] );
				}
			}
			const float averageS = idMath::Ftoi( ( minS + maxS ) * 0.5f );
			const float averageT = idMath::Ftoi( ( minT + maxT ) * 0.5f );
			for( int k = 0; k < tri->numVerts; k++ )
			{
				if( vertIslands[k] == j )
				{
					verts[k * 8 + 3] -= averageS;
					verts[k * 8 + 4] -= averageT;
				}
			}
		}
#endif
		
		R_AllocStaticTriSurfVerts( tri, tri->numVerts );
		for( int j = 0; j < tri->numVerts; j++ )
		{
			tri->verts[j].xyz[0] = verts[j * 8 + 0];
			tri->verts[j].xyz[1] = verts[j * 8 + 1];
			tri->verts[j].xyz[2] = verts[j * 8 + 2];
			tri->verts[j].SetTexCoord( verts[j * 8 + 3], verts[j * 8 + 4] );
			tri->verts[j].SetNormal( verts[j * 8 + 5], verts[j * 8 + 6], verts[j * 8 + 7] );
		}
		
		R_AllocStaticTriSurfIndexes( tri, tri->numIndexes );
		for( int j = 0; j < tri->numIndexes; j++ )
		{
			tri->indexes[j] = indexes[j];
		}
		src->ExpectTokenString( "}" );
		
		// add the completed surface to the model
		model->AddSurface( surf );
	}
	
	src->ExpectTokenString( "}" );
	
	model->FinishSurfaces();
	
	if( fileOut != NULL && model->SupportsBinaryModel() && r_binaryLoadRenderModels.GetBool() )
	{
		model->WriteBinaryModel( fileOut, &mapTimeStamp );
	}
	
	return model;
}
Example #20
0
bool MeshLoaderB3D::ReadVrts() {
	const int max_tex_coords = 3;
	int flags, tex_coord_sets, tex_coord_set_size;

	flags = _file->ReadInt();
	tex_coord_sets = _file->ReadInt();
	tex_coord_set_size = _file->ReadInt();

	if (tex_coord_sets >= max_tex_coords || tex_coord_set_size >= 4) // Something is wrong 
	{
		Sys_Printf("tex_coord_sets or tex_coord_set_size too big");
		return false;
	}

	//------ Allocate Memory, for speed -----------//

	int sizeOfVertex = 3;
	bool hasNormal = false;
	bool hasVertexColors = false;
	if (flags & 1) {
		hasNormal = true;
		sizeOfVertex += 3;
	}
	if (flags & 2) {
		sizeOfVertex += 4;
		hasVertexColors=true;
	}

	sizeOfVertex += tex_coord_sets*tex_coord_set_size;
	unsigned int size = _stack[_stack.size() - 1] - _file->Tell();
	//106407 16800
	unsigned int numVertex = size / sizeof(float) ;
	numVertex /= sizeOfVertex;

	srfTriangles_t* tri = _mesh->AllocGeo();
	tri->numVerts = numVertex;
	R_AllocStaticTriSurfVerts(tri, numVertex);

	int idx = 0;
	while( CheckSize()) {
		float color[4]={1.0f, 1.0f, 1.0f, 1.0f};
		tri->verts[idx].xyz = _file->ReadVec3();

		if (flags & 1) {
			tri->verts[idx].normal = _file->ReadVec3();
		}
		if (flags & 2) {
			color[0] = _file->ReadFloat();
			color[1] = _file->ReadFloat();
			color[2] = _file->ReadFloat();
			color[3] = _file->ReadFloat();
		}
		float u, v;
		for (int i = 0; i < tex_coord_sets; ++i) {
			//for (int j = 0; j < tex_coord_set_size; ++j)
			{
				u = _file->ReadFloat();
				v = 1.0f - _file->ReadFloat();
			}
		}

		tri->verts[idx].st = Vec2(u, v);
		idx++;
	}

	return true;
}