0

嗨,我目前正在为 C# / XNA 应用程序开发导入器,我需要一些帮助来将输入(每行是“新”字符串的字符串列表)过滤成更小的块(更小的字符串列表)。

这是如何将输入划分为“帧”的示例,其中包含创建“关键帧”所需的网格和相机数据。

num_frames 4
start 1
end 24
frame_rate 24

frame 1
meshes 2
    name pCube1
        color F:/MayaImporterExporter/ImporterExporter/Bin/Textures/image2.gif
        bump F:/MayaImporterExporter/ImporterExporter/Bin/Textures/images.jpg
        bumpDepth 1
        vertices 36
            meshData...
    name pCube2
        color NONE
        bump none
        bumpDepth 0
        vertices 36
            meshData...
cameras 1
    name persp
        cameraData... 
frame 5
meshes 2
    name pCube1
        color F:/MayaImporterExporter/ImporterExporter/Bin/Textures/image2.gif
        bump F:/MayaImporterExporter/ImporterExporter/Bin/Textures/images.jpg
        bumpDepth 1
        vertices 36
            meshData...
    name pCube2
        color NONE
        bump none
        bumpDepth 0
        vertices 36
            meshData...
cameras 1
    name persp
cameraData...       
frame 10
meshes 2
    name pCube1
        color F:/MayaImporterExporter/ImporterExporter/Bin/Textures/image2.gif
        bump F:/MayaImporterExporter/ImporterExporter/Bin/Textures/images.jpg
        bumpDepth 1
        vertices 36
            meshData...
    name pCube2
        color NONE
        bump none
        bumpDepth 0
        vertices 36
            meshData...
cameras 1
    name persp
        cameraData...
frame 24
meshes 2
    name pCube1
        color F:/MayaImporterExporter/ImporterExporter/Bin/Textures/image2.gif
        bump F:/MayaImporterExporter/ImporterExporter/Bin/Textures/images.jpg
        bumpDepth 1
        vertices 36
            meshData...
    name pCube2
        color NONE
        bump none
        bumpDepth 0
        vertices 36
            meshData...
cameras 1
    name persp
        cameraData...

所以我需要做的是:

  1. 将输入拆分为一个较小的列表,其中包含每个关键帧的网格和相机数据。
  2. 将关键帧数据分成两个列表(一个用于网格,一个用于摄像机)。
  3. 将网格/相机拆分为字符串列表。
  4. 创建网格和相机形成“字符串列表”(我知道这部分)。

所以我需要一些帮助来弄清楚如何将输入数据过滤成更小的块,以从输入中创建网格和相机。

4

2 回答 2

2

您可以使用类似的东西:

       var lines = File.ReadAllLines( path )
                    .Select( s => s.Trim( ) )
                    .Where( s => s.Length > 0 ).ToArray( );
        int index = 0;

        void Next() { index++; }

        bool Peek(string token ) { return lines[index].StartsWith( token ) ;}

        string ReadStringValue  ( ) { 
           var value = lines[index].Split( ' ' )[1]; 
           Next( ); 
           return value; 
        };

        string ReadIntValue () { 
          var value = lines[index].Split( ' ' )[1]; 
          Next( ); 
          return int.Parse(value); 
        };

        Header ReadAnimation() {
           var anim= new Animation();
           while (index<lines.Length)
           {
               if (Peek("num_frames")) anim.NuMFrames = ReadIntValue();
               if (Peek("start")) ....
               if (Peek("frame")) anim.AddFrame( ReadFrame() );
           }

        }

        Frame ReadFrame() {
           if (Peek("frame")) {
              var frame = new Frame();
              frame.Index = ReadIntValue();
              ReadMeshes( frame );
              ReadCameras( frame );                  
              return frame;
           }
           return null;
        }

        void ReadMeshes(Frame frame)
        {
            if (Peek("meshes")) {
                int count = ReadIntValue();
                for (int i =0; i<count; i++) {
                    frame.Meshes.Add( ReadMesh() );
                }
            }
        }

        Mesh ReadMesh() {
           ....
        }
于 2013-08-05T14:52:34.870 回答
0

在成功实施导入器的一些失败尝试之后,我终于想出了如何让它工作。

namespace Importer
{
class ImportHandler
{

    List<string> inputString;
    Readanyfile read= new Readanyfile();
    int num_frames, start, end, frame_rate;
    GraphicsDevice graphicsDevice;
    classes_stat.KeyFrameAnimation Animation;
    public ImportHandler(GraphicsDevice graphicsDevice, Game game,string _inputFile)
    {
        this.graphicsDevice = graphicsDevice;
        this.inputString = read.Load();
        ReadRawScene();
    }


