Пример #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;
        }
Пример #2
0
        public static byte[] packAOToDXT5A(float[] AoVals, int numXVerts)
        {
            byte[] inData = new byte[AoVals.Length * 4];
            int    c      = 0;

            for (int x = 0; x < numXVerts; x++)
            {
                for (int z = 0; z < numXVerts; z++)
                {
                    int dstIndex = 4 * (x * numXVerts + z);
                    int srcIndex = (x + numXVerts * z);

                    float k = AoVals[srcIndex] > 1 ? 1 : AoVals[srcIndex];

                    inData[dstIndex + 0] = 1;
                    inData[dstIndex + 1] = 1;
                    inData[dstIndex + 2] = 1;
                    inData[dstIndex + 3] = (byte)(k * 255);
                }
            }
            //for (int i = 0; i < AoVals.Length; i++)
            //{
            //   float k = AoVals[i] > 1 ? 1 : AoVals[i];

            //   inData[c++] = 1;
            //   inData[c++] = 1;
            //   inData[c++] = 1;
            //   inData[c++] = (byte)(k * 255);
            //}

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

            ExportTo360.toCompressedFormat(inData, numXVerts, numXVerts, sizeof(UInt32), BDXTFormat.cDXT5A, eDXTQuality.cDXTQualityBest, 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;
            }
            //swizzle this data

            inData = null;
            return(outDat);
        }
Пример #3
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;
        }
Пример #4
0
        public unsafe bool export_XSD(string filename, ExportSettings expSettings, ref Export360.ExportResults results)
        {
            DateTime n = DateTime.Now;

            //update before we do anything
            TerrainGlobals.getEditor().getSimRep().updateForExport();// update(false);//

            headerToChunk();

            results.terrainSimMemorySize = simDataToChunk();


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

            TimeSpan ts = DateTime.Now - n;

            results.terrainSimTime = ts.TotalMinutes;

            return(exportOK);
        }
Пример #5
0
        //-----------------------------------------------------------------------------------
        public bool export_XTH(string filename, ExportSettings expSettings, ref ExportResults results)
        {
            DateTime n = DateTime.Now;



            HeightsGen hg = new HeightsGen();

            hg.computeHeightField(256, 256, true, BMathLib.unitZ, 8);

            headerToChunk();
            heightFieldToChunk(hg, ref results); //turn our data into a ECF chunk
            heightFieldAlphaToChunk(ref results);
            bool exportOK = ExportTo360.safeECFFileWrite(filename, ".XTH");

            hg.destroy();


            TimeSpan ts = DateTime.Now - n;

            results.terrainGPUHeighfieldTime = ts.TotalMinutes;

            return(exportOK);
        }
Пример #6
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);
        }
Пример #7
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;
            }
        }
Пример #8
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);
        }
Пример #9
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;
        }
Пример #10
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;
        }