Example #1
0
        void ImportGeometry(Collada141.geometry geometry)
        {
            var mesh = geometry.Item as Collada141.mesh;
            if (mesh == null) return;
            var float_array = mesh.source[0].Item as Collada141.float_array;
            this.Coordinates = new Vector3[float_array.Values.Length / 3];
            for (int i = 0; i < Coordinates.Length; i++)
            {
                Coordinates[i] = new Vector3(
                        (float)float_array.Values[i * 3 + 0],
                        (float)float_array.Values[i * 3 + 1],
                        (float)float_array.Values[i * 3 + 2]);
            }

            var poly_list = mesh.Items[0] as Collada141.polylist;
            if (poly_list == null) return;
            Triangle[] triangles = new Triangle[poly_list.count];
            var raw_indices = Collada141.COLLADA.ConvertIntArray(poly_list.p);
            for (int i = 0; i < triangles.Length; i++)
            {
                triangles[i] = new Triangle()
                {
                    MaterialID = 0,
                    Vertex1 = (ushort)raw_indices[i * (3 * 2) + (0 * 2)],
                    Vertex2 = (ushort)raw_indices[i * (3 * 2) + (1 * 2)],
                    Vertex3 = (ushort)raw_indices[i * (3 * 2) + (2 * 2)],
                };
            }
            List<ushort> triangle_indices = new List<ushort>(triangles.Length * 3);
            foreach (var triangle in triangles)
            {
                triangle_indices.AddRange(triangle.ToArray());
            }
            Adjacencies adj = new Adjacencies(triangle_indices.ToArray());
            this.Indices = adj.GenerateTriangleStrip();
            this.Primitives = new MeshPrimitive[] { new MeshPrimitive(0, (ushort)Indices.Length) };
        }
