//----------------------------------------------------------------------------------- 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; }
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); }
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); }
//----------------------------------------- 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; }
//---------------------------------------------- //---------------------------------------------- //---------------------------------------------- //---------------------------------------------- //---------------------------------------------- //---------------------------------------------- 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); }
//----------------------------------------------------------------------------------- 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)); }
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)); }
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; }
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; }