Beispiel #1
0
        /// <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));
 }
Beispiel #3
0
        /// <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);
                        }
                    }
                }
            }
        }
Beispiel #4
0
        /// <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();
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
 public override void Init(
     SlotModel clusterSlotModel,
     ByteTrio clusterSize,
     bool fillCluster)
 {
     Init(clusterSlotModel, clusterSize, fillCluster, AxisOrder.XYZ);
 }
Beispiel #8
0
 public virtual void Init(
     SlotModel clusterSlotModel,
     ByteTrio clusterSize,
     bool fillCluster,
     AxisOrder clusterPlaneOrder)
 {
     planeOrder = clusterPlaneOrder;
     base.Init(clusterSlotModel, clusterSize, fillCluster);
 }
Beispiel #9
0
        /// <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)));;
        }
Beispiel #11
0
 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);
 }
Beispiel #12
0
        /// <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);
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        /// <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));
        }
Beispiel #16
0
        /// <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);
        }
Beispiel #17
0
        /// <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);
        }
Beispiel #18
0
        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);
        }
Beispiel #19
0
        /// <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);
        }
Beispiel #20
0
        /// <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);
        }
Beispiel #25
0
        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);
        }
Beispiel #26
0
        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);
        }
Beispiel #29
0
        /// <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);
        }