Пример #1
0
        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);
            }
        }
Пример #2
0
        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);
        }