コード例 #1
0
ファイル: Mesh.cs プロジェクト: kholdfuzion/halo2x-sunfish
        public void ImportWavefrontObject(WavefrontObject Wavefront, CompressionBounds boundingBox)
        {
            List<D3DVertex> temp = new List<D3DVertex>(Wavefront.FaceCount * 3);
            for (int Material = 0; Material < Wavefront.MaterialCount; Material++)
            {
                int[] FaceIndices = Wavefront.GetFaceIndicesUsingMaterialID(Material);
                for (int Face = 0; Face < FaceIndices.Length; Face++)
                {
                    for (int Component = 0; Component < 3; Component++)
                    {
                        D3DVertex d3DVertex = new D3DVertex();
                        d3DVertex.Position = Wavefront.Vertices[Wavefront.Faces[FaceIndices[Face]].VertexIndices[Component]];
                        d3DVertex.Texture = Wavefront.Texcoords[Wavefront.Faces[FaceIndices[Face]].TexcoordIndices[Component]];
                        d3DVertex.Normal = Wavefront.Normals[Wavefront.Faces[FaceIndices[Face]].NormalIndices[Component]];
                        temp.Add(d3DVertex);
                    }
                }
            }
            //Hashtable D3DVertexHashtable = new Hashtable(Wavefront.FaceCount * 3);
            List<short> tempIndices = new List<short>(Wavefront.FaceCount * 3);
            List<D3DVertex> D3DVertexList = new List<D3DVertex>(Wavefront.FaceCount * 3);
            short IndiceIndex = 0;
            for (int Index = 0; Index < temp.Count; Index++)
            {
                D3DVertex d3DVertex = temp[Index];
                if (!D3DVertexList.Contains(d3DVertex))
                {
                    //D3DVertexHashtable.Add(d3DVertex, d3DVertex);
                    D3DVertexList.Add(d3DVertex);
                    tempIndices.Add(IndiceIndex);
                    IndiceIndex++;
                }
                else
                {
                    tempIndices.Add((short)D3DVertexList.IndexOf(d3DVertex));
                }
            }
            this.Indices = tempIndices.ToArray();
            D3DVertex[] D3DVertices = D3DVertexList.ToArray();

            RenderDevice Device = new RenderDevice();
            Device.InitializeDevice();

            Microsoft.DirectX.Direct3D.Mesh mesh = new Microsoft.DirectX.Direct3D.Mesh(Wavefront.FaceCount, D3DVertices.Length, MeshFlags.SystemMemory, D3DVertex.Format, Device.Device);

            List<int> newAttributes = new List<int>(Wavefront.FaceCount);
            foreach (Face f in Wavefront.Faces)
            {
                newAttributes.Add(f.MaterialID);
            }
            mesh.LockAttributeBuffer(LockFlags.None);
            mesh.UnlockAttributeBuffer(newAttributes.ToArray());
            mesh.SetIndexBufferData(Indices.ToArray(), LockFlags.None);
            mesh.SetVertexBufferData(D3DVertices.ToArray(), LockFlags.None);

            int[] adj = new int[Wavefront.FaceCount * 3];
            mesh.GenerateAdjacency(0.005F, adj);
            mesh.OptimizeInPlace(MeshFlags.OptimizeAttributeSort, adj);
            IndexBuffer iBuffer = mesh.IndexBuffer;

            short[] D3DIndices;
            int IndiceCount;

            short[][] MaterialFaceIndices = new short[Wavefront.MaterialCount][];

            for (int Material = 0; Material < Wavefront.MaterialCount; Material++)
            {
                iBuffer = Microsoft.DirectX.Direct3D.Mesh.ConvertMeshSubsetToSingleStrip(mesh, Material, MeshFlags.SystemMemory, out IndiceCount);
                GraphicsStream graphics = iBuffer.Lock(0, 0, LockFlags.None);
                unsafe
                {
                    short* IndiceArray = (short*)graphics.InternalData.ToPointer();
                    D3DIndices = new short[IndiceCount];
                    for (int Index = 0; Index < IndiceCount; Index++)
                    {
                        D3DIndices[Index] = IndiceArray[Index];
                    }
                }
                MaterialFaceIndices[Material] = D3DIndices;
            }

            List<short> newIndices = new List<short>();
            Groups = new Group[MaterialFaceIndices.Length];
            for (int i = 0; i < MaterialFaceIndices.Length; i++)
            {
                Groups[i] = new Group();
                Groups[i].IndiceStart = (short)newIndices.Count;
                Groups[i].IndiceCount = (short)MaterialFaceIndices[i].Length;
                Groups[i].ShaderIndex = (short)i;
                newIndices.AddRange(MaterialFaceIndices[i]);
            }
            this.Indices = newIndices.ToArray();

            this._Vertices = new Vector3[D3DVertices.Length];
            this.Texcoords = new Vector2[D3DVertices.Length];
            this.Normals = new Vector3[D3DVertices.Length];
            for (int i = 0; i < D3DVertices.Length; i++)
            {
                _Vertices[i] = D3DVertices[i].Position;
                Texcoords[i] = D3DVertices[i].Texture;
                Normals[i] = D3DVertices[i].Normal;
            }

            CalculateTangentArray(_Vertices.Length, _Vertices, Normals, Texcoords, mesh.NumberFaces, Wavefront.Faces.ToArray(), out Bitangents, out Tangents);
            mesh.Dispose();
        }
