/// <summary> /// Callback when a slot is added to the cluster. /// </summary> /// <param name="slot"></param> protected override void OnSlotAdded(T_SLOT slot) { ByteTrio coord = slot.m_coordinates; m_slots[coord] = slot; base.OnSlotAdded(slot); }
protected virtual int3 OnSizeChanged(ByteTrio oldSize) { return(int3( m_size.x - oldSize.x, m_size.y - oldSize.y, m_size.z - oldSize.z)); }
/// <summary> /// Fills all empty slots in this cluster with. /// </summary> public override void Fill() { //TODO : Implement fill methods accounting for planeOrder. int sizeX = m_size.x, sizeY = m_size.y, sizeZ = m_size.z; ByteTrio coords; float3 o = pos, origin = pos, slotSize = m_slotModel.size; int index; T_SLOT slot; for (int z = 0; z < sizeZ; z++) // volume { for (int y = 0; y < sizeY; y++) // plane { for (int x = 0; x < sizeX; x++) // line { coords = new ByteTrio(x, y, z); index = x + m_lineLength * y + m_planeLength * z; slot = m_slotList[index]; if (slot == null) { Add(coords); } } } } }
/// <summary> /// Fills all empty slots in this cluster with. /// </summary> public override void Fill() { #if UNITY_EDITOR UnityEngine.Debug.LogWarning("If you need to use Fill() on a SlotClusterFlex<V>, " + "using a SlotClusterFixed<V> instead will yield better performance & reduce memory fragmentation."); #endif int sizeX = m_size.x, sizeY = m_size.y, sizeZ = m_size.z; ByteTrio coords; float3 o = pos, origin = pos, slotSize = m_slotModel.size; m_slotList.Capacity = m_size.Volume(); for (int z = 0; z < sizeZ; z++) // volume { for (int y = 0; y < sizeY; y++) // plane { for (int x = 0; x < sizeX; x++) // line { coords = new ByteTrio(x, y, z); if (!TryGet(coords, out ISlot slot)) { Add(coords); } } } } }
public virtual void Init( SlotModel clusterSlotModel, ByteTrio clusterSize, WrapMode wrapX, WrapMode wrapY, WrapMode wrapZ, bool fillCluster) { Clear(true); m_slotModel = clusterSlotModel; B b = default; b.wrapX = wrapX; b.wrapY = wrapY; b.wrapZ = wrapZ; b.clusterSize = clusterSize; SetBrain(m_brain); if (fillCluster) { Fill(); } }
public bool TryGetCoordOf(float3 location, out ByteTrio coord) { coord = ByteTrio.zero; if (!bounds.Contains(location)) { return(false); } float3 loc = location - pos; float lx = location.x - pos.x, ly = location.y - pos.y, lz = location.z - pos.z, ssx = m_slotSize.x, ssy = m_slotSize.y, ssz = m_slotSize.z; coord = Clamp( (int)((lx - (lx % ssx)) / ssx), (int)((ly - (ly % ssy)) / ssy), (int)((lz - (lz % ssz)) / ssz)); return(true); }
public override void Init( SlotModel clusterSlotModel, ByteTrio clusterSize, bool fillCluster) { Init(clusterSlotModel, clusterSize, fillCluster, AxisOrder.XYZ); }
public virtual void Init( SlotModel clusterSlotModel, ByteTrio clusterSize, bool fillCluster, AxisOrder clusterPlaneOrder) { planeOrder = clusterPlaneOrder; base.Init(clusterSlotModel, clusterSize, fillCluster); }
/// <summary> /// Return the slot index of the given coordinates /// </summary> /// <param name="coord"></param> /// <returns></returns> public override int IndexOf(ByteTrio coord) { if (m_slots.TryGetValue(m_brain.Clamp(coord), out ISlot slot)) { return(m_slotList.IndexOf(slot as T_SLOT)); } return(-1); }
public float3 ComputePosition(ref ByteTrio coords) { float y = coords.y * m_slotSize.y + m_slotOffset.y; return(m_pos + Maths.RotateAroundPivot( float3(0f, y, (m_slotSize.x * m_clusterSize.x) / Maths.TAU + m_slotSize.z * coords.z), float3(0f, y, 0f), float3(0f, (Maths.TAU / m_clusterSize.x) * coords.x, 0f)));; }
public override void Init( SlotModel clusterSlotModel, ByteTrio clusterSize, WrapMode wrapX, WrapMode wrapY, WrapMode wrapZ, bool fillCluster) { Init(clusterSlotModel, clusterSize, wrapX, wrapY, wrapZ, fillCluster, AxisOrder.XYZ); }
/// <summary> /// Set the slot occupation at a given coordinate. /// </summary> /// <param name="coord"></param> /// <param name="slot"></param> /// <param name="releaseExisting"></param> /// <returns></returns> public override T_SLOT Set(ByteTrio coord, ISlot slot, bool releaseExisting = false) { int index = IndexOf(coord); if (index == -1) { return(null); } T_SLOT vSlot = slot as T_SLOT; #if UNITY_EDITOR if (vSlot == null) { throw new System.ArgumentException("slot cannot be null."); } #endif if (vSlot.cluster == this) { if (vSlot.m_coordinates == coord) { return(vSlot); } else { Remove(vSlot.m_coordinates); //a slot can only exists at a single coordinate } } T_SLOT existingSlot = m_slotList[index]; if (existingSlot != null) { if (existingSlot == vSlot) { return(vSlot); } m_slotList[index] = null; OnSlotRemoved(existingSlot); if (releaseExisting) { existingSlot.Release(); } } vSlot.m_coordinates = coord; m_slotList[index] = vSlot; OnSlotAdded(vSlot); return(vSlot); }
public override int IndexOf(ByteTrio coord) { //Compute index based on X Y Z values, according to current plane order. m_brain.Clamp(ref coord); if (!m_brain.Contains(ref coord)) { return(-1); } return(coord.x + m_lineLength * coord.y + m_planeLength * coord.z); }
/// <summary> /// Gets the slot associated with the specified coordinates. /// </summary> /// <param name="coord"></param> /// <param name="slot"></param> /// <returns></returns> /// <remarks>Input coordinates are wrapped per-axis using each of the cluster's individual wrap mode.</remarks> public override bool TryGet(ByteTrio coord, out ISlot slot) { int index = IndexOf(coord); if (index == -1 || index >= m_slotList.Length) { slot = null; return(false); } slot = m_slotList[index]; return(slot == null ? false : true); }
/// <summary> /// /// </summary> /// <param name="coord"></param> /// <param name="contents"></param> /// <param name="candidates"></param> /// <returns></returns> public bool TryGetCandidates( ByteTrio coord, ref NativeList <Neighbor> contents, ref NativeList <int> candidates, ref NativeList <float> weights, out int length) { if (!TryGetSlotNeighbors(coord, ref contents, out length)) { return(false); } return(TryGetCandidates(ref contents, ref candidates, ref weights, out length)); }
/// <summary> /// Remove the slot at the given coordinates and returns it. /// </summary> /// <param name="coord"></param> /// <returns></returns> public override T_SLOT Remove(ByteTrio coord) { int index = IndexOf(coord); if (index == -1) { return(null); } T_SLOT slot = m_slotList[index]; m_slotList[index] = null; return(slot); }
/// <summary> /// Remove the slot at the given coordinates and returns it. /// </summary> /// <param name="coord"></param> /// <returns></returns> public override T_SLOT Remove(ByteTrio coord) { T_SLOT vSlot; if (m_slots.TryGetValue(coord, out ISlot slot)) { vSlot = slot as T_SLOT; m_slotList.Remove(vSlot); m_slots.Remove(coord); return(vSlot); } return(null); }
public float3 ComputePosition(ref ByteTrio coords) { float r = (m_slotSize.x * m_clusterSize.x) / Maths.TAU, a = (Maths.TAU / m_clusterSize.x) * coords.x; float3 p = coords * m_slotSize + m_slotOffset, pt = float3(0f, p.y, r + m_slotSize.z * coords.z); pt = Maths.RotateAroundPivot(pt, float3(0f, p.y, 0f), float3(0f, a, 0f)); return(m_pos + pt); }
/// <summary> /// Set the slot occupation at a given coordinate. /// </summary> /// <param name="coord"></param> /// <param name="slot"></param> /// <param name="releaseExisting"></param> /// <returns></returns> public override T_SLOT Set(ByteTrio coord, ISlot slot, bool releaseExisting = false) { T_SLOT vSlot = slot as T_SLOT; #if UNITY_EDITOR if (vSlot == null) { throw new System.ArgumentException("slot cannot be null."); } #endif if (vSlot.cluster == this) { if (vSlot.m_coordinates == coord) { return(vSlot); } else { m_slots.Remove(vSlot.m_coordinates); //a slot can only exists at a single coordinate } } else { m_slotList.Add(vSlot); } if (m_slots.TryGetValue(coord, out ISlot existingSlot)) { if (existingSlot == vSlot) { return(vSlot); } T_SLOT vExistingSlot = existingSlot as T_SLOT; m_slotList.Remove(vExistingSlot); OnSlotRemoved(vExistingSlot); if (releaseExisting) { existingSlot.Release(); } } vSlot.m_coordinates = coord; OnSlotAdded(vSlot); return(vSlot); }
/// <summary> /// Create a slot at the given coordinates and return it. /// If a slot already exists at the given location, that slot is returned instead. /// </summary> /// <param name="coord"></param> /// <returns></returns> public override T_SLOT Add(ByteTrio coord) { if (m_slots.TryGetValue(coord, out ISlot dslot)) { return(dslot as T_SLOT); } T_SLOT slot = Pool.Rent <T_SLOT>(); slot.m_coordinates = coord; m_slotList.Add(slot); OnSlotAdded(slot); return(slot); }
public bool TryGetCoordOf(float3 location, out ByteTrio coord) { coord = ByteTrio.zero; if (!m_bounds.Contains(location)) { return(false); } float lx = location.x - pos.x, ly = location.y - pos.y, lz = location.z - pos.z, ssx = m_slotSize.x, ssy = m_slotSize.y, ssz = m_slotSize.z; if (m_cylinderActive) { float csx = m_clusterSize.x, dist = length(float2(lx, lz)), rMin = (ssx * csx) / Maths.TAU; if (dist < rMin || dist > (rMin + ssz * m_clusterSize.z)) { return(false); } float a = atan2(lx, lz); if (a < 0f) { a += Maths.TAU; } lx = (ssx * csx) * (a / Maths.TAU); lz = dist - rMin; } coord = Clamp( (int)((lx - (lx % ssx)) / ssx), (int)((ly - (ly % ssy)) / ssy), (int)((lz - (lz % ssz)) / ssz)); return(true); }
public bool Contains(ref ByteTrio coord) { if (m_wrapX == WrapMode.NONE && (coord.x < 0 || coord.x >= m_clusterSize.x)) { return(false); } else if (m_wrapY == WrapMode.NONE && (coord.y < 0 || coord.y >= m_clusterSize.y)) { return(false); } else if (m_wrapZ == WrapMode.NONE && (coord.z < 0 || coord.z >= m_clusterSize.z)) { return(false); } return(true); }
public virtual void Init( SlotModel clusterSlotModel, ByteTrio clusterSize, bool fillCluster) { Clear(true); m_slotModel = clusterSlotModel; m_brain.clusterSize = clusterSize; SetBrain(m_brain); if (fillCluster) { Fill(); } }
/// <summary> /// Checks if a given coordinate satisfies a given header. /// </summary> /// <param name="coord"></param> /// <param name="moduleIndex"></param> /// <returns></returns> public bool ModuleMatches( ref ByteTrio coord, ref int moduleIndex) { Neighbor content = default; int3 center = coord, socket; for (int s = 0; s < m_socketCount; s++) { content.socket = s; socket = center + m_socketOffsets[s]; m_brain.Clamp(ref socket); if (m_inputSlotCoordinateMap.TryGetValue(socket, out int _s)) { content.value = m_results[_s]; if (content.IsUndefined) { if (RequiresNull(ref moduleIndex, ref content.socket)) { return(false); } else { continue; } } } else { content.value = SlotContent.NULL; } if (!SocketContains(ref moduleIndex, ref content)) { return(false); } } return(true); }
protected override int3 OnSizeChanged(ByteTrio oldSize) { int3 diff = base.OnSizeChanged(oldSize); if (m_slotList.Count == 0 || (diff.x >= 0 && diff.y >= 0 && diff.z >= 0)) { return(diff); } //TOOD : Find a more elegant and efficient way to resize. List <SlotIndex> outgoing = new List <SlotIndex>(); T_SLOT slot; ByteTrio coord; SlotIndex s; int sizeX = oldSize.x, sizeY = oldSize.y, sizeZ = oldSize.z; for (int i = 0, count = m_slotList.Count; i < count; i++) { slot = m_slotList[i]; coord = slot.m_coordinates; if (coord.x >= sizeX || coord.y >= sizeY || coord.z >= sizeZ) { outgoing.Add(new SlotIndex(i, slot)); } } for (int i = 0, count = outgoing.Count; i < count; i++) { s = outgoing[i]; m_slotList.RemoveAt(s.index); OnSlotRemoved(s.slot); s.slot.Release(); } outgoing.Clear(); return(diff); }
public bool TryGetCoordOf(float3 location, out ByteTrio coord) { coord = ByteTrio.zero; if (!m_bounds.Contains(location)) { coord = ByteTrio.zero; return(false); } float3 loc = location - pos; float dist = length(float2(loc.x, loc.z)), r = (m_slotSize.x * m_clusterSize.x) / Maths.TAU, rMax = r + m_slotSize.z * m_clusterSize.z; if (dist < r || dist > rMax) { coord = ByteTrio.zero; return(false); } float a = atan2(loc.x, loc.z); a = a < 0f ? a + Maths.TAU : a; loc.x = (m_slotSize.x * m_clusterSize.x) * (a / Maths.TAU); loc.z = dist - r; float modX = loc.x % m_slotSize.x, modY = loc.y % m_slotSize.y, modZ = loc.z % m_slotSize.z; int posX = (int)((loc.x - modX) / m_slotSize.x), posY = (int)((loc.y - modY) / m_slotSize.y), posZ = (int)((loc.z - modZ) / m_slotSize.z); coord = Clamp(posX, posY, posZ); return(true); }
/// <summary> /// Find the current neighbors for a given slot coordinate. /// </summary> /// <param name="coord"></param> /// <param name="contents"></param> /// <param name="length"></param> /// <returns></returns> public bool TryGetSlotNeighbors( ByteTrio coord, ref NativeList <Neighbor> contents, out int length) { contents.Clear(); m_brain.Clamp(ref coord); int3 center = coord, ccoord; int _s; if (!m_inputSlotCoordinateMap.TryGetValue(coord, out _s)) { length = 0; return(false); } // Identify the content of each neighboring socket, if any for (int s = 0; s < m_socketCount; s++) { ccoord = center + m_socketOffsets[s]; m_brain.Clamp(ref ccoord); if (m_inputSlotCoordinateMap.TryGetValue(ccoord, out _s)) { _s = m_results[_s]; } else { _s = SlotContent.NULL; } contents.Add(new Neighbor() { socket = s, value = _s }); } length = contents.Length; return(length > 0); }
public ByteTrio Clamp(ByteTrio coord) { if (m_wrapX != WrapMode.NONE) { if (coord.x < 0) { coord.x = (byte)(m_wrapX == WrapMode.LOOP ? m_clusterSize.x + (coord.x % m_clusterSize.x) : 0); } else if (coord.x >= m_clusterSize.x) { coord.x = (byte)(m_wrapX == WrapMode.LOOP ? coord.x % m_clusterSize.x : m_clusterSize.x - 1); } } if (m_wrapY != WrapMode.NONE) { if (coord.y < 0) { coord.y = (byte)(m_wrapY == WrapMode.LOOP ? m_clusterSize.y + (coord.y % m_clusterSize.y) : 0); } else if (coord.y >= m_clusterSize.y) { coord.y = (byte)(m_wrapY == WrapMode.LOOP ? coord.y % m_clusterSize.y : m_clusterSize.y - 1); } } if (m_wrapZ != WrapMode.NONE) { if (coord.z < 0) { coord.z = (byte)(m_wrapZ == WrapMode.LOOP ? m_clusterSize.z + (coord.z % m_clusterSize.z) : 0); } else if (coord.z >= m_clusterSize.y) { coord.z = (byte)(m_wrapZ == WrapMode.LOOP ? coord.z % m_clusterSize.z : m_clusterSize.z - 1); } } return(coord); }
/// <summary> /// Create a slot at the given coordinates and return it. /// If a slot already exists at the given location, that slot is returned instead. /// </summary> /// <param name="coord"></param> /// <returns></returns> public override T_SLOT Add(ByteTrio coord) { int index = IndexOf(coord); if (index == -1) { return(null); } T_SLOT slot = m_slotList[index]; if (slot != null) { return(slot); } slot = Pool.Rent <T_SLOT>(); slot.m_coordinates = coord; m_slotList[index] = slot; OnSlotAdded(slot); return(slot); }
/// /// Base logic /// /// <summary> /// Retrieve the coordinates that contain the given location, /// based on cluster location & slot's size /// </summary> /// <param name="location"></param> /// <returns></returns> public bool TryGetCoordOf(float3 location, out ByteTrio coord) { if (!bounds.Contains(location)) { coord = ByteTrio.zero; return(false); } float3 loc = location - pos; float modX = loc.x % m_slotSize.x, modY = loc.y % m_slotSize.y, modZ = loc.z % m_slotSize.z; int posX = (int)((loc.x - modX) / m_slotSize.x), posY = (int)((loc.y - modY) / m_slotSize.y), posZ = (int)((loc.z - modZ) / m_slotSize.z); coord = Clamp(posX, posY, posZ); return(true); }