Beispiel #1
0
        public static void Write(Model model, string name, ParsingFlags ps = ParsingFlags.WriteAll)
        {
            int mi = 0, ei = 0;

            foreach (ModelMesh mesh in model.Meshes)
            {
                // Get All The Distinct Meshes
                foreach (ModelMeshPart mp in mesh.MeshParts.Distinct(new MMComp()))
                {
                    string       nfObj = name + "." + mi + ".obj";
                    StreamWriter fObj  = new StreamWriter(new BufferedStream(File.Create(nfObj)));
                    WriteObj(new MeshPart(mp), fObj, ps);
                    fObj.Flush(); fObj.Close();
                    mi++;
                }
                // Get All The Distinct Effects
                foreach (EffectMaterial e in mesh.Effects)
                {
                    string       nfEff = name + "." + ei + ".fxc";
                    StreamWriter fEff  = new StreamWriter(new BufferedStream(File.Create(nfEff)));
                    WriteEffect(e, fEff);
                    fEff.Flush(); fEff.Close();
                    ei++;
                }
            }
        }
Beispiel #2
0
 private void LoadBulletModel(RTSRenderer renderer, Stream s, ParsingFlags pf = ParsingFlags.ConversionOpenGL)
 {
     VertexPositionNormalTexture[] v;
     int[] inds;
     ObjParser.TryParse(s, out v, out inds, pf);
     VertexPositionTexture[] verts = new VertexPositionTexture[v.Length];
     for (int i = 0; i < verts.Length; i++)
     {
         verts[i].Position          = v[i].Position;
         verts[i].TextureCoordinate = v[i].TextureCoordinate;
     }
     plBullets.VBuffer = renderer.CreateVertexBuffer(VertexPositionTexture.VertexDeclaration, verts.Length, BufferUsage.WriteOnly);
     plBullets.VBuffer.SetData(verts);
     plBullets.IBuffer = renderer.CreateIndexBuffer(IndexElementSize.ThirtyTwoBits, inds.Length, BufferUsage.WriteOnly);
     plBullets.IBuffer.SetData(inds);
 }
Beispiel #3
0
 public static bool TryParse(Stream s, out ObjTriangle[] tris, ParsingFlags ps = ParsingFlags.None)
 {
     VertexPositionNormalTexture[] verts;
     int[] inds;
     if (TryParse(s, out verts, out inds, ps))
     {
         tris = new ObjTriangle[inds.Length / 3];
         for (int ti = 0, i = 0; ti < tris.Length; ti++)
         {
             tris[ti] = new ObjTriangle(
                 verts[inds[i]],
                 verts[inds[i + 1]],
                 verts[inds[i + 2]]
                 );
             i += 3;
         }
         return(true);
     }
     tris = null;
     return(false);
 }
Beispiel #4
0
        public static void WriteObj(MeshPart mp, StreamWriter writer, ParsingFlags ps = ParsingFlags.WriteAll)
        {
            ParsingFlags capable = ParsingFlags.None;

            // Loop Through All Vertex Elements
            VertexElement[] elements = mp.VBuffer.VertexDeclaration.GetVertexElements();
            foreach (VertexElement ve in elements)
            {
                // Choose Formatting Functions By Type
                switch (ve.VertexElementFormat)
                {
                case VertexElementFormat.Vector2: WriteElement <Vector2>(writer, ve, mp, Format, ref capable); break;

                case VertexElementFormat.Vector3: WriteElement <Vector3>(writer, ve, mp, Format, ref capable); break;

                case VertexElementFormat.Vector4: WriteElement <Vector4>(writer, ve, mp, Format, ref capable); break;

                case VertexElementFormat.Single: WriteElement <float>(writer, ve, mp, Format, ref capable); break;

                case VertexElementFormat.Color: WriteElement <Color>(writer, ve, mp, Format, ref capable); break;

                case VertexElementFormat.Byte4: WriteElement <Color>(writer, ve, mp, Format, ref capable); break;

                default:
                    // Those Are The Basic Types
                    break;
                }
            }
            // Only Write What Is Capable
            ps &= capable;

            // Write Indices
            switch (mp.IBuffer.IndexElementSize)
            {
            case IndexElementSize.SixteenBits: WriteIndices <short>(writer, mp, Format, ps); break;

            case IndexElementSize.ThirtyTwoBits: WriteIndices <int>(writer, mp, Format, ps); break;
            }
        }