コード例 #2
0
        public static void CreateWavefrontOBJFile(WavefrontObject wavefront, string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Read);
            StreamWriter sw = new StreamWriter(fs);
            sw.NewLine = "\r\n";
            if (wavefront.VertexCount > 0)
                foreach (Vector3 v in wavefront.Vertices)
                {
                    sw.WriteLine("v " + Math.Round((double)v.X, 5, MidpointRounding.ToEven).ToString() + " " + Math.Round((double)v.Y, 5, MidpointRounding.ToEven).ToString() + " " + Math.Round((double)v.Z, 5, MidpointRounding.ToEven).ToString());
                }
            sw.WriteLine("# " + wavefront.VertexCount.ToString() + " Vertices");
            sw.WriteLine();

            if (wavefront.TexcoordCount > 0)
                foreach (Vector2 vt in wavefront.Texcoords)
                {
                    sw.WriteLine("vt " + Math.Round((double)vt.X, 5, MidpointRounding.ToEven).ToString() + " " + Math.Round((double)vt.Y, 5, MidpointRounding.ToEven).ToString());
                }
            sw.WriteLine("# " + wavefront.TexcoordCount.ToString() + " Texcoords");
            sw.WriteLine();
            if (wavefront.NormalCount > 0)
                foreach (Vector3 vn in wavefront.Normals)
                {
                    sw.WriteLine("vn " + Math.Round((double)vn.X, 5, MidpointRounding.ToEven).ToString() + " " + Math.Round((double)vn.Y, 5, MidpointRounding.ToEven).ToString() + " " + Math.Round((double)vn.Z, 5, MidpointRounding.ToEven).ToString());
                }
            sw.WriteLine("# " + wavefront.NormalCount.ToString() + " Normals");
            sw.WriteLine();

            if (wavefront.FaceCount > 0)
            {
                Dictionary<int, string> MaterialNames;
                MaterialNames = wavefront.Materials.ToDictionary(x => x.Value, x => x.Key);
                int[] Faces;
                string curMat = "";
                string newMat;
                Face temp;
                for (int Group = 0; Group < wavefront.GroupCount; Group++)
                {
                    Faces = wavefront.GetFaceIndicesUsingGroupID(Group);
                    for (int Face = 0; Face < Faces.Length; Face++)
                    {
                        temp = wavefront.Faces[Faces[Face]];
                        newMat = MaterialNames[temp.MaterialID];
                        if (curMat != newMat)
                        {
                            curMat = newMat;
                            sw.WriteLine("usemtl " + curMat);
                        }
                        sw.WriteLine("f " + temp.ToString());
                    }
                    sw.WriteLine("# " + Faces.Length.ToString() + " Faces");
                    sw.WriteLine();
                    curMat = "";
                }
            }

            sw.Dispose();
            fs.Dispose();
        }