    string ReadStringValue(string str)
    {
        var value = str.Split(' ')[1]; 

       return value; 
    }
    public int strToInt(string str)
    {
        var value = str.Split(' ')[1]; 
       return int.Parse(value); 

    }
    public float strToFloat(string str)
    {
        var value = str.Split(' ')[1]; 
        return float.Parse(value);

    }
    public double strToDouble(string str)
    {
        var value = str.Split(' ')[1]; 
        try
        {
            return double.Parse(value, System.Globalization.CultureInfo.InvariantCulture);
        }
        catch
        {
            return (double) 0.1f;
        }



    }
     private static float[] ParseFloatArray(string str, int count)
    {
        var floats = new float[count];

        var segments = str.Split(' ');

        for (int i = 0; i < count; i++)
        {
            if (i < segments.Length)
            {
                try
                {
                    floats[i] = (float)double.Parse(segments[i], System.Globalization.CultureInfo.InvariantCulture);
                }
                catch
                {
                    floats[i] = 0;
                }
            }
        }

        return floats;
    }
private Vector2 ParseVector2(string str)
    {
        var components = ParseFloatArray(str, 3);

        var vec = new Vector2(components[0], components[1]);

        return components[2] == 0
            ? vec
            : vec / components[2];
    }


    private Vector3 ParseVector3(string str)
    {
        var components = ParseFloatArray(str, 4);

        var vec = new Vector3(components[0], components[1], components[2]);

        return components[3] == 0
            ? vec
            : vec / components[3];
    }
    public void ReadRawScene()
    {
        List<classes_stat.KeyFrame> tempAni = new List<classes_stat.KeyFrame>();
        for (int i = 0; i < inputString.Count(); i++ )
        {
            if (inputString[i].StartsWith("num_frames"))
            {
                num_frames = strToInt(inputString[i]);
            }
            if (inputString[i].StartsWith("start"))
            {
                start = strToInt(inputString[i]);
            }
            if (inputString[i].StartsWith("end"))
            {
                end = strToInt(inputString[i]);
            }
            if (inputString[i].StartsWith("frame_rate"))
            {
                frame_rate = strToInt(inputString[i]);
            }
            if (inputString[i].StartsWith("frame"))
            { tempAni.Add(ReadFrames(strToInt(inputString[i]), i, inputString));
            }
            Animation = new classes_stat.KeyFrameAnimation(frame_rate, start, end, num_frames, tempAni);

        }

    }
    public classes_stat.KeyFrame ReadFrames(int frameIndex,int currentIndex, List<string> inputString )
    {
        List<MeshFromBinary> tempOutPutMesh = new List<MeshFromBinary>();
        List<CameraFromBinary> tempOutPutCam = new List<CameraFromBinary>();
        for (int i = currentIndex + 3; i < inputString.Count(); i++)
        {

            if (inputString[i].StartsWith("meshes"))
            {



                int count = strToInt(inputString[i]);

                for (int x = 0; x < count; x++)
                {

                    MeshFromBinary temp = ReadMeshes(i, inputString);
                    tempOutPutMesh.Add(temp);

                }

            }
            if (inputString[i].StartsWith("cameras"))
            {
                int count = strToInt(inputString[i]);

                for (int x = 0; x < count; x++)
                {
                    tempOutPutCam.Add(ReadCameras(i, inputString));
                }
            }
            if (inputString[i].StartsWith("frame"))
            {
                break;
            }

        }
        classes_stat.KeyFrame frame = new classes_stat.KeyFrame(frameIndex, tempOutPutMesh, tempOutPutCam);
        return frame;
    }
    private MeshFromBinary ReadMeshes(int currentIndex, List<string> inputString)
    {

        int tempCurrentIndex = 0;
        List<classes_stat.MyOwnVertexFormat> temp = new List<classes_stat.MyOwnVertexFormat>();
        string name;
        Texture2D color = ContentTextures.crateTexture; 
        Texture2D bump = ContentTextures.crateTexture;
        double bumpDepth = 0;
        List<Vector3> tmpPos = new List<Vector3>();
        List<Vector3> tmpNor = new List<Vector3>();
        List<Vector3> tmpTan = new List<Vector3>();
        List<Vector2> tmpUV = new List<Vector2>();
        int numberofvertices = 0;
        for (int i = currentIndex; i < inputString.Count(); i++)
        {
            if (inputString[i].StartsWith("name"))
            {


                name = ReadStringValue(inputString[i]);
            }
            if (inputString[i].StartsWith("color"))
            {
                string tmp = ReadStringValue(inputString[i]);
                System.IO.FileStream stream = new System.IO.FileStream(tmp, System.IO.FileMode.Open);
                color = Texture2D.FromStream(graphicsDevice, stream);
                stream.Close();
                stream.Dispose();
                //temp.Add(ReadStringValue());
            }
            if (inputString[i].StartsWith("normalMap"))
            {
                string tmp = ReadStringValue(inputString[i]);
                System.IO.FileStream stream = new System.IO.FileStream(tmp, System.IO.FileMode.Open);
                bump = Texture2D.FromStream(graphicsDevice, stream);
                stream.Close();
                stream.Dispose();
            }
            if (inputString[i].StartsWith("bumpDepth"))
            {
                bumpDepth = strToDouble(inputString[i]);
            }
            if (inputString[i].StartsWith("vertices"))
            {
                numberofvertices = strToInt(inputString[i]);

            }
            if (inputString[i].StartsWith("v"))
            {
                tempCurrentIndex = (i - 1);
                break;
            }
        }
        for (int i = tempCurrentIndex; i < inputString.Count(); i++)
        {
            if (inputString[i].StartsWith("v"))
            {

                tmpPos.Add(ParseVector3(inputString[i]));

            }
            if (inputString[i].StartsWith("vn"))
            {

                tmpNor.Add(ParseVector3(inputString[i]));
            }
            if (inputString[i].StartsWith("t"))
            {

                tmpTan.Add(ParseVector3(inputString[i]));

            }
            if (inputString[i].StartsWith("vt"))
            {
                tmpUV.Add(ParseVector2(inputString[i]));
            }
            if (inputString[i].StartsWith("cameras"))
            {
                break;
            }
            if (inputString[i].StartsWith("name"))
            {
                break;
            }
        }
        for (int i = 0; i < numberofvertices; i++)
        {

            temp.Add(new classes_stat.MyOwnVertexFormat(tmpPos[i], tmpNor[i], tmpTan[i], tmpUV[i]));

        }
        MeshFromBinary mMesh;
        return mMesh = new MeshFromBinary(graphicsDevice, temp, color, bump, bumpDepth);
    }
    private CameraFromBinary ReadCameras(int currentIndex, List<string> inputString)
    {
        int tempCurrentIndex = 0;
        CameraFromBinary temp;
        string name;
        Vector3 tmpPos = new Vector3();
        Vector3 tmpDir = new Vector3();
        Vector3 tmpUp = new Vector3();
        double tmpV_FOV = new double();
        double tmpH_FOV = new double(); 
        double tmpNear_clipping_plane = new double();
        double tmpFar_clipping_plane = new double();
        double tmpAspect_ratio = new double();
        for (int i = currentIndex; i < inputString.Count(); i++)
        {
            if (inputString[i].StartsWith("name"))
            {

                System.Console.WriteLine(ReadStringValue(inputString[i]));
                name = ReadStringValue(inputString[i]);

                tempCurrentIndex = (i + 1);
                break;
            }
        }

        for (int i = tempCurrentIndex; i < inputString.Count(); i++)
        {
            if (inputString[i].StartsWith("eye"))
            {
                tmpPos = ParseVector3(inputString[i]);
            }
            else if (inputString[i].StartsWith("up"))
            {
                tmpUp = ParseVector3(inputString[i]);
            }
            else if (inputString[i].StartsWith("rotXYZ"))
            {
                tmpDir = ParseVector3(inputString[i]);
            }
            else if (inputString[i].StartsWith("v_fov"))
            {
                tmpV_FOV = strToDouble(inputString[i]);
            }
            else if (inputString[i].StartsWith("h_fov"))
            {
                tmpH_FOV = strToDouble(inputString[i]);
            }
            else if (inputString[i].StartsWith("near_clipping_plane"))
            {
                tmpNear_clipping_plane = strToDouble(inputString[i]);
            }
            else if (inputString[i].StartsWith("far_clipping_plane"))
            {
                tmpFar_clipping_plane = strToDouble(inputString[i]);
            }
            else if (inputString[i].StartsWith("aspect_ratio"))
            {
                tmpAspect_ratio = strToDouble(inputString[i]);
            }
            else if (inputString[i].StartsWith("frame"))
            {
                break;
            }
            else if (inputString[i].StartsWith("cameras"))
            {
                break;
            }
            else if (inputString[i].StartsWith("name"))
            {
                break;
            }
        }

        return temp = new CameraFromBinary(tmpPos, tmpDir, tmpV_FOV, tmpAspect_ratio, tmpNear_clipping_plane, tmpFar_clipping_plane);
    }
}
}
于 2013-08-14T00:42:15.630 回答