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