コード例 #3
0
ファイル: Mesh.cs プロジェクト: kholdfuzion/halo2x-sunfish
        public void ExportWavefrontObject(Shader[] shaders)
        {
            WavefrontObject wfo = new WavefrontObject();
            wfo.Vertices = new List<Vector3>( _Vertices);
            wfo.VertexCount = _Vertices.Length;
            wfo.Texcoords = new List<Vector2>(Texcoords);
            wfo.TexcoordCount = Texcoords.Length;
            wfo.Normals = new List<Vector3>(Normals);
            wfo.NormalCount = Normals.Length;
            wfo.Materials = new Dictionary<string, int>();
            for (int i = 0; i < shaders.Length; i++)
                wfo.Materials.Add("Default_" + i.ToString(), i);
            wfo.GroupCount = Groups.Length;


            List<Face> FaceArray = new List<Face>(Indices.Length);

            for (int i = 0; i < Groups.Length; i++)
            {
                int Start = Groups[i].IndiceStart;
                int End = Groups[i].IndiceStart + Groups[i].IndiceCount - 2;
                bool Winding = true;

                for (int x = Start; x < End; x++)
                {
                    Face Temp = new Face(
                        Indices[x], 
                        Indices[x + 1], 
                        Indices[x + 2], 
                        Indices[x], 
                        Indices[x + 1], 
                        Indices[x + 2], 
                        Indices[x], 
                        Indices[x + 1], 
                        Indices[x + 2]
                        );
                    Temp.MaterialID = Groups[i].ShaderIndex;
                    Temp.GroupID = i;
                    if (!Temp.IsDegenerate)
                    {
                        FaceArray.Add(Temp);
                        if (Winding == false)
                        {
                            short y = Temp.VertexIndices[1];
                            short z = Temp.VertexIndices[2];
                            Temp.VertexIndices[1] = z;
                            Temp.VertexIndices[2] = y;
                            y = Temp.TexcoordIndices[1];
                            z = Temp.TexcoordIndices[2];
                            Temp.TexcoordIndices[1] = z;
                            Temp.TexcoordIndices[2] = y;
                            y = Temp.NormalIndices[1];
                            z = Temp.NormalIndices[2];
                            Temp.NormalIndices[1] = z;
                            Temp.NormalIndices[2] = y;
                            Winding = true;
                        }
                        else
                        {
                            Winding = false;
                        }

                    }
                    else
                    {
                        if (Winding == false) { Winding = true; }
                        else { Winding = false; }
                    }
                }
            }
            FaceArray.TrimExcess();
            wfo.Faces = FaceArray;
            wfo.FaceCount = FaceArray.Count;

            Wavefront.CreateWavefrontOBJFile(wfo, "O:\\test.obj");
        }
コード例 #4
0
        public static WavefrontObject ParseWavefrontOBJFile(string filename)
        {
            StreamReader sr = new StreamReader(File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
            string s = sr.ReadToEnd();
            sr.Close();
            string[] Lines = s.Split(new string[] { "\r\n", "\n\r", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries);
            s = "";

            WavefrontObject Wavefront = new WavefrontObject();

            int Material = -1;
            int Group = -1;

            string Line;
            string[] components;
            string t;
            string last;
            int Length;

            bool Scan = true;

            for (int Pass = 0; Pass < 2; Pass++)
            {
                for (int i = 0; i < Lines.Length; i++)
                {
                    Line = Lines[i].Trim();
                    Length = Line.IndexOf(" ");
                    if (Length > 0)
                        Line = Line.Substring(0, Length);
                    last = s;
                    switch (Line)
                    {
                        case "v":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.VertexCount++;
                            else
                            {
                                float x = float.Parse(components[1]);
                                float y = float.Parse(components[2]);
                                float z = float.Parse(components[3]);
                                Wavefront.Vertices.Add(new Vector3(x, y, z));
                            }
                            break;
                        case "vt":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.TexcoordCount++;
                            else
                            {
                                float u = float.Parse(components[1]);
                                float v = float.Parse(components[2]);
                                Wavefront.Texcoords.Add(new Vector2(u, v));
                            }
                            break;
                        case "vn":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.NormalCount++;
                            else
                            {
                                float x = float.Parse(components[1]);
                                float y = float.Parse(components[2]);
                                float z = float.Parse(components[3]);
                                Wavefront.Normals.Add(new Vector3(x, y, z));
                            }
                            break;
                        case "f":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " ", "/" }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.FaceCount++;
                            else
                            {
                                Face temp = new Face(components);
                                temp.MaterialID = Material;
                                temp.GroupID = Group;
                                Wavefront.Faces.Add(temp);
                            }
                            break;
                        case "l":
                            t = Lines[i].Trim();
                            if (Scan)
                                Wavefront.LineCount++;
                            else
                            {
                                Line temp = new Line(t);
                                Wavefront.Lines.Add(temp);
                            }
                            break;
                        case "g":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.GroupCount++;
                            else
                            {
                                if (!(components.Length == 1) && !Wavefront.Groups.ContainsKey(components[1]))
                                {
                                    Wavefront.Groups.Add(components[1], Wavefront.Groups.Count);
                                    Group = Wavefront.Groups[components[1]];
                                }
                                else if (!(components.Length == 1))
                                    Group = Wavefront.Groups[components[1]];
                            }
                            break;
                        case "usemtl":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.MaterialCount++;
                            else
                            {
                                if (!Wavefront.Materials.ContainsKey(components[1]))
                                    Wavefront.Materials.Add(components[1], Wavefront.Materials.Count);
                                Material = Wavefront.Materials[components[1]];
                            }
                            break;
                        default:
                            break;
                    }
                }

                if (Scan)
                {
                    Wavefront.Initialize();
                    Scan = false;
                }
            }
            return Wavefront;
        }