Пример #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
        //-----------------------------------------------------------------------------------
        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;
        }
Пример #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
        private int writeBuildable()
        {
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);


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

            // Write buildable
            bool[] landBuildable = simRep.getDataTiles().getSimLandBuildable();
            int    numTiles      = simRep.getNumXTiles();

            byte tru = 0xFF;
            byte fal = 0x00;

            for (int x = 0; x < numTiles; x++)
            {
                for (int z = 0; z < numTiles; z++)
                {
                    int index = (x * numTiles + z);

                    if (landBuildable[index])
                    {
                        binWriter.Write(tru);
                    }
                    else
                    {
                        binWriter.Write(fal);
                    }
                }
            }



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

            return(landBuildable.Length * sizeof(byte));
        }
Пример #5
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;
        }
Пример #6
0
        public void writeAOData(ref ExportResults results)
        {
            //WRITE THE CHUNK
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

            byte[] data = packAOToDXT5A(TerrainGlobals.getEditor().getAmbientOcclusionValues(), TerrainGlobals.getTerrain().getNumXVerts());
            for (int i = 0; i < data.Length; i++)
            {
                binWriter.Write(data[i]);
            }
            results.terrainAOMemorySize = data.Length;
            data = null;

            ExportTo360.mECF.addChunk((int)eXTD_ChunkID.cXTD_AOChunk, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;
        }
Пример #7
0
        void writeAlpha(ref ExportResults results)
        {
            //WRITE THE CHUNK
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);


            #region DXT5Alpha
            byte[] dataAlpha = packAlphaToDXT5A(TerrainGlobals.getEditor().getAlphaValues(), TerrainGlobals.getTerrain().getNumXVerts());
            for (int i = 0; i < dataAlpha.Length; i++)
            {
                binWriter.Write(dataAlpha[i]);
            }
            results.terrainAlphaMemorySize = dataAlpha.Length;
            dataAlpha = null;
            #endregion

            ExportTo360.mECF.addChunk((int)eXTD_ChunkID.cXTD_AlphaChunk, chunkHolder, binWriter.BaseStream.Length);
            binWriter.Close();
            binWriter = null;
            chunkHolder.Close();
            chunkHolder = null;
        }
Пример #8
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;
        }
Пример #9
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;
        }
Пример #10
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;
        }
Пример #11
0
        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;
        }
Пример #12
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;
            }
        }
Пример #13
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));
        }
Пример #14
0
        private int writeTileType()
        {
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);

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


            // Write tile types
            int numTiles             = simRep.getNumXTiles();
            int obstructionArraySize = numTiles * numTiles;

            SimTerrainType.loadTerrainTileTypes();
            int tileTypeArraySize = obstructionArraySize;

            byte[] tileTypeArray = new byte[tileTypeArraySize];
            for (int x = 0; x < numTiles; x++)
            {
                for (int z = 0; z < numTiles; z++)
                {
                    int index = (x * numTiles + z);

                    //if we have a tile type override, use it
                    int typeOverride = TerrainGlobals.getEditor().getSimRep().getDataTiles().getJaggedTileType(z, x);
                    if (typeOverride > 0)
                    {
                        tileTypeArray[index] = (byte)typeOverride;
                    }
                    else
                    {
                        // Get each tile's dominant texture index
                        int dominantTextureIndex = TerrainGlobals.getEditor().giveDominantTextureAtTile(x, z, simRep);

                        tileTypeArray[index] = 0;
                        if (dominantTextureIndex != -1)
                        {
                            byte   numTypes            = (byte)SimTerrainType.mTerrainTileTypes.mTypes.Count;
                            string dominantTextureType = SimTerrainType.mTextureList[dominantTextureIndex].TileType;
                            // Find the dominant texture's type
                            for (byte typeIndex = 0; typeIndex < numTypes; typeIndex++)
                            {
                                if (SimTerrainType.mTerrainTileTypes.mTypes[typeIndex].Name == dominantTextureType)
                                {
                                    tileTypeArray[index] = typeIndex;
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            binWriter.Write(tileTypeArray);

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

            return(tileTypeArray.Length);
        }
Пример #15
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;
        }
Пример #16
0
        private int writeObstructions()
        {
            ECF.ECFChunkHolder chunkHolder = new ECF.ECFChunkHolder();
            chunkHolder.mDataMemStream = new MemoryStream();
            BinaryWriter binWriter = new BinaryWriter(chunkHolder.mDataMemStream);


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

            // Write obstructions
            bool[] landObstructions     = simRep.getDataTiles().getSimLandObstructions();
            int    numTiles             = simRep.getNumXTiles();
            int    obstructionArraySize = numTiles * numTiles;

            byte[] obstructionsFlags = new byte[obstructionArraySize];

            bool[] alreadyDone = new bool[numTiles * numTiles];
            for (int i = 0; i < numTiles * numTiles; i++)
            {
                alreadyDone[i] = false;
            }

            for (int x = 0; x < numTiles; x++)
            {
                for (int z = 0; z < numTiles; z++)
                {
                    int index = (x * numTiles + z);


                    bool obstructsLand   = simRep.getDataTiles().isLandObstructedComposite(x, z);
                    bool obstructsFlood  = simRep.getDataTiles().isFloodObstructed(x, z);
                    bool obstructsScarab = simRep.getDataTiles().isScarabObstructed(x, z);


                    obstructionsFlags[index] = 0;

                    if (obstructsLand && obstructsFlood && obstructsScarab)
                    {
                        obstructionsFlags[index] = (byte)BTerrainSimRep.eObstructionType.cObstrtuction_Land_Flood_Scarab;
                    }
                    else if (obstructsLand && obstructsFlood && !obstructsScarab)
                    {
                        obstructionsFlags[index] = (byte)BTerrainSimRep.eObstructionType.cObstrtuction_Land_Flood;
                    }
                    else if (obstructsLand && !obstructsFlood && obstructsScarab)
                    {
                        obstructionsFlags[index] = (byte)BTerrainSimRep.eObstructionType.cObstrtuction_Land_Scarab;
                    }
                    else if (obstructsLand && !obstructsFlood && !obstructsScarab)
                    {
                        obstructionsFlags[index] = (byte)BTerrainSimRep.eObstructionType.cObstrtuction_Land;
                    }
                    else if (!obstructsLand && obstructsFlood && obstructsScarab)
                    {
                        obstructionsFlags[index] = (byte)BTerrainSimRep.eObstructionType.cObstrtuction_Flood_Scarab;
                    }
                    else if (!obstructsLand && obstructsFlood && !obstructsScarab)
                    {
                        obstructionsFlags[index] = (byte)BTerrainSimRep.eObstructionType.cObstrtuction_Flood;
                    }
                    else if (!obstructsLand && !obstructsFlood && obstructsScarab)
                    {
                        obstructionsFlags[index] = (byte)BTerrainSimRep.eObstructionType.cObstrtuction_Scarab;
                    }
                    else if (!obstructsLand && !obstructsFlood && !obstructsScarab)
                    {
                        obstructionsFlags[index] = (byte)BTerrainSimRep.eObstructionType.cNoObstruction;
                    }
                }
            }

            binWriter.Write(obstructionsFlags);

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

            return(obstructionsFlags.Length);
        }
Пример #17
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));
        }
Пример #18
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);
        }
Пример #19
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;
        }