Esempio n. 1
0
        //-----------------------------------------------------------------------------------
        void heightFieldToChunk(HeightsGen hg, ref ExportResults results)
        {
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

            binWriter.Write(Xbox_EndianSwap.endSwapI32((int)hg.mHeightFieldAttributes.mWidth));
            binWriter.Write(Xbox_EndianSwap.endSwapI32((int)hg.mHeightFieldAttributes.mHeight));

            binWriter.Write(Xbox_EndianSwap.endSwapF32(hg.mHeightFieldAttributes.mWorldMinY));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(hg.mHeightFieldAttributes.mWorldMaxY));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(hg.mHeightFieldAttributes.mWorldRangeY));

            binWriter.Write(Xbox_EndianSwap.endSwapF32(hg.mHeightFieldAttributes.mBounds.min.X));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(hg.mHeightFieldAttributes.mBounds.min.Y));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(hg.mHeightFieldAttributes.mBounds.min.Z));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(hg.mHeightFieldAttributes.mBounds.max.X));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(hg.mHeightFieldAttributes.mBounds.max.Y));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(hg.mHeightFieldAttributes.mBounds.max.Z));

            binWriteMatrix(binWriter, hg.mHeightFieldAttributes.mNormZToWorld);
            binWriteMatrix(binWriter, hg.mHeightFieldAttributes.mWorldToNormZ);


            binWriter.Write(Xbox_EndianSwap.endSwapI32(hg.mHeightFieldAttributes.mpTexelsHI.Length));
            int memSize = hg.mHeightFieldAttributes.mpTexelsHI.Length * 2 * sizeof(short);

            binWriter.Write(Xbox_EndianSwap.endSwapI32(memSize));

            //expect the texture as G16R16, NON FLOAT! Just 16 bits of short.
            int numShorts = hg.mHeightFieldAttributes.mpTexelsHI.Length * 2;

            short[] sArray = new short[numShorts];
            for (int i = 0; i < hg.mHeightFieldAttributes.mpTexelsHI.Length; i++)
            {
                sArray[i * 2 + 0] = (short)Xbox_EndianSwap.endSwapI16((ushort)hg.mHeightFieldAttributes.mpTexelsHI[i]);
                sArray[i * 2 + 1] = (short)Xbox_EndianSwap.endSwapI16((ushort)hg.mHeightFieldAttributes.mpTexelsLO[i]);
            }

            //tileswap
            short[] tempbytearray = new short[sArray.Length];
            sArray.CopyTo(tempbytearray, 0);
            ExportTo360.tileCopy(ref tempbytearray, tempbytearray, (int)hg.mHeightFieldAttributes.mWidth, (int)hg.mHeightFieldAttributes.mHeight, ExportTo360.eTileCopyFormats.cTCFMT_G16R16);
            //  tempbytearray.CopyTo(sArray, 0);
            for (int i = 0; i < tempbytearray.Length; i++)
            {
                binWriter.Write(tempbytearray[i]);
            }

            ExportTo360.mECF.addChunk((int)eXTH_ChunkID.cXTH_TerrainHeightfield, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;

            results.terrainGPUHeighfieldMemory = memSize;
        }
Esempio n. 2
0
 public void endianSwap()
 {
     mHeaderMagic        = (uint)Xbox_EndianSwap.endSwapI32((int)mHeaderMagic);
     mHeaderSize         = (uint)Xbox_EndianSwap.endSwapI32((int)mHeaderSize);
     mHeaderAdler32      = (uint)Xbox_EndianSwap.endSwapI32((int)mHeaderAdler32);
     mFileSize           = (uint)Xbox_EndianSwap.endSwapI32((int)mFileSize);// totalheaderSize;
     mNumChunks          = (ushort)Xbox_EndianSwap.endSwapI16((ushort)mNumChunks);
     mFlags              = (ushort)Xbox_EndianSwap.endSwapI16((ushort)mFlags);
     mID                 = (uint)Xbox_EndianSwap.endSwapI32((int)mID);
     mChunkExtraDataSize = 0;
 }
Esempio n. 3
0
            public void endianSwap()
            {
                mID      = Xbox_EndianSwap.endSwapI64(mID);
                mOfs     = Xbox_EndianSwap.endSwapI32(mOfs);
                mSize    = Xbox_EndianSwap.endSwapI32(mSize);
                mAdler32 = Xbox_EndianSwap.endSwapI32(mAdler32);

                //public byte mFlags;
                //public byte mAlignmentLog2;

                //public Int16 mPad0;
            }
Esempio n. 4
0
 public void endianSwap()
 {
     version    = Xbox_EndianSwap.endSwapI32(version);
     numXVerts  = Xbox_EndianSwap.endSwapI32(numXVerts);
     numXChunks = Xbox_EndianSwap.endSwapI32(numXChunks);
     tileScale  = Xbox_EndianSwap.endSwapF32(tileScale);
     worldMin.X = Xbox_EndianSwap.endSwapF32(worldMin.X);
     worldMin.Y = Xbox_EndianSwap.endSwapF32(worldMin.Y);
     worldMin.Z = Xbox_EndianSwap.endSwapF32(worldMin.Z);
     worldMax.X = Xbox_EndianSwap.endSwapF32(worldMax.X);
     worldMax.Y = Xbox_EndianSwap.endSwapF32(worldMax.Y);
     worldMax.Z = Xbox_EndianSwap.endSwapF32(worldMax.Z);
 }
