Exemple #1
0
        public float?GetAverageHeightFromNeighbourhood(int pKernelSizeMultiplier)
        {
            int pKernelSize = CGroundArray.GetKernelSize();

            pKernelSize *= pKernelSizeMultiplier;

            int   defined   = 0;
            float heightSum = 0;

            for (int x = -pKernelSize; x < pKernelSize; x++)
            {
                for (int y = -pKernelSize; y < pKernelSize; y++)
                {
                    int    xIndex = indexInField.Item1 + x;
                    int    yIndex = indexInField.Item2 + y;
                    CField el     = GetFieldWithOffset(x, y);
                    if (el != null && el.IsDefined())
                    {
                        defined++;
                        heightSum += (float)el.GetHeight();
                    }
                }
            }
            if (defined == 0)
            {
                return(null);
            }
            return(heightSum / defined);
        }
Exemple #2
0
        /// <summary>
        /// Add points of given class to the partitions
        /// </summary>
        public static void AddPoints(EClass pClass)
        {
            for (int x = 0; x < CProjectData.Points.groundArray.arrayXRange; x += partitionStepSize)
            {
                for (int y = 0; y < CProjectData.Points.groundArray.arrayYRange; y += partitionStepSize)
                {
                    List <Vector3> points = new List <Vector3>();
                    for (int _x = x; _x < x + partitionStepSize; _x++)
                    {
                        for (int _y = y; _y < y + partitionStepSize; _y++)
                        {
                            CField element = CProjectData.Points.GetField(pClass, _x, _y);
                            //CField element = CProjectData.Points.groundArray.GetField(_x, _y);
                            if (element != null)
                            {
                                points.AddRange(element.points);
                            }
                        }
                    }
                    Obj pointsObj = new Obj(GetPointsObjName(pClass));
                    CObjExporter.AddPointsToObj(ref pointsObj, points);
                    pointsObj.UseMtl = CMaterialManager.GetPointsMaterial(pClass).Name;

                    AddObj(x, y, pointsObj);
                }
            }
        }
Exemple #3
0
 public static float Get2DDistance(CField pField1, CField pField2)
 {
     if (pField1 == null || pField2 == null)
     {
         CDebug.Error("Field is null");
         return(0);
     }
     return(Get2DDistance(pField1.Center, pField2.Center));
 }
Exemple #4
0
        /// <summary>
        /// Finds the closest neighbour in given direction which doesnt contain any of the given points
        /// </summary>
        public CField GetClosestNeighbourWithout(List <Vector3> pPoints, EDirection pDirection)
        {
            CField current = GetNeighbour(pDirection);

            while (current != null && current.Contains(pPoints, false))
            {
                current = current.GetNeighbour(pDirection);
            }
            return(current);
        }
Exemple #5
0
        public static EDirection GetDirection(CField pFrom, CField pTo)
        {
            Vector3 dir = pTo.Center - pFrom.Center;

            dir = Vector3.Normalize(dir);
            const float angle_limit = 0.35f;

            if (dir.X > angle_limit)
            {
                if (dir.Y > angle_limit)
                {
                    return(EDirection.RightTop);
                }
                else if (dir.Y < -angle_limit)
                {
                    return(EDirection.RightBot);
                }
                else
                {
                    return(EDirection.Right);
                }
            }
            else if (dir.X < -angle_limit)
            {
                if (dir.Y > angle_limit)
                {
                    return(EDirection.LeftTop);
                }
                else if (dir.Y < -angle_limit)
                {
                    return(EDirection.LeftBot);
                }
                else
                {
                    return(EDirection.Left);
                }
            }
            else
            {
                if (dir.Y > angle_limit)
                {
                    return(EDirection.Top);
                }
                else if (dir.Y < -angle_limit)
                {
                    return(EDirection.Bot);
                }
                else
                {
                    return(EDirection.None);
                }
            }
        }
Exemple #6
0
        public override bool Equals(object obj)
        {
            // Check for null values and compare run-time types.
            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }

            CField e = (CField)obj;

            return((indexInField.Item1 == e.indexInField.Item1) && (indexInField.Item2 == e.indexInField.Item2));
        }
Exemple #7
0
        public Tuple <int, int> GetIndexInArray(Vector3 pPoint)
        {
            Tuple <int, int> pos = GetIndexInArray(pPoint, topLeftCorner, stepSize);

            CField el = GetField(pos.Item1, pos.Item2);

            if (el != null && el.IsPointOutOfField(pPoint))
            {
                CDebug.Error($"point {pPoint} is too far from center {el.Center}");
            }

            return(pos);
        }
