Exemplo n.º 1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CAMR"/> class.
        /// </summary>
        /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
        public CAMR(BaseChunk from) : base(from)
        {
            while (!EndOfData)
            {
                BaseChunk nextChunk = ReadChunk();

                switch (nextChunk.ChunkName)
                {
                case "NAME":
                    Name = nextChunk.ReadString(nextChunk.Data.Length);
                    break;

                case "DATA":
                    //consists of floats only
                    //a float has a size of 4 bytes
                    int len = nextChunk.Data.Length / 4;
                    CameraData = new float[len];

                    for (int i = 0; i < CameraData.Length; i++)
                    {
                        CameraData[i] = nextChunk.ReadFloat();
                    }
                    break;
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MSH2"/> class.
        /// </summary>
        /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
        public MSH2(BaseChunk from) : base(from)
        {
            Models = new List <MODL>();

            while (!EndOfData)
            {
                BaseChunk nextChunk = ReadChunk();

                switch (nextChunk.ChunkName)
                {
                case "SINF":
                    SelectionInformation = new SINF(nextChunk);
                    break;

                case "CAMR":
                    Camera = new CAMR(nextChunk);
                    break;

                case "MATL":
                    MaterialList = new MATL(nextChunk);
                    break;

                case "MODL":
                    Models.Add(new MODL(nextChunk));
                    break;
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Use this Constructor to create a new Chunk from a given <see cref="BaseChunk" />. This must be overriden by every subclass!
        /// </summary>
        /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
        public BaseChunk(BaseChunk from)
        {
            Log.Add("Process Chunk " + from.ChunkName, LogType.Info);

            ChunkName = from.ChunkName;
            data.AddRange(from.data);
            Owner = from.Owner;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Writes a given Chunk into the data stream
        /// </summary>
        /// <param name="chunk">The chunk to write</param>
        public void WriteChunk(BaseChunk chunk)
        {
            if (chunk == null)
            {
                return;
            }

            chunk.WriteData();
            chunk.WriteChunkLength();

            data.AddRange(chunk.data);
            chunk.FlushData();
        }
Exemplo n.º 5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SINF"/> class.
        /// </summary>
        /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
        public SINF(BaseChunk from) : base(from) {
            while (!EndOfData) {
                BaseChunk nextChunk = ReadChunk();

                switch (nextChunk.ChunkName) {
                    case "NAME":
                        Name = nextChunk.ReadString(nextChunk.Data.Length);
                        break;
                    case "FRAM":
                        FrameInformation = new FRAM(nextChunk);
                        break;
                    case "BBOX":
                        BoundingBox = new BBOX(nextChunk);
                        break;
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Creates a new Chunk from given byte data
        /// </summary>
        /// <param name="inputData">The data to read from</param>
        /// <param name="offset">The offset in the byte array to start reading from</param>
        /// <returns>The new Chunk</returns>
        /// <exception cref="EndOfDataException">Unexpected end of Data</exception>
        /// <exception cref="InvalidChunkException">If Chunk name is not valid or the read chunk length is negative</exception>
        public static BaseChunk FromData(byte[] inputData, int offset, MSH owner)
        {
            if (inputData.Length < 8 || offset + 8 > inputData.Length)
            {
                Log.Add("Unexpected end of Data!", LogType.Error);
                throw new EndOfDataException("Unexpected end of Data!");
            }

            BaseChunk chunk = new BaseChunk(owner);

            //every chunk starts with a chunk name (4 bytes)
            chunk.ChunkName = inputData.SubArray(offset, 4).GetString();
            offset         += 4;

            //and an Int32 defining the length of the chunk (in bytes)
            int length = BitConverter.ToInt32(inputData, offset);

            offset += 4;

            if (!Regex.Match(chunk.ChunkName, ValidChunkRegEx).Success)
            {
                Log.Add(chunk.ChunkName + " is not a valid Chunk Name!", LogType.Error);
                throw new InvalidChunkException(chunk.ChunkName + " is not a valid Chunk Name!");
            }

            if (length < 0)
            {
                Log.Add(length + " is not a valid Chunk Length!", LogType.Error);
                throw new InvalidChunkException(length + " is not a valid Chunk Length!");
            }

            if (offset + length > inputData.Length)
            {
                Log.Add("Unexpected end of Data!", LogType.Error);
                throw new EndOfDataException("Unexpected end of Data!");
            }

            //create own data
            chunk.data.AddRange(inputData.SubArray(offset, length));

            chunk.ResetPosition();
            Log.Add("Valid Chunk " + chunk.ChunkName + " found of length " + chunk.data.Count, LogType.Info);

            return(chunk);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GEOM"/> class.
        /// </summary>
        /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
        public GEOM(BaseChunk from) : base(from)
        {
            while (!EndOfData)
            {
                BaseChunk nextChunk = ReadChunk();

                switch (nextChunk.ChunkName)
                {
                case "BBOX":
                    BoundingBox = new BBOX(nextChunk);
                    break;

                case "SEGM":
                    SEGM segm = new SEGM(nextChunk);
                    Segments.Add(segm);
                    break;
                }
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Reads a chunk from given data
        /// </summary>
        /// <returns></returns>
        /// <exception cref="EndOfStreamException">Unexpected end of Data!</exception>
        public BaseChunk ReadChunk()
        {
            //a new Chunk as to be at least 8 Bytes in size!
            if (position + 8 > data.Count)
            {
                Log.Add("Unexpected end of Data!", LogType.Error);
                throw new EndOfDataException("Unexpected end of Data!");
            }

            //we just need to pass the data from our current position
            //The newly created chunk will cut it futher down later
            //byte[] chunkData = Data.SubArray(position, Data.Length - position);

            BaseChunk newChunk = FromData(data.ToArray(), position, Owner);

            //length of the chunk + header size
            position += newChunk.data.Count + 8;

            return(newChunk);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MODL"/> class.
        /// </summary>
        /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
        public MODL(BaseChunk from) : base(from)
        {
            while (!EndOfData)
            {
                BaseChunk nextChunk = ReadChunk();

                switch (nextChunk.ChunkName)
                {
                case "MTYP":
                    Type = (MTYP)nextChunk.ReadInt32();
                    break;

                case "MNDX":
                    index = nextChunk.ReadInt32();
                    break;

                case "NAME":
                    Name = nextChunk.ReadString(nextChunk.Data.Length);
                    break;

                case "PRNT":
                    parentName = nextChunk.ReadString(nextChunk.Data.Length);
                    break;

                case "FLGS":
                    Flag = new ModelFlag(true, nextChunk.ReadInt32());
                    break;

                case "TRAN":
                    Scale       = nextChunk.ReadVector3();
                    Rotation    = nextChunk.ReadVector3();
                    Translation = nextChunk.ReadVector3();
                    UnknownTRAN = nextChunk.ReadFloat();
                    break;

                case "GEOM":
                    Geometry = new GEOM(nextChunk);
                    break;
                }
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="HEDR"/> class.
        /// </summary>
        /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
        public HEDR(BaseChunk from) : base(from)
        {
            while (!EndOfData)
            {
                BaseChunk nextChunk = ReadChunk();

                switch (nextChunk.ChunkName)
                {
                case "SHVO":
                    Shvo = nextChunk.ReadInt32();
                    break;

                case "MSH2":
                    Mesh = new MSH2(nextChunk);
                    break;

                default:
                    break;
                }
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Creates a new Chunk from given Stream
        /// </summary>
        /// <param name="stream">The Stream to read from</param>
        /// <returns>The new Chunk</returns>
        /// <exception cref="EndOfDataException">Unexpected end of Data</exception>
        /// <exception cref="InvalidChunkException">If Chunk name is not valid or the read chunk length is negative</exception>
        public static BaseChunk FromData(ChunkStream stream, MSH owner)
        {
            BaseChunk chunk = new BaseChunk(owner);

            //every chunk starts with a chunk name (4 bytes)
            chunk.ChunkName = stream.ReadString(4);

            //and an Int32 defining the length of the chunk (in bytes)
            int length = stream.ReadInt32();

            if (!Regex.Match(chunk.ChunkName, ValidChunkRegEx).Success)
            {
                Log.Add(chunk.ChunkName + " is not a valid Chunk Name!", LogType.Error);
                throw new InvalidChunkException(chunk.ChunkName + " is not a valid Chunk Name!");
            }

            if (length < 0)
            {
                Log.Add(length + " is not a valid Chunk Length!", LogType.Error);
                throw new InvalidChunkException(length + " is not a valid Chunk Length!");
            }

            //read all the data
            byte[] buffer = new byte[length];

            try {
                stream.Read(buffer, 0, length);
                chunk.data.AddRange(buffer);
            }
            catch (ArgumentOutOfRangeException ex) {
                Log.Add("Unexpected end of Data!", LogType.Error);
                throw new EndOfDataException("Unexpected end of Data!", ex);
            }

            chunk.ResetPosition();

            return(chunk);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MATL"/> class.
        /// </summary>
        /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
        public MATL(BaseChunk from) : base(from)
        {
            Materials = new List <MATD>();

            //The first four bytes of data contain sa 32-bit integer specifying the number of MATD sections contained in this section.
            int len = ReadInt32();

            while (!EndOfData)
            {
                BaseChunk nextChunk = ReadChunk();

                switch (nextChunk.ChunkName)
                {
                case "MATD":
                    Materials.Add(new MATD(nextChunk));
                    break;
                }
            }

            if (len != Materials.Count)
            {
                Log.Add("The number of expected materials (" + len + ") does not match the number of actually read materials (" + Materials.Count + ")!", LogType.Warning);
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MATD"/> class.
        /// </summary>
        /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
        public MATD(BaseChunk from) : base(from)
        {
            while (!EndOfData)
            {
                BaseChunk nextChunk = ReadChunk();

                switch (nextChunk.ChunkName)
                {
                case "NAME":
                    Name = nextChunk.ReadString(nextChunk.Data.Length);
                    break;

                case "DATA":
                    Diffuse  = nextChunk.ReadColor();
                    Ambient  = nextChunk.ReadColor();
                    Specular = nextChunk.ReadColor();

                    SpecularSharpness = nextChunk.ReadFloat();
                    break;

                case "ATRB":
                    attribute = nextChunk.ReadInt32();
                    break;
                }

                //catch texture entrys (usually TX0D)
                Match txMatch = Regex.Match(nextChunk.ChunkName, "TX[0-9]{1}D");
                if (txMatch.Success)
                {
                    //the number sits at the 3rd position = [2]
                    //the symbol "0" ist at position 48 in the ascii table
                    int index = txMatch.Value[2] - 48;
                    Textures[index] = nextChunk.ReadString(nextChunk.Data.Length);
                }
            }
        }
Exemplo n.º 14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SEGM"/> class.
        /// </summary>
        /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
        public SEGM(BaseChunk from) : base(from)
        {
            List <Vector3> verts   = new List <Vector3>();
            List <Vector3> normals = new List <Vector3>();
            List <Vector2> uvs     = new List <Vector2>();

            Polygon currentPoly = new Polygon(vertices);
            bool    lastBoundry = false;

            while (!EndOfData)
            {
                BaseChunk nextChunk = ReadChunk();
                int       count     = 0;

                switch (nextChunk.ChunkName)
                {
                case "MATI":
                    matIndex = nextChunk.ReadInt32();
                    break;

                case "POSL":
                    count = nextChunk.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        verts.Add(nextChunk.ReadVector3());
                    }
                    break;

                case "NRML":
                    count = nextChunk.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        normals.Add(nextChunk.ReadVector3());
                    }
                    break;

                case "UV0L":
                    count = nextChunk.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        uvs.Add(nextChunk.ReadVector2());
                    }
                    break;

                case "STRP":
                    count = nextChunk.ReadInt32();
                    for (int i = 0; i < count; i++)
                    {
                        VertexIndex next = nextChunk.ReadVertexIndex();

                        if (next.polyBoundary && !lastBoundry)
                        {
                            //polygon finished, add to buffer
                            if (currentPoly.VertexIndices.Count > 0)
                            {
                                polygons.Add(currentPoly);
                            }

                            //start new polygon
                            currentPoly = new Polygon(vertices);

                            //write first index value to polygon
                            currentPoly.VertexIndices.Add(next.index);
                        }
                        else
                        {
                            if (currentPoly != null)
                            {
                                currentPoly.VertexIndices.Add(next.index);
                            }
                            else
                            {
                                //this should never happen
                                Log.Add("Warning: Lone Vertex in Strip Buffer!", LogType.Warning);
                            }
                        }

                        lastBoundry = next.polyBoundary;
                    }
                    break;
                }
            }

            if (uvs.Count > 0)
            {
                hasUVs = true;
            }

            for (int i = 0; i < verts.Count; i++)
            {
                //since uv coordinates are optional, deliver empty ones if non existent
                Vector2 uv = (i < uvs.Count) ? uvs[i] : new Vector2();

                vertices.Add(new Vertex(verts[i], normals[i], uv));
            }

            //Add last Polygon
            if (currentPoly != null && currentPoly.VertexIndices.Count > 0)
            {
                polygons.Add(currentPoly);
            }
        }
Exemplo n.º 15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FRAM"/> class.
 /// </summary>
 /// <param name="from">The <see cref="BaseChunk" /> to use for creating this Chunk. The given data will be interpreted respectively.</param>
 public FRAM(BaseChunk from) : base(from)
 {
     Start     = ReadInt32();
     End       = ReadInt32();
     FrameRate = ReadFloat();
 }
Exemplo n.º 16
0
 public BBOX(BaseChunk from) : base(from)
 {
     Rotation    = ReadVector4();
     Translation = ReadVector3();
     Dimension   = ReadVector4();
 }