public override void MakeDefault() { if (this.Disposed == true) { throw new ObjectDisposedException(this.GetType().Name); } _defaulted = true; // throw out any surfaces we already have Purge(); // create one new surface RenderModelSurface surf = new RenderModelSurface(); surf.Material = idE.RenderSystem.DefaultMaterial; surf.Geometry = new Surface(); surf.Geometry.Vertices = new Vertex[24]; surf.Geometry.Indexes = new int[36]; AddCubeFace(surf.Geometry, 0, new Vector3(-1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, -1, 1), new Vector3(-1, -1, 1)); AddCubeFace(surf.Geometry, 1, new Vector3(-1, 1, -1), new Vector3(-1, -1, -1), new Vector3(1, -1, -1), new Vector3(-1, 1, -1)); AddCubeFace(surf.Geometry, 2, new Vector3(1, -1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, -1), new Vector3(1, -1, -1)); AddCubeFace(surf.Geometry, 3, new Vector3(-1, -1, 1), new Vector3(-1, -1, -1), new Vector3(-1, 1, -1), new Vector3(-1, 1, 1)); AddCubeFace(surf.Geometry, 4, new Vector3(-1, -1, 1), new Vector3(1, -1, 1), new Vector3(1, -1, -1), new Vector3(-1, -1, -1)); AddCubeFace(surf.Geometry, 5, new Vector3(-1, 1, 1), new Vector3(-1, 1, -1), new Vector3(1, 1, -1), new Vector3(1, 1, 1)); surf.Geometry.GenerateNormals = true; AddSurface(surf); FinishSurfaces(); }
public override void AddSurface(RenderModelSurface surface) { if (this.Disposed == true) { throw new ObjectDisposedException(this.GetType().Name); } _surfaces.Add(surface); if (surface.Geometry != null) { _bounds += surface.Geometry.Bounds; } }
/// <summary> /// Dynamic model instantiations will be created with this. /// </summary> /// <remarks> /// the geometry data will be owned by the model, and freed when it is freed /// the geoemtry should be raw triangles, with no extra processing /// </remarks> /// <param name="surface"></param> public abstract void AddSurface(RenderModelSurface surface);
/// <summary> /// /// </summary> /// <remarks> /// The mergeShadows option allows surfaces with different textures to share /// silhouette edges for shadow calculation, instead of leaving shared edges /// hanging. /// <para/> /// 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. /// <para/> /// If there is only one surface, a separate merged surface won't be generated. /// <para/> /// A model with multiple surfaces can't later have a skinned shader change the /// state of the noSelfShadow flag. /// <para/> /// ----------------- /// <para/> /// Creates mirrored copies of two sided surfaces with normal maps, which would /// otherwise light funny. /// <para/> /// Extends the bounds of deformed surfaces so they don't cull incorrectly at screen edges. /// </remarks> 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); } } }
public override void MakeDefault() { if(this.Disposed == true) { throw new ObjectDisposedException(this.GetType().Name); } _defaulted = true; // throw out any surfaces we already have Purge(); // create one new surface RenderModelSurface surf = new RenderModelSurface(); surf.Material = idE.RenderSystem.DefaultMaterial; surf.Geometry = new Surface(); surf.Geometry.Vertices = new Vertex[24]; surf.Geometry.Indexes = new int[36]; AddCubeFace(surf.Geometry, 0, new Vector3(-1, 1, 1), new Vector3(1, 1, 1), new Vector3(1, -1, 1), new Vector3(-1, -1, 1)); AddCubeFace(surf.Geometry, 1, new Vector3(-1, 1, -1), new Vector3(-1, -1, -1), new Vector3(1, -1, -1), new Vector3(-1, 1, -1)); AddCubeFace(surf.Geometry, 2, new Vector3(1, -1, 1), new Vector3(1, 1, 1), new Vector3(1, 1, -1), new Vector3(1, -1, -1)); AddCubeFace(surf.Geometry, 3, new Vector3(-1, -1, 1), new Vector3(-1, -1, -1), new Vector3(-1, 1, -1), new Vector3(-1, 1, 1)); AddCubeFace(surf.Geometry, 4, new Vector3(-1, -1, 1), new Vector3(1, -1, 1), new Vector3(1, -1, -1), new Vector3(-1, -1, -1)); AddCubeFace(surf.Geometry, 5, new Vector3(-1, 1, 1), new Vector3(-1, 1, -1), new Vector3(1, 1, -1), new Vector3(1, 1, 1)); surf.Geometry.GenerateNormals = true; AddSurface(surf); FinishSurfaces(); }
public override void AddSurface(RenderModelSurface surface) { if(this.Disposed == true) { throw new ObjectDisposedException(this.GetType().Name); } _surfaces.Add(surface); if(surface.Geometry != null) { _bounds += surface.Geometry.Bounds; } }
private idRenderModel ParseShadowModel(idLexer lexer) { lexer.ExpectTokenString("{"); // parse the name idToken token = lexer.ExpectAnyToken(); idRenderModel model = idE.RenderModelManager.AllocateModel(); model.InitEmpty(token.ToString()); RenderModelSurface modelSurface = new RenderModelSurface(); modelSurface.Material = idE.RenderSystem.DefaultMaterial; modelSurface.Geometry = new Surface(); modelSurface.Geometry.ShadowVertices = new ShadowVertex[lexer.ParseInt()]; modelSurface.Geometry.ShadowIndexesNoCapsCount = lexer.ParseInt(); modelSurface.Geometry.ShadowIndexesNoFrontCapsCount = lexer.ParseInt(); modelSurface.Geometry.Indexes = new int[lexer.ParseInt()]; modelSurface.Geometry.ShadowCapPlaneBits = lexer.ParseInt(); modelSurface.Geometry.Bounds.Clear(); int count = modelSurface.Geometry.ShadowVertices.Length; for(int j = 0; j < count; j++) { float[] vec = lexer.Parse1DMatrix(3); modelSurface.Geometry.ShadowVertices[j].Position = new Vector4(vec[0], vec[1], vec[2], 1); modelSurface.Geometry.Bounds.AddPoint(modelSurface.Geometry.ShadowVertices[j].Position); } count = modelSurface.Geometry.Indexes.Length; for(int j = 0; j < count; j++) { modelSurface.Geometry.Indexes[j] = lexer.ParseInt(); } // add the completed surface to the model model.AddSurface(modelSurface); lexer.ExpectTokenString("}"); // we do NOT do a model->FinishSurfaces, because we don't need sil edges, planes, tangents, etc. // model.FinishSurfaces(); return model; }
private idRenderModel ParseModel(idLexer lexer) { if(this.Disposed == true) { throw new ObjectDisposedException(this.GetType().Name); } RenderModelSurface modelSurface; lexer.ExpectTokenString("{"); // parse the name idToken token = lexer.ExpectAnyToken(); idRenderModel model = idE.RenderModelManager.AllocateModel(); model.InitEmpty(token.ToString()); int surfaceCount = lexer.ParseInt(); int loopCount = 0; if(surfaceCount < 0) { lexer.Error("ParseModel: bad surfaceCount"); } for(int i = 0; i < surfaceCount; i++) { lexer.ExpectTokenString("{"); token = lexer.ExpectAnyToken(); modelSurface = new RenderModelSurface(); modelSurface.Material = idE.DeclManager.FindMaterial(token.ToString()); modelSurface.Material.AddReference(); modelSurface.Geometry = new Surface(); modelSurface.Geometry.Vertices = new Vertex[lexer.ParseInt()]; modelSurface.Geometry.Indexes = new int[lexer.ParseInt()]; loopCount = modelSurface.Geometry.Vertices.Length; for(int j = 0; j < loopCount; j++) { float[] vec = lexer.Parse1DMatrix(8); modelSurface.Geometry.Vertices[j].Position = new Vector3(vec[0], vec[1], vec[2]); modelSurface.Geometry.Vertices[j].TextureCoordinates = new Vector2(vec[3], vec[4]); modelSurface.Geometry.Vertices[j].Normal = new Vector3(vec[5], vec[6], vec[7]); } loopCount = modelSurface.Geometry.Indexes.Length; for(int j = 0; j < loopCount; j++) { modelSurface.Geometry.Indexes[j] = lexer.ParseInt(); } lexer.ExpectTokenString("}"); // add the completed surface to the model model.AddSurface(modelSurface); } lexer.ExpectTokenString("}"); model.FinishSurfaces(); return model; }