Exemple #8
0
        /// <summary>
        /// Returns the interpolated height.
        /// Interpolation = bilinear.
        /// </summary>
        public float?GetHeight(Vector3 pPoint)
        {
            if (!HasAllNeighbours() || !HasAllNeighboursDefined(true))
            {
                if (!IsDefined())
                {
                    return(null);
                }
                return(GetHeight());
            }
            //return GetHeight(); //uncomment to cancel interpolation

            //http://www.geocomputation.org/1999/082/gc_082.htm
            //3.4 Bilinear interpolation

            List <CField> bilinearFields = GetBilinearFieldsFor(pPoint);
            CField        h1             = bilinearFields[0];
            CField        h2             = bilinearFields[1];
            CField        h3             = bilinearFields[2];
            CField        h4             = bilinearFields[3];

            float a00 = (float)h1.GetHeight();
            float a10 = (float)h2.GetHeight() - (float)h1.GetHeight();
            float a01 = (float)h3.GetHeight() - (float)h1.GetHeight();
            float a11 = (float)h1.GetHeight() - (float)h2.GetHeight() - (float)h3.GetHeight() + (float)h4.GetHeight();

            float step = CParameterSetter.groundArrayStep;

            float x = pPoint.X - Center.X;

            x += step / 2;
            x  = x / step;
            float y = Center.Y - pPoint.Y;

            y += step / 2;
            y  = y / step;

            if (x < 0 || x > 1 || y < 0 || y > 1)
            {
                CDebug.Error("field " + this + " interpolation is incorrect! x = " + x + " z = " + y);
            }

            //pPoint space coords are X and Z, Y = height
            float hi = a00 + a10 * x + a01 * y + a11 * x * y;

            return(hi);
        }
Exemple #9
0
        public List <CField> GetPerpendicularNeighbours(EDirection pToDirection)
        {
            List <CField> neigh = new List <CField>();
            CField        n1    = null;
            CField        n2    = null;

            switch (pToDirection)
            {
            case EDirection.Top:
            case EDirection.Bot:
                n1 = GetNeighbour(EDirection.Left);
                n2 = GetNeighbour(EDirection.Right);
                break;

            case EDirection.RightTop:
            case EDirection.LeftBot:
                n1 = GetNeighbour(EDirection.LeftTop);
                n2 = GetNeighbour(EDirection.RightBot);
                break;

            case EDirection.Right:
            case EDirection.Left:
                n1 = GetNeighbour(EDirection.Top);
                n2 = GetNeighbour(EDirection.Bot);
                break;

            case EDirection.RightBot:
            case EDirection.LeftTop:
                n1 = GetNeighbour(EDirection.RightTop);
                n2 = GetNeighbour(EDirection.LeftBot);
                break;
            }
            if (n1 != null)
            {
                neigh.Add(n1);
            }
            if (n2 != null)
            {
                neigh.Add(n2);
            }
            return(neigh);
        }
Exemple #10
0
        public List <CField> GetFieldsInDistance(int pSteps)
        {
            List <CField> fields = new List <CField>();

            for (int x = -pSteps; x <= pSteps; x++)
            {
                for (int y = -pSteps; y <= pSteps; y++)
                {
                    CField field = GetFieldWithOffset(x, y);
                    if (field != null)
                    {
                        fields.Add(field);
                    }
                }
            }
            fields.Sort((a, b) =>
                        CUtils.Get2DDistance(Center, a.Center).CompareTo(
                            CUtils.Get2DDistance(Center, b.Center)));

            return(fields);
        }
Exemple #11
0
        protected List <TypeField> GetPathFrom(TypeField pFieldFrom, TypeField pFieldTo, float pMaxPathLength = int.MaxValue)
        {
            //todo: check if generated path is valid

            TypeField        current = pFieldFrom;
            List <TypeField> path    = new List <TypeField>()
            {
                current
            };
            float pathLength = 0;

            while (!current.Equals(pFieldTo) && pathLength < pMaxPathLength)
            {
                EDirection dir        = CField.GetDirection(current, pFieldTo);
                TypeField  newCurrent = (TypeField)current.GetNeighbour(dir);
                pathLength += CUtils.Get2DDistance(current, newCurrent);
                current     = newCurrent;
                path.Add(current);
            }
            return(path);
        }
Exemple #12
0
        /// <summary>
        /// Returnd point with given local position to this point
        /// </summary>
        private CField GetFieldWithOffset(int pIndexOffsetX, int pIndexOffsetY)
        {
            CField el = this;

            for (int x = 0; x < Math.Abs(pIndexOffsetX); x++)
            {
                el = pIndexOffsetX > 0 ? el.Right : el.Left;
                if (el == null)
                {
                    return(null);
                }
            }
            for (int y = 0; y < Math.Abs(pIndexOffsetY); y++)
            {
                el = pIndexOffsetY > 0 ? el.Top : el.Bot;
                if (el == null)
                {
                    return(null);
                }
            }
            return(el);
        }