Beispiel #5
0
        static void WriteIndices <T>(StreamWriter writer, MeshPart mp, Func <T, int> formatter, ParsingFlags ps) where T : struct
        {
            IndexBuffer iBuffer = mp.IBuffer;

            T[] data  = new T[mp.NumIndices];
            int iSize = mp.IBuffer.IndexElementSize == IndexElementSize.SixteenBits ? 2 : 4;

            mp.IBuffer.GetData(mp.StartIndex * iSize, data, 0, data.Length);
            int i = 0;

            while (i < data.Length)
            {
                writer.Write("f");
                for (int vi = 0; vi < 3 && i < data.Length; vi++)
                {
                    int vert;
                    if (ps.HasFlag(ParsingFlags.FlipTriangleOrder))
                    {
                        vert = formatter(data[i + (2 - vi)]) + 1;
                    }
                    else
                    {
                        vert = formatter(data[i + vi]) + 1;
                    }

                    writer.Write(" " + vert);
                    writer.Write("/");
                    if (ps.HasFlag(ParsingFlags.WriteUV))
                    {
                        writer.Write(vert);
                    }
                    writer.Write("/");
                    if (ps.HasFlag(ParsingFlags.WriteNorms))
                    {
                        writer.Write(vert);
                    }
                }
                i += 3;
                writer.WriteLine("");
            }
        }
Beispiel #6
0
        static void WriteElementByUsage <T>(StreamWriter writer, T[] data, VertexElement ve, Func <T, string> formatter, ref ParsingFlags ps)
        {
            switch (ve.VertexElementUsage)
            {
            case VertexElementUsage.Position:
                if (ve.UsageIndex == 0)
                {
                    WriteAllElements(writer, data, "v", formatter);
                }
                else
                {
                    WriteAllElements(writer, data, "v" + ve.UsageIndex, formatter);
                }
                break;

            case VertexElementUsage.Normal:
                ps |= ParsingFlags.WriteNorms;
                if (ve.UsageIndex == 0)
                {
                    WriteAllElements(writer, data, "vn", formatter);
                }
                else
                {
                    WriteAllElements(writer, data, "vn" + ve.UsageIndex, formatter);
                }
                break;

            case VertexElementUsage.TextureCoordinate:
                ps |= ParsingFlags.WriteUV;
                if (ps.HasFlag(ParsingFlags.FlipTexCoordV))
                {
                    Vector2[] vt = data as Vector2[];
                    if (vt != null)
                    {
                        for (int i = 0; i < vt.Length; i++)
                        {
                            vt[i].Y = 1 - vt[i].Y;
                        }
                        data = vt as T[];
                    }
                }
                if (ve.UsageIndex == 0)
                {
                    WriteAllElements(writer, data, "vt", formatter);
                }
                else
                {
                    WriteAllElements(writer, data, "vt" + ve.UsageIndex, formatter);
                }
                break;

            case VertexElementUsage.Color:
                ps |= ParsingFlags.WriteColor;
                if (ve.UsageIndex == 0)
                {
                    WriteAllElements(writer, data, "vc", formatter);
                }
                else
                {
                    WriteAllElements(writer, data, "vc" + ve.UsageIndex, formatter);
                }
                break;
            }
        }
