public static Collada Load_File(string file_name) { try { Collada col_scenes = null; XmlSerializer sr = new XmlSerializer(typeof(Collada)); TextReader tr = new StreamReader(file_name); col_scenes = (Collada)(sr.Deserialize(tr)); tr.Close(); return(col_scenes); } catch (Exception) { return(null); } }
public static ColladaGeometry LoadGeometries(ColladaDotNet.Collada Collada) { Matrix4 transform = new Matrix4( 1, 0, 0, 0, //x_x, x_y, x_z, t 0, 1, 0, 0, //y_x, y_y, y_z, t 0, 0, 1, 0, //z_x, z_y, z_z, t 0, 0, 0, 1 ); List <ColladaGeometry> geometries = new List <ColladaGeometry>(); //Build the geometry index Dictionary <String, Collada_Geometry> geometryNodes = new Dictionary <string, Collada_Geometry>(); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Creating Geometry Dictionary"); foreach (Collada_Geometry geometry in Collada.Library_Geometries.Geometry) { geometryNodes.Add("#" + geometry.ID, geometry); //Number sign for easier look ups } //Build the material ID index Dictionary <String, Color> effectIdNodes = new Dictionary <string, Color>(); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Creating Effect Dictionary"); foreach (Collada_Effect effect in Collada.Library_Effects.Effect) { //Check that it's a valid effect if (!(effect.Profile_COMMON[0].Technique.Lambert == null)) { if (effect.Profile_COMMON[0].Technique.Lambert.Diffuse.Color != null) { float[] RGBA = effect.Profile_COMMON[0].Technique.Lambert.Diffuse.Color.Value(); Color color = Color.FromArgb( (int)(RGBA[3] * 255), (int)(RGBA[0] * 255), (int)(RGBA[1] * 255), (int)(RGBA[2] * 255)); if (RGBA.Average() == 0) { color = Color.Black; } effectIdNodes.Add("#" + effect.ID, color); } else { effectIdNodes.Add("#" + effect.ID, Color.Black); } } else { //it might be a constant if (!(effect.Profile_COMMON[0].Technique.Constant == null)) { float[] RGBA = effect.Profile_COMMON[0].Technique.Constant.Transparent.Color.Value(); Color color = Color.FromArgb( (int)(RGBA[3] * 255), (int)(RGBA[0] * 255), (int)(RGBA[1] * 255), (int)(RGBA[2] * 255)); if (RGBA.Average() == 0) { color = Color.Black; } effectIdNodes.Add("#" + effect.ID, color); } else { effectIdNodes.Add("#" + effect.ID, Color.Black); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Effect with ID " + effect.ID + " has an invalid material, assuming black."); } } } //Build the color ID index Dictionary <String, Color> colorNodes = new Dictionary <string, Color>(); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Creating Color Dictionary"); foreach (Collada_Material material in Collada.Library_Materials.Material) { colorNodes.Add("#" + material.ID, effectIdNodes[material.Instance_Effect.URL]); //Resolve the material effect Id } //and build individual geometry nodes //DEBUG LOGGING DebugTools.Log("[Model Loader]: Building Node Dictionary"); Dictionary <String, Collada_Node> nodeNodes = new Dictionary <string, Collada_Node>(); foreach (Collada_Node node in Collada.Library_Visual_Scene.Visual_Scene[0].Node) { recursiveAddNodes(node, ref nodeNodes); } if (Collada.Library_Nodes != null) { foreach (Collada_Node node in Collada.Library_Nodes.Node) { recursiveAddNodes(node, ref nodeNodes); } } DebugTools.Log("[Model Loader]: Parsing Geometry, " + nodeNodes.Count + " nodes."); foreach (Collada_Node node in nodeNodes.Values) { ParseGeometryFromNode(node, transform, ref colorNodes, ref geometries, ref geometryNodes, ref nodeNodes); } //DEBUG LOGGING DebugTools.Log("[Model Loader]: Removing duplicate triangles."); //and output ColladaGeometry outputGeometry = new ColladaGeometry(); //and finally, merge all of the geometries into one single one foreach (ColladaGeometry geometry in geometries) { outputGeometry.geometryLines.AddRange(geometry.geometryLines); outputGeometry.triangles.AddRange(geometry.triangles); } int preOptimization = outputGeometry.triangles.Count; int i = 0; if (outputGeometry.triangles.Count < 100000) { do { //DEBUG LOGGING DebugTools.Log("[Model Loader]: Parsed " + i + "/" + outputGeometry.triangles.Count); List <Triangle> removeList = new List <Triangle>(); foreach (Triangle t in outputGeometry.triangles) { var x1 = outputGeometry.triangles[i].vertices[0].X + outputGeometry.triangles[i].vertices[1].X + outputGeometry.triangles[i].vertices[2].X; var y1 = outputGeometry.triangles[i].vertices[0].Y + outputGeometry.triangles[i].vertices[1].Y + outputGeometry.triangles[i].vertices[2].Y; var z1 = outputGeometry.triangles[i].vertices[0].Z + outputGeometry.triangles[i].vertices[1].Z + outputGeometry.triangles[i].vertices[2].Z; var x2 = t.vertices[0].X + t.vertices[1].X + t.vertices[2].X; var y2 = t.vertices[0].Y + t.vertices[1].Y + t.vertices[2].Y; var z2 = t.vertices[0].Z + t.vertices[1].Z + t.vertices[2].Z; if (x1 == x2 & y1 == y2 & z1 == z2 & !outputGeometry.triangles[i].Equals(t)) { //DEBUG LOGGING DebugTools.Log("[Model Loader]: Clipping triangles - {" + t.vertices[0].X.ToString("N1") + "," + t.vertices[0].Y.ToString("N1") + "," + t.vertices[0].Z.ToString("N1") + "}{" + t.vertices[0].X.ToString("N1") + "," + t.vertices[1].Y.ToString("N1") + "," + t.vertices[2].Z.ToString("N1") + "}{" + t.vertices[0].X.ToString("N1") + "," + t.vertices[1].Y.ToString("N1") + "," + t.vertices[2].Z.ToString("N1") + "}"); removeList.Add(t); break; //Usually only one duplicate } } foreach (Triangle t in removeList) { outputGeometry.triangles.Remove(t); } i++; } while (i < outputGeometry.triangles.Count); } else { //DEBUG LOGGING DebugTools.Log("[Model Loader]: Skipping polygon optimization, too many triangles to do so."); } //DEBUG LOGGING DebugTools.Log("[Model Loader]: Pre-optimization: " + preOptimization + " tri's, Post-optimization: " + outputGeometry.triangles.Count + " tri's"); DebugTools.Log("[Model Loader]: Lines: " + outputGeometry.geometryLines.Count); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Shifting geometry to center."); var min = new Vector3(99999999999, 999999999999, 99999999999); var max = new Vector3(0, 0, 0); foreach (Triangle tri in outputGeometry.triangles) { foreach (Vector3 vertex in tri.vertices) { if (vertex.X < min.X) { min.X = vertex.X; } if (vertex.Y < min.Y) { min.Y = vertex.Y; } if (vertex.Z < min.Z) { min.Z = vertex.Z; } if (vertex.X > max.X) { max.X = vertex.X; } if (vertex.Y > max.Y) { max.Y = vertex.Y; } if (vertex.Z > max.Z) { max.Z = vertex.Z; } } } Vector3 shiftVector = new Vector3((max + min) / 2); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Shifting Model by " + shiftVector.ToString()); foreach (Triangle tri in outputGeometry.triangles) { tri.vertices[0] = tri.vertices[0] - shiftVector; tri.vertices[1] = tri.vertices[1] - shiftVector; tri.vertices[2] = tri.vertices[2] - shiftVector; } foreach (GeometryLine line in outputGeometry.geometryLines) { line.vertices[0] = line.vertices[0] - shiftVector; line.vertices[1] = line.vertices[1] - shiftVector; } //and return return(outputGeometry); }