示例#1
0
        void contractSetValue(ref DAGMask src, ref DAGMask dst)
        {
            Point[] neighOffset = new Point[] { new Point(-1, -1), new Point(-1, 0), new Point(-1, 1),
                                                new Point(1, -1), new Point(1, 0), new Point(1, 1),
                                                new Point(0, -1), new Point(0, 1) };

            for (int x = 0; x < src.Width; x++)
            {
                for (int y = 0; y < src.Height; y++)
                {
                    float min = float.MaxValue;

                    for (int i = 0; i < neighOffset.Length; i++)
                    {
                        Point off = neighOffset[i];
                        if (x + off.X < 0 || x + off.X >= src.Width ||
                            y + off.Y < 0 || y + off.Y >= src.Height)
                        {
                            continue;
                        }

                        if (src[x + off.X, y + off.Y] < min)
                        {
                            min = src[x + off.X, y + off.Y];
                        }
                    }
                    dst[x, y] = min;
                }
            }
        }
示例#2
0
      public DAGMask execute(int width, int height)
      {
         List<int> outputNodes = findIndexesOfNodesOfType(typeof(Device_ToCurrentMask));

         if(outputNodes.Count ==0)
         {
            MessageBox.Show("Error: Cannot compute graph:\n Missing ToCurrentMask output node", "Cannot execute graph", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return null;
         }
         else if (outputNodes.Count > 1)
         {
            MessageBox.Show("Error: Cannot compute graph:\n Multiple ToCurrentMask output nodes found.", "Cannot execute graph", MessageBoxButtons.OK, MessageBoxIcon.Error);
            return null;
         }

         Device_ToCurrentMask dcm = mNodes[outputNodes[0]] as Device_ToCurrentMask;
         
         OutputGenerationParams ogp = new OutputGenerationParams();
         ogp.Width = width;
         ogp.Height = height;

         if (!dcm.computeOutput(null, ogp))
            return null;

         DAGMask dMask = dcm.ResultMask.Clone();
          
         return dMask;

      }
示例#3
0
        public DAGMask Clone()
        {
            DAGMask m = new DAGMask(mWidth, mHeight);

            CopyTo(m);
            return(m);
        }
示例#4
0
        override public bool computeOutput(ConnectionPoint connPoint, OutputGenerationParams parms)
        {
            if (!verifyInputConnections())
            {
                return(false);
            }

            if (!gatherInputAndParameters(parms))
            {
                return(false);
            }

            MaskParam mp = ((MaskParam)(connPoint.ParamType));

            mp.Value = InputMask.Clone();
            mp.Value.mConstraintMask = ConstraintMask;

            int     numTimesToRun = parms.Width >> 1;
            DAGMask outMask       = InputMask.Clone();//

            DAGMask distMask = new DAGMask(parms.Width, parms.Height);

            int maxRange = 0;

            for (int i = 0; i < numTimesToRun; i++)
            {
                DAGMask smallerMask = new DAGMask(parms.Width, parms.Height);
                bool    madeChange  = contractSetValue(ref outMask, ref smallerMask, ref distMask, i);

                outMask = smallerMask.Clone();
                if (madeChange)
                {
                    maxRange = i;
                }
                else
                {
                    break;
                }
            }


            //normalize our input now...
            for (int x = 0; x < parms.Width; x++)
            {
                for (int y = 0; y < parms.Height; y++)
                {
                    mp.Value[x, y] = distMask[x, y] / (float)maxRange;
                }
            }

            outMask = null;

            return(true);
        }
示例#5
0
        void transferSoil(DAGMask inMask, List <Point> travelPath, int width, int height, ref DAGMask subMask, ref DAGMask addMask, float slopeBiasScalar)
        {
            float amtOfSoilInStream = 0;
            Point currPt            = new Point();
            Point nxtPt             = new Point();

            for (int i = 0; i < travelPath.Count - 1; i++)
            {
                currPt.X = travelPath[i].X;
                currPt.Y = travelPath[i].Y;
                nxtPt.X  = travelPath[i + 1].X;
                nxtPt.Y  = travelPath[i + 1].Y;

                //determine sediment saturation based upon slope^2
                float Height  = inMask[currPt.X, currPt.Y] - subMask[currPt.X, currPt.Y] + addMask[currPt.X, currPt.Y];
                float nHeight = inMask[nxtPt.X, nxtPt.Y] - subMask[nxtPt.X, nxtPt.Y] + addMask[nxtPt.X, nxtPt.Y];

                float slope = Height - nHeight;

                float cDepositThreshold = 0.00390625f;// 1/256 //CLM MAGIC NUMBER
                if (slope < cDepositThreshold || amtOfSoilInStream > SedimentCarryAmt)
                {
                    //deposit soil

                    //how much soil should we deposit?
                    float soilAmt = (slope * (1.0f - SoilHardness));
                    if (amtOfSoilInStream > 0)
                    {
                        amtOfSoilInStream -= soilAmt;
                        addSoil(soilAmt, currPt.X, currPt.Y, ref inMask, ref subMask, ref addMask);
                    }
                }
                else
                {
                    //pickup soil
                    float soilAmt = (slope * (1.0f - SoilHardness)); // CLM MAGIC NUMBER
                    amtOfSoilInStream += soilAmt;
                    removeSoil(soilAmt, currPt.X, currPt.Y, ref inMask, ref subMask, ref addMask);
                }



                if (amtOfSoilInStream < 0)
                {
                    break;
                }
            }

            //do we have soil suspended in the stream?
            //  if (amtOfSoilInStream > 0)
            //    addSoil(amtOfSoilInStream, currPt.X, currPt.Y, ref inMask, ref subMask, ref addMask);
        }
示例#6
0
        void calculateErosion(DAGMask inMask, int width, int height, ref DAGMask subMask, ref DAGMask addMask, int amtScalar)
        {
            Random rnd    = new Random();
            Point  prevPt = new Point(rnd.Next(width), rnd.Next(width));

            for (int passCount = 0; passCount < width * Amount; passCount++)
            {
                Point currPt = new Point(rnd.Next(width), rnd.Next(width));

                List <Point> travelPath = calculatePath(inMask, width, height, ref subMask, ref addMask, currPt);
                transferSoil(inMask, travelPath, width, height, ref subMask, ref addMask, 1.0f);
            }
        }
示例#7
0
        public bool writeToFile(string filename, OutputGenerationParams parms)
        {
            if (!verifyInputConnections())
            {
                return(false);
            }

            DAGMask m = mInputMask.Value;
            //temp haxor
            string ext = Path.GetExtension(filename);

            if (ext == ".r16")
            {
                FileStream   s = File.Open(filename, FileMode.OpenOrCreate, FileAccess.Write);
                BinaryWriter f = new BinaryWriter(s);

                for (int x = 0; x < parms.Width; x++)
                {
                    for (int y = 0; y < parms.Height; y++)
                    {
                        float  k       = m[x, y];
                        float  scaledk = (k + 1) * 0.5f;
                        ushort v       = (ushort)(scaledk * ushort.MaxValue);
                        f.Write(v);
                    }
                }
                f.Close();
                s.Close();
            }
            else if (ext == ".raw")
            {
                FileStream   s = File.Open(filename, FileMode.OpenOrCreate, FileAccess.Write);
                BinaryWriter f = new BinaryWriter(s);

                for (int x = 0; x < parms.Width; x++)
                {
                    for (int y = 0; y < parms.Height; y++)
                    {
                        float k       = m[x, y];
                        float scaledk = (k + 1) * 0.5f;
                        byte  v       = (byte)(scaledk * byte.MaxValue);
                        f.Write(v);
                    }
                }
                f.Close();
                s.Close();
            }

            return(true);
        }
示例#8
0
        override public bool computeOutput(ConnectionPoint connPoint, OutputGenerationParams parms)
        {
            if (!verifyInputConnections())
            {
                return(false);
            }

            gatherInputAndParameters(parms);


            MaskParam mp = ((MaskParam)(connPoint.ParamType));
            // mp.Value = InputMask.Clone();

            DAGMask baseMask = InputMask.Clone();

            DAGMask addMask = new DAGMask(parms.Width, parms.Height);
            DAGMask subMask = new DAGMask(parms.Width, parms.Height);

            //if we're doing multiscale erosion
            if (MultiscaleEnable)
            {
                //subtract multiscale mask from our base mask before doing erosion
                multiscaleDisplace(ref baseMask, ref subMask, ref addMask);
            }


            //CLM it actually looks better (less noisy) w/o this high fidelity step!
            calculateErosion(baseMask, baseMask.Width, baseMask.Height, ref subMask, ref addMask, 0);


            //calculate our mask 'channels'

            for (int x = 0; x < parms.Width; x++)
            {
                for (int y = 0; y < parms.Height; y++)
                {
                    baseMask[x, y] = baseMask[x, y] + addMask[x, y] - subMask[x, y];
                }
            }

            //need to find which output this connection point is connected to...
            mp.Value = baseMask.Clone();


            return(true);
        }
示例#9
0
      public void generatePreview(CanvasNode cn)
      {
          OutputGenerationParams ogp = new OutputGenerationParams();
          ogp.Width = 128;
          ogp.Height = 128;

          MaskDAGGraphNode gn = (MaskDAGGraphNode)cn;
          MaskParam mp = new MaskParam();
          InputConnectionPoint icp = new InputConnectionPoint(mp,true,"Preview",gn,this);
          gn.computeOutput(icp,ogp);

          if (onUpdateCallback != null)
          {
              DAGMask m = mp.Value;
              onUpdateCallback(ref m);
          }
       }
示例#10
0
        override public bool computeOutput(ConnectionPoint connPoint, OutputGenerationParams parms)
        {
            if (!verifyInputConnections())
            {
                return(false);
            }

            if (!gatherInputAndParameters(parms))
            {
                return(false);
            }

            MaskParam mp = ((MaskParam)(connPoint.ParamType));

            mp.Value = InputMask.Clone();
            mp.Value.mConstraintMask = ConstraintMask;


            DAGMask outMask = InputMask.Clone();

            for (int i = 0; i < NumPixels; i++)
            {
                DAGMask smallerMask = new DAGMask(parms.Width, parms.Height);
                contractSetValue(ref outMask, ref smallerMask);

                outMask = smallerMask.Clone();
            }


            //normalize our input now...
            for (int x = 0; x < parms.Width; x++)
            {
                for (int y = 0; y < parms.Height; y++)
                {
                    mp.Value[x, y] = outMask[x, y];
                }
            }

            outMask = null;

            return(true);
        }
示例#11
0
        bool contractSetValue(ref DAGMask src, ref DAGMask dst, ref DAGMask distMask, float valToSet)
        {
            Point[] neighOffset = new Point[] { new Point(-1, -1), new Point(-1, 0), new Point(-1, 1),
                                                new Point(1, -1), new Point(1, 0), new Point(1, 1),
                                                new Point(0, -1), new Point(0, 1) };

            bool setVal = false;

            for (int x = 0; x < src.Width; x++)
            {
                for (int y = 0; y < src.Height; y++)
                {
                    float min = float.MaxValue;

                    for (int i = 0; i < neighOffset.Length; i++)
                    {
                        Point off = neighOffset[i];
                        if (x + off.X < 0 || x + off.X >= src.Width ||
                            y + off.Y < 0 || y + off.Y >= src.Height)
                        {
                            continue;
                        }

                        if (src[x + off.X, y + off.Y] < min)
                        {
                            min = src[x + off.X, y + off.Y];
                        }
                    }

                    if (min < src[x, y])
                    {
                        distMask[x, y] = valToSet;
                        setVal         = true;
                    }


                    dst[x, y] = min;
                }
            }
            return(setVal);
        }
示例#12
0
        void multiscaleDisplace(ref DAGMask baseMask, ref DAGMask subMask, ref DAGMask addMask)
        {
            eFilterType type  = eFilterType.cFilter_Linear;//eFilterType.cFilter_Nearest;//
            int         level = 4;

            // int l = level;
            for (int l = level; l > 0; l--)
            {
                //resize to smaller texture
                DAGMask smallMask = new DAGMask(baseMask.Width >> l, baseMask.Height >> l);
                resizeF32Img(baseMask, smallMask, baseMask.Width, baseMask.Height, smallMask.Width, smallMask.Height, type);

                DAGMask addMaskSmall = new DAGMask(smallMask.Width, smallMask.Height);
                DAGMask subMaskSmall = new DAGMask(smallMask.Width, smallMask.Height);
                resizeF32Img(addMask, addMaskSmall, addMask.Width, addMask.Height, addMaskSmall.Width, addMaskSmall.Height, type);
                resizeF32Img(subMask, subMaskSmall, subMask.Width, subMask.Height, subMaskSmall.Width, subMaskSmall.Height, type);

                //calculate erosion
                calculateErosion(smallMask, smallMask.Width, smallMask.Height, ref subMaskSmall, ref addMaskSmall, l);

                //move back
                DAGMask addMaskBig = new DAGMask(baseMask.Width, baseMask.Height);
                DAGMask subMaskBig = new DAGMask(baseMask.Width, baseMask.Height);
                resizeF32Img(addMaskSmall, addMaskBig, addMaskSmall.Width, addMaskSmall.Height, addMask.Width, addMask.Height, type);
                resizeF32Img(subMaskSmall, subMaskBig, subMaskSmall.Width, subMaskSmall.Height, subMask.Width, subMask.Height, type);

                DAGMask smallMaskBig = new DAGMask(baseMask.Width, baseMask.Height);
                resizeF32Img(smallMask, smallMaskBig, smallMask.Width, smallMask.Height, smallMaskBig.Width, smallMaskBig.Height, type);

                for (int x = 0; x < baseMask.Width; x++)
                {
                    for (int y = 0; y < baseMask.Height; y++)
                    {
                        // baseMask[x, y] = smallMaskBig[x, y];
                        addMask[x, y] = addMaskBig[x, y];
                        subMask[x, y] = subMaskBig[x, y];
                    }
                }
            }
        }
示例#13
0
        public bool loadAndExecute()
        {
            if (mGraphMemoryStream == null)
            {
                return(false);
            }

            mGraphMemoryStream.Seek(0, SeekOrigin.Begin);
            int tWidth  = CoreGlobals.getEditorMain().mITerrainShared.getNumXVerts();
            int tHeight = CoreGlobals.getEditorMain().mITerrainShared.getNumXVerts();

            DAGCanvas dg = new DAGCanvas(512, 512);

            dg.loadCanvasFromMemoryStream(mGraphMemoryStream);
            DAGMask resMask = dg.execute(tWidth, tHeight);

            if (resMask == null)
            {
                MessageBox.Show("There was an error computing Mask");
                return(false);
            }

            mOutputMask = new ArrayBasedMask(mCapacity);


            for (int x = 0; x < tWidth; x++)
            {
                for (int y = 0; y < tHeight; y++)
                {
                    mOutputMask.SetMaskWeight(x * tWidth + y, resMask[x, y]);
                }
            }
            dg.newCanvas();
            dg = null;
            mGraphMemoryStream.Seek(0, SeekOrigin.Begin);
            return(true);
        }
示例#14
0
        void removeSoil(float soilAmt, int x, int y, ref DAGMask inMask, ref DAGMask subMask, ref DAGMask addMask)
        {
            //for visual clairty, make this a 2x2
            subMask[x, y] += soilAmt;

            float hlfSol = soilAmt * 0.5f;

            if (y - 1 > 0)
            {
                subMask[x, y - 1] += hlfSol;
            }
            if (x - 1 > 0)
            {
                subMask[x - 1, y] += hlfSol;
            }
            if (y + 1 < inMask.Height)
            {
                subMask[x, y + 1] += hlfSol;
            }
            if (x + 1 < inMask.Width)
            {
                subMask[x + 1, y] += hlfSol;
            }
        }
示例#15
0
        static public void resizeF32Img(DAGMask inputTexture, DAGMask outputTexture, int inputWidth, int inputHeight, int newWidth, int newHeight, eFilterType method)
        {
            if (outputTexture == null)
            {
                outputTexture = new DAGMask(newWidth, newHeight);
            }
            if (inputWidth == newWidth && inputHeight == newHeight)
            {
                outputTexture = inputTexture.Clone();
                return;
            }
            float xFactor = (float)inputWidth / newWidth;
            float yFactor = (float)inputHeight / newHeight;

            int dstOffset = inputWidth - newWidth;

            //create a new texture of new size

            switch (method)
            {
            case eFilterType.cFilter_Nearest:
            {
                int ox, oy;


                // for each line
                for (int y = 0; y < newHeight; y++)
                {
                    // Y coordinate of the nearest point
                    oy = (int)(y * yFactor);

                    // for each pixel
                    for (int x = 0; x < newWidth; x++)
                    {
                        // X coordinate of the nearest point
                        ox = (int)(x * xFactor);

                        int srcIndex = oy * inputWidth + ox;

                        outputTexture[x, y] = inputTexture[ox, oy];
                    }
                    //     dstIndex += dstOffset;
                }
                break;
            }

            case eFilterType.cFilter_Linear:
            {
                float ox, oy, dx1, dy1, dx2, dy2;
                int   ox1, oy1, ox2, oy2;
                int   ymax = inputHeight - 1;
                int   xmax = inputWidth - 1;
                float v1, v2;


                // for each line
                for (int y = 0; y < newHeight; y++)
                {
                    // Y coordinates
                    oy  = (float)y * yFactor;
                    oy1 = (int)oy;
                    oy2 = (oy1 == ymax) ? oy1 : oy1 + 1;
                    dy1 = oy - (float)oy1;
                    dy2 = 1.0f - dy1;

                    // for each pixel
                    for (int x = 0; x < newWidth; x++)
                    {
                        // X coordinates
                        ox  = (float)x * xFactor;
                        ox1 = (int)ox;
                        ox2 = (ox1 == xmax) ? ox1 : ox1 + 1;
                        dx1 = ox - (float)ox1;
                        dx2 = 1.0f - dx1;


                        // interpolate using 4 points
                        {
                            v1 = (float)(dx2 * (inputTexture[ox1, oy1]) + dx1 * (inputTexture[ox2, oy1]));
                            v2 = (float)(dx2 * (inputTexture[ox1, oy2]) + dx1 * (inputTexture[ox2, oy2]));
                            outputTexture[x, y] = (float)(dy2 * v1 + dy1 * v2);
                        }
                    }
                    //  dstIndex += dstOffset;
                }
                break;
            }
            }
            ;
        }
示例#16
0
        override public bool computeOutput(ConnectionPoint connPoint, OutputGenerationParams parms)
        {
            if (!verifyInputConnections())
            {
                return(false);
            }

            if (!gatherInputAndParameters(parms))
            {
                return(false);
            }

            MaskParam mp = ((MaskParam)(connPoint.ParamType));

            mp.Value = InputMask.Clone();
            mp.Value.mConstraintMask = ConstraintMask;



            int r = Radius;

            int[]   w       = CreateGaussianBlurRow(r);
            int     wlen    = w.Length;
            DAGMask tmpMask = new DAGMask(parms.Width, parms.Height);


            {
                float[] waSums = new float[wlen];
                float[] wcSums = new float[wlen];
                float[] aSums  = new float[wlen];


                for (int y = 0; y < parms.Height; ++y)
                {
                    float waSum = 0;
                    float wcSum = 0;
                    float aSum  = 0;


                    int dstx = 0;

                    for (int wx = 0; wx < wlen; ++wx)
                    {
                        int srcX = wx - r;
                        waSums[wx] = 0;
                        wcSums[wx] = 0;
                        aSums[wx]  = 0;


                        if (srcX >= 0 && srcX < parms.Width)
                        {
                            for (int wy = 0; wy < wlen; ++wy)
                            {
                                int srcY = y + wy - r;

                                if (srcY >= 0 && srcY < parms.Height)
                                {
                                    float c  = InputMask[srcX, srcY];
                                    float wp = w[wy];

                                    waSums[wx] += wp;
                                    wp         *= c;// +(c >> 7);
                                    wcSums[wx] += wp;
                                    //wp >>= 8;

                                    aSums[wx] += wp * c;
                                }
                            }

                            int wwx = w[wx];
                            waSum += wwx * waSums[wx];
                            wcSum += wwx * wcSums[wx];
                            aSum  += wwx * aSums[wx];
                        }
                    }

                    // wcSum >>= 8;

                    if (waSum == 0 || wcSum == 0)
                    {
                        tmpMask[dstx, y] = 0;
                    }
                    else
                    {
                        tmpMask[dstx, y] = aSum / waSum;
                    }

                    ++dstx;

                    for (int x = 1; x < parms.Width; ++x)
                    {
                        for (int i = 0; i < wlen - 1; ++i)
                        {
                            waSums[i] = waSums[i + 1];
                            wcSums[i] = wcSums[i + 1];
                            aSums[i]  = aSums[i + 1];
                        }

                        waSum = 0;
                        wcSum = 0;
                        aSum  = 0;


                        int wx;
                        for (wx = 0; wx < wlen - 1; ++wx)
                        {
                            float wwx = w[wx];
                            waSum += wwx * waSums[wx];
                            wcSum += wwx * wcSums[wx];
                            aSum  += wwx * aSums[wx];
                        }

                        wx = wlen - 1;

                        waSums[wx] = 0;
                        wcSums[wx] = 0;
                        aSums[wx]  = 0;


                        int srcX = x + wx - r;

                        if (srcX >= 0 && srcX < parms.Width)
                        {
                            for (int wy = 0; wy < wlen; ++wy)
                            {
                                int srcY = y + wy - r;

                                if (srcY >= 0 && srcY < parms.Height)
                                {
                                    float c  = InputMask[srcX, srcY];
                                    float wp = w[wy];

                                    waSums[wx] += wp;
                                    wp         *= c;// +(c >> 7);
                                    wcSums[wx] += wp;
                                    //wp >>= 8;

                                    aSums[wx] += wp * c;
                                }
                            }

                            int wr = w[wx];
                            waSum += wr * waSums[wx];
                            wcSum += wr * wcSums[wx];
                            aSum  += wr * aSums[wx];
                        }

                        // wcSum >>= 8;

                        if (waSum == 0 || wcSum == 0)
                        {
                            tmpMask[x, y] = 0;
                        }
                        else
                        {
                            tmpMask[x, y] = (aSum / waSum);
                        }

                        ++dstx;
                    }
                }
            }



            //copy back
            for (int x = 0; x < parms.Width; x++)
            {
                for (int y = 0; y < parms.Height; y++)
                {
                    mp.Value[x, y] = tmpMask[x, y];
                }
            }

            tmpMask = null;

            return(true);
        }
示例#17
0
        void addSoil(float soilAmt, int x, int y, ref DAGMask inMask, ref DAGMask subMask, ref DAGMask addMask)
        {
            addMask[x, y] += soilAmt;
            return;
            //if the addition of the soil makes me taller than any neighbor
            //then distribute soil between them and myself.

            //float currHeight = inMask[x, y] - subMask[x, y] + addMask[x, y] + soilAmt;

            //bool[] lowerPts = new bool[8];
            //float[] diffPts = new float[8];


            ////calculate neighbor info
            //float slope = 0;
            //float diffSum = 0;
            //int lowestDiffIdx = 0;
            //float lowestDiff = float.MaxValue;
            //bool foundLower = false;
            //for (int i = 0; i < neighOffset.Length; i++)
            //{
            //   Point off = neighOffset[i];
            //   if (x + off.X < 0 || x + off.X >= inMask.Width ||
            //      y + off.Y < 0 || y + off.Y >= inMask.Height )
            //   {
            //      lowerPts[i] = false;
            //      diffPts[i] = 0;
            //      continue;
            //   }

            //   float nHeight = inMask[x + off.X, y + off.Y] - subMask[x + off.X, y + off.Y] + addMask[x + off.X, y + off.Y];

            //   if (currHeight > nHeight)
            //   {
            //      lowerPts[i] = true;
            //      diffPts[i] = currHeight - nHeight;
            //      diffSum += diffPts[i];
            //      foundLower = true;
            //      if(lowestDiff > diffPts[i])
            //      {
            //         lowestDiff = diffPts[i];
            //         lowestDiffIdx = i;
            //      }
            //   }
            //   else
            //   {
            //      lowerPts[i] = false;
            //      diffPts[i] = 0;
            //   }
            //}

            //if(!foundLower)
            //{
            //   addMask[x, y] += soilAmt;
            //   return;
            //}


            ////distribute soil
            //float amtToDistribute = lowestDiff;
            //addMask[x, y] += soilAmt - lowestDiff;

            //for (int i = 0; i < neighOffset.Length; i++)
            //{
            //   if (lowerPts[i])
            //   {
            //      float weight = diffPts[i] / diffSum;

            //      addMask[x, y] += amtToDistribute * weight;
            //   }
            //}
        }
示例#18
0
        List <Point> calculatePath(DAGMask inMask, int width, int height, ref DAGMask subMask, ref DAGMask addMask, Point currPt)
        {
            List <Point> points = new List <Point>();

            points.Add(currPt);
            Point prevPt = currPt;

            int distanceMax = inMask.Width;

            while (distanceMax > 0)
            {
                float currHeight = inMask[currPt.X, currPt.Y] - subMask[currPt.X, currPt.Y] + addMask[currPt.X, currPt.Y];

                bool[]  lowerPts = new bool[8];
                float[] diffPts  = new float[8];


                //calculate neighbor info

                float diffSum    = 0;
                bool  foundLower = false;
                for (int i = 0; i < neighOffset.Length; i++)
                {
                    Point off = neighOffset[i];
                    if (currPt.X + off.X < 0 || currPt.X + off.X >= width ||
                        currPt.Y + off.Y < 0 || currPt.Y + off.Y >= height ||
                        (currPt.X + off.X == prevPt.X && currPt.Y + off.Y == prevPt.Y))
                    {
                        lowerPts[i] = false;
                        diffPts[i]  = 0;
                        continue;
                    }

                    float nHeight = inMask[currPt.X + off.X, currPt.Y + off.Y] - subMask[currPt.X + off.X, currPt.Y + off.Y] + addMask[currPt.X + off.X, currPt.Y + off.Y];

                    if (currHeight > nHeight)
                    {
                        lowerPts[i] = true;
                        diffPts[i]  = (currHeight - nHeight) * neighWeight[i];
                        diffSum    += diffPts[i];
                        foundLower  = true;
                    }
                    else
                    {
                        lowerPts[i] = false;
                        diffPts[i]  = 0;
                    }
                }

                //we fell in a local minima;
                if (!foundLower)
                {
                    break;
                }


                //randomly pick one of our next stebs based upon propbability of weight
                int   minIndex     = 0;
                float randomNum    = (float)mRand.NextDouble();
                float runningTotal = 0;
                for (int i = 0; i < neighOffset.Length; i++)
                {
                    if (lowerPts[i])
                    {
                        float weight = diffPts[i] / diffSum;
                        if (runningTotal + weight > randomNum)
                        {
                            minIndex = i;
                            break;
                        }
                        runningTotal += weight;
                    }
                }

                prevPt.X = currPt.X;
                prevPt.Y = currPt.Y;

                currPt.X += neighOffset[minIndex].X;
                currPt.Y += neighOffset[minIndex].Y;

                points.Add(currPt);

                distanceMax--;
                if (distanceMax < 0)
                {
                    break;
                }
            }
            ;

            return(points);
        }
示例#19
0
        override public bool computeOutput(ConnectionPoint connPoint, OutputGenerationParams parms)
        {
            if (!verifyInputConnections())
            {
                return(false);
            }

            if (!gatherInputAndParameters(parms))
            {
                return(false);
            }

            MaskParam mp = ((MaskParam)(connPoint.ParamType));

            mp.Value = InputMask.Clone();
            mp.Value.mConstraintMask = ConstraintMask;


            ConvMatrix filter = new ConvMatrix(1, 2, 1, 2, 4, 2, 1, 2, 1);

            filter.mFactor = 16;
            filter.mOffset = 0;

            for (int i = 0; i < SmoothPower; i++)
            {
                int[] neightbors = new int[] { -1, 1,     //top left
                                               0, 1,      //top center
                                               1, 1,      //top right

                                               -1, 0,     //mid left
                                               0, 0,      //mid center
                                               1, 0,      //mid right

                                               -1, -1,    //bot left
                                               0, -1,     //bot center
                                               1, -1,     //bot right
                };


                DAGMask tempImgArray = new DAGMask(parms.Width, parms.Height);

                for (int x = 0; x < parms.Width; x++)
                {
                    for (int y = 0; y < parms.Height; y++)
                    {
                        float total = 0;
                        for (int k = 0; k < 9; k++)
                        {
                            int xIndex = x + neightbors[k * 2];
                            int zIndex = y + neightbors[k * 2 + 1];
                            if (xIndex < 0 || xIndex > parms.Width - 1 || zIndex < 0 || zIndex > parms.Height - 1)
                            {
                                continue;
                            }


                            total += filter.mFilterCoeffs[k] * mp.Value[xIndex, zIndex];
                        }
                        total = total / filter.mFactor + filter.mOffset;

                        if (total > 1.0f)
                        {
                            total = 1.0f;
                        }
                        if (total < 0)
                        {
                            total = 0;
                        }

                        tempImgArray[x, y] = total;
                    }
                }

                //send our mask back
                for (int x = 0; x < parms.Width; x++)
                {
                    for (int y = 0; y < parms.Height; y++)
                    {
                        mp.Value[x, y] = BMathLib.Clamp(tempImgArray[x, y], 0, 1);
                    }
                }


                tempImgArray = null;
            }


            return(true);
        }