Exemplo n.º 1
0
        public void computeHeightField(uint width, uint height, bool includeSimMod, Vector3 upDir, uint cNumSamples)
        {
            copyTempD3DValues();
            TerrainGlobals.getTerrain().getQuadNodeRoot().clearVisibleDatHandle();
            TerrainGlobals.getVisual().destroyAllHandles();
            TerrainGlobals.getVisual().setHandleGenMode(true);
            GC.WaitForPendingFinalizers();

            ExportTo360.checkLoadRender();

            createTempTextures(width, height);

            calculateWorldBounds(includeSimMod);


            mHeightFieldAttributes = new BHeightFieldAttributes(width, height);

            Matrix       worldToView = Matrix.Identity;
            Matrix       viewToProj = Matrix.Identity;
            BBoundingBox worldBounds = new BBoundingBox();
            double       worldMinY = 0, worldMaxY = 0;

            computeTransforms(upDir, ref worldToView, ref viewToProj, ref worldBounds, ref worldMinY, ref worldMaxY);

            Random rand = new Random();

            double minDepth = float.MaxValue;
            double maxDepth = float.MinValue;



            cNumSamples = (uint)BMathLib.Clamp(cNumSamples, 1, 32);

            for (uint sampleIndex = 0; sampleIndex < cNumSamples; sampleIndex++)
            {
                float xOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f;
                float yOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f;

                Matrix projOfs = Matrix.Translation(xOfs / width, yOfs / height, 0.0f);

                generateDepthBuffer(ref pHighDepthSurf, width, height, false, worldToView, viewToProj * projOfs, includeSimMod);
                generateDepthBuffer(ref pLowDepthSurf, width, height, true, worldToView, viewToProj * projOfs, includeSimMod);

                fillHeightFieldTexture(width, height, mHeightFieldAttributes, pLowDepths, pHighDepths, ref minDepth, ref maxDepth);
            }

            viewToProj = viewToProj * Matrix.Translation(0.0f, 0.0f, (float)(-minDepth)) * Matrix.Scaling(1.0f, 1.0f, (float)(1.0f / (maxDepth - minDepth)));
            double newWorldMinY = worldMinY + (worldMaxY - worldMinY) * minDepth;

            worldMaxY = worldMinY + (worldMaxY - worldMinY) * maxDepth;
            worldMinY = newWorldMinY;
            minDepth  = 0.0f;
            maxDepth  = 1.0f;

            mHeightFieldAttributes.mWidth  = width;
            mHeightFieldAttributes.mHeight = height;
            mHeightFieldAttributes.mBounds = worldBounds;

            mHeightFieldAttributes.mWorldMinY   = (float)worldMinY;
            mHeightFieldAttributes.mWorldMaxY   = (float)worldMaxY;
            mHeightFieldAttributes.mWorldRangeY = (float)(worldMaxY - worldMinY);


            float minZ = 0;
            float maxZ = 1;
            float x    = 0;
            float y    = 0;

            Matrix cMTProjToScreen = BMathLib.matrixFrom16floats(
                width * .5f, 0.0f, 0.0f, 0.0f,
                0.0f, height * -.5f, 0.0f, 0.0f,
                0.0f, 0.0f, maxZ - minZ, 0.0f,
                x + width * .5f, y + height * .5f, minZ, 1.0f);

            mHeightFieldAttributes.mWorldToNormZ = worldToView * viewToProj * cMTProjToScreen;


            Matrix screenToProj    = Matrix.Invert(cMTProjToScreen);
            Matrix projToView      = Matrix.Invert(viewToProj);
            Matrix cMTScreenToView = Matrix.Multiply(screenToProj, projToView);

            mHeightFieldAttributes.mNormZToWorld = cMTScreenToView * Matrix.Invert(worldToView);

            releaseTempTextures();
            restoreTempD3DValues();
            TerrainGlobals.getVisual().setHandleGenMode(false);
            ExportTo360.checkUnloadRender();

            //copy our pixels from the previous point
            {
                for (int q = 0; q < width; q++)
                {
                    mHeightFieldAttributes.mpTexelsLO[(width - 1) * width + q] = mHeightFieldAttributes.mpTexelsLO[(width - 2) * width + q];
                    mHeightFieldAttributes.mpTexelsLO[q * width + (width - 1)] = mHeightFieldAttributes.mpTexelsLO[q * width + (width - 2)];
                    mHeightFieldAttributes.mpTexelsLO[q]         = mHeightFieldAttributes.mpTexelsLO[width + q];
                    mHeightFieldAttributes.mpTexelsLO[q * width] = mHeightFieldAttributes.mpTexelsLO[q * width + (1)];

                    mHeightFieldAttributes.mpTexelsHI[(width - 1) * width + q] = mHeightFieldAttributes.mpTexelsHI[(width - 2) * width + q];
                    mHeightFieldAttributes.mpTexelsHI[q * width + (width - 1)] = mHeightFieldAttributes.mpTexelsHI[q * width + (width - 2)];
                    mHeightFieldAttributes.mpTexelsHI[q]         = mHeightFieldAttributes.mpTexelsHI[width + q];
                    mHeightFieldAttributes.mpTexelsHI[q * width] = mHeightFieldAttributes.mpTexelsHI[q * width + (1)];
                }
            }

            #region dumpHeightfiled
            //{
            //   FileStream s = File.Open(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + "\\out.raw", FileMode.OpenOrCreate, FileAccess.Write);
            //   BinaryWriter f = new BinaryWriter(s);
            //   for (int i = 0; i < width * height; i++)
            //   {
            //      f.Write(mHeightFieldAttributes.mpTexelsLO[i]);
            //      f.Write(mHeightFieldAttributes.mpTexelsHI[i]);
            //   }
            //   f.Close();
            //   s.Close();
            //}

            #endregion
        }
