/// <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)); }
/// <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)); }
/// <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)); }