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); }
private void generateGridChunks(ref XTDVisualHeader header) { //Create and write our flat terrain quadnode chunks BTerrainQuadNode[] mLeafNodes = TerrainGlobals.getTerrain().getQuadNodeLeafArray(); for (int i = 0; i < mLeafNodes.Length; i++) { int width = (int)BTerrainQuadNode.getMaxNodeWidth(); ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder(); chunkHolder.mDataMemStream = new MemoryStream(); BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream); XTDTerrainChunk gridNode = new XTDTerrainChunk(); int locX = mLeafNodes[i].getDesc().mMinXVert / width; int locZ = mLeafNodes[i].getDesc().mMinZVert / width; gridNode.gridLocX = locX; gridNode.gridLocZ = locZ; //calculate our chunk data gridNode.heightmapOnly = false; gridNode.maxVertStride = 64; //lets get our verts, normals, and ambOcclu int mnX = locX * width; int mnZ = locZ * width; BBoundingBox bb = new BBoundingBox(); bb.empty(); for (int z = 0; z < width + 1; z++) { for (int x = 0; x < width + 1; x++) { int xVal = (int)(mnX + x); int zVal = (int)(mnZ + z); Vector3 v = TerrainGlobals.getTerrain().getPos(xVal, zVal); bb.addPoint(v); } } gridNode.mMin = bb.min; gridNode.mMax = bb.max; //IF WE CONTAIN FOLIAGE! increase the size of our bounding boxes.. if (FoliageManager.isChunkUsed(mLeafNodes[i])) { BBoundingBox bbA = FoliageManager.giveMaxBBs(); gridNode.mMin += bbA.min; gridNode.mMax += bbA.max; } //expand our box a tad float scle = TerrainGlobals.getTerrain().getTileScale(); gridNode.mMin -= new Vector3(scle, scle, scle); gridNode.mMax += new Vector3(scle, scle, scle); //send the verts off to the compressor to be compressed properly into an image (using whatever technique) //be sure to assign a corolary ID so we can reference it later. writeChunk(gridNode, binWriter); //add this chunk to our main data stream ExportTo360.mECF.addChunk((int)eXTD_ChunkID.cXTD_TerrainChunk, chunkHolder, binWriter.BaseStream.Length); binWriter.Close(); binWriter = null; chunkHolder.Close(); chunkHolder = null; } mLeafNodes = null; }