Exemplo n.º 2
0
        //-----------------------------------------------------------------------------------
        //-----------------------------------------------------------------------------------

        public void computeHeightFieldDirectFloat(uint width, uint height, bool includeSimMod, Vector3 upDir, bool onlyDoOneSample, ref float[] output)
        {
            copyTempD3DValues();
            TerrainGlobals.getTerrain().getQuadNodeRoot().clearVisibleDatHandle();
            TerrainGlobals.getVisual().destroyAllHandles();
            TerrainGlobals.getVisual().setHandleGenMode(true);
            GC.WaitForPendingFinalizers();

            ExportTo360.checkLoadRender();

            createTempTextures(width, height);

            calculateWorldBounds(includeSimMod);


            mHeightFieldAttributes = new BHeightFieldAttributes(width, height);

            Matrix       worldToView = Matrix.Identity;
            Matrix       viewToProj = Matrix.Identity;
            BBoundingBox worldBounds = new BBoundingBox();
            double       worldMinY = 0, worldMaxY = 0;

            computeTransforms(upDir, ref worldToView, ref viewToProj, ref worldBounds, ref worldMinY, ref worldMaxY);

            float mWorldRangeY = (float)(mWorldMax.Y - mWorldMin.Y);

            uint numVals = width * height;

            if (output == null || output.Length != numVals)
            {
                output = new float[numVals];
                for (uint i = 0; i < numVals; i++)
                {
                    output[i] = float.MinValue;
                }
            }

            uint   cNumSamples = (uint)(onlyDoOneSample?1:4);
            Random rand        = new Random();

            for (uint sampleIndex = 0; sampleIndex < cNumSamples; sampleIndex++)
            {
                float xOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f;
                float yOfs = sampleIndex != 0 ? (float)((rand.NextDouble() * 2) - 1) : 0.0f;

                Matrix projOfs = Matrix.Translation(xOfs / width, yOfs / height, 0.0f);

                generateHeightBuffer(ref pHighDepthSurf, width, height, true, worldToView, viewToProj * projOfs, includeSimMod);

                #region fill & lock

                //mWorldMin.Y += 1.0f;
                //mWorldMax.Y -= 1.0f;

                unsafe
                {
                    GraphicsStream texstreamHI = pHighDepths.LockRectangle(0, LockFlags.None);
                    float *        pSrcHigh    = (float *)texstreamHI.InternalDataPointer;

                    //copy the data out so we can screw with it.
                    for (uint c = 0; c < numVals; c++)
                    {
                        output[c] = (float)Math.Max(output[c], pSrcHigh[c]);
                    }
                    pHighDepths.UnlockRectangle(0);
                }
                //find the max & min depth for this slice


                #endregion
            }



            releaseTempTextures();
            restoreTempD3DValues();
            TerrainGlobals.getVisual().setHandleGenMode(false);
            ExportTo360.checkUnloadRender();


            //#region dumpHeightfiled
            //{
            //   FileStream s = File.Open("_outHiDirect.raw", FileMode.OpenOrCreate, FileAccess.Write);
            //   BinaryWriter f = new BinaryWriter(s);
            //   for (int i = 0; i < width * height; i++)
            //   {
            //      float kp = (output[i] - mWorldMin.Y) / mWorldRangeY;
            //      ushort op = (ushort)(kp * ushort.MaxValue);
            //      f.Write(op);
            //   }
            //   f.Close();
            //   s.Close();
            //}

            //#endregion
        }