Esempio n. 5
0
        //-----------------------------------------------------------------------------------
        void headerToChunk()
        {
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

            int version = (int)eFileVersions.cXTHVersion;

            binWriter.Write(Xbox_EndianSwap.endSwapI32(version));
            ExportTo360.mECF.addChunk((int)eXTH_ChunkID.cXTH_XTHHeader, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;
        }
Esempio n. 6
0
 public void endianSwap()
 {
     numZBlocks        = Xbox_EndianSwap.endSwapI32(numZBlocks);
     numXBlocks        = Xbox_EndianSwap.endSwapI32(numXBlocks);
     numXVerts         = Xbox_EndianSwap.endSwapI32(numXVerts);
     tileScale         = Xbox_EndianSwap.endSwapF32(tileScale);
     yAxis_hvMemSize   = Xbox_EndianSwap.endSwapI32(yAxis_hvMemSize);
     yAxis_dcMemSize   = Xbox_EndianSwap.endSwapI32(yAxis_dcMemSize);
     xAxis_hvMemSize   = Xbox_EndianSwap.endSwapI32(xAxis_hvMemSize);
     zAxis_hvMemSize   = Xbox_EndianSwap.endSwapI32(zAxis_hvMemSize);
     xzAxis_dcMemSize  = Xbox_EndianSwap.endSwapI32(xzAxis_dcMemSize);
     yAxis_ranges      = new Vector3(0, Xbox_EndianSwap.endSwapF32(yAxis_ranges.Y), Xbox_EndianSwap.endSwapF32(yAxis_ranges.Z));
     xAxis_ranges      = new Vector3(Xbox_EndianSwap.endSwapF32(xAxis_ranges.X), Xbox_EndianSwap.endSwapF32(xAxis_ranges.Y), Xbox_EndianSwap.endSwapF32(xAxis_ranges.Z));
     zAxis_ranges      = new Vector3(Xbox_EndianSwap.endSwapF32(zAxis_ranges.X), Xbox_EndianSwap.endSwapF32(zAxis_ranges.Y), Xbox_EndianSwap.endSwapF32(zAxis_ranges.Z));
     xyBasis_hvMemSize = Xbox_EndianSwap.endSwapI32(xyBasis_hvMemSize);
     zwBasis_hvMemSize = Xbox_EndianSwap.endSwapI32(zwBasis_hvMemSize);
 }
Esempio n. 7
0
        public void writeHeaderToChunk()
        {
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

            List <FoliageSet> validSets = new List <FoliageSet>();

            for (int i = 0; i < FoliageManager.getNumSets(); i++)
            {
                if (FoliageManager.isSetUsed(FoliageManager.giveSet(i)))
                {
                    validSets.Add(FoliageManager.giveSet(i));
                }
            }

            binWriter.Write(Xbox_EndianSwap.endSwapI32(validSets.Count));
            for (int i = 0; i < validSets.Count; i++)
            {
                string tName = validSets[i].mFullFileName;
                if (tName.Contains(".xml"))
                {
                    tName = tName.Substring(0, tName.LastIndexOf(".xml"));
                }

                string fName    = tName.Remove(0, CoreGlobals.getWorkPaths().mGameArtDirectory.Length + 1);
                char[] filename = new char[256];
                fName.CopyTo(0, filename, 0, fName.Length);
                binWriter.Write(filename);

                ExportTo360.addTextureChannelDependencies(tName);
                if (File.Exists(Path.ChangeExtension(tName, ".xml")))
                {
                    ExportTo360.mDEP.addFileDependent(Path.ChangeExtension(tName, ".xml"), false);
                }
            }


            ExportTo360.mECF.addChunk((int)eXTT_ChunkID.cXTT_FoliageHeaderChunk, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;
        }
Esempio n. 8
0
        //-----------------------------------------
        private unsafe void headerToChunk()
        {
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

            int version = (int)eFileVersions.cXSDVersion;

            binWriter.Write(Xbox_EndianSwap.endSwapI32(version));

            //sim terrain data stuff
            binWriter.Write(Xbox_EndianSwap.endSwapI32(TerrainGlobals.getEditor().getSimRep().getNumXTiles()));     //simTileScale
            binWriter.Write(Xbox_EndianSwap.endSwapF32(TerrainGlobals.getEditor().getSimRep().getTileScale()));     //simTileScale
            binWriter.Write(Xbox_EndianSwap.endSwapF32(TerrainGlobals.getEditor().getSimRep().getVisToSimScale())); //visToSimScale


            //round our sim-rep up to next multiple of 8 for XBOX360 memory effecient tiling
            int width      = (TerrainGlobals.getEditor().getSimRep().getNumXVerts() - 1) * cSimHeightResMultiplier + 1;
            int numXBlocks = width / 8;

            if (width % 8 != 0)
            {
                numXBlocks++;
            }
            int newWidth = numXBlocks * 8;

            float heightTileScale = (TerrainGlobals.getEditor().getSimRep().getTileScale() / (float)cSimHeightResMultiplier);


            binWriter.Write(Xbox_EndianSwap.endSwapI32(width));                   //numHeightVerts
            binWriter.Write(Xbox_EndianSwap.endSwapI32(newWidth));                //numHeightVertsCacheFeriently
            binWriter.Write(Xbox_EndianSwap.endSwapF32(heightTileScale));         //height tile scale
            binWriter.Write(Xbox_EndianSwap.endSwapI32(cSimHeightResMultiplier)); //DataToHeightMultiplier



            ExportTo360.mECF.addChunk((int)eXSD_ChunkID.cXSD_XSDHeader, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;
        }
Esempio n. 9
0
        //----------------------------------------------
        //----------------------------------------------
        //----------------------------------------------
        //----------------------------------------------
        //----------------------------------------------


        //----------------------------------------------


        private unsafe int writeChunk(XTDTerrainChunk chunk, BinaryWriter mem)
        {
            mem.Write(Xbox_EndianSwap.endSwapI32(chunk.gridLocX));
            mem.Write(Xbox_EndianSwap.endSwapI32(chunk.gridLocZ));
            mem.Write(Xbox_EndianSwap.endSwapI32(chunk.maxVertStride));
            mem.Write(Xbox_EndianSwap.endSwapF32(chunk.mMin.X));
            mem.Write(Xbox_EndianSwap.endSwapF32(chunk.mMin.Y));
            mem.Write(Xbox_EndianSwap.endSwapF32(chunk.mMin.Z));
            mem.Write(Xbox_EndianSwap.endSwapF32(chunk.mMax.X));
            mem.Write(Xbox_EndianSwap.endSwapF32(chunk.mMax.Y));
            mem.Write(Xbox_EndianSwap.endSwapF32(chunk.mMax.Z));
            bool canCastShadows = true;

            if (chunk.mMax.Y - chunk.mMin.Y < 2)
            {
                canCastShadows = false;
            }
            mem.Write(canCastShadows);

            return(0);
        }
Esempio n. 10
0
        //-----------------------------------------------------------------------------------
        void binWriteMatrix(BinaryWriter binWriter, Matrix mat)
        {
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M11));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M12));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M13));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M14));

            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M21));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M22));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M23));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M24));

            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M31));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M32));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M33));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M34));

            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M41));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M42));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M43));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(mat.M44));
        }
