NumberStyles.HexNumber); // max value for a single coordinate

        #region converting IDs and back again
        #region Flags

        /****** Flags ******
         * within the last 5 (LSB) bits of the long, the flags are encoded.
         * these result in a boolean, a VoxelRoleType and a int(byte):
         * bool btmIsInside: which is true if the bottom coordinate is inside the solid
         * VoxelRoleType: Empty, Partial, Full
         * these are not independent as Empty is always false for btmIsInside, and
         * Full is always true for btmIsInside
         * As a result, the first 2 bits correspond to:
         * 00: Empty (btmIsInside = false)
         * 01: Full (btmIsInside = true)
         * 10: Partial (btmIsInside = false)
         * 11: Partial (btmIsInside = true)
         *
         * Then bits 3, 4, & 5 encode the level. One big issue! Bit 5 is also
         * potentially used as the most detailed bit of the xCoord. It would only
         * be used at the highest level.
         * Level-0: 000xx
         * Level-1: 001xx
         * Level-2: 010xx
         * Level-3: 100xx
         * Level-4: 101xx
         * Level-5: 110xx
         * Level-6: ?11xx
         * This only allows us to encode up to 7 levels. Why not 8? Well, 011 and 111
         * both correspond to level 6. As in level-6, that fifth bit is used as part
         * of the x coordinate.          */
        /// <summary>
        /// Gets the role flags.
        /// </summary>
        /// <param name="ID">The identifier.</param>
        /// <param name="level">The level.</param>
        /// <param name="role">The role.</param>
        /// <param name="btmIsInside">if set to <c>true</c> [BTM is inside].</param>
        internal static void GetAllFlags(long ID, out byte level, out VoxelRoleTypes role, out bool btmIsInside)
        {
            level = (byte)((ID & 12) >> 2); //12 is (1100)
            if (level == 3)
            {
                level = 6;             //level 3 (11) is actually 6 (See comment above)
            }
            else if ((ID & 16) != 0)
            {
                level += 3;
            }

            if ((ID & 2) == 0) // 0_
            {
                if ((ID & 1) == 0)
                {
                    //00
                    btmIsInside = false;
                    role        = VoxelRoleTypes.Empty;
                }
                else
                {
                    //01
                    btmIsInside = true;
                    role        = VoxelRoleTypes.Full;
                }
            }
            else // 1_
            {
                role        = VoxelRoleTypes.Partial;
                btmIsInside = (ID & 1) == 1; // 11
            }
        }
 internal static long SetRole(long id, VoxelRoleTypes value)
 {
     if ((id & 2) != 0) //then partial
     {
         id -= 2;
     }
     else if ((id & 1) != 0) // then full
     {
         if (value == VoxelRoleTypes.Partial)
         {
             id += 2;
         }
         else if (value == VoxelRoleTypes.Empty)
         {
             id -= 1;
         }
     }
     else //then must be empty
     {
         if (value == VoxelRoleTypes.Partial)
         {
             id += 2;
         }
         else if (value == VoxelRoleTypes.Full)
         {
             id += 1;
         }
     }
     return(id);
 }
Beispiel #3
0
        internal int CountDescendants(long ancestor, int ancestorLevel, VoxelRoleTypes role)
        {
            ancestor = comparer.ParentMask(ancestor, ancestorLevel);
            int count = 0;

            for (int i = 0; i < lastIndex; i++)
            {
                if (slots[i].hashCode >= 0)
                {
                    if (comparer.IsDescendantOf(slots[i].value, ancestor, ancestorLevel) && Constants.GetRole(slots[i].value) == role)
                    {
                        count++;
                    }
                }
            }
            return(count);
        }
Beispiel #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VoxelBinClass"/> class.
 /// </summary>
 /// <param name="ID">The identifier.</param>
 /// <param name="voxelRole">The voxel role.</param>
 /// <param name="solid">The solid.</param>
 public VoxelBinClass(long ID, VoxelRoleTypes voxelRole, VoxelizedSolid solid,
                      bool btmCoordIsInside = false)
 {
     InnerVoxels = new VoxelHashSet[solid.lastLevel];
     for (int i = 1; i < solid.numberOfLevels; i++)
     {
         InnerVoxels[i - 1] = new VoxelHashSet(i, solid.bitLevelDistribution);
     }
     Role    = voxelRole;
     this.ID = Constants.ClearFlagsFromID(ID) +
               Constants.MakeFlags(Level, Role, Role == VoxelRoleTypes.Full || btmCoordIsInside);
     BtmCoordIsInside  = btmCoordIsInside;
     SideLength        = solid.VoxelSideLengths[Level];
     CoordinateIndices = Constants.GetCoordinateIndices(ID, solid.singleCoordinateShifts[0]);
     BottomCoordinate  =
         solid.GetRealCoordinates(Level, CoordinateIndices[0], CoordinateIndices[1], CoordinateIndices[2]);
 }
        /// <summary>
        /// Sets the role flags.
        /// </summary>
        /// <param name="level">The level.</param>
        /// <param name="role">The role.</param>
        /// <param name="btmIsInside">if set to <c>true</c> [BTM is inside].</param>
        /// <returns>System.Int64.</returns>
        internal static long MakeFlags(int level, VoxelRoleTypes role, bool btmIsInside = false)
        {
            var result = (btmIsInside || role == VoxelRoleTypes.Full) ? 1L : 0L;

            if (role == VoxelRoleTypes.Partial)
            {
                result += 2;
            }
            if (level == 6)
            {
                return(result + 12);
            }
            result += (level % 3) << 2;
            if (level > 2)
            {
                result += 16;
            }
            return(result);
        }
 private long CountVoxels(VoxelBinClass voxel0, int level, VoxelRoleTypes role)
 {
     return(voxel0.InnerVoxels[level - 1].Count(v => Constants.GetRole(v) == role));
 }