Ejemplo n.º 1
0
        public unsafe bool writeToFile(string filename)
        {
            if (File.Exists(filename))
            {
                File.Delete(filename);
            }
            FileStream   s = File.Open(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            BinaryWriter f = new BinaryWriter(s);
            BinaryReader r = new BinaryReader(s);

            //open reading from our temp file..
            mTempChunkFile.Position = 0;
            BinaryReader tbr = new BinaryReader(mTempChunkFile);


            //WRITE OUR HEADER
            mHeader = new ECFHeader();
            mHeader.mHeaderMagic = cECFHeaderMagic;
            mHeader.mHeaderSize  = (uint)sizeof(ECFHeader);              //THIS IS JUST THE SIZE OF THIS HEADER


            f.Write(ExportTo360.StructToByteArray(mHeader));



            /////////////////////////////////////////
            //WRITE OUR CHUNK HEADERS (Dummies!)
            BECFChunkHeader[] headers  = new BECFChunkHeader[mChunks.Count];
            ushort            padVal   = 0;
            Int32             padVal32 = 0;

            BECFChunkHeader ch = new BECFChunkHeader();

            for (int i = 0; i < mChunks.Count; i++)
            {
                headers[i].mID      = mChunks[i].mID;
                headers[i].mOfs     = (int)f.BaseStream.Position;
                headers[i].mSize    = (int)mChunks[i].mLength;
                headers[i].mAdler32 = (int)mChunks[i].mHeaderAdler32;//THIS IS THE ADLER FOR THE ACTUAL CHUNK DATA WE REPRESENT (Post endiean converted!)

                headers[i].mFlags         = 0;
                headers[i].mAlignmentLog2 = 2;
                headers[i].mPad0          = (short)padVal;
                //headers[i].endianSwap();//not yet....

                f.Write(ExportTo360.StructToByteArray(headers[i]));
            }



            ////////////////////////////////////////////////
            //WRITE OUR CHUNK BLOCKS

            for (int i = 0; i < mChunks.Count; i++)
            {
                //CLM [03.13.07] ECF Changes
                //we need to ensure each chunk is aligned to the boundry defined by ch.mAlignmentLog2
                //so check to see if our position pointer is a multiple of 4 (2^2)
                //if it's not, write the number of bytes required to MAKE it that multiple.
                long pos    = f.BaseStream.Position;
                long modPos = pos & 3;
                if (modPos != 0)
                {
                    long   numBytesToWrite = 4 - modPos;
                    byte[] b = new byte[numBytesToWrite];
                    f.Write(b);
                }

                long streampos = f.BaseStream.Length;

                f.Write(tbr.ReadBytes((int)mChunks[i].mLength));

                //fill in our header data
                headers[i].mOfs = (int)streampos;


                //seek back to our header and update our position pointer
                //f.Seek(sizeof(ECFHeader) + (sizeof(BECFChunkHeader) * i) + sizeof(Int64), SeekOrigin.Begin);
                //f.Write(Xbox_EndianSwap.endSwapI32((int)streampos));
                //f.Seek(0, SeekOrigin.End);
            }



            //REWRITE OUR HEADER WITH THE PROPER DATA

            //write our actual file length back to the header
            mHeader.mFileSize           = (uint)f.BaseStream.Length; // totalheaderSize;
            mHeader.mNumChunks          = (ushort)mChunks.Count;
            mHeader.mFlags              = 0;                         // mFlags;
            mHeader.mID                 = cXTD_ECFFileID;
            mHeader.mChunkExtraDataSize = 0;
            mHeader.endianSwap();

            //CLM we have to calculate the adler of the endianswapped data, then endian swap ourselves
            mHeader.mHeaderAdler32 = calcAdler32(ExportTo360.StructToByteArray(mHeader),
                                                 (uint)(sizeof(Int32) * cECFAdler32DWORDsToSkip),
                                                 (uint)(sizeof(ECFHeader) - sizeof(Int32) * cECFAdler32DWORDsToSkip));
            mHeader.mHeaderAdler32 = (uint)Xbox_EndianSwap.endSwapI32((int)mHeader.mHeaderAdler32);

            f.Seek(0, SeekOrigin.Begin);
            f.Write(ExportTo360.StructToByteArray(mHeader));
            // f.Seek(0, SeekOrigin.End);

            /////////////////////////////////////////
            //WRITE OUR CHUNK HEADERS (Real!)
            for (int i = 0; i < mChunks.Count; i++)
            {
                headers[i].endianSwap();
                f.Write(ExportTo360.StructToByteArray(headers[i]));
            }



            headers = null;


            f.Close();
            f = null;
            s.Close();
            s = null;

            tbr.Close();
            tbr = null;

            clear();
            return(true);
        }
Ejemplo n.º 2
0
        public bool export_XTD(string filename, ExportSettings expSettings, ref ExportResults results)
        {
            DateTime start = DateTime.Now;

            //write the header for the entire XTD file
            XTDVisualHeader header = new XTDVisualHeader();

            header.version    = (int)eFileVersions.cXTDVersion;
            header.numXVerts  = TerrainGlobals.getTerrain().getNumXVerts();
            header.numXChunks = (int)(TerrainGlobals.getTerrain().getNumXVerts() / BTerrainQuadNode.cMaxWidth);
            header.tileScale  = TerrainGlobals.getTerrain().getTileScale();

            BBoundingBox simRepBB  = SimGlobals.getSimMain().getBBoxForDecalObjects();
            Vector3      visRepMin = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_min - new Vector3(0, header.tileScale, 0);
            Vector3      visRepMax = TerrainGlobals.getTerrain().getQuadNodeRoot().getDesc().m_max + new Vector3(0, header.tileScale, 0);

            if (!CoreGlobals.mbLoadTerrainVisRep)
            {
                visRepMin = simRepBB.min;
                visRepMax = simRepBB.max;
            }


            header.worldMin = visRepMin;
            header.worldMax = visRepMax;
            header.endianSwap();


            //write our header first.
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

            binWriter.Write(ExportTo360.StructToByteArray(header));
            ExportTo360.mECF.addChunk((int)eXTD_ChunkID.cXTD_XTDHeader, chunkHolder, (int)chunkHolder.mDataMemStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;

            header.endianSwap();


            generateGridChunks(ref header);

            writeAtlasToMemory(ref results);

            writeAOData(ref results);

            writeAlpha(ref results);

            writeTessData(expSettings.RefineTerrain, expSettings.RefineEpsilon, expSettings.RefineMinorityBias, ref results);

            writeLightData(ref expSettings, ref results);

            bool exportOK = ExportTo360.safeECFFileWrite(filename, ".XTD");


            TimeSpan ts = DateTime.Now - start;

            results.totalTime = ts.TotalMinutes;

            return(exportOK);
        }