Esempio n. 11
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);
        }
Esempio n. 12
0
        private void writeLightData(ref ExportSettings settings, ref ExportResults results)
        {
            if (!LightManager.hasTerrainLightData())
            {
                return;
            }

            DateTime n      = DateTime.Now;
            int      width  = TerrainGlobals.getTerrain().getNumXVerts();
            int      height = TerrainGlobals.getTerrain().getNumZVerts();

            Vector3 [] lht = new Vector3[width * height];

            //CLM this needs to be changed for batch exporting!
            LightManager.rasterTerrainLightsToExportGrid(lht);

            //convert our data to a DXT1 texture!
            //CLM this is swapped all to shit... WTF!?

            byte[] inData = new byte[width * height * 4];
            int    c      = 0;

            //for (int i = 0; i < lht.Length; i++)

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    //as an encoding step, divide by our overbright (2)
                    //now convert back to srgb
                    int     i = x * width + y;
                    Vector3 v = lht[i];
                    v.X = (float)Math.Sqrt(BMathLib.Clamp((float)(v.X * 0.5), 0, 1));
                    v.Y = (float)Math.Sqrt(BMathLib.Clamp((float)(v.Y * 0.5), 0, 1));
                    v.Z = (float)Math.Sqrt(BMathLib.Clamp((float)(v.Z * 0.5), 0, 1));

                    inData[c++] = (byte)(BMathLib.Clamp(v.Z * 255 + 0.5f, 0, 255));
                    inData[c++] = (byte)(BMathLib.Clamp(v.Y * 255 + 0.5f, 0, 255));
                    inData[c++] = (byte)(BMathLib.Clamp(v.X * 255 + 0.5f, 0, 255));
                    inData[c++] = 0;
                }
            }


            byte[] outDat     = null;
            int    outMemSize = 0;

            ExportTo360.toCompressedFormat(inData, width, height, sizeof(UInt32), BDXTFormat.cDXT1, settings.ExportTextureCompressionQuality, ref outDat, ref outMemSize);


            //endianswap this data...
            int count = outMemSize;

            for (int i = 0; i < count - 1; i += 2)
            {
                byte a = outDat[i];
                outDat[i]     = outDat[i + 1];
                outDat[i + 1] = a;
            }

            //tileswap
            byte[] tempbytearray = new byte[outDat.Length];
            outDat.CopyTo(tempbytearray, 0);
            ExportTo360.tileCopy(ref tempbytearray, tempbytearray, (int)width, (int)height, (int)ExportTo360.eTileCopyFormats.cTCFMT_DXT1);
            tempbytearray.CopyTo(outDat, 0);
            tempbytearray = null;

            //WRITE THE CHUNK
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

            //just write the DXT1 texture
            binWriter.Write(Xbox_EndianSwap.endSwapI32(outMemSize));
            binWriter.Write(outDat);

            ExportTo360.mECF.addChunk((int)eXTD_ChunkID.cXTD_LightingChunk, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;

            results.terrainLightingMemorySize = outMemSize;
            TimeSpan ts = DateTime.Now - n;

            results.terrainLightingTime = ts.TotalMinutes;



            lht    = null;
            inData = null;
            outDat = null;
        }
Esempio n. 13
0
        public void writeAtlasToMemory(ref ExportResults results)
        {
            int len = TerrainGlobals.getTerrain().getNumZVerts() * TerrainGlobals.getTerrain().getNumXVerts();

            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);


            #region 32bit pos
            Vector3 min   = new Vector3(9000, 9000, 9000);
            Vector3 max   = new Vector3(-9000, -9000, -9000);
            Vector3 range = new Vector3(0, 0, 0);
            findMaxsMinsRange(ref max, ref min, ref range);

            Vector3 adjustedMidValue = calcAdjustedMidValue(min);

            //write our mins & ranges (shoudl use XTDAtlasVisual here..)
            binWriter.Write(Xbox_EndianSwap.endSwapF32(adjustedMidValue.X));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(adjustedMidValue.Y));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(adjustedMidValue.Z));
            binWriter.Write(0); //padd to allow 360 to read XMVECTOR from disk
            binWriter.Write(Xbox_EndianSwap.endSwapF32(range.X));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(range.Y));
            binWriter.Write(Xbox_EndianSwap.endSwapF32(range.Z));
            binWriter.Write(0); //padd to allow 360 to read XMVECTOR from disk

            //CLM i'm trying this out...
            long currLen = binWriter.BaseStream.Position;
            binWriter.BaseStream.SetLength(currLen + ((sizeof(int) * len) * 2));

            //make sure we swizzle it...
            Vector3[] detail   = TerrainGlobals.getEditor().getDetailPoints();
            Int32[]   tmpArray = new Int32[len];
            for (int i = 0; i < len; i++)
            {
                tmpArray[i] = (int)packPosTo32Bits(detail[i], min, range);
            }


            ExportTo360.tileCopy(ref tmpArray, tmpArray, TerrainGlobals.getTerrain().getNumXVerts(), TerrainGlobals.getTerrain().getNumZVerts());

            for (int i = 0; i < len; i++)
            {
                binWriter.Write(Xbox_EndianSwap.endSwapI32((int)tmpArray[i]));//(int)packPosTo32Bits(expData.mTerrainPoints[i],min,range)));
            }
            #endregion

            #region 32bit normal
            Vector3[] normals = TerrainGlobals.getEditor().getNormals();
            for (int i = 0; i < len; i++)
            {
                tmpArray[i] = (int)packNormTo32Bits(normals[i]);
            }


            ExportTo360.tileCopy(ref tmpArray, tmpArray, TerrainGlobals.getTerrain().getNumXVerts(), TerrainGlobals.getTerrain().getNumZVerts());

            for (int i = 0; i < len; i++)
            {
                binWriter.Write(Xbox_EndianSwap.endSwapI32((int)tmpArray[i]));//(int)packPosTo32Bits(expData.mTerrainPoints[i],min,range)));
            }
            #endregion

            tmpArray = null;



            ExportTo360.mECF.addChunk((int)eXTD_ChunkID.cXTD_AtlasChunk, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;



            results.terrainPositionMemorySize = len * sizeof(UInt32);
            results.terrainNormalsMemorySize  = len * sizeof(UInt32);



            normals = null;
            detail  = null;
        }
