protected void AddWhiteMat() { if (m_Model.m_Materials.ContainsKey("default_white")) return; ModelBase.MaterialDef mat = new ModelBase.MaterialDef("default_white", m_Model.m_Materials.Count); m_Model.m_Materials.Add("default_white", mat); }
protected void AddWhiteMat() { if (m_Model.m_Materials.ContainsKey("default_white")) { return; } ModelBase.MaterialDef mat = new ModelBase.MaterialDef("default_white", m_Model.m_Materials.Count); m_Model.m_Materials.Add("default_white", mat); }
public override ModelBase LoadModel(float scale) { ModelBase.BoneDef rootBone = new ModelBase.BoneDef("CollisionMap"); m_Model.m_BoneTree.AddRootBone(rootBone); rootBone.CalculateBranchTransformations(); m_Model.m_BoneTransformsMap.Add(rootBone.m_ID, m_Model.m_BoneTransformsMap.Count); ModelBase.GeometryDef geometry = new ModelBase.GeometryDef("geometry-0"); rootBone.m_Geometries.Add(geometry.m_ID, geometry); List <int> uniqueCollisionTypes = new List <int>(); foreach (KCL.ColFace plane in m_KCL.m_Planes) { if (!uniqueCollisionTypes.Contains(plane.type)) { uniqueCollisionTypes.Add(plane.type); } } uniqueCollisionTypes.Sort(); CollisionMapColours collisionMapColours = new CollisionMapColours(); foreach (int type in uniqueCollisionTypes) { ModelBase.MaterialDef material = new ModelBase.MaterialDef("material-" + type); material.m_Diffuse = collisionMapColours[type]; m_Model.m_Materials.Add(material.m_ID, material); rootBone.m_MaterialsInBranch.Add(material.m_ID); ModelBase.PolyListDef tmp = new ModelBase.PolyListDef("polylist-" + type, material.m_ID); tmp.m_FaceLists.Add(new ModelBase.FaceListDef(ModelBase.PolyListType.Triangles)); rootBone.m_Geometries[geometry.m_ID].m_PolyLists.Add("polylist-" + type, tmp); } foreach (KCL.ColFace plane in m_KCL.m_Planes) { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0].m_Position = plane.point1; face.m_Vertices[1].m_Position = plane.point2; face.m_Vertices[2].m_Position = plane.point3; for (int vert = 0; vert < face.m_Vertices.Length; vert++) { face.m_Vertices[vert].m_TextureCoordinate = null; face.m_Vertices[vert].m_Normal = null; face.m_Vertices[vert].m_VertexColour = Color.White; face.m_Vertices[vert].m_VertexBoneIndex = 0; } geometry.m_PolyLists["polylist-" + plane.type].m_FaceLists[0].m_Faces.Add(face); } return(m_Model); }
protected void AddTexture(ModelBase.TextureDefBase texture, ModelBase.MaterialDef matDef) { matDef.m_TextureDefID = texture.m_ID; IEnumerable <ModelBase.TextureDefBase> matchingHash = m_Model.m_Textures.Values.Where( tex0 => tex0.m_ImgHash.Equals(texture.m_ImgHash)); if (matchingHash.Count() > 0) { matDef.m_TextureDefID = matchingHash.ElementAt(0).m_ID; return; } m_Model.m_Textures.Add(texture.m_ID, texture); }
private void ReadMaterials() { if (this.library_materials == null || this.library_materials.material.Length == 0) { AddWhiteMat(); return; } foreach (material mat in this.library_materials.material) { string id = mat.id; string effectID = mat.instance_effect.url.Replace("#", ""); ModelBase.MaterialDef matDef = new ModelBase.MaterialDef(id, m_Model.m_Materials.Count); ReadMaterialEffect(matDef, effectID); m_Model.m_Materials.Add(id, matDef); } return; }
protected void ReadMaterials(XmlNode material_array) { if (material_array == null) { return; } int materialArray_size = int.Parse(material_array.Attributes["size"].Value); if (materialArray_size < 1) { return; } XmlNodeList materials = material_array.SelectNodes("material"); foreach (XmlNode material in materials) { string name = material.Attributes["name"].Value; int index = int.Parse(material.Attributes["index"].Value); bool[] lights = new bool[4]; for (int i = 0; i < 4; i++) { lights[i] = material.Attributes["light" + i].Value.Equals("on"); } string face = material.Attributes["face"].Value; ModelBase.MaterialDef.PolygonDrawingFace polygonDrawingFace; switch (face) { case "front": polygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Front; break; case "back": polygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Back; break; case "both": polygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.FrontAndBack; break; default: goto case "front"; } int alpha = int.Parse(material.Attributes["alpha"].Value); bool wire_mode = material.Attributes["wire_mode"].Value.Equals("on"); string polygon_mode = material.Attributes["polygon_mode"].Value; ModelBase.MaterialDef.PolygonMode polygonMode; switch (polygon_mode) { case "modulate": polygonMode = ModelBase.MaterialDef.PolygonMode.Modulation; break; case "decal": polygonMode = ModelBase.MaterialDef.PolygonMode.Decal; break; case "toon_highlight": polygonMode = ModelBase.MaterialDef.PolygonMode.Toon_HighlightShading; break; case "shadow": polygonMode = ModelBase.MaterialDef.PolygonMode.Shadow; break; default: goto case "modulate"; } int polygon_id = int.Parse(material.Attributes["polygon_id"].Value); bool fog_flag = material.Attributes["fog_flag"].Value.Equals("on"); bool depth_test_decal = material.Attributes["depth_test_decal"].Value.Equals("on"); bool translucent_update_depth = material.Attributes["translucent_update_depth"].Value.Equals("on"); bool render_1_pixel = material.Attributes["render_1_pixel"].Value.Equals("on"); bool far_clipping = material.Attributes["far_clipping"].Value.Equals("on"); byte[] diffuse = Array.ConvertAll <string, byte>( material.Attributes["diffuse"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToByte); byte[] ambient = Array.ConvertAll <string, byte>( material.Attributes["ambient"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToByte); byte[] specular = Array.ConvertAll <string, byte>( material.Attributes["specular"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToByte); byte[] emission = Array.ConvertAll <string, byte>( material.Attributes["emission"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToByte); bool shininess_table_flag = material.Attributes["shininess_table_flag"].Value.Equals("on"); int tex_image_idx = int.Parse(material.Attributes["tex_image_idx"].Value); int tex_palette_idx = int.Parse(material.Attributes["tex_palette_idx"].Value); ModelBase.MaterialDef.TexTiling[] tex_tiling = new ModelBase.MaterialDef.TexTiling[2]; string[] tmpsplit = (material.Attributes["tex_tiling"] != null) ? material.Attributes["tex_tiling"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries) : null; if (tex_image_idx >= 0) { for (int i = 0; i < 2; i++) { switch (tmpsplit[i]) { case "clamp": tex_tiling[i] = ModelBase.MaterialDef.TexTiling.Clamp; break; case "repeat": tex_tiling[i] = ModelBase.MaterialDef.TexTiling.Repeat; break; case "flip": tex_tiling[i] = ModelBase.MaterialDef.TexTiling.Flip; break; default: goto case "repeat"; } } } float[] tex_scale = (tex_image_idx >= 0) ? Array.ConvertAll( material.Attributes["tex_scale"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToSingle) : null; float tex_rotate = (tex_image_idx >= 0) ? float.Parse(material.Attributes["tex_rotate"].Value, Helper.USA) : 0f; float[] tex_translate = (tex_image_idx >= 0) ? Array.ConvertAll( material.Attributes["tex_translate"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToSingle) : null; string tex_gen_mode = (tex_image_idx >= 0) ? material.Attributes["tex_gen_mode"].Value : null; ModelBase.TexGenMode texGenMode; switch (tex_gen_mode) { case "none": texGenMode = ModelBase.TexGenMode.None; break; case null: goto case "none"; case "tex": texGenMode = ModelBase.TexGenMode.Tex; break; case "nrm": texGenMode = ModelBase.TexGenMode.Normal; break; case "pos": texGenMode = ModelBase.TexGenMode.Pos; break; default: goto case "none"; } string tex_gen_st_src = (material.Attributes["tex_gen_st_src"] != null) ? material.Attributes["tex_gen_st_src"].Value : null; string tex_effect_mtx = (material.Attributes["tex_effect_mtx"] != null) ? material.Attributes["tex_effect_mtx"].Value : null; ModelBase.MaterialDef matDef = new ModelBase.MaterialDef(name, index); matDef.m_TextureDefID = (tex_image_idx >= 0) ? m_Model.m_Textures.Values.ElementAt(tex_image_idx).m_ID : null; matDef.m_Lights = lights; matDef.m_PolygonDrawingFace = polygonDrawingFace; matDef.m_Alpha = (int)((alpha / 31f) * 255f); matDef.m_WireMode = wire_mode; matDef.m_PolygonMode = polygonMode; matDef.m_FogFlag = fog_flag; matDef.m_DepthTestDecal = depth_test_decal; matDef.m_RenderOnePixelPolygons = render_1_pixel; matDef.m_FarClipping = far_clipping; matDef.m_Diffuse = Color.FromArgb( (int)(diffuse[0] / 31f * 255f), (int)(diffuse[1] / 31f * 255f), (int)(diffuse[2] / 31f * 255f)); matDef.m_Ambient = Color.FromArgb( (int)(ambient[0] / 31f * 255f), (int)(ambient[1] / 31f * 255f), (int)(ambient[2] / 31f * 255f)); matDef.m_Specular = Color.FromArgb( (int)(specular[0] / 31f * 255f), (int)(specular[1] / 31f * 255f), (int)(specular[2] / 31f * 255f)); matDef.m_Emission = Color.FromArgb( (int)(emission[0] / 31f * 255f), (int)(emission[1] / 31f * 255f), (int)(emission[2] / 31f * 255f)); matDef.m_TexTiling = tex_tiling; matDef.m_TextureScale = (tex_scale != null) ? new Vector2(tex_scale[0], tex_scale[1]) : Vector2.One; matDef.m_TextureRotation = tex_rotate; matDef.m_TextureTranslation = (tex_translate != null) ? new Vector2(tex_translate[0], tex_translate[1]) : Vector2.Zero; matDef.m_TexGenMode = texGenMode; m_Model.m_Materials.Add(matDef.m_ID, matDef); } }
public override ModelBase LoadModel(OpenTK.Vector3 scale) { foreach (BMD.ModelChunk mdchunk in m_BMD.m_ModelChunks) { ModelBase.BoneDef bone = new ModelBase.BoneDef(mdchunk.m_Name); bone.SetScale(mdchunk.m_20_12Scale); bone.SetRotation(mdchunk.m_4_12Rotation); bone.SetTranslation(mdchunk.m_20_12Translation); if (mdchunk.m_ParentOffset == 0) { m_Model.m_BoneTree.AddRootBone(bone); } else { List <ModelBase.BoneDef> listOfBones = m_Model.m_BoneTree.GetAsList(); listOfBones[listOfBones.Count + mdchunk.m_ParentOffset].AddChild(bone); } ModelBase.GeometryDef geomDef = null; if (mdchunk.m_MatGroups.Length > 0) { geomDef = new ModelBase.GeometryDef("geometry-0"); bone.m_Geometries.Add(geomDef.m_ID, geomDef); } foreach (BMD.MaterialGroup matgroup in mdchunk.m_MatGroups) { if (!geomDef.m_PolyLists.ContainsKey(matgroup.m_Name)) { ModelBase.PolyListDef pld = new ModelBase.PolyListDef("polylist-" + matgroup.m_Name, matgroup.m_Name); geomDef.m_PolyLists.Add(pld.m_MaterialName, pld); } ModelBase.PolyListDef polyListDef = geomDef.m_PolyLists[matgroup.m_Name]; ModelBase.MaterialDef material = new ModelBase.MaterialDef(matgroup.m_Name, m_Model.m_Materials.Count); material.m_Diffuse = matgroup.m_DiffuseColor; material.m_Ambient = matgroup.m_AmbientColor; material.m_Specular = matgroup.m_SpecularColor; material.m_Emission = matgroup.m_EmissionColor; bool hasTextures = (matgroup.m_Texture != null); if (hasTextures) { if (!m_Model.m_Textures.ContainsKey(matgroup.m_Texture.m_TexName)) { ModelBase.TextureDefBase texture = new ModelBase.TextureDefInMemoryBitmap( matgroup.m_Texture.m_TexName, ConvertBMDTextureToBitmap(matgroup.m_Texture)); m_Model.m_Textures.Add(texture.m_ID, texture); } material.m_TextureDefID = matgroup.m_Texture.m_TexName; } material.m_Alpha = matgroup.m_Alpha; if ((matgroup.m_PolyAttribs & 0xC0) == 0xC0) { material.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.FrontAndBack; } else if ((matgroup.m_PolyAttribs & 0xC0) == 0x80) { material.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Front; } else if ((matgroup.m_PolyAttribs & 0xC0) == 0x40) { material.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Back; } if (!m_Model.m_Materials.ContainsKey(material.m_ID)) { m_Model.m_Materials.Add(material.m_ID, material); } bone.m_MaterialsInBranch.Add(matgroup.m_Name); ModelBase.BoneDef upToRoot = bone; while ((upToRoot = upToRoot.m_Parent) != null) { if (!upToRoot.m_MaterialsInBranch.Contains(matgroup.m_Name)) { upToRoot.m_MaterialsInBranch.Add(matgroup.m_Name); } } foreach (BMD.VertexList geometry in matgroup.m_Geometry) { uint polyType = geometry.m_PolyType; List <BMD.Vertex> vtxList = geometry.m_VertexList; switch (polyType) { case 0: //Separate Triangles { ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(ModelBase.PolyListType.Triangles); if (vtxList.Count <= 3) //Just 1 triangle { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[0].m_Position, vtxList[0].m_TexCoord, vtxList[0].m_Normal, vtxList[0].m_Color, (int)matgroup.m_BoneIDs[vtxList[0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[1].m_Position, vtxList[1].m_TexCoord, vtxList[1].m_Normal, vtxList[1].m_Color, (int)matgroup.m_BoneIDs[vtxList[1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[2].m_Position, vtxList[2].m_TexCoord, vtxList[2].m_Normal, vtxList[2].m_Color, (int)matgroup.m_BoneIDs[vtxList[2].m_MatrixID]); faceList.m_Faces.Add(face); } else if (vtxList.Count > 3 && (float)vtxList.Count % 3 == 0.0f) //Eg. 9 vertices in 3 triangles { int numFaces = vtxList.Count / 3; for (int a = 0, b = 0; a < numFaces; a++, b = b + 3) { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[b + 0].m_Position, vtxList[b + 0].m_TexCoord, vtxList[b + 0].m_Normal, vtxList[b + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[b + 1].m_Position, vtxList[b + 1].m_TexCoord, vtxList[b + 1].m_Normal, vtxList[b + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[b + 2].m_Position, vtxList[b + 2].m_TexCoord, vtxList[b + 2].m_Normal, vtxList[b + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 2].m_MatrixID]); faceList.m_Faces.Add(face); } } polyListDef.m_FaceLists.Add(faceList); break; } case 1: //Separate Quadrilaterals { ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(ModelBase.PolyListType.Polygons); if (vtxList.Count <= 4) //Just 1 quadrilateral { ModelBase.FaceDef face = new ModelBase.FaceDef(4); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[0].m_Position, vtxList[0].m_TexCoord, vtxList[0].m_Normal, vtxList[0].m_Color, (int)matgroup.m_BoneIDs[vtxList[0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[1].m_Position, vtxList[1].m_TexCoord, vtxList[1].m_Normal, vtxList[1].m_Color, (int)matgroup.m_BoneIDs[vtxList[1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[2].m_Position, vtxList[2].m_TexCoord, vtxList[2].m_Normal, vtxList[2].m_Color, (int)matgroup.m_BoneIDs[vtxList[2].m_MatrixID]); face.m_Vertices[3] = new ModelBase.VertexDef(vtxList[3].m_Position, vtxList[3].m_TexCoord, vtxList[3].m_Normal, vtxList[3].m_Color, (int)matgroup.m_BoneIDs[vtxList[3].m_MatrixID]); faceList.m_Faces.Add(face); } else if (vtxList.Count > 4 && (float)vtxList.Count % 4 == 0.0f) //Eg. 8 vertices in 2 quadrilaterals { int numFaces = vtxList.Count / 4; for (int a = 0, b = 0; a < numFaces; a++, b = b + 4) { ModelBase.FaceDef face = new ModelBase.FaceDef(4); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[b + 0].m_Position, vtxList[b + 0].m_TexCoord, vtxList[b + 0].m_Normal, vtxList[b + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[b + 1].m_Position, vtxList[b + 1].m_TexCoord, vtxList[b + 1].m_Normal, vtxList[b + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[b + 2].m_Position, vtxList[b + 2].m_TexCoord, vtxList[b + 2].m_Normal, vtxList[b + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 2].m_MatrixID]); face.m_Vertices[3] = new ModelBase.VertexDef(vtxList[b + 3].m_Position, vtxList[b + 3].m_TexCoord, vtxList[b + 3].m_Normal, vtxList[b + 3].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 3].m_MatrixID]); faceList.m_Faces.Add(face); } } polyListDef.m_FaceLists.Add(faceList); break; } case 2: //Triangle Strips { //3+(N-1) vertices per N triangles //(N-3)+1 Triangles per N Vertices int numFaces = vtxList.Count - 2; if (vtxList.Count < 3) //Should never be { break; } ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(ModelBase.PolyListType.TriangleStrip); //Convert all faces with more than 3 vertices to ones with only 3 for (int n = 0; n < numFaces; n++) { if (n % 2 == 0) { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[n + 0].m_Position, vtxList[n + 0].m_TexCoord, vtxList[n + 0].m_Normal, vtxList[n + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[n + 1].m_Position, vtxList[n + 1].m_TexCoord, vtxList[n + 1].m_Normal, vtxList[n + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[n + 2].m_Position, vtxList[n + 2].m_TexCoord, vtxList[n + 2].m_Normal, vtxList[n + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 2].m_MatrixID]); faceList.m_Faces.Add(face); } else { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[n + 2].m_Position, vtxList[n + 2].m_TexCoord, vtxList[n + 2].m_Normal, vtxList[n + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 2].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[n + 1].m_Position, vtxList[n + 1].m_TexCoord, vtxList[n + 2].m_Normal, vtxList[n + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[n + 0].m_Position, vtxList[n + 0].m_TexCoord, vtxList[n + 0].m_Normal, vtxList[n + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 0].m_MatrixID]); faceList.m_Faces.Add(face); } //Because of how normals are defined in triangle strips, every 2nd triangle is clockwise, whereas all others are anti-clockwise } polyListDef.m_FaceLists.Add(faceList); break; } case 3: //Quadrilateral Strips { //4+(N-1)*2 vertices per N quads //((N-4)/2) + 1 Quads. per N Vertices int numFaces = ((vtxList.Count - 4) / 2) + 1; if (vtxList.Count < 4) //Should never be { break; } ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(); for (int n = 0, p = 0; n < numFaces; n++, p = p + 2) { ModelBase.FaceDef face = new ModelBase.FaceDef(4); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[p + 0].m_Position, vtxList[p + 0].m_TexCoord, vtxList[p + 0].m_Normal, vtxList[p + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[p + 1].m_Position, vtxList[p + 1].m_TexCoord, vtxList[p + 1].m_Normal, vtxList[p + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[p + 3].m_Position, vtxList[p + 3].m_TexCoord, vtxList[p + 3].m_Normal, vtxList[p + 3].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 3].m_MatrixID]); face.m_Vertices[3] = new ModelBase.VertexDef(vtxList[p + 2].m_Position, vtxList[p + 2].m_TexCoord, vtxList[p + 2].m_Normal, vtxList[p + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 2].m_MatrixID]); faceList.m_Faces.Add(face); } polyListDef.m_FaceLists.Add(faceList); break; } default: MessageBox.Show("Unknown polygon type."); break; }//End polyType switch } } bone.CalculateBranchTransformations(); } m_Model.ApplyTransformations(); return(m_Model); }
private void LoadMaterials(string filename) { Stream fs; try { fs = File.OpenRead(filename); } catch { MessageBox.Show("Material library not found:\n\n" + filename + "\n\nA default white material will be used instead."); AddWhiteMat(); return; } StreamReader sr = new StreamReader(fs); string curmaterial = ""; string imagesNotFound = ""; string curline; while ((curline = sr.ReadLine()) != null) { curline = curline.Trim(); // skip empty lines and comments if (curline.Length < 1) { continue; } if (curline[0] == '#') { if (curline == "#Materials exported from Google Sketchup") { m_SketchupHack = true; } continue; } string[] parts = curline.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length < 1) { continue; } switch (parts[0]) { case "newmtl": // new material definition { if (parts.Length < 2) { continue; } curmaterial = parts[1]; ModelBase.MaterialDef mat = new ModelBase.MaterialDef(curmaterial); if (!m_Model.m_Materials.ContainsKey(curmaterial)) { m_Model.m_Materials.Add(curmaterial, mat); } } break; case "d": case "Tr": // opacity { if (parts.Length < 2) { continue; } float o = Helper.ParseFloat(parts[1]); if (m_SketchupHack) { o *= 31; } ModelBase.MaterialDef mat = (ModelBase.MaterialDef)m_Model.m_Materials[curmaterial]; mat.m_Alpha = (byte)(Math.Max(0, Math.Min(31, (int)(o * 31)))); } break; case "Kd": // diffuse colour { if (parts.Length < 4) { continue; } float r = Helper.ParseFloat(parts[1]); float g = Helper.ParseFloat(parts[2]); float b = Helper.ParseFloat(parts[3]); Color col = Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255)); ModelBase.MaterialDef mat = (ModelBase.MaterialDef)m_Model.m_Materials[curmaterial]; mat.m_Diffuse = col; } break; case "Ka": // ambient colour { if (parts.Length < 4) { continue; } float r = Helper.ParseFloat(parts[1]); float g = Helper.ParseFloat(parts[2]); float b = Helper.ParseFloat(parts[3]); Color col = Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255)); ModelBase.MaterialDef mat = (ModelBase.MaterialDef)m_Model.m_Materials[curmaterial]; mat.m_Ambient = col; } break; case "Ks": // specular colour { if (parts.Length < 4) { continue; } float r = Helper.ParseFloat(parts[1]); float g = Helper.ParseFloat(parts[2]); float b = Helper.ParseFloat(parts[3]); Color col = Color.FromArgb((int)(r * 255), (int)(g * 255), (int)(b * 255)); ModelBase.MaterialDef mat = (ModelBase.MaterialDef)m_Model.m_Materials[curmaterial]; mat.m_Specular = col; } break; case "map_Kd": case "mapKd": // diffuse map (texture) { string texname = curline.Substring(parts[0].Length + 1).Trim(); string fullPath = (File.Exists(texname)) ? texname : (m_ModelPath + Path.DirectorySeparatorChar + texname); ModelBase.TextureDefBase texture = new ModelBase.TextureDefExternalBitmap(texname, fullPath); AddTexture(texture, m_Model.m_Materials[curmaterial]); break; } case "PDF": { ModelBase.MaterialDef mat = (ModelBase.MaterialDef)m_Model.m_Materials[curmaterial]; switch (parts[1].ToLowerInvariant()) { case "front": mat.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Front; break; case "back": mat.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Back; break; case "both": mat.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.FrontAndBack; break; default: goto case "front"; } } break; } } if (!imagesNotFound.Equals("")) { MessageBox.Show("The following images were not found:\n\n" + imagesNotFound); } sr.Close(); }
public override ModelBase LoadModel(float scale) { foreach (BMD.ModelChunk mdchunk in m_BMD.m_ModelChunks) { ModelBase.BoneDef bone = new ModelBase.BoneDef(mdchunk.m_Name); bone.SetScale(mdchunk.m_20_12Scale); bone.SetRotation(mdchunk.m_4_12Rotation); bone.SetTranslation(mdchunk.m_20_12Translation); bone.m_Billboard = mdchunk.m_Billboard; if (mdchunk.m_ParentOffset == 0) { m_Model.m_BoneTree.AddRootBone(bone); } else { List <ModelBase.BoneDef> listOfBones = m_Model.m_BoneTree.GetAsList(); listOfBones[listOfBones.Count + mdchunk.m_ParentOffset].AddChild(bone); } m_Model.m_BoneTransformsMap.Add(bone.m_ID, m_Model.m_BoneTransformsMap.Count); ModelBase.GeometryDef geomDef = null; if (mdchunk.m_MatGroups.Length > 0) { geomDef = new ModelBase.GeometryDef("geometry-0"); bone.m_Geometries.Add(geomDef.m_ID, geomDef); } foreach (BMD.MaterialGroup matgroup in mdchunk.m_MatGroups) { string polyListKey = "polylist-" + matgroup.m_Name; ModelBase.PolyListDef polyListDef; if (!geomDef.m_PolyLists.TryGetValue(polyListKey, out polyListDef)) { polyListDef = new ModelBase.PolyListDef(polyListKey, matgroup.m_Name); geomDef.m_PolyLists.Add(polyListDef.m_ID, polyListDef); } ModelBase.MaterialDef material = new ModelBase.MaterialDef(matgroup.m_Name); material.m_Diffuse = matgroup.m_DiffuseColor; material.m_Ambient = matgroup.m_AmbientColor; material.m_Specular = matgroup.m_SpecularColor; material.m_Emission = matgroup.m_EmissionColor; bool hasTextures = (matgroup.m_Texture != null); if (hasTextures) { if (!m_Model.m_Textures.ContainsKey(matgroup.m_Texture.m_TextureName)) { ModelBase.TextureDefBase texture = new ModelBase.TextureDefNitro(matgroup.m_Texture); m_Model.m_Textures.Add(texture.m_ID, texture); } material.m_TextureDefID = matgroup.m_Texture.m_TextureName; } material.m_Alpha = matgroup.m_Alpha; if ((matgroup.m_PolyAttribs & 0xC0) == 0xC0) { material.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.FrontAndBack; } else if ((matgroup.m_PolyAttribs & 0xC0) == 0x80) { material.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Front; } else if ((matgroup.m_PolyAttribs & 0xC0) == 0x40) { material.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Back; } material.m_TexGenMode = (ModelBase.TexGenMode)(matgroup.m_TexParams >> 30); material.m_TextureScale = matgroup.m_TexCoordScale; material.m_TextureRotation = matgroup.m_TexCoordRot; material.m_TextureTranslation = matgroup.m_TexCoordTrans; byte sRepeat = (byte)((matgroup.m_TexParams & 0x10000) >> 0x10); byte tRepeat = (byte)((matgroup.m_TexParams & 0x20000) >> 0x11); byte sFlip = (byte)((matgroup.m_TexParams & 0x40000) >> 0x12); byte tFlip = (byte)((matgroup.m_TexParams & 0x80000) >> 0x13); material.m_TexTiling[0] = (sRepeat == 1) ? ModelBase.MaterialDef.TexTiling.Repeat : ModelBase.MaterialDef.TexTiling.Clamp; material.m_TexTiling[0] = (sFlip == 1) ? ModelBase.MaterialDef.TexTiling.Flip : material.m_TexTiling[0]; material.m_TexTiling[1] = (tRepeat == 1) ? ModelBase.MaterialDef.TexTiling.Repeat : ModelBase.MaterialDef.TexTiling.Clamp; material.m_TexTiling[1] = (tFlip == 1) ? ModelBase.MaterialDef.TexTiling.Flip : material.m_TexTiling[1]; material.m_FogFlag = (matgroup.m_PolyAttribs & 0x8000) > 0; byte lights = (byte)(matgroup.m_PolyAttribs & 0x0F); for (int i = 0; i < 4; i++) { byte value = (byte)(lights >> i); material.m_Lights[i] = (value == 1); } Console.WriteLine("Materials Start"); if (!m_Model.m_Materials.ContainsKey(material.m_ID)) { m_Model.m_Materials.Add(material.m_ID, material); } Console.WriteLine("Materials End"); if (!bone.m_MaterialsInBranch.Contains(matgroup.m_Name)) { bone.m_MaterialsInBranch.Add(matgroup.m_Name); } ModelBase.BoneDef upToRoot = bone; while ((upToRoot = upToRoot.m_Parent) != null) { if (!upToRoot.m_MaterialsInBranch.Contains(matgroup.m_Name)) { upToRoot.m_MaterialsInBranch.Add(matgroup.m_Name); } } foreach (BMD.VertexList geometry in matgroup.m_Geometry) { uint polyType = geometry.m_PolyType; List <BMD.Vertex> vtxList = geometry.m_VertexList; switch (polyType) { case 0: //Separate Triangles { ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(ModelBase.PolyListType.Triangles); int numFaces = vtxList.Count / 3; for (int a = 0, b = 0; a < numFaces; a++, b = b + 3) { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[b + 0].m_Position, vtxList[b + 0].m_TexCoord, vtxList[b + 0].m_Normal, vtxList[b + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[b + 1].m_Position, vtxList[b + 1].m_TexCoord, vtxList[b + 1].m_Normal, vtxList[b + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[b + 2].m_Position, vtxList[b + 2].m_TexCoord, vtxList[b + 2].m_Normal, vtxList[b + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 2].m_MatrixID]); faceList.m_Faces.Add(face); } polyListDef.m_FaceLists.Add(faceList); break; } case 1: //Separate Quadrilaterals { ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(ModelBase.PolyListType.Polygons); int numFaces = vtxList.Count / 4; for (int a = 0, b = 0; a < numFaces; a++, b = b + 4) { ModelBase.FaceDef face = new ModelBase.FaceDef(4); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[b + 0].m_Position, vtxList[b + 0].m_TexCoord, vtxList[b + 0].m_Normal, vtxList[b + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[b + 1].m_Position, vtxList[b + 1].m_TexCoord, vtxList[b + 1].m_Normal, vtxList[b + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[b + 2].m_Position, vtxList[b + 2].m_TexCoord, vtxList[b + 2].m_Normal, vtxList[b + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 2].m_MatrixID]); face.m_Vertices[3] = new ModelBase.VertexDef(vtxList[b + 3].m_Position, vtxList[b + 3].m_TexCoord, vtxList[b + 3].m_Normal, vtxList[b + 3].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 3].m_MatrixID]); faceList.m_Faces.Add(face); } polyListDef.m_FaceLists.Add(faceList); break; } case 2: //Triangle Strips { //3+(N-1) vertices per N triangles //(N-3)+1 Triangles per N Vertices int numFaces = vtxList.Count - 2; if (vtxList.Count < 3) //Should never be { break; } ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(ModelBase.PolyListType.TriangleStrip); //Convert all faces with more than 3 vertices to ones with only 3 for (int n = 0; n < numFaces; n++) { if (n % 2 == 0) { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[n + 0].m_Position, vtxList[n + 0].m_TexCoord, vtxList[n + 0].m_Normal, vtxList[n + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[n + 1].m_Position, vtxList[n + 1].m_TexCoord, vtxList[n + 1].m_Normal, vtxList[n + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[n + 2].m_Position, vtxList[n + 2].m_TexCoord, vtxList[n + 2].m_Normal, vtxList[n + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 2].m_MatrixID]); faceList.m_Faces.Add(face); } else { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[n + 2].m_Position, vtxList[n + 2].m_TexCoord, vtxList[n + 2].m_Normal, vtxList[n + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 2].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[n + 1].m_Position, vtxList[n + 1].m_TexCoord, vtxList[n + 1].m_Normal, vtxList[n + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[n + 0].m_Position, vtxList[n + 0].m_TexCoord, vtxList[n + 0].m_Normal, vtxList[n + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 0].m_MatrixID]); faceList.m_Faces.Add(face); } //Because of how normals are defined in triangle strips, every 2nd triangle is clockwise, whereas all others are anti-clockwise } polyListDef.m_FaceLists.Add(faceList); break; } case 3: //Quadrilateral Strips { //4+(N-1)*2 vertices per N quads //((N-4)/2) + 1 Quads. per N Vertices int numFaces = ((vtxList.Count - 4) / 2) + 1; if (vtxList.Count < 4) //Should never be { break; } ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(ModelBase.PolyListType.Polygons); for (int n = 0, p = 0; n < numFaces; n++, p = p + 2) { ModelBase.FaceDef face = new ModelBase.FaceDef(4); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[p + 0].m_Position, vtxList[p + 0].m_TexCoord, vtxList[p + 0].m_Normal, vtxList[p + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[p + 1].m_Position, vtxList[p + 1].m_TexCoord, vtxList[p + 1].m_Normal, vtxList[p + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[p + 3].m_Position, vtxList[p + 3].m_TexCoord, vtxList[p + 3].m_Normal, vtxList[p + 3].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 3].m_MatrixID]); face.m_Vertices[3] = new ModelBase.VertexDef(vtxList[p + 2].m_Position, vtxList[p + 2].m_TexCoord, vtxList[p + 2].m_Normal, vtxList[p + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 2].m_MatrixID]); faceList.m_Faces.Add(face); } polyListDef.m_FaceLists.Add(faceList); break; } default: MessageBox.Show("Unknown polygon type."); break; }//End polyType switch } } bone.CalculateBranchTransformations(); } m_Model.ApplyTransformations(); return(m_Model); }
public override ModelBase LoadModel(OpenTK.Vector3 scale) { ModelBase.BoneDef rootBone = new ModelBase.BoneDef("CollisionMap"); m_Model.m_BoneTree.AddRootBone(rootBone); ModelBase.GeometryDef geometry = new ModelBase.GeometryDef("geometry-0"); rootBone.m_Geometries.Add(geometry.m_ID, geometry); List<int> uniqueCollisionTypes = new List<int>(); foreach (KCL.ColFace plane in m_KCL.m_Planes) { if (!uniqueCollisionTypes.Contains(plane.type)) uniqueCollisionTypes.Add(plane.type); } uniqueCollisionTypes.Sort(); List<Color> uniqueColours = GetColours(uniqueCollisionTypes[uniqueCollisionTypes.Count - 1] + 1); foreach (int type in uniqueCollisionTypes) { ModelBase.MaterialDef material = new ModelBase.MaterialDef("material-" + type, m_Model.m_Materials.Count); material.m_Diffuse = uniqueColours[type]; m_Model.m_Materials.Add(material.m_ID, material); rootBone.m_MaterialsInBranch.Add(material.m_ID); ModelBase.PolyListDef tmp = new ModelBase.PolyListDef("polylist-" + type, material.m_ID); tmp.m_FaceLists.Add(new ModelBase.FaceListDef()); rootBone.m_Geometries[geometry.m_ID].m_PolyLists.Add("polylist-" + type, tmp); } foreach (KCL.ColFace plane in m_KCL.m_Planes) { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0].m_Position = plane.point1; face.m_Vertices[1].m_Position = plane.point2; face.m_Vertices[2].m_Position = plane.point3; for (int vert = 0; vert < face.m_Vertices.Length; vert++) { face.m_Vertices[vert].m_TextureCoordinate = Vector2.Zero; face.m_Vertices[vert].m_Normal = null; face.m_Vertices[vert].m_VertexColour = Color.White; face.m_Vertices[vert].m_VertexBoneID = 0; } geometry.m_PolyLists["polylist-" + plane.type].m_FaceLists[0].m_Faces.Add(face); } return m_Model; }
protected void ReadMaterials(XmlNode material_array) { if (material_array == null) return; int materialArray_size = int.Parse(material_array.Attributes["size"].Value); if (materialArray_size < 1) return; XmlNodeList materials = material_array.SelectNodes("material"); foreach (XmlNode material in materials) { string name = material.Attributes["name"].Value; int index = int.Parse(material.Attributes["index"].Value); bool[] lights = new bool[4]; for (int i = 0; i < 4; i++) lights[i] = material.Attributes["light" + i].Value.Equals("on"); string face = material.Attributes["face"].Value; ModelBase.MaterialDef.PolygonDrawingFace polygonDrawingFace; switch (face) { case "front": polygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Front; break; case "back": polygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Back; break; case "both": polygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.FrontAndBack; break; default: goto case "front"; } int alpha = int.Parse(material.Attributes["alpha"].Value); bool wire_mode = material.Attributes["wire_mode"].Value.Equals("on"); string polygon_mode = material.Attributes["polygon_mode"].Value; ModelBase.MaterialDef.PolygonMode polygonMode; switch (polygon_mode) { case "modulate": polygonMode = ModelBase.MaterialDef.PolygonMode.Modulation; break; case "decal": polygonMode = ModelBase.MaterialDef.PolygonMode.Decal; break; case "toon_highlight": polygonMode = ModelBase.MaterialDef.PolygonMode.Toon_HighlightShading; break; case "shadow": polygonMode = ModelBase.MaterialDef.PolygonMode.Shadow; break; default: goto case "modulate"; } int polygon_id = int.Parse(material.Attributes["polygon_id"].Value); bool fog_flag = material.Attributes["fog_flag"].Value.Equals("on"); bool depth_test_decal = material.Attributes["depth_test_decal"].Value.Equals("on"); bool translucent_update_depth = material.Attributes["translucent_update_depth"].Value.Equals("on"); bool render_1_pixel = material.Attributes["render_1_pixel"].Value.Equals("on"); bool far_clipping = material.Attributes["far_clipping"].Value.Equals("on"); byte[] diffuse = Array.ConvertAll<string, byte>( material.Attributes["diffuse"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToByte); byte[] ambient = Array.ConvertAll<string, byte>( material.Attributes["ambient"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToByte); byte[] specular = Array.ConvertAll<string, byte>( material.Attributes["specular"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToByte); byte[] emission = Array.ConvertAll<string, byte>( material.Attributes["emission"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToByte); bool shininess_table_flag = material.Attributes["shininess_table_flag"].Value.Equals("on"); int tex_image_idx = int.Parse(material.Attributes["tex_image_idx"].Value); int tex_palette_idx = int.Parse(material.Attributes["tex_palette_idx"].Value); ModelBase.MaterialDef.TexTiling[] tex_tiling = new ModelBase.MaterialDef.TexTiling[2]; string[] tmpsplit = (material.Attributes["tex_tiling"] != null) ? material.Attributes["tex_tiling"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries) : null; if (tex_image_idx >= 0) { for (int i = 0; i < 2; i++) { switch (tmpsplit[i]) { case "clamp": tex_tiling[i] = ModelBase.MaterialDef.TexTiling.Clamp; break; case "repeat": tex_tiling[i] = ModelBase.MaterialDef.TexTiling.Repeat; break; case "flip": tex_tiling[i] = ModelBase.MaterialDef.TexTiling.Flip; break; default: goto case "repeat"; } } } float[] tex_scale = (tex_image_idx >= 0) ? Array.ConvertAll( material.Attributes["tex_scale"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToSingle) : null; float tex_rotate = (tex_image_idx >= 0) ? float.Parse(material.Attributes["tex_rotate"].Value, Helper.USA) : 0f; float[] tex_translate = (tex_image_idx >= 0) ? Array.ConvertAll( material.Attributes["tex_translate"].Value.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries), Convert.ToSingle) : null; string tex_gen_mode = (tex_image_idx >= 0) ? material.Attributes["tex_gen_mode"].Value : null; ModelBase.TexGenMode texGenMode; switch (tex_gen_mode) { case "none": texGenMode = ModelBase.TexGenMode.None; break; case null: goto case "none"; case "tex": texGenMode = ModelBase.TexGenMode.Tex; break; case "nrm": texGenMode = ModelBase.TexGenMode.Normal; break; case "pos": texGenMode = ModelBase.TexGenMode.Pos; break; default: goto case "none"; } string tex_gen_st_src = (material.Attributes["tex_gen_st_src"] != null) ? material.Attributes["tex_gen_st_src"].Value : null; string tex_effect_mtx = (material.Attributes["tex_effect_mtx"] != null) ? material.Attributes["tex_effect_mtx"].Value : null; ModelBase.MaterialDef matDef = new ModelBase.MaterialDef(name, index); matDef.m_TextureDefID = (tex_image_idx >= 0) ? m_Model.m_Textures.Values.ElementAt(tex_image_idx).m_ID : null; matDef.m_Lights = lights; matDef.m_PolygonDrawingFace = polygonDrawingFace; matDef.m_Alpha = (int)((alpha / 31f) * 255f); matDef.m_WireMode = wire_mode; matDef.m_PolygonMode = polygonMode; matDef.m_FogFlag = fog_flag; matDef.m_DepthTestDecal = depth_test_decal; matDef.m_RenderOnePixelPolygons = render_1_pixel; matDef.m_FarClipping = far_clipping; matDef.m_Diffuse = Color.FromArgb( (int)(diffuse[0] / 31f * 255f), (int)(diffuse[1] / 31f * 255f), (int)(diffuse[2] / 31f * 255f)); matDef.m_Ambient = Color.FromArgb( (int)(ambient[0] / 31f * 255f), (int)(ambient[1] / 31f * 255f), (int)(ambient[2] / 31f * 255f)); matDef.m_Specular = Color.FromArgb( (int)(specular[0] / 31f * 255f), (int)(specular[1] / 31f * 255f), (int)(specular[2] / 31f * 255f)); matDef.m_Emission = Color.FromArgb( (int)(emission[0] / 31f * 255f), (int)(emission[1] / 31f * 255f), (int)(emission[2] / 31f * 255f)); matDef.m_TexTiling = tex_tiling; matDef.m_TextureScale = (tex_scale != null) ? new Vector2(tex_scale[0], tex_scale[1]) : Vector2.One; matDef.m_TextureRotation = tex_rotate; matDef.m_TextureTranslation = (tex_translate != null) ? new Vector2(tex_translate[0], tex_translate[1]) : Vector2.Zero; matDef.m_TexGenMode = texGenMode; m_Model.m_Materials.Add(matDef.m_ID, matDef); } }
public override ModelBase LoadModel(OpenTK.Vector3 scale) { foreach (BMD.ModelChunk mdchunk in m_BMD.m_ModelChunks) { ModelBase.BoneDef bone = new ModelBase.BoneDef(mdchunk.m_Name); bone.SetScale(mdchunk.m_20_12Scale); bone.SetRotation(mdchunk.m_4_12Rotation); bone.SetTranslation(mdchunk.m_20_12Translation); if (mdchunk.m_ParentOffset == 0) { m_Model.m_BoneTree.AddRootBone(bone); } else { List<ModelBase.BoneDef> listOfBones = m_Model.m_BoneTree.GetAsList(); listOfBones[listOfBones.Count + mdchunk.m_ParentOffset].AddChild(bone); } ModelBase.GeometryDef geomDef = null; if (mdchunk.m_MatGroups.Length > 0) { geomDef = new ModelBase.GeometryDef("geometry-0"); bone.m_Geometries.Add(geomDef.m_ID, geomDef); } foreach (BMD.MaterialGroup matgroup in mdchunk.m_MatGroups) { if (!geomDef.m_PolyLists.ContainsKey(matgroup.m_Name)) { ModelBase.PolyListDef pld = new ModelBase.PolyListDef("polylist-" + matgroup.m_Name, matgroup.m_Name); geomDef.m_PolyLists.Add(pld.m_MaterialName, pld); } ModelBase.PolyListDef polyListDef = geomDef.m_PolyLists[matgroup.m_Name]; ModelBase.MaterialDef material = new ModelBase.MaterialDef(matgroup.m_Name, m_Model.m_Materials.Count); material.m_Diffuse = matgroup.m_DiffuseColor; material.m_Ambient = matgroup.m_AmbientColor; material.m_Specular = matgroup.m_SpecularColor; material.m_Emission = matgroup.m_EmissionColor; bool hasTextures = (matgroup.m_Texture != null); if (hasTextures) { if (!m_Model.m_Textures.ContainsKey(matgroup.m_Texture.m_TexName)) { ModelBase.TextureDefBase texture = new ModelBase.TextureDefInMemoryBitmap( matgroup.m_Texture.m_TexName, ConvertBMDTextureToBitmap(matgroup.m_Texture)); m_Model.m_Textures.Add(texture.m_ID, texture); } material.m_TextureDefID = matgroup.m_Texture.m_TexName; } material.m_Alpha = matgroup.m_Alpha; if ((matgroup.m_PolyAttribs & 0xC0) == 0xC0) material.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.FrontAndBack; else if ((matgroup.m_PolyAttribs & 0xC0) == 0x80) material.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Front; else if ((matgroup.m_PolyAttribs & 0xC0) == 0x40) material.m_PolygonDrawingFace = ModelBase.MaterialDef.PolygonDrawingFace.Back; if (!m_Model.m_Materials.ContainsKey(material.m_ID)) m_Model.m_Materials.Add(material.m_ID, material); bone.m_MaterialsInBranch.Add(matgroup.m_Name); ModelBase.BoneDef upToRoot = bone; while ((upToRoot = upToRoot.m_Parent) != null) { if (!upToRoot.m_MaterialsInBranch.Contains(matgroup.m_Name)) upToRoot.m_MaterialsInBranch.Add(matgroup.m_Name); } foreach (BMD.VertexList geometry in matgroup.m_Geometry) { uint polyType = geometry.m_PolyType; List<BMD.Vertex> vtxList = geometry.m_VertexList; switch (polyType) { case 0://Separate Triangles { ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(ModelBase.PolyListType.Triangles); if (vtxList.Count <= 3)//Just 1 triangle { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[0].m_Position, vtxList[0].m_TexCoord, vtxList[0].m_Normal, vtxList[0].m_Color, (int)matgroup.m_BoneIDs[vtxList[0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[1].m_Position, vtxList[1].m_TexCoord, vtxList[1].m_Normal, vtxList[1].m_Color, (int)matgroup.m_BoneIDs[vtxList[1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[2].m_Position, vtxList[2].m_TexCoord, vtxList[2].m_Normal, vtxList[2].m_Color, (int)matgroup.m_BoneIDs[vtxList[2].m_MatrixID]); faceList.m_Faces.Add(face); } else if (vtxList.Count > 3 && (float)vtxList.Count % 3 == 0.0f)//Eg. 9 vertices in 3 triangles { int numFaces = vtxList.Count / 3; for (int a = 0, b = 0; a < numFaces; a++, b = b + 3) { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[b + 0].m_Position, vtxList[b + 0].m_TexCoord, vtxList[b + 0].m_Normal, vtxList[b + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[b + 1].m_Position, vtxList[b + 1].m_TexCoord, vtxList[b + 1].m_Normal, vtxList[b + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[b + 2].m_Position, vtxList[b + 2].m_TexCoord, vtxList[b + 2].m_Normal, vtxList[b + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 2].m_MatrixID]); faceList.m_Faces.Add(face); } } polyListDef.m_FaceLists.Add(faceList); break; } case 1://Separate Quadrilaterals { ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(ModelBase.PolyListType.Polygons); if (vtxList.Count <= 4)//Just 1 quadrilateral { ModelBase.FaceDef face = new ModelBase.FaceDef(4); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[0].m_Position, vtxList[0].m_TexCoord, vtxList[0].m_Normal, vtxList[0].m_Color, (int)matgroup.m_BoneIDs[vtxList[0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[1].m_Position, vtxList[1].m_TexCoord, vtxList[1].m_Normal, vtxList[1].m_Color, (int)matgroup.m_BoneIDs[vtxList[1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[2].m_Position, vtxList[2].m_TexCoord, vtxList[2].m_Normal, vtxList[2].m_Color, (int)matgroup.m_BoneIDs[vtxList[2].m_MatrixID]); face.m_Vertices[3] = new ModelBase.VertexDef(vtxList[3].m_Position, vtxList[3].m_TexCoord, vtxList[3].m_Normal, vtxList[3].m_Color, (int)matgroup.m_BoneIDs[vtxList[3].m_MatrixID]); faceList.m_Faces.Add(face); } else if (vtxList.Count > 4 && (float)vtxList.Count % 4 == 0.0f)//Eg. 8 vertices in 2 quadrilaterals { int numFaces = vtxList.Count / 4; for (int a = 0, b = 0; a < numFaces; a++, b = b + 4) { ModelBase.FaceDef face = new ModelBase.FaceDef(4); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[b + 0].m_Position, vtxList[b + 0].m_TexCoord, vtxList[b + 0].m_Normal, vtxList[b + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[b + 1].m_Position, vtxList[b + 1].m_TexCoord, vtxList[b + 1].m_Normal, vtxList[b + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[b + 2].m_Position, vtxList[b + 2].m_TexCoord, vtxList[b + 2].m_Normal, vtxList[b + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 2].m_MatrixID]); face.m_Vertices[3] = new ModelBase.VertexDef(vtxList[b + 3].m_Position, vtxList[b + 3].m_TexCoord, vtxList[b + 3].m_Normal, vtxList[b + 3].m_Color, (int)matgroup.m_BoneIDs[vtxList[b + 3].m_MatrixID]); faceList.m_Faces.Add(face); } } polyListDef.m_FaceLists.Add(faceList); break; } case 2://Triangle Strips { //3+(N-1) vertices per N triangles //(N-3)+1 Triangles per N Vertices int numFaces = vtxList.Count - 2; if (vtxList.Count < 3)//Should never be break; ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(ModelBase.PolyListType.TriangleStrip); //Convert all faces with more than 3 vertices to ones with only 3 for (int n = 0; n < numFaces; n++) { if (n % 2 == 0) { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[n + 0].m_Position, vtxList[n + 0].m_TexCoord, vtxList[n + 0].m_Normal, vtxList[n + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[n + 1].m_Position, vtxList[n + 1].m_TexCoord, vtxList[n + 1].m_Normal, vtxList[n + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[n + 2].m_Position, vtxList[n + 2].m_TexCoord, vtxList[n + 2].m_Normal, vtxList[n + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 2].m_MatrixID]); faceList.m_Faces.Add(face); } else { ModelBase.FaceDef face = new ModelBase.FaceDef(3); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[n + 2].m_Position, vtxList[n + 2].m_TexCoord, vtxList[n + 2].m_Normal, vtxList[n + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 2].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[n + 1].m_Position, vtxList[n + 1].m_TexCoord, vtxList[n + 2].m_Normal, vtxList[n + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[n + 0].m_Position, vtxList[n + 0].m_TexCoord, vtxList[n + 0].m_Normal, vtxList[n + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[n + 0].m_MatrixID]); faceList.m_Faces.Add(face); } //Because of how normals are defined in triangle strips, every 2nd triangle is clockwise, whereas all others are anti-clockwise } polyListDef.m_FaceLists.Add(faceList); break; } case 3://Quadrilateral Strips { //4+(N-1)*2 vertices per N quads //((N-4)/2) + 1 Quads. per N Vertices int numFaces = ((vtxList.Count - 4) / 2) + 1; if (vtxList.Count < 4)//Should never be break; ModelBase.FaceListDef faceList = new ModelBase.FaceListDef(); for (int n = 0, p = 0; n < numFaces; n++, p = p + 2) { ModelBase.FaceDef face = new ModelBase.FaceDef(4); face.m_Vertices[0] = new ModelBase.VertexDef(vtxList[p + 0].m_Position, vtxList[p + 0].m_TexCoord, vtxList[p + 0].m_Normal, vtxList[p + 0].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 0].m_MatrixID]); face.m_Vertices[1] = new ModelBase.VertexDef(vtxList[p + 1].m_Position, vtxList[p + 1].m_TexCoord, vtxList[p + 1].m_Normal, vtxList[p + 1].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 1].m_MatrixID]); face.m_Vertices[2] = new ModelBase.VertexDef(vtxList[p + 3].m_Position, vtxList[p + 3].m_TexCoord, vtxList[p + 3].m_Normal, vtxList[p + 3].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 3].m_MatrixID]); face.m_Vertices[3] = new ModelBase.VertexDef(vtxList[p + 2].m_Position, vtxList[p + 2].m_TexCoord, vtxList[p + 2].m_Normal, vtxList[p + 2].m_Color, (int)matgroup.m_BoneIDs[vtxList[p + 2].m_MatrixID]); faceList.m_Faces.Add(face); } polyListDef.m_FaceLists.Add(faceList); break; } default: MessageBox.Show("Unknown polygon type."); break; }//End polyType switch } } bone.CalculateBranchTransformations(); } m_Model.ApplyTransformations(); return m_Model; }