/// <summary>
        /// Chooses the most common value.
        /// </summary>
        private static unsafe TLeafData HistogramFilterInternal(TLeafData *pdata)
        {
            for (int i = 0; i < CHILD_COUNT; ++i)
            {
                TLeafData key = pdata[i];
                int       count;
                m_histogram.TryGetValue(key, out count);
                ++count;
                m_histogram[key] = count;
            }

            TLeafData mostCommon      = default(TLeafData);
            int       mostCommonCount = 0;

            foreach (var entry in m_histogram)
            {
                if (entry.Value > mostCommonCount)
                {
                    mostCommonCount = entry.Value;
                    mostCommon      = entry.Key;
                }
            }
            m_histogram.Clear();
            return(mostCommon);
        }
 public static unsafe void SetAllData(TLeafData *dst, TLeafData value)
 {
     for (int i = 0; i < CHILD_COUNT; ++i)
     {
         dst[i] = value;
     }
 }
 public static unsafe bool AllDataSame(TLeafData *pData, TLeafData value)
 {
     for (int i = 1; i < CHILD_COUNT; ++i)
     {
         if (pData[i] != value)
         {
             return(false);
         }
     }
     return(true);
 }
        /// <summary>
        /// Treats value as normalized signed distance in given LOD. Since LOD size doubles, distance halves for all cases except max value.
        /// </summary>
        private static unsafe TLeafData SignedDistanceFilterInternal(TLeafData *pData)
        {
            float signedDist   = ToSignedDistance(pData[0]);
            var   average      = AverageValueFilterInternal(pData);
            var   averageSDist = ToSignedDistance(average);

            if (averageSDist != signedDist || (signedDist != 1f && signedDist != -1f))
            {
                signedDist *= 0.5f; // distance is halved in higher lod since sample size is doubled
                // maybe the average could also be taken into account to get an idea on which side of surface this sample is ...
            }
            return(FromSignedDistance(signedDist));
        }
        public static unsafe bool AllDataSame(TLeafData *pData)
        {
            TLeafData refValue = pData[0];

            for (int i = 1; i < CHILD_COUNT; ++i)
            {
                if (pData[i] != refValue)
                {
                    return(false);
                }
            }
            return(true);
        }
        /// <summary>
        /// Chooses average of all values.
        /// </summary>
        private static unsafe TLeafData AverageValueFilterInternal(TLeafData *pData)
        {
            float sum = 0;

            for (int i = 0; i < CHILD_COUNT; ++i)
            {
                sum += ToSignedDistance(pData[i]);
            }

            sum /= CHILD_COUNT;
            if (sum != 1f && sum != -1f)
            {
                sum *= 0.5f; // distance is halved in higher lod since sample size is doubled
            }
            return(FromSignedDistance(sum));
        }
Exemple #7
0
        /// <summary>
        /// Chooses the most common value.
        /// </summary>
        private static unsafe TLeafData HistogramFilterInternal(TLeafData *pdata, int lod)
        {
            if (Histogram == null)
            {
                Histogram = new Dictionary <byte, int>(8);
            }

            for (int i = 0; i < CHILD_COUNT; ++i)
            {
                TLeafData key = pdata[i];
                if (key == MyVoxelConstants.NULL_MATERIAL)
                {
                    continue;
                }

                int count;
                Histogram.TryGetValue(key, out count);
                ++count;
                Histogram[key] = count;
            }

            if (Histogram.Count == 0)
            {
                return(MyVoxelConstants.NULL_MATERIAL);
            }

            TLeafData mostCommon      = default(TLeafData);
            int       mostCommonCount = 0;

            foreach (var entry in Histogram)
            {
                if (entry.Value > mostCommonCount)
                {
                    mostCommonCount = entry.Value;
                    mostCommon      = entry.Key;
                }
            }
            Histogram.Clear();
            return(mostCommon);
        }
        /// <summary>
        /// Chooses value which is the closest to isosurface level. Whether
        /// from above, or from below is chosen depending on which is majority.
        /// </summary>
        private static unsafe TLeafData IsoSurfaceFilterInternal(TLeafData *pData)
        {
            TLeafData bestBelow  = 0;
            TLeafData bestAbove  = TLeafData.MaxValue;
            int       aboveCount = 0;
            int       belowCount = 0;

            for (int i = 0; i < CHILD_COUNT; ++i)
            {
                var data = pData[i];
                if (data < MyVoxelConstants.VOXEL_ISO_LEVEL)
                {
                    ++belowCount;
                    if (data > bestBelow)
                    {
                        bestBelow = data;
                    }
                }
                else
                {
                    ++aboveCount;
                    if (data < bestAbove)
                    {
                        bestAbove = data;
                    }
                }
            }

            var res = (belowCount > aboveCount) ? bestBelow : bestAbove;

            float cornerSignedDistance = (res / (float)TLeafData.MaxValue) * 2f - 1f;

            if (cornerSignedDistance != 1f && cornerSignedDistance != -1f)
            {
                cornerSignedDistance *= 0.5f; // distance is halved in higher lod since sample size is doubled
            }
            cornerSignedDistance = cornerSignedDistance * 0.5f + 0.5f;
            return((TLeafData)(cornerSignedDistance * TLeafData.MaxValue));
        }
Exemple #9
0
        /// <summary>
        /// Treats value as normalized signed distance in given LOD. Since LOD size doubles, distance halves for all cases except max value.
        /// </summary>
        private static unsafe TLeafData SignedDistanceFilterInternal(TLeafData *pData, int lod)
        {
            if (lod > 2)
            {
                int totWeight = 0;
                for (int i = 0; i < 8; i++)
                {
                    totWeight += pData[i];
                }

                return((TLeafData)(totWeight >> 3));
            }

            float signedDist   = ToSignedDistance(pData[0]);
            var   average      = AverageValueFilterInternal(pData, lod);
            var   averageSDist = ToSignedDistance(average);

            if (averageSDist != signedDist || (signedDist != 1f && signedDist != -1f))
            {
                signedDist *= 0.5f; // distance is halved in higher lod since sample size is doubled
                // maybe the average could also be taken into account to get an idea on which side of surface this sample is ...
            }
            return(FromSignedDistance(signedDist));
        }