Exemplo n.º 3
0
        //-----------------------------------------------------------------------------------

        //-----------------------------------------------------------------------------------
        unsafe void fillHeightFieldTexture(
            uint width, uint height,
            BHeightFieldAttributes heightAttribs,
            Texture pLowDepths,
            Texture pHighDepths,
            ref double minDepthF, ref double maxDepthF)
        {
            GraphicsStream texstreamLOW = pLowDepths.LockRectangle(0, LockFlags.None);
            float *        pSrcLow      = (float *)texstreamLOW.InternalDataPointer;
            GraphicsStream texstreamHI  = pHighDepths.LockRectangle(0, LockFlags.None);
            float *        pSrcHigh     = (float *)texstreamHI.InternalDataPointer;

            bool firstPass = (minDepthF == float.MaxValue);

            //find the max & min depth for this slice
            uint numVals = width * height;

            if (minDepthF == float.MaxValue)
            {
                minDepthF = float.MaxValue;
                maxDepthF = 0;

                for (uint c = 0; c < numVals; c++)
                {
                    float l = pSrcLow[c];
                    float h = pSrcHigh[c];

                    if (!BMathLib.compare(l, 1) && !BMathLib.compare(l, 0))
                    {
                        if (l < minDepthF)
                        {
                            minDepthF = l;
                        }
                        if (l > maxDepthF)
                        {
                            maxDepthF = l;
                        }
                    }

                    if (!BMathLib.compare(h, 1) && !BMathLib.compare(h, 0))
                    {
                        if (h < minDepthF)
                        {
                            minDepthF = h;
                        }
                        if (h > maxDepthF)
                        {
                            maxDepthF = h;
                        }
                    }
                }

                if (BMathLib.compare((float)minDepthF, float.MaxValue))
                {
                    minDepthF = 0;
                    maxDepthF = 1;
                }

                if (BMathLib.compare((float)minDepthF, (float)maxDepthF))
                {
                    if (minDepthF == 0)
                    {
                        maxDepthF++;
                    }
                    else
                    {
                        minDepthF--;
                    }
                }
            }


            //add the depth values to the array, compress them based upon difference
            float diff = (float)(maxDepthF - minDepthF);

            for (uint c = 0; c < numVals; c++)
            {
                float l = pSrcLow[c];
                if (!BMathLib.compare(l, 1) && !BMathLib.compare(l, 0))
                {
                    if (l < minDepthF)
                    {
                        l = (float)minDepthF;
                    }
                    else if (l > maxDepthF)
                    {
                        l = (float)maxDepthF;
                    }
                }

                float h = pSrcHigh[c];
                if (!BMathLib.compare(h, 1) && !BMathLib.compare(h, 0))
                {
                    if (h < minDepthF)
                    {
                        h = (float)minDepthF;
                    }
                    else if (h > maxDepthF)
                    {
                        h = (float)maxDepthF;
                    }
                }

                h = ((float)(h - minDepthF) / diff);
                l = ((float)(l - minDepthF) / diff);


                int    shortRange = 0xFFFF;
                ushort hiVal      = (ushort)BMathLib.Clamp((shortRange * h), 0, ushort.MaxValue);
                ushort loVal      = (ushort)BMathLib.Clamp((shortRange * l), 0, ushort.MaxValue);

                if (firstPass)
                {
                    //if(loVal != 0xFFFF && loVal != 0)
                    heightAttribs.mpTexelsLO[c] = loVal;
                    //if (hiVal != 0xFFFF && hiVal != 0)
                    heightAttribs.mpTexelsHI[c] = hiVal;
                }
                else
                {
                    // if (loVal != 0xFFFF && loVal != 0)
                    heightAttribs.mpTexelsLO[c] = (ushort)Math.Min(heightAttribs.mpTexelsLO[c], loVal);
                    // if (hiVal != 0xFFFF && hiVal != 0)
                    heightAttribs.mpTexelsHI[c] = (ushort)Math.Min(heightAttribs.mpTexelsHI[c], hiVal);
                }
            }

            //fill in any blank spots that might be conflicting..

            //for (uint y = 0; y < height; y++)
            //{
            //   for (uint x = 0; x < width; x++)
            //   {
            //      uint ofs = x + y * mHeightFieldAttributes.mWidth;

            //      uint l = heightAttribs.mpTexelsLO[ofs];
            //      uint h = heightAttribs.mpTexelsHI[ofs];

            //      bool modified = false;

            //      if (l == 0)
            //      {
            //         float ave = 0.0f;
            //         uint num = 0;

            //         for (int xd = -1; xd < 1; xd++)
            //         {
            //            int yd;
            //            for (yd = -1; yd < 1; yd++)
            //            {
            //               int xx = (int)BMathLib.Clamp(xd + x, 0, width - 1);
            //               int yy = (int)BMathLib.Clamp(yd + y, 0, height - 1);

            //               uint p = heightAttribs.mpTexelsLO[xx + yy * mHeightFieldAttributes.mWidth];//lowHeights(xx, yy);
            //               if (p != 0)
            //               {
            //                  ave += p;
            //                  num++;
            //               }
            //            }
            //         }

            //         if (num != 0)
            //         {
            //            l = (uint)BMathLib.Clamp(BMathLib.FloatToIntRound(ave / num), 0, 65535U);
            //            heightAttribs.mpTexelsLO[ofs] = (ushort)l;
            //         }
            //      }

            //      modified = false;

            //      if (h == 1)
            //      {
            //         float ave = 0.0f;
            //         uint num = 0;

            //         for (int xd = -2; xd < 2; xd++)
            //         {
            //            int yd;
            //            for (yd = -2; yd < 2; yd++)
            //            {
            //               int xx = (int)BMathLib.Clamp(xd + x, 0, width - 1);
            //               int yy = (int)BMathLib.Clamp(yd + y, 0, height - 1);

            //               uint p = heightAttribs.mpTexelsHI[xx + yy * mHeightFieldAttributes.mWidth];//highHeights(xx, yy);
            //               if (p != 0)
            //               {
            //                  ave += p;
            //                  num++;
            //               }
            //            }
            //         }

            //         if (num != 0)
            //         {
            //            h = (uint)BMathLib.Clamp(BMathLib.FloatToIntRound(ave / num), 0, 65535U);
            //            heightAttribs.mpTexelsHI[ofs] = (ushort)h;
            //         }
            //      }
            //   }
            //}


            pLowDepths.UnlockRectangle(0);
            pHighDepths.UnlockRectangle(0);
        }