Пример #1
0
        /// <summary>
        /// Constructor. Creates a data structure out of the XFile given in the memory block.
        /// </summary>
        /// <param name="buffer"></param>
        public XFileParser(byte[] buffer)
        {
            this.buffer = buffer;
            majorVersion = minorVersion = 0;
            isBinaryFormat = false;
            binaryNumCount = 0;
            p = end = -1;
            lineNumber = 0;
            scene = null;

            // vector to store uncompressed file for INFLATE'd X files
            byte[] uncompressed;

            // set up memory pointers
            p = 0;
            end = buffer.Length;

            string header = Encoding.Default.GetString(buffer, 0, 16);
            // check header
            if (header.Substring(0, 4) != "xof ")
                throw new Exception("Header mismatch, file is not an XFile.");

            // read version. It comes in a four byte format such as "0302"
            majorVersion = uint.Parse(header.Substring(4, 2));
            minorVersion = uint.Parse(header.Substring(6, 2));

            bool compressed = false;

            // txt - pure ASCII text format
            if (header.Substring(8, 4) == "txt ")
            {
                isBinaryFormat = false;
            }// bin - Binary format
            else if (header.Substring(8, 4) == "bin ")
            {
                isBinaryFormat = true;
            }
            // tzip - Inflate compressed text format
            else if (header.Substring(8, 4) == "tzip")
            {
                isBinaryFormat = false;
                compressed = true;
            }
            // bzip - Inflate compressed binary format
            else if (header.Substring(8, 4) == "bzip")
            {
                isBinaryFormat = true;
                compressed = true;
            }
            else ThrowException(string.Format("Unsupported xfile format '{0}'", header.Substring(8, 4)));

            // float size
            binaryFloatSize = uint.Parse(header.Substring(12, 4));

            if (binaryFloatSize != 32 && binaryFloatSize != 64)
                ThrowException(string.Format("Unknown float size {0} specified in xfile header.", binaryFloatSize));

            // The x format specifies size in bits, but we work in bytes
            binaryFloatSize /= 8;

            p += 16;

            // If this is a compressed X file, apply the inflate algorithm to it
            if (compressed)
            {
                //throw (new Exception("Assimp was built without compressed X support"));
                MemoryStream stream = new MemoryStream(buffer);
                stream.Position += 16;
                stream.Position += 6;
                long p1 = stream.Position;
                uint estOut = 0;
                while (p1 + 3 < end)
                {
                    ushort ofs = BitConverter.ToUInt16(buffer, (int)p1);
                    p1 += 2;
                    if (ofs >= MSZIP_BLOCK)
                    {
                        throw (new Exception("X: Invalid offset to next MSZIP compressed block"));
                    }
                    ushort magic = BitConverter.ToUInt16(buffer, (int)p1);
                    p1 += 2;
                    if (magic != MSZIP_MAGIC)
                    {
                        throw (new Exception("X: Unsupported compressed format, expected MSZIP header"));
                    }
                    p1 += ofs;
                    estOut += MSZIP_BLOCK;
                }

                uncompressed = new byte[estOut + 1];
                int uncompressedEnd = 0;
                while (p + 3 < end)
                {
                    ushort ofs = BitConverter.ToUInt16(buffer, (int)p);
                    p += 4;
                    if (p + ofs > end + 2)
                    {
                        throw (new Exception("X: Unexpected EOF in compressed chunk"));
                    }
                    stream.Position = p;
                    DeflateStream uncomp = new DeflateStream(stream, CompressionMode.Decompress);
                    int readLnegth = uncomp.Read(uncompressed, 0, (int)MSZIP_BLOCK);
                    uncompressedEnd += readLnegth;
                    p += ofs;
                }
                this.buffer = uncompressed;
                this.end = uncompressedEnd;
                this.p = 0;
            }
            else
            {
                // start reading here
                ReadUntilEndOfLine();
            }

            scene = new Scene();
            ParseFile();

            // filter the imported hierarchy for some degenerated cases
            if (scene.RootNode != null)
            {
                FilterHierarchy(scene.RootNode);
            }
        }
Пример #2
0
        /// <summary>
        /// Constructs the return data structure out of the imported data.
        /// </summary>
        /// <param name="scene">The scene to construct the return data in.</param>
        /// <param name="sdata">The imported data in the internal temporary representation.</param>
        protected void CreateDataRepresentationFromImport(AssimpSharp.Scene scene, Scene data)
        {
            // Read the global materials first so that meshes referring to them can find them later
            ConvertMaterials(scene, data.GlobalMaterial);

            // copy nodes, extracting meshes and materials on the way
            scene.RootNode = CreateNodes(scene, null, data.RootNode);

            // extract animations
            CreateAnimations(scene, data);

            // read the global meshes that were stored outside of any node
            if (data.GlobalMeshes.Count > 0)
            {
                // create a root node to hold them if there isn't any, yet
                if (scene.RootNode == null)
                {
                    scene.RootNode = new AssimpSharp.Node();
                    scene.RootNode.Name = "$dummy_node";
                }

                // convert all global meshes and store them in the root node.
                // If there was one before, the global meshes now suddenly have its transformation matrix...
                // Don't know what to do there, I don't want to insert another node under the present root node
                // just to avoid this.
                CreateMeshes(scene, scene.RootNode, data.GlobalMeshes);
            }

            if (scene.RootNode == null)
            {
                throw (new DeadlyImportError("No root node"));
            }

            // Convert everything to OpenGL space... it's the same operation as the conversion back, so we can reuse the step directly
            var convertProcess = new MakeLeftHandedProcess();
            convertProcess.Execute(scene);

            var flipper = new FlipWindingOrderProcess();
            flipper.Execute(scene);

            // finally: create a dummy material if not material was imported
            if (scene.Materials.Count == 0)
            {
                var mat = new aiMaterial();
                mat.ShadingMode = ShadingMode.Gouraud;
                mat.ColorEmissive = new Color4(0, 0, 0, 1);
                mat.ColorSpecular = new Color4(0, 0, 0, 1);
                mat.ColorDiffuse = new Color4(0.5f, 0.5f, 0.5f, 1);
                mat.Shininess = 1.401298e-45f;
                scene.Materials.Add(mat);
            }
        }