idTech4.Renderer.idRenderModel_Static.FinishSurfaces C# (CSharp) Method

FinishSurfaces() public method

The mergeShadows option allows surfaces with different textures to share silhouette edges for shadow calculation, instead of leaving shared edges hanging. If any of the original shaders have the noSelfShadow flag set, the surfaces can't be merged, because they will need to be drawn in different order. If there is only one surface, a separate merged surface won't be generated. A model with multiple surfaces can't later have a skinned shader change the state of the noSelfShadow flag. ----------------- Creates mirrored copies of two sided surfaces with normal maps, which would otherwise light funny. Extends the bounds of deformed surfaces so they don't cull incorrectly at screen edges.
public FinishSurfaces ( ) : void
return void
		public override void FinishSurfaces()
		{
			if(this.Disposed == true)
			{
				throw new ObjectDisposedException(this.GetType().Name);
			}

			_purged = false;

			// make sure we don't have a huge bounds even if we don't finish everything
			_bounds = idBounds.Zero;

			if(_surfaces.Count == 0)
			{
				return;
			}
			
			// renderBump doesn't care about most of this
			if(_fastLoad == true)
			{
				_bounds = idBounds.Zero;

				foreach(RenderModelSurface surf in _surfaces)
				{
					idHelper.BoundTriangleSurface(surf.Geometry);
					_bounds.AddBounds(surf.Geometry.Bounds);
				}

				return;
			}

			// cleanup all the final surfaces, but don't create sil edges
			int totalVerts = 0;
			int totalIndexes = 0;

			// decide if we are going to merge all the surfaces into one shadower
			int	numOriginalSurfaces = _surfaces.Count;

			// make sure there aren't any NULL shaders or geometry
			for(int i = 0; i < numOriginalSurfaces; i++)
			{
				RenderModelSurface surf = _surfaces[i];

				if((surf.Geometry == null) || (surf.Material == null))
				{
					MakeDefault();
					idConsole.Error("Model {0}, surface {1} had NULL goemetry", this.Name, i);
				}

				if(surf.Material == null)
				{
					MakeDefault();
					idConsole.Error("Model {0}, surface {1} had NULL material", this.Name, i);
				}
			}

			// duplicate and reverse triangles for two sided bump mapped surfaces
			// note that this won't catch surfaces that have their shaders dynamically
			// changed, and won't work with animated models.
			// It is better to create completely separate surfaces, rather than
			// add vertexes and indexes to the existing surface, because the
			// tangent generation wouldn't like the acute shared edges
			for(int i = 0; i < numOriginalSurfaces; i++)
			{
				RenderModelSurface surf = _surfaces[i];
				
				if(surf.Material.ShouldCreateBackSides == true)
				{
					idConsole.Warning("TODO: should create back sides");

					/*srfTriangles_t *newTri;

					newTri = R_CopyStaticTriSurf( surf->geometry );
					R_ReverseTriangles( newTri );

					modelSurface_t	newSurf;

					newSurf.shader = surf->shader;
					newSurf.geometry = newTri;

					AddSurface( newSurf );*/
				}
			}

			// clean the surfaces
			// TODO: clean surfaces	
			/*for ( i = 0 ; i < surfaces.Num() ; i++ ) {
				const modelSurface_t	*surf = &surfaces[i];

				R_CleanupTriangles( surf->geometry, surf->geometry->generateNormals, true, surf->shader->UseUnsmoothedTangents() );
				if ( surf->shader->SurfaceCastsShadow() ) {
					totalVerts += surf->geometry->numVerts;
					totalIndexes += surf->geometry->numIndexes;
				}
			}*/

			// add up the total surface area for development information
			// TODO: surf dev info
			/*for ( i = 0 ; i < surfaces.Num() ; i++ ) {
				const modelSurface_t	*surf = &surfaces[i];
				srfTriangles_t	*tri = surf->geometry;

				for ( int j = 0 ; j < tri->numIndexes ; j += 3 ) {
					float	area = idWinding::TriangleArea( tri->verts[tri->indexes[j]].xyz,
						 tri->verts[tri->indexes[j+1]].xyz,  tri->verts[tri->indexes[j+2]].xyz );
					const_cast<idMaterial *>(surf->shader)->AddToSurfaceArea( area );
				}
			}*/

			// calculate the bounds
			int surfaceCount = _surfaces.Count;

			if(surfaceCount == 0)
			{
				_bounds = idBounds.Zero;
			}
			else
			{
				_bounds.Clear();

				for(int i = 0; i < surfaceCount; i++)
				{
					RenderModelSurface surf = _surfaces[i];

					// if the surface has a deformation, increase the bounds
					// the amount here is somewhat arbitrary, designed to handle
					// autosprites and flares, but could be done better with exact
					// deformation information.
					// Note that this doesn't handle deformations that are skinned in
					// at run time...
					if(surf.Material.Deform != DeformType.None)
					{
						idConsole.Warning("TODO: deform");

						/*srfTriangles_t	*tri = surf->geometry;
						idVec3	mid = ( tri->bounds[1] + tri->bounds[0] ) * 0.5f;
						float	radius = ( tri->bounds[0] - mid ).Length();
						radius += 20.0f;

						tri->bounds[0][0] = mid[0] - radius;
						tri->bounds[0][1] = mid[1] - radius;
						tri->bounds[0][2] = mid[2] - radius;

						tri->bounds[1][0] = mid[0] + radius;
						tri->bounds[1][1] = mid[1] + radius;
						tri->bounds[1][2] = mid[2] + radius;*/
					}

					// add to the model bounds
					_bounds.AddBounds(surf.Geometry.Bounds);
				}
			}
		}