示例#1
0
        private void markOverrideTessellations(ErrorMetricRefine refiner)
        {
            JaggedContainer <byte> v = TerrainGlobals.getEditor().getJaggedTesselation();

            int width = TerrainGlobals.getTerrain().getNumXVerts();

            long id;
            byte maskValue;

            v.ResetIterator();
            while (v.MoveNext(out id, out maskValue))
            {
                if (maskValue == BTerrainEditor.cTesselationEmptyVal)
                {
                    continue;
                }

                int x = (int)(id / width);
                int z = (int)(id - x * width);

                if (maskValue == (int)BTerrainEditor.eTessOverrideVal.cTess_Max)
                {
                    refiner.setMarkedPt(x, z, true);
                }
                else if (maskValue == (int)BTerrainEditor.eTessOverrideVal.cTess_Min)
                {
                    refiner.setMarkedPt(x, z, false);
                }
            }
        }
示例#2
0
        private byte giveMaxTesselation(ref ErrorMetricRefine refiner, int xOff, int zOff, int nodeWidth, float minortyBias)
        {
            int PatchWidth = 17;
            int numP       = 0;
            int numF       = 0;

            refiner.giveStatsInArea(xOff, zOff, PatchWidth, PatchWidth, out numP, out numF);

            float rat = (float)numP / (float)numF;

            //CLM THIS MUST MATCH THE 360
            //float[] tessLevels ={ 15, 7, 3, 1 };
            byte maxTess = 3;

            if (numP == 0)
            {
                maxTess = 3;
            }
            else if (numF == 0)
            {
                maxTess = 0;
            }
            else
            {
                if (rat <= 0.25f)
                {
                    maxTess = 3; //==1
                }
                else if (rat <= 0.5f)
                {
                    maxTess = 2; //==3
                }
                else if (rat <= 0.75f)
                {
                    maxTess = 1; //==7
                }
                else //if (rat <= 1.0f)
                {
                    maxTess = 0; //==15
                }
            }

            return(maxTess);
        }
示例#3
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;
        }