Example #2
0
        public bool ImportFromWavefront(string filename)
        {
            Log.Info(string.Format("Loading file {0} into memory buffer", filename));
            byte[] buffer = null;
            using (var file = File.OpenRead(filename))
            {
                buffer = new byte[file.Length];
                file.Read(buffer, 0, buffer.Length);
            } if (buffer == null)
            {
                Log.Error("Failed to create memory buffer");
                return false;
            }
            MemoryStream stream = new MemoryStream(buffer);
            StreamReader reader = new StreamReader(stream);

            WavefrontOBJ.Object[] objects = new WavefrontOBJ.Object[1] { new WavefrontOBJ.Object() { faces_start_index = 0 } };
            List<WavefrontOBJ.Face> faces = new List<WavefrontOBJ.Face>();
            List<Vector3> vertex_coords = new List<Vector3>();
            List<Vector2> texture_coords = new List<Vector2>();
            List<Vector3> normals = new List<Vector3>();
            Dictionary<string, int> material_names = new Dictionary<string, int>();
            material_names.Add("default", 0);
            int selected_material = 0;
            bool default_object = true;
            bool default_object_processed = false;
            bool has_normals = false;
            bool has_texcoords = false;

            Log.Info("Begin parsing Wavefront Object data from buffer");
            while (!reader.EndOfStream)
            {
                string line = reader.ReadLine().Trim();
                if (line.StartsWith("# "))
                {
                    Log.Info(line);
                    continue;
                }
                if (line.StartsWith("o "))
                {
                    // if this is the first object token, use the default object
                    if (default_object) default_object = false;
                    else
                    {
                        Log.Warn(@"Support for multiple wavefront objects per mesh not implemented.
                                   Meshes can only accept a single wavefront object. Continuing, but only using first object!");
                        if (!default_object_processed)
                        {
                            objects[0].faces_count = faces.Count;
                            default_object_processed = true;
                        }
                    }
                }
                else if (line.StartsWith("v "))
                {
                    Vector3 vertex;
                    if (!WavefrontExtensions.TryParseVector3(out vertex, line)) return false;
                    vertex_coords.Add(vertex);
                }
                else if (line.StartsWith("vt "))
                {
                    has_texcoords = true;
                    Vector2 texcoord;
                    if (!WavefrontExtensions.TryParseVector2(out texcoord, line)) return false;
                    texture_coords.Add(texcoord);
                }
                else if (line.StartsWith("vn "))
                {
                    has_normals = true;
                    Vector3 normal;
                    if (!WavefrontExtensions.TryParseVector3(out normal, line)) return false;
                    normals.Add(normal);
                }
                else if (line.StartsWith("usemtl "))
                {
                    string name = line.Replace("usemtl ", "").Trim();
                    if (!material_names.ContainsKey(name)) material_names.Add(name, material_names.Count);
                    selected_material = material_names[name];
                }
                else if (line.StartsWith("f "))
                {
                    WavefrontOBJ.Face face;
                    if (!WavefrontOBJ.Face.TryParse(line, out face))
                    {
                        Log.Error(string.Format("Error parsing line: {0}", line));
                        return false;
                    }
                    else
                    {
                        face.material_id = selected_material;
                        faces.Add(face);
                    }
                }
                else Log.Warn(string.Format("Unsupported format found while parsing line: {0}", line));
            }
            if (!default_object_processed)
            {
                objects[0].faces_count = faces.Count;
                default_object_processed = true;
            }
            Log.Info("Partial success... finished parsing Wavefront Object data from buffer");

            List<Triangle> triangle_list = new List<Triangle>(faces.Count);
            List<Vector3> vertex_coordiantes = new List<Vector3>(vertex_coords.Count);
            List<Vector2> texture_coordinates = new List<Vector2>(vertex_coords.Count);
            List<Vector3> vertex_normals = new List<Vector3>(vertex_coords.Count);
            List<string> tokens = new List<string>();

            for (int i = 0; i < faces.Count; i++)
            {
                Triangle triangle = new Triangle() { MaterialID = faces[i].material_id };
                for (int token = 0; token < 3; ++token)
                {
                    if (!tokens.Contains(faces[i].GetToken(token)))
                    {
                        triangle.Vertex1 = (ushort)vertex_coordiantes.Count;
                        tokens.Add(faces[i].GetToken(0));
                        vertex_coordiantes.Add(vertex_coords[faces[i].vertex_indices[token] - 1]);
                        texture_coordinates.Add(faces[i].has_texcoord ? texture_coords[faces[i].texcoord_indices[token] - 1] : Vector2.Zero);
                        vertex_normals.Add(faces[i].has_normals ? normals[faces[i].normal_indices[token] - 1] : Vector3.Zero);
                    }
                    else
                    {
                        triangle.Vertex1 = (ushort)tokens.IndexOf(faces[i].GetToken(token));
                    }
                }
                triangle_list.Add(triangle);
            }

            List<TriangleStrip> strips = new List<TriangleStrip>(material_names.Count);
            foreach (var material in material_names)
            {
                var material_faces = triangle_list.Where(x => x.MaterialID == material.Value).Select(x => x.AsEnumerable<ushort>());
                List<ushort> tris = new List<ushort>(material_faces.Count() * 3);
                foreach (var item in material_faces)
                {
                    tris.AddRange(item.ToArray());
                }
                if (tris.Count > 0)
                {
                    Adjacencies stripper = new Adjacencies(tris.ToArray());
                    strips.Add(new TriangleStrip() { MaterialID = (ushort)material.Value, Indices = stripper.GenerateTriangleStrip() });
                }
            }
            this.Coordinates = vertex_coordiantes.ToArray();
            this.TextureCoordinates = texture_coordinates.ToArray();
            this.Normals = vertex_normals.ToArray();

            this.Primitives = new MeshPrimitive[strips.Count];

            Log.Info("Parsing shader groups from triangle strips...");
            TriangleStrip combined_strip = new TriangleStrip() { Indices = new ushort[0] };
            ushort offset = 0;
            for (int i = 0; i < strips.Count; ++i)
            {
                TriangleStrip.Append(ref combined_strip, strips[i]);
                this.Primitives[i] = new MeshPrimitive(offset, (ushort)(combined_strip.Indices.Length - offset)) { shader_index = (ushort)i };
                Log.Info(string.Format(@"ShaderGroup[ {0} ] {{ Start = {1}, Length = {2} }}", i, offset, (combined_strip.Indices.Length - offset).ToString()));
                offset = (ushort)combined_strip.Indices.Length;

            }
            this.Indices = combined_strip.Indices;
            if (!has_texcoords)
            {
                Log.Warn("No texture coordinates found while parsing Wavefront file..." +
                        "\nGenerating uv coordinates from vertex positions (flat mapping)");
                this.GenerateTexCoords();
            }
            if (!has_normals)
            {
                Log.Warn("No normals found while parsing Wavefront file..." +
                        "\nGenerating normals...");
                this.GenerateNormals();
            }
            Log.Info("Generating tangent space vectors...");
            this.GenerateTangentSpaceVectors();
            Log.Info("Success, import finished! Returning true from ImportFromWavefront();");
            return true;
        }