Example #1
0
 public static ColladaGeometry LoadDAE(string DAE_NAME)
 {
     if (!File.Exists(Constants.CacheDir + DAE_NAME + ".engine_cached_model"))
     {
         //DEBUG LOGGING
         DebugTools.Log("[Model Loader]: No cached geometry found, parsing now.");
         //No Cache, load it the old way
         var Collada  = ColladaDotNet.Collada.Load_File(DAE_NAME);
         var geometry = ColladaGeometry.LoadGeometries(Collada);
         //and save the cache
         geometry.Save(Constants.CacheDir + DAE_NAME + ".engine_cached_model");
         return(geometry);
     }
     else
     {
         return(ColladaGeometry.Load(Constants.CacheDir + DAE_NAME + ".engine_cached_model"));
     }
 }
Example #2
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            world = WorldRenderer.Create(ColladaGeometry.LoadDAE("Assets/room.dae"));
            Box   = PhysicsObjectRenderer.Create(ColladaGeometry.LoadDAE("Assets/box.dae"));

            Box.BuildDisplayList();

            InitializeOpenGL();

            Mouse.ButtonDown += MouseClick;
            //build the world
            world.BuildDisplayList();
            world.AddToPhysics(physics_world);
            icons[0] = ImageLoader.LoadTexture("Assets/InterfaceTextures/AI Spawn.png");
            icons[1] = ImageLoader.LoadTexture("Assets/InterfaceTextures/Camera.png");
            icons[2] = ImageLoader.LoadTexture("Assets/InterfaceTextures/Physics Spawn.png");
            icons[3] = ImageLoader.LoadTexture("Assets/InterfaceTextures/Waypoint Logo.png");
        }
Example #3
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);
        }
Example #4
0
        public static ColladaGeometry parseGeometry(Matrix4 transform, Collada_Geometry geometry, Dictionary <string, Color> colors)
        {
            //Parse all of the geometry
            ColladaGeometry geom = new ColladaGeometry();

            //get the raw geometry
            float[] Vertices = geometry.Mesh.Source[0].Float_Array.Value();
            float[] Normals  = { };
            if (geometry.Mesh.Source.Length > 1)
            {
                Normals = geometry.Mesh.Source[1].Float_Array.Value(); //the normals
            }
            //build the vertex and normal lookup table
            List <Vector3> vertices = new List <Vector3>();
            List <Vector3> normals  = new List <Vector3>();

            //and parse
            for (int i = 0; i < Vertices.Length; i += 3)
            {
                Vector3 vertex = new Vector3(Vertices[i], Vertices[i + 1], Vertices[i + 2]).MultiplyByMatrix4(transform);
                if (geometry.Mesh.Source.Length > 1)
                {
                    Vector3 normal = new Vector3(Normals[i], Normals[i + 1], Normals[i + 2]); //.MultiplyByMatrix3x4(transform);
                    normals.Add(normal);
                }
                //add to list
                vertices.Add(vertex);
            }
            //and now construct triangle geometry from that
            if (!(geometry.Mesh.Triangles == null))
            {
                foreach (Collada_Triangles t in geometry.Mesh.Triangles)
                {
                    int[] geometryIds = t.P.Value();
                    //and parse the list through the lookup table
                    for (int i = 0; i < geometryIds.Length; i += 3)
                    {
                        Triangle tri = new Triangle();
                        tri.vertices[0] = vertices[geometryIds[i]];
                        tri.normals[0]  = normals[geometryIds[i]];

                        tri.vertices[1] = vertices[geometryIds[i + 1]];
                        tri.normals[1]  = normals[geometryIds[i + 1]];

                        tri.vertices[2] = vertices[geometryIds[i + 2]];
                        tri.normals[2]  = normals[geometryIds[i + 2]];

                        //color
                        tri.color = colors[t.Material];

                        //and add it to the triangles list
                        geom.triangles.Add(tri);
                    }
                }
            }
            else
            {
                //DEBUG LOGGING
                //PRINT THE GEOMETRY ID IF NO TRIANGLES
                DebugTools.Log("[Model Loader]: No triangles in geometry with ID " + geometry.ID);
            }

            if (!(geometry.Mesh.Lines == null))
            {
                //and now the lines...
                int[] lineIds = geometry.Mesh.Lines[0].P.Value();
                //and parse the list through the lookup table
                for (int i = 0; i < lineIds.Length; i += 2)
                {
                    GeometryLine line = new GeometryLine();
                    //build the vertex list
                    line.vertices[0] = vertices[lineIds[i]];

                    line.vertices[1] = vertices[lineIds[i + 1]];

                    //and add it to the lines list
                    geom.geometryLines.Add(line);
                }
            }
            else
            {
                //DEBUG LOGGING
                //PRINT THE GEOMETRY ID IF NO LINES
                DebugTools.Log("[Model Loader]: No lines in geometry with ID " + geometry.ID);
            }

            return(geom);
        }