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