Esempio n. 14
0
        void heightFieldAlphaToChunk(ref ExportResults results)
        {
            //i think for visual reasons, the resolution of this alpha data needs to match
            //the density of the terrain alpha..

            BTerrainSimRep simRep = TerrainGlobals.getEditor().getSimRep();

            int width  = TerrainGlobals.getTerrain().getNumXVerts();
            int height = TerrainGlobals.getTerrain().getNumXVerts();

            if (width < 256 || height < 256)
            {
                return; //don't write for small maps..
            }
            byte[] AlphaVals = TerrainGlobals.getEditor().getAlphaValues();

            DXT3_1111 img = new DXT3_1111(width, height);


            //walk through all the terrain alpha values,
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    int  index   = x * width + y;
                    bool visible = AlphaVals[index] > 0;// if it's invisible, so are we.

                    //walk through the sim rep. If it's passable, we're visible.
                    float normalizedX   = x / (float)width;
                    float normalizedZ   = y / (float)height;
                    bool  obstructsLand = simRep.getDataTiles().isLandObstructedComposite(normalizedX, normalizedZ);
                    visible |= !obstructsLand;


                    img.setValue(x, y, visible);
                }
            }


            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

            int packedWidth = width >> 2;

            binWriter.Write(Xbox_EndianSwap.endSwapI32(packedWidth));
            binWriter.Write(Xbox_EndianSwap.endSwapI32(height));

            int numBlocks = img.getNumBlocks();

            //numXBlocks-1 + numXBlocks * numYBlocks
            int texelMemSize = numBlocks * sizeof(Int64);// (((width >> 4) - 1) + (width >> 4) * ((height >> 2) - 1)) * sizeof(Int64);

            binWriter.Write(Xbox_EndianSwap.endSwapI32(texelMemSize));


            for (int i = 0; i < numBlocks; i++)
            {
                binWriter.Write(img.getBlock(i));
            }

            ExportTo360.mECF.addChunk((int)eXTH_ChunkID.cXTH_TerrainHeightfieldAlpha, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;

            results.terrainGPUHeighfieldMemory += texelMemSize;

            img = null;
        }