Beispiel #7
0
 static void WriteElement <T>(StreamWriter writer, VertexElement ve, MeshPart mp, Func <T, string> formatter, ref ParsingFlags ps) where T : struct
 {
     T[] data = new T[mp.NumVertices];
     mp.VBuffer.GetData(ve.Offset + mp.VertexOffset * mp.VertexStride, data, 0, data.Length, mp.VertexStride);
     WriteElementByUsage(writer, data, ve, formatter, ref ps);
 }
Beispiel #8
0
 public static bool TryParse(Stream s, GraphicsDevice g, out VertexBuffer vb, out IndexBuffer ib, ParsingFlags ps = ParsingFlags.None)
 {
     VertexPositionNormalTexture[] verts;
     int[] inds;
     if (!TryParse(s, out verts, out inds, ps))
     {
         vb = null;
         ib = null;
         return(false);
     }
     vb = new VertexBuffer(g, VertexPositionNormalTexture.VertexDeclaration, verts.Length, BufferUsage.WriteOnly);
     vb.SetData(verts);
     ib = new IndexBuffer(g, IndexElementSize.ThirtyTwoBits, inds.Length, BufferUsage.WriteOnly);
     ib.SetData(inds);
     return(true);
 }
Beispiel #9
0
        public static bool TryParse(Stream s, GraphicsDevice g, ContentManager c, out Effect fx, ref List <object> refs, ParsingFlags ps = ParsingFlags.None)
        {
            fx = null;
            StreamReader f = new StreamReader(new BufferedStream(s));

            // Get The Arguments From The Material File
            List <string[]> args = new List <string[]>();

            while (!f.EndOfStream)
            {
                string line = f.ReadLine();
                if (string.IsNullOrWhiteSpace(line))
                {
                    continue;
                }
                string[] split = line.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
                if (split.Length < 1)
                {
                    continue;
                }
                split[0] = split[0].Trim().ToLower();
                switch (split[0])
                {
                case "fx": if (split.Length >= 2)
                    {
                        args.Add(split);
                    }
                    break;

                case "fxpt": if (split.Length >= 3)
                    {
                        args.Add(split);
                    }
                    break;

                case "fxptc": if (split.Length >= 3)
                    {
                        args.Add(split);
                    }
                    break;

                case "fxpf": if (split.Length >= 4)
                    {
                        args.Add(split);
                    }
                    break;
                }
            }

            // Get The Effect For This Material
            Predicate <string[]> fxMatch = (a) => { return(a[0].Equals("fx")); };

            string[] fxArg = args.Find(fxMatch);
            if (fxArg == null)
            {
                return(false);
            }
            args.RemoveAll(fxMatch);


            // Try To Create The Effect
            if (ps.HasFlag(ParsingFlags.LoadEffectByteCode))
            {
                try {
                    byte[] code = null;
                    using (FileStream fxs = File.OpenRead(fxArg[1].Trim())) {
                        code = new byte[fxs.Length];
                        fxs.Read(code, 0, code.Length);
                    }
                    fx = new Effect(g, code);
                }
                catch (Exception) { fx = null; return(false); }
            }
            else
            {
                try { fx = c.Load <Effect>(fxArg[1].Trim()); }
                catch (Exception) { fx = null; return(false); }
            }

            // Will Attempt To Set As Many Uniforms As Possible Without Raising Errors
            foreach (string[] arg in args)
            {
                switch (arg[0])
                {
                case "fxpt":
                    EffectParameter fxpt = fx.Parameters[arg[1].Trim()];
                    if (fxpt == null)
                    {
                        continue;
                    }
                    try {
                        Texture2D t = null;
                        if (ps.HasFlag(ParsingFlags.LoadTextureStream))
                        {
                            using (FileStream ts = File.OpenRead(arg[2].Trim())) {
                                t = Texture2D.FromStream(g, ts);
                            }
                        }
                        else
                        {
                            t = c.Load <Texture2D>(arg[2].Trim());
                        }
                        if (t != null)
                        {
                            refs.Add(t);
                            fxpt.SetValue(t);
                        }
                    }
                    catch (Exception) { continue; }
                    break;

                case "fxptc":     // Texture Cube Parameter
                    EffectParameter fxptc = fx.Parameters[arg[1].Trim()];
                    if (fxptc == null)
                    {
                        continue;
                    }
                    try {
                        TextureCube tc = c.Load <TextureCube>(arg[2].Trim());
                        if (tc != null)
                        {
                            refs.Add(tc);
                            fxptc.SetValue(tc);
                        }
                    }
                    catch (Exception) { continue; }
                    break;

                case "fxpf":     // Vector Parameter
                    EffectParameter fxptv = fx.Parameters[arg[1].Trim()];
                    int             comps;
                    if (fxptv == null || !int.TryParse(arg[2], out comps))
                    {
                        continue;
                    }
                    string[] sc = arg[3].Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                    if (sc.Length != comps)
                    {
                        continue;
                    }
                    switch (comps)
                    {
                    case 1:
                        float v1;
                        if (float.TryParse(sc[0], out v1))
                        {
                            fxptv.SetValue(v1);
                        }
                        break;

                    case 2:
                        Vector2 v2 = Vector2.Zero;
                        if (float.TryParse(sc[0], out v2.X) &&
                            float.TryParse(sc[1], out v2.Y)
                            )
                        {
                            fxptv.SetValue(v2);
                        }
                        break;

                    case 3:
                        Vector3 v3 = Vector3.Zero;
                        if (float.TryParse(sc[0], out v3.X) &&
                            float.TryParse(sc[1], out v3.Y) &&
                            float.TryParse(sc[2], out v3.Z)
                            )
                        {
                            fxptv.SetValue(v3);
                        }
                        break;

                    case 4:
                        Vector4 v4 = Vector4.Zero;
                        if (float.TryParse(sc[0], out v4.X) &&
                            float.TryParse(sc[1], out v4.Y) &&
                            float.TryParse(sc[2], out v4.Z) &&
                            float.TryParse(sc[3], out v4.W)
                            )
                        {
                            fxptv.SetValue(v4);
                        }
                        break;

                    default:
                        if (comps > 4)
                        {
                            float[] vn  = new float[comps];
                            bool    vnc = true;
                            for (int i = 0; i < sc.Length && i < vn.Length && vnc; i++)
                            {
                                if (!float.TryParse(sc[i], out vn[i]))
                                {
                                    vnc = false;
                                }
                            }
                            if (vnc)
                            {
                                fxptv.SetValue(vn);
                            }
                        }
                        break;
                    }
                    break;
                }
            }
            return(true);
        }