Exemple #13
0
        /// <summary>
        /// Sets SmoothHeight based on average from neighbourhood
        /// </summary>
        public void CalculateSmoothHeight(double[,] pGaussKernel)
        {
            if (!IsDefined())
            {
                return;
            }

            //int defined = 0;
            float heightSum = 0;

            float midHeight = (float)GetHeight();

            int kernelSize = CGroundArray.GetKernelSize();

            float gaussWeightSum = 0;

            for (int x = 0; x < kernelSize; x++)
            {
                for (int y = 0; y < kernelSize; y++)
                {
                    int    xIndex   = indexInField.Item1 + x - kernelSize / 2;
                    int    yIndex   = indexInField.Item2 + y - kernelSize / 2;
                    CField el       = CProjectData.Points.groundArray.GetField(xIndex, yIndex);
                    float? elHeight = el?.GetHeight();

                    //if element is not defined, use height from the middle element
                    float definedHeight = midHeight;
                    if (elHeight != null)
                    {
                        definedHeight = (float)elHeight;
                    }
                    float gaussWeight = (float)pGaussKernel[x, y];
                    gaussWeightSum += gaussWeight;
                    heightSum      += definedHeight * gaussWeight;
                }
            }

            SmoothHeight = heightSum;
        }
Exemple #14
0
        /// <summary>
        /// Returns neighbour using 8-neighbourhood
        /// </summary>
        /// <param name="pIncludeThis"></param>
        /// <returns></returns>
        public List <CField> GetNeighbours(bool pIncludeThis = false)
        {
            if (neighbours != null)
            {
                if (pIncludeThis)
                {
                    List <CField> neighbourCopy = new List <CField>();
                    neighbourCopy.Add(this);
                    foreach (CField n in neighbours)
                    {
                        neighbourCopy.Add(n);
                    }
                    return(neighbourCopy);
                }
                return(neighbours);
            }

            neighbours = new List <CField>();
            if (pIncludeThis)
            {
                neighbours.Add(this);
            }

            var directions = Enum.GetValues(typeof(EDirection));

            foreach (EDirection d in directions)
            {
                CField neighour = GetNeighbour(d);
                if (neighour != null)
                {
                    neighbours.Add(neighour);
                }
            }

            return(neighbours);
        }
Exemple #15
0
 /// <summary>
 /// Returns number of steps required to reach 'pField' in 4-neighbourhood stepping
 /// </summary>
 public int GetStepCountTo(CField pField)
 {
     return(Math.Abs(indexInField.Item1 - pField.indexInField.Item1) +
            Math.Abs(indexInField.Item2 - pField.indexInField.Item2));
 }
Exemple #16
0
        /// <summary>
        /// Finds closest defined fields in direction based on pDiagonal parameter.
        /// Returns average of 2 found heights considering their distance from this field.
        /// </summary>
        public float?GetAverageHeightFromClosestDefined(int pMaxSteps, bool pDiagonal, EHeight pType)
        {
            if (IsDefined())
            {
                return(GetHeight(pType));
            }

            CField closestFirst  = null;
            CField closestSecond = null;
            CField closestLeft   = GetClosestDefined(pDiagonal ? EDirection.LeftTop : EDirection.Left, pMaxSteps);
            CField closestRight  = GetClosestDefined(pDiagonal ? EDirection.RightBot : EDirection.Right, pMaxSteps);
            CField closestTop    = GetClosestDefined(pDiagonal ? EDirection.RightTop : EDirection.Top, pMaxSteps);
            CField closestBot    = GetClosestDefined(pDiagonal ? EDirection.LeftBot : EDirection.Bot, pMaxSteps);

            closestFirst  = closestLeft;
            closestSecond = closestRight;
            if ((closestFirst == null || closestSecond == null) && closestTop != null && closestBot != null)
            {
                closestFirst  = closestTop;
                closestSecond = closestBot;
            }

            if (closestFirst != null && closestSecond != null)
            {
                CField smaller = closestFirst;
                CField higher  = closestSecond;
                if (closestSecond.GetHeight(pType) < closestFirst.GetHeight(pType))
                {
                    higher  = closestFirst;
                    smaller = closestSecond;
                }
                int   totalDistance = smaller.GetStepCountTo(higher);
                float?heightDiff    = higher.GetHeight(pType) - smaller.GetHeight(pType);
                if (heightDiff != null)
                {
                    float?smallerHeight     = smaller.GetHeight();
                    float distanceToSmaller = GetStepCountTo(smaller);

                    return(smallerHeight + distanceToSmaller / totalDistance * heightDiff);
                }
            }
            else if (!HasAllNeighbours())
            {
                if (closestLeft != null)
                {
                    return(closestLeft.GetHeight(pType));
                }
                if (closestTop != null)
                {
                    return(closestTop.GetHeight(pType));
                }
                if (closestRight != null)
                {
                    return(closestRight.GetHeight(pType));
                }
                if (closestBot != null)
                {
                    return(closestBot.GetHeight(pType));
                }
            }
            if (!pDiagonal)
            {
                return(GetAverageHeightFromClosestDefined(pMaxSteps, true, pType));
            }

            return(null);
        }
Exemple #17
0
 public float GetDistanceTo(CField pField)
 {
     return(this.GetDistanceTo(pField.Center));
 }