Esempio n. 15
0
        private int simHeightsToChunk()
        {
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

            int width = (TerrainGlobals.getEditor().getSimRep().getNumXVerts() - 1) * cSimHeightResMultiplier + 1;


            //float[] heights = TerrainGlobals.getEditor().getSimRep().getHeightRep().get.getSimHeights();
            //CLM : INFACT! Don't even consider doing this....
            //our res is good enough..
            //if (cSimHeightResMultiplier!=1)
            //{
            //   heights = new float[width * width];

            //   //CLM Generate a higher res Sim Heights rep
            //   int xRes = 2048;
            //   float[] gpuHeightRepArray = new float[xRes * xRes];
            //   TerrainGlobals.getEditor().getSimRep().genHeightGPU(xRes, ref gpuHeightRepArray);

            //   float[] resPlusOne = ImageManipulation.resizeF32Img(gpuHeightRepArray, xRes, xRes, width - 1, width - 1, ImageManipulation.eFilterType.cFilter_Linear);//new float[xRes * xRes];
            //   for (int x = 0; x < width - 1; x++)
            //   {
            //      for (int z = 0; z < width - 1; z++)
            //      {
            //         heights[x * width + z] = resPlusOne[x * (width - 1) + z];
            //      }
            //   }

            //   //fill our edges with the previous height val.
            //   for (int q = 0; q < width - 1; q++)
            //   {
            //      heights[(width - 1) * width + q] = heights[(width - 2) * width + q];
            //      heights[q * width + (width - 1)] = heights[q * width + (width - 2)];
            //   }

            //   resPlusOne = null;
            //}

            //find our xbox specific terrain representation (close)
            float min   = 9000;
            float max   = -9000;
            float range = 0;

            findMaxsMinsRange(ref max, ref min, ref range);
            float adjustedMid = calcAdjustedMidValue(min);



            int numXBlocks = width / 8;

            if (width % 8 != 0)
            {
                numXBlocks++;
            }
            int newWidth = numXBlocks * 8;

            //swizzle our data to be more cache friendly..

            //first, padd our data to the next multiple of 8
            float[] tvals = new float[newWidth * newWidth];
            for (int i = 0; i < width; i++)
            {
                for (int k = 0; k < width; k++)
                {
                    int srcIndex = i + k * width;
                    int dstIndex = i + k * newWidth;
                    tvals[dstIndex] = TerrainGlobals.getEditor().getSimRep().getHeightRep().getCompositeHeight(k, i);//heights[srcIndex];

                    //  int v = (int)packPosTo32Bits(tvals[dstIndex], min, range);
                    //  unpackVisualToPos(v, ref tvals[dstIndex], ref adjustedMid, ref range);
                }
            }


            ////now swizzle the bastard.
            int blockSize = 8;

            float[] kvals   = new float[newWidth * newWidth];
            int     dstIndx = 0;

            for (int x = 0; x < numXBlocks; x++)
            {
                for (int z = 0; z < numXBlocks; z++)
                {
                    int blockIndex = x + z * numXBlocks;
                    //swizzle create this block
                    for (int i = 0; i < blockSize; i++)
                    {
                        for (int j = 0; j < blockSize; j++)
                        {
                            int k = (z * blockSize) + j; // (blockSize - 1 - j);
                            int l = (x * blockSize) + i; // (blockSize - 1 - i);

                            int srcIndx = k * newWidth + l;
                            //int dstIndx = i * blockSize + j;
                            kvals[dstIndx++] = tvals[srcIndx];
                        }
                    }
                }
            }

            //FileStream st = File.Open("outTT.raw", FileMode.OpenOrCreate, FileAccess.Write);
            //BinaryWriter ft = new BinaryWriter(st);

            //convert to float16 & write to disk.
            float16[] sList = BMathLib.Float32To16Array(kvals);
            for (int c = 0; c < sList.Length; c++)
            {
                ushort s = ((ushort)sList[c].getInternalDat());
                binWriter.Write(Xbox_EndianSwap.endSwapI16(s));
                //ft.Write(s);
            }
            //ft.Close();
            //st.Close();


            ExportTo360.mECF.addChunk((int)eXSD_ChunkID.cXSD_SimHeights, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;

            //heights = null;

            return(tvals.Length * sizeof(ushort));
        }
Esempio n. 16
0
        private int writeFlightHeights()
        {
            TerrainGlobals.getEditor().getSimRep().getFlightRep().recalculateHeights();

            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);


            int width      = (int)TerrainGlobals.getEditor().getSimRep().getFlightRep().getNumXPoints();
            int numXBlocks = width / 8;

            if (width % 8 != 0)
            {
                numXBlocks++;
            }
            int newWidth = numXBlocks * 8;

            //write our header information.
            float heightTileScale = TerrainGlobals.getEditor().getSimRep().getFlightRep().getTileScale();


            binWriter.Write(Xbox_EndianSwap.endSwapI32(width));                 //numHeightVerts
            binWriter.Write(Xbox_EndianSwap.endSwapI32(newWidth));              //numHeightVertsCacheFeriently
            binWriter.Write(Xbox_EndianSwap.endSwapF32(heightTileScale));       //height tile scale



            //swizzle our data to be more cache friendly..

            //first, padd our data to the next multiple of 8
            float[] tvals = new float[newWidth * newWidth];
            for (int i = 0; i < width; i++)
            {
                for (int k = 0; k < width; k++)
                {
                    int dstIndex = i + k * newWidth;
                    tvals[dstIndex] = TerrainGlobals.getEditor().getSimRep().getFlightRep().getCompositeHeight(k, i);// heights[srcIndex];
                }
            }


            ////now swizzle the bastard.
            int blockSize = 8;

            float[] kvals   = new float[newWidth * newWidth];
            int     dstIndx = 0;

            for (int x = 0; x < numXBlocks; x++)
            {
                for (int z = 0; z < numXBlocks; z++)
                {
                    int blockIndex = x + z * numXBlocks;
                    //swizzle create this block
                    for (int i = 0; i < blockSize; i++)
                    {
                        for (int j = 0; j < blockSize; j++)
                        {
                            int k = (z * blockSize) + j; // (blockSize - 1 - j);
                            int l = (x * blockSize) + i; // (blockSize - 1 - i);

                            int srcIndx = k * newWidth + l;
                            //int dstIndx = i * blockSize + j;
                            kvals[dstIndx++] = tvals[srcIndx];
                        }
                    }
                }
            }


            //convert to float16 & write to disk.
            float16[] sList = BMathLib.Float32To16Array(kvals);
            for (int c = 0; c < sList.Length; c++)
            {
                ushort s = ((ushort)sList[c].getInternalDat());
                binWriter.Write(Xbox_EndianSwap.endSwapI16(s));
            }


            ExportTo360.mECF.addChunk((int)eXSD_ChunkID.cXSD_FlightHeights, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;

            return(tvals.Length * sizeof(ushort));
        }
Esempio n. 17
0
        public void exportRoads(ref ExportResults results)
        {
            DateTime n = DateTime.Now;

            //for each road,
            for (int roadIndex = 0; roadIndex < RoadManager.giveNumRoads(); roadIndex++)
            {
                List <RoadTriangle> triList = new List <RoadTriangle>();
                Road rd = RoadManager.giveRoad(roadIndex);

                if (rd.getNumControlPoints() == 0) //don't export roads w/o points on the map
                {
                    continue;
                }

                //Step 1, generate polygon lists////////////////////////////////////////////////////
                for (int rcpIndex = 0; rcpIndex < rd.getNumControlPoints(); rcpIndex++)
                {
                    roadControlPoint rcp = rd.getPoint(rcpIndex);
                    int numTris          = (int)(rcp.mVerts.Count / 3);
                    for (int triIndex = 0; triIndex < numTris; triIndex++)
                    {
                        RoadTriangle rt = new RoadTriangle();
                        rt.mVerts[0]      = new RoadVert();
                        rt.mVerts[0].mPos = new Vector3(rcp.mVerts[triIndex * 3 + 0].x, rcp.mVerts[triIndex * 3 + 0].y, rcp.mVerts[triIndex * 3 + 0].z);
                        rt.mVerts[0].mUv0 = new Vector2(rcp.mVerts[triIndex * 3 + 0].u0, rcp.mVerts[triIndex * 3 + 0].v0);

                        rt.mVerts[1]      = new RoadVert();
                        rt.mVerts[1].mPos = new Vector3(rcp.mVerts[triIndex * 3 + 1].x, rcp.mVerts[triIndex * 3 + 1].y, rcp.mVerts[triIndex * 3 + 1].z);
                        rt.mVerts[1].mUv0 = new Vector2(rcp.mVerts[triIndex * 3 + 1].u0, rcp.mVerts[triIndex * 3 + 1].v0);

                        rt.mVerts[2]      = new RoadVert();
                        rt.mVerts[2].mPos = new Vector3(rcp.mVerts[triIndex * 3 + 2].x, rcp.mVerts[triIndex * 3 + 2].y, rcp.mVerts[triIndex * 3 + 2].z);
                        rt.mVerts[2].mUv0 = new Vector2(rcp.mVerts[triIndex * 3 + 2].u0, rcp.mVerts[triIndex * 3 + 2].v0);


                        triList.Add(rt);
                    }
                }

                //now add our triStrip segments (into triLists)
                for (int segIndex = 0; segIndex < rd.getNumRoadSegments(); segIndex++)
                {
                    roadSegment rs        = rd.getRoadSegment(segIndex);
                    int         numTris   = rs.mNumVerts - 2;
                    int         vertIndex = rs.mStartVertInParentSegment + 2;
                    for (int i = 0; i < numTris; i++)
                    {
                        RoadTriangle rt = new RoadTriangle();
                        rt.mVerts[0]      = new RoadVert();
                        rt.mVerts[0].mPos = new Vector3(rd.mVerts[vertIndex - 2].x, rd.mVerts[vertIndex - 2].y, rd.mVerts[vertIndex - 2].z);
                        rt.mVerts[0].mUv0 = new Vector2(rd.mVerts[vertIndex - 2].u0, rd.mVerts[vertIndex - 2].v0);

                        rt.mVerts[1]      = new RoadVert();
                        rt.mVerts[1].mPos = new Vector3(rd.mVerts[vertIndex - 1].x, rd.mVerts[vertIndex - 1].y, rd.mVerts[vertIndex - 1].z);
                        rt.mVerts[1].mUv0 = new Vector2(rd.mVerts[vertIndex - 1].u0, rd.mVerts[vertIndex - 1].v0);

                        rt.mVerts[2]      = new RoadVert();
                        rt.mVerts[2].mPos = new Vector3(rd.mVerts[vertIndex].x, rd.mVerts[vertIndex].y, rd.mVerts[vertIndex].z);
                        rt.mVerts[2].mUv0 = new Vector2(rd.mVerts[vertIndex].u0, rd.mVerts[vertIndex].v0);



                        triList.Add(rt);
                        vertIndex++;
                    }
                }


                //Step 2, split Polygons////////////////////////////////////////////////////
                int width     = (int)(BTerrainQuadNode.cMaxWidth);
                int numPlanes = (int)(TerrainGlobals.getTerrain().getNumXVerts() / width);

                //Split along XPlane
                for (int planeIndex = 0; planeIndex < numPlanes; planeIndex++)
                {
                    Plane pl = Plane.FromPointNormal(new Vector3(planeIndex * width * TerrainGlobals.getTerrain().getTileScale(), 0, 0), BMathLib.unitX);
                    splitPolyListAgainstPlane(pl, triList);
                }

                //split along ZPlane
                for (int planeIndex = 0; planeIndex < numPlanes; planeIndex++)
                {
                    Plane pl = Plane.FromPointNormal(new Vector3(0, 0, planeIndex * width * TerrainGlobals.getTerrain().getTileScale()), BMathLib.unitZ);
                    splitPolyListAgainstPlane(pl, triList);
                }

                //Step 3, add polies to qn./////////////////////////////////////////////////
                List <RoadQN> roadQNs = new List <RoadQN>();
                int           numQNs  = (int)(TerrainGlobals.getTerrain().getNumXVerts() / width);
                int           qnWidth = (int)(width * TerrainGlobals.getTerrain().getTileScale());
                for (int qnX = 0; qnX < numQNs; qnX++)
                {
                    for (int qnZ = 0; qnZ < numQNs; qnZ++)
                    {
                        float  x   = qnX * qnWidth;
                        float  z   = qnZ * qnWidth;
                        RoadQN rqn = new RoadQN();

                        for (int triIndex = 0; triIndex < triList.Count; triIndex++)
                        {
                            if (triContainedInBox(triList[triIndex], x, z, x + qnWidth, z + qnWidth))
                            {
                                triList[triIndex].ensureWinding();
                                rqn.mTris.Add(triList[triIndex]);
                                rqn.mOwnerQNIndex = qnX * numQNs + qnZ;
                            }
                        }

                        if (rqn.mTris.Count != 0)
                        {
                            roadQNs.Add(rqn);
                        }
                    }
                }

                //Step 4, write road chunk to disk./////////////////////////////////////////////
                ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
                chunkHolder.mDataMemStream = new MemoryStream();
                BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

                //Filename
                string fName = CoreGlobals.getWorkPaths().mRoadsPath + "\\" + rd.getRoadTextureName();
                fName = fName.Remove(0, CoreGlobals.getWorkPaths().mGameArtDirectory.Length + 1);
                char[] filename = new char[32];
                fName.CopyTo(0, filename, 0, fName.Length);
                binWriter.Write(filename);

                ExportTo360.addTextureChannelDependencies(CoreGlobals.getWorkPaths().mRoadsPath + "\\" + rd.getRoadTextureName());

                float zero        = 0;
                int   totalMemory = 0;
                //write our chunks
                binWriter.Write(Xbox_EndianSwap.endSwapI32(roadQNs.Count));
                for (int qnI = 0; qnI < roadQNs.Count; qnI++)
                {
                    binWriter.Write(Xbox_EndianSwap.endSwapI32(roadQNs[qnI].mOwnerQNIndex));
                    binWriter.Write(Xbox_EndianSwap.endSwapI32(roadQNs[qnI].mTris.Count));
                    int memSize = roadQNs[qnI].mTris.Count * (3 * (sizeof(short) * 6));
                    binWriter.Write(Xbox_EndianSwap.endSwapI32(memSize));

                    List <float> vList = new List <float>();
                    for (int c = 0; c < roadQNs[qnI].mTris.Count; c++)
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            vList.Add(roadQNs[qnI].mTris[c].mVerts[i].mPos.X);
                            vList.Add(roadQNs[qnI].mTris[c].mVerts[i].mPos.Y);
                            vList.Add(roadQNs[qnI].mTris[c].mVerts[i].mPos.Z);
                            vList.Add(zero); //padd;
                            vList.Add(roadQNs[qnI].mTris[c].mVerts[i].mUv0.X);
                            vList.Add(roadQNs[qnI].mTris[c].mVerts[i].mUv0.Y);
                        }
                    }
                    float16[] sList = BMathLib.Float32To16Array(vList.ToArray());
                    for (int c = 0; c < vList.Count; c++)
                    {
                        ushort s = ((ushort)sList[c].getInternalDat());
                        binWriter.Write(Xbox_EndianSwap.endSwapI16(s));
                    }
                    totalMemory += memSize;
                }

                ExportTo360.mECF.addChunk((int)eXTT_ChunkID.cXTT_RoadsChunk, chunkHolder, binWriter.BaseStream.Length);
                binWriter.Close();
                binWriter = null;
                chunkHolder.Close();
                chunkHolder = null;

                roadQNs.Clear();
                triList.Clear();

                TimeSpan ts = DateTime.Now - n;
                results.terrainRoadTime   = ts.TotalMinutes;
                results.terrainRoadMemory = totalMemory;
            }
        }