Beispiel #10
0
        public static bool TryParse(Stream s, out VertexPositionNormalTexture[] verts, out int[] inds, ParsingFlags ps = ParsingFlags.None)
        {
            // Default Values
            verts = null; inds = null;

            // Encapsulate Stream To A Buffered Stream Reader
            BufferedStream bs = new BufferedStream(s);
            StreamReader   f  = new StreamReader(bs);

            // List Of Components
            List <Vector3> pos   = new List <Vector3>(100);
            List <Vector2> uv    = new List <Vector2>(100);
            List <Vector3> norms = new List <Vector3>(100);
            List <Tri>     tris  = new List <Tri>(200);

            // Buffer Vectors
            Vector3 v3 = Vector3.Zero; Vector2 v2 = Vector2.Zero;

            // Get All The Information From The Stream
            string line; string[] spl;

            while (!f.EndOfStream)
            {
                line = f.ReadLine();
                spl  = Regex.Split(line, @"\s+", RegexOptions.IgnorePatternWhitespace);
                switch (spl[0].ToLower())
                {
                case "v":     // Vertex Position
                    if (spl.Length != 4)
                    {
                        return(false);
                    }
                    if (!float.TryParse(spl[1], out v3.X))
                    {
                        return(false);
                    }
                    if (!float.TryParse(spl[2], out v3.Y))
                    {
                        return(false);
                    }
                    if (!float.TryParse(spl[3], out v3.Z))
                    {
                        return(false);
                    }
                    pos.Add(v3);
                    break;

                case "vt":     // Vertex Texture Coordinate
                    if (spl.Length != 3)
                    {
                        return(false);
                    }
                    if (!float.TryParse(spl[1], out v2.X))
                    {
                        return(false);
                    }
                    if (!float.TryParse(spl[2], out v2.Y))
                    {
                        return(false);
                    }
                    // Possibly Flip Tex Coords
                    if (ps.HasFlag(ParsingFlags.FlipTexCoordV))
                    {
                        v2.Y = 1 - v2.Y;
                    }
                    uv.Add(v2);
                    break;

                case "vn":     // Vertex Normal
                    if (spl.Length != 4)
                    {
                        return(false);
                    }
                    if (!float.TryParse(spl[1], out v3.X))
                    {
                        return(false);
                    }
                    if (!float.TryParse(spl[2], out v3.Y))
                    {
                        return(false);
                    }
                    if (!float.TryParse(spl[3], out v3.Z))
                    {
                        return(false);
                    }
                    norms.Add(v3);
                    break;

                case "f":     // Mesh Triangle
                    if (spl.Length != 4)
                    {
                        return(false);
                    }
                    try {
                        // Add In Correct Triangle Ordering
                        if (ps.HasFlag(ParsingFlags.FlipTriangleOrder))
                        {
                            tris.Add(new Tri(spl[1], spl[3], spl[2]));
                        }
                        else
                        {
                            tris.Add(new Tri(spl[1], spl[2], spl[3]));
                        }
                    }
                    catch (Exception) {
                        return(false);
                    }
                    break;
                }
            }



            // Create Indices
            VertDict vd = new VertDict();

            inds = new int[tris.Count * 3];
            int ii = 0;

            foreach (Tri tri in tris)
            {
                inds[ii++] = vd.Get(tri.V1);
                inds[ii++] = vd.Get(tri.V2);
                inds[ii++] = vd.Get(tri.V3);
            }

            // Create Vertices
            verts = new VertexPositionNormalTexture[vd.Count];
            foreach (VertDict.Key v in vd)
            {
                verts[v.Index].Position = pos[v.Vertex.PosInd];

                if (v.Vertex.UVInd < 0)
                {
                    verts[v.Index].TextureCoordinate = Vector2.Zero;
                }
                else
                {
                    verts[v.Index].TextureCoordinate = uv[v.Vertex.UVInd];
                }

                if (v.Vertex.NormInd < 0)
                {
                    verts[v.Index].Normal = Vector3.Zero;
                }
                else
                {
                    verts[v.Index].Normal = norms[v.Vertex.NormInd];
                }
            }

            return(true);
        }
 private void LoadBulletModel(RTSRenderer renderer, Stream s, ParsingFlags pf = ParsingFlags.ConversionOpenGL)
 {
     VertexPositionNormalTexture[] v;
     int[] inds;
     ObjParser.TryParse(s, out v, out inds, pf);
     VertexPositionTexture[] verts = new VertexPositionTexture[v.Length];
     for(int i = 0; i < verts.Length; i++) {
         verts[i].Position = v[i].Position;
         verts[i].TextureCoordinate = v[i].TextureCoordinate;
     }
     plBullets.VBuffer = renderer.CreateVertexBuffer(VertexPositionTexture.VertexDeclaration, verts.Length, BufferUsage.WriteOnly);
     plBullets.VBuffer.SetData(verts);
     plBullets.IBuffer = renderer.CreateIndexBuffer(IndexElementSize.ThirtyTwoBits, inds.Length, BufferUsage.WriteOnly);
     plBullets.IBuffer.SetData(inds);
 }