Esempio n. 18
0
        public void buildAOFiles(string inputFilename, int numSections)
        {
            float [] AOVals = null;
            for (int i = 0; i < numSections; i++)
            {
                //work\scenario\development\coltTest\coltTest.AO0, .AO1, .AO2...., .AON
                string outFileName = Path.ChangeExtension(inputFilename, ".AO" + i);

                FileStream   sr = File.Open(outFileName, FileMode.Open, FileAccess.Read);
                BinaryReader fr = new BinaryReader(sr);

                int majik = fr.ReadInt32();
                if (majik != cMajik)
                {
                    AOVals = null;
                    sr.Close();
                    sr = null;
                    fr.Close();
                    fr = null;

                    return;
                }

                int numSectionsT = fr.ReadInt32();
                Debug.Assert(numSectionsT == numSections);

                int mySecetion       = fr.ReadInt32();
                int numSamples       = fr.ReadInt32();
                int startSampleCount = fr.ReadInt32();
                int endSampleCount   = fr.ReadInt32();
                int width            = fr.ReadInt32();
                int height           = fr.ReadInt32();

                if (AOVals == null)
                {
                    AOVals = new float[width * height];
                }

                for (int x = 0; x < width * height; x++)
                {
                    AOVals[x] += fr.ReadSingle();
                    Debug.Assert(AOVals[x] > 1);
                }

                sr.Close();
                sr = null;
                fr.Close();
                fr = null;
            }



            //now that we have our AO data read from file and accumulated, open our XTD and write over the previous AO Values.
            //first we have to get the file pointer offset from reading the file...
            int       AOOffset            = 0;
            int       AOHeaderAdlerOffset = 0;
            ECFReader ecfR = new ECFReader();

            string XTDName = Path.ChangeExtension(inputFilename, ".XTD");

            if (!ecfR.openForRead(XTDName))
            {
                return;
            }

            int numXVerts = 0;

            for (uint i = 0; i < ecfR.getNumChunks(); i++)
            {
                ECF.BECFChunkHeader chunkHeader = ecfR.getChunkHeader(i);
                eXTD_ChunkID        id          = (eXTD_ChunkID)chunkHeader.mID;
                switch (id)
                {
                case eXTD_ChunkID.cXTD_XTDHeader:
                    int version = Xbox_EndianSwap.endSwapI32(ecfR.readInt32());
                    numXVerts = Xbox_EndianSwap.endSwapI32(ecfR.readInt32());
                    break;

                case eXTD_ChunkID.cXTD_AOChunk:
                    AOHeaderAdlerOffset  = (int)(i * ECF.BECFChunkHeader.giveSize() + ECF.ECFHeader.giveSize());
                    AOHeaderAdlerOffset += sizeof(Int64) * 2;

                    AOOffset = chunkHeader.mOfs;

                    break;
                }
            }

            ecfR.close();
            ecfR = null;



            //now that we have our offset into the file, open it for write
            //generate our data
            byte[] data = XTDExporter.packAOToDXT5A(AOVals, numXVerts);

            FileStream   s = File.Open(XTDName, FileMode.Open, FileAccess.ReadWrite);
            BinaryWriter f = new BinaryWriter(s);


            //reset the ADLER32 for this chunk..
            f.Seek(AOHeaderAdlerOffset, SeekOrigin.Begin);
            uint adler32 = (uint)Xbox_EndianSwap.endSwapI32((int)ECF.calcAdler32(data, 0, (uint)data.Length));

            f.Write(adler32);


            f.Seek(AOOffset, SeekOrigin.Begin);
            for (int i = 0; i < data.Length; i++)
            {
                f.Write(data[i]);
            }
            data = null;


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

            //DONE!
        }
Esempio n. 19
0
        public void writeQNsToChunk(ref ExportResults results)
        {
            DateTime n           = DateTime.Now;
            int      totalMemory = 0;

            int width = TerrainGlobals.getTerrain().getNumXVerts();

            for (int qi = 0; qi < FoliageManager.getNumChunks(); qi++)
            {
                FoliageQNChunk chunk = FoliageManager.getChunk(qi);

                List <int> setIndexes          = new List <int>();
                List <int> setPolyCounts       = new List <int>();
                int        totalPhysicalMemory = 0;
                List <int> indMemSizes         = new List <int>();
                List <int> bladeIBs            = new List <int>();

                for (int setI = 0; setI < chunk.mSetsUsed.Count; setI++)
                {
                    int        numBlades  = 0;
                    int        startIndex = bladeIBs.Count;
                    FoliageSet fs         = FoliageManager.giveSet(chunk.mSetsUsed[setI]);

                    //walk through the main grid for our current chunk
                    //pack the data into proper inds..
                    for (int x = 0; x < BTerrainQuadNode.cMaxWidth; x++)
                    {
                        for (int z = 0; z < BTerrainQuadNode.cMaxWidth; z++)
                        {
                            int             index = (x + chunk.mOwnerNodeDesc.mMinXVert) + width * (z + chunk.mOwnerNodeDesc.mMinZVert);
                            FoliageVertData fvd   = FoliageManager.mVertData.GetValue(index);
                            if (fvd.compare(FoliageManager.cEmptyVertData))
                            {
                                continue;
                            }

                            if (FoliageManager.giveIndexOfSet(fvd.mFoliageSetName) == FoliageManager.giveIndexOfSet(chunk.mSetsUsed[setI]))
                            {
                                numBlades++;

                                //our local blade index is transposed on the 360
                                int localIndex = x * FoliageManager.cNumXBladesPerChunk + z;
                                int bladeIndex = fvd.mFoliageSetBladeIndex << 16;

                                for (short t = 0; t < fs.mNumVertsPerBlade; t++)
                                {
                                    int packedID = bladeIndex | (0xFFFF & (localIndex * fs.mNumVertsPerBlade) + t);
                                    bladeIBs.Add(packedID);
                                }
                                bladeIBs.Add(0xFFFF); //360 specific tag to stop a strip.
                            }
                        }
                    }

                    int numVerts = bladeIBs.Count - startIndex;
                    if (numVerts == 0)
                    {
                        continue;
                    }

                    setIndexes.Add(FoliageManager.giveIndexOfSet(chunk.mSetsUsed[setI]));
                    setPolyCounts.Add(numBlades * (fs.mNumVertsPerBlade + 1) - 2);
                    indMemSizes.Add(numVerts * sizeof(int));
                    totalPhysicalMemory += indMemSizes[indMemSizes.Count - 1];
                }

                //now write this chunk..
                ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
                chunkHolder.mDataMemStream = new MemoryStream();
                BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

                //our chunk index is transposed in the game
                int minQNX               = (int)(chunk.mOwnerNodeDesc.mMinXVert / BTerrainQuadNode.cMaxWidth);
                int minQNZ               = (int)(chunk.mOwnerNodeDesc.mMinZVert / BTerrainQuadNode.cMaxHeight);
                int numXChunks           = (int)(TerrainGlobals.getTerrain().getNumXVerts() / BTerrainQuadNode.cMaxWidth);
                int transposedOwnerIndex = minQNX * numXChunks + minQNZ;

                binWriter.Write(Xbox_EndianSwap.endSwapI32(transposedOwnerIndex));//chunk.mOwnerQNIndex));
                binWriter.Write(Xbox_EndianSwap.endSwapI32(setIndexes.Count));

                int numSets = setIndexes.Count;
                for (int i = 0; i < numSets; i++)
                {
                    binWriter.Write(Xbox_EndianSwap.endSwapI32(setIndexes[i]));
                }

                for (int i = 0; i < numSets; i++)
                {
                    binWriter.Write(Xbox_EndianSwap.endSwapI32(setPolyCounts[i]));
                }


                binWriter.Write(Xbox_EndianSwap.endSwapI32(totalPhysicalMemory));
                totalMemory += totalPhysicalMemory;

                for (int i = 0; i < numSets; i++)
                {
                    binWriter.Write(Xbox_EndianSwap.endSwapI32(indMemSizes[i]));
                }

                for (int i = 0; i < bladeIBs.Count; i++)
                {
                    binWriter.Write(Xbox_EndianSwap.endSwapI32(bladeIBs[i]));
                }


                ExportTo360.mECF.addChunk((int)eXTT_ChunkID.cXTT_FoliageQNChunk, chunkHolder, binWriter.BaseStream.Length);
                binWriter.Close();
                binWriter = null;
                chunkHolder.Close();
                chunkHolder = null;
            }

            TimeSpan ts = DateTime.Now - n;

            results.terrainFoliageTime   = ts.TotalMinutes;
            results.terrainFoliageMemory = totalMemory;
        }
Esempio n. 20
0
        private void writeTessData(bool refineTerrain, float eLOD, float minorityBias, ref ExportResults results)
        {
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);


            //write the 'header'
            int nodeWidth   = 16;
            int numXPatches = (int)(TerrainGlobals.getTerrain().getNumXVerts() / (float)nodeWidth);
            int numZPatches = (int)(TerrainGlobals.getTerrain().getNumXVerts() / (float)nodeWidth);
            int numXChunks  = (int)(TerrainGlobals.getTerrain().getNumXVerts() / (float)BTerrainQuadNode.getMaxNodeDepth());
            int numPatches  = numXPatches * numZPatches;


            binWriter.Write(Xbox_EndianSwap.endSwapI32(numXPatches));
            binWriter.Write(Xbox_EndianSwap.endSwapI32(numZPatches));
            //do this for each patch


            byte[]    tDat  = new byte[numPatches];
            Vector4[] bbDat = new Vector4[numPatches * 2];

            //CLM - instead of writing floating point values (and taking up more memory)
            //write indexes into our discrete step array

            if (refineTerrain)
            {
                ErrorMetricRefine refiner = null;
                refiner = new ErrorMetricRefine();
                refiner.init(TerrainGlobals.getTerrain().getNumXVerts(), TerrainGlobals.getTerrain().getNumZVerts());

                refiner.refine(eLOD);//, nodeWidth + 1);

                markOverrideTessellations(refiner);


                for (int x = 0; x < numXPatches; x++)
                {
                    for (int z = 0; z < numZPatches; z++)
                    {
                        int xMinVert = x * nodeWidth;
                        int zMinVert = z * nodeWidth;

                        tDat[x + z * numXPatches] = giveMaxTesselation(ref refiner, xMinVert, zMinVert, nodeWidth, minorityBias);
                    }
                }
                refiner.destroy();
                refiner = null;

                smoothTessNeighbors(tDat, numXPatches, numZPatches);
            }
            else
            {
                for (int i = 0; i < numPatches; i++)
                {
                    tDat[i] = 0;
                }
            }


            //write to the disk
            for (int i = 0; i < tDat.Length; i++)
            {
                binWriter.Write(tDat[i]);
            }


            //generate and write our bounding boxes
            for (int x = 0; x < numXPatches; x++)
            {
                for (int z = 0; z < numZPatches; z++)
                {
                    Vector4 min = new Vector4(9000, 9000, 9000, 0);
                    Vector4 max = new Vector4(-9000, -9000, -9000, 0);
                    for (int i = 0; i < nodeWidth + 1; i++)
                    {
                        for (int j = 0; j < nodeWidth + 1; j++)
                        {
                            int xVal = x * nodeWidth + i;
                            int zVal = z * nodeWidth + j;
                            if (xVal >= TerrainGlobals.getTerrain().getNumXVerts() || zVal >= TerrainGlobals.getTerrain().getNumXVerts())
                            {
                                continue;
                            }

                            long    kIndex = xVal + TerrainGlobals.getTerrain().getNumXVerts() * zVal;
                            Vector3 v      = TerrainGlobals.getTerrain().getPos(xVal, zVal);
                            if (v.X < min.X)
                            {
                                min.X = v.X;
                            }
                            if (v.Y < min.Y)
                            {
                                min.Y = v.Y;
                            }
                            if (v.Z < min.Z)
                            {
                                min.Z = v.Z;
                            }
                            if (v.X > max.X)
                            {
                                max.X = v.X;
                            }
                            if (v.Y > max.Y)
                            {
                                max.Y = v.Y;
                            }
                            if (v.Z > max.Z)
                            {
                                max.Z = v.Z;
                            }
                        }
                    }

                    //NOTE: THE GAME EXPECTS THIS DATA IN NON-SWIZZLED FORM

                    int q = x + z * numZPatches;
                    q *= 2;

                    bbDat[q]     = min;
                    bbDat[q + 1] = max;
                }
            }
            for (int i = 0; i < bbDat.Length; i++)
            {
                binWriter.Write(Xbox_EndianSwap.endSwapF32(bbDat[i].X));
                binWriter.Write(Xbox_EndianSwap.endSwapF32(bbDat[i].Y));
                binWriter.Write(Xbox_EndianSwap.endSwapF32(bbDat[i].Z));
                binWriter.Write(Xbox_EndianSwap.endSwapF32(bbDat[i].W));
            }


            ExportTo360.mECF.addChunk((int)eXTD_ChunkID.cXTD_TessChunk, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;

            results.terrainTessValuesMemorySize = tDat.Length + (bbDat.Length * sizeof(float) * 4);

            tDat  = null;
            bbDat = null;
        }