示例#1
0
        // Retrieve all coincident entries by their position, also searches in neighbor cells so the results are exhaustive
        // NOTE: Neighbor cells are consulted only if within _epsilon threshold
        public void                     FindAllIncludeNeighborCells(ref float3 _position, List <keyValue_t> _result, float _epsilon)
        {
            int    minCellX, minCellY, minCellZ;
            float3 posMin = _position - _epsilon * float3.One;

            GetCellIndices(ref posMin, out minCellX, out minCellY, out minCellZ);

            int    maxCellX, maxCellY, maxCellZ;
            float3 posMax = _position + _epsilon * float3.One;

            GetCellIndices(ref posMax, out maxCellX, out maxCellY, out maxCellZ);

            for (int Z = minCellZ; Z <= maxCellZ; Z++)
            {
                for (int Y = minCellY; Y <= maxCellY; Y++)
                {
                    for (int X = minCellX; X <= maxCellX; X++)
                    {
                        uint       hash    = ComputeHash(X, Y, Z);
                        keyValue_t current = m_table[hash];
                        while (current != null)
                        {
                            if (Compare(ref current.position, ref _position, _epsilon))
                            {
                                _result.Add(current);                                   // Another match!
                            }
                            current = current.next;
                        }
                    }
                }
            }
        }
示例#2
0
 // Clears the entire table
 public void                     Clear()
 {
     Array.Clear(m_table, 0, m_table.Length);
     if (m_maxEntries > 0)
     {
         for (int nodeIndex = 0; nodeIndex < m_maxEntries - 1; nodeIndex++)
         {
             m_nodesPool[nodeIndex].next = m_nodesPool[nodeIndex + 1];
             m_nodesPool[nodeIndex].hash = ~0U;
         }
         m_nodesPool[m_maxEntries - 1].next = null;
     }
     m_freeNode     = m_nodesPool[0];            // All free!
     m_entriesCount = 0;
 }
示例#3
0
        // Retrieve all coincident entries by their position
        public void                     FindAll(ref float3 _position, List <keyValue_t> _result, float _epsilon)
        {
            uint hash = ComputeHash(ref _position);

            keyValue_t current = m_table[hash];

            while (current != null)
            {
                if (Compare(ref current.position, ref _position, _epsilon))
                {
                    _result.Add(current);                       // Another match!
                }
                current = current.next;
            }
        }
示例#4
0
        // Update the entry's position
        public bool                     Update(keyValue_t _entry, float3 _newPosition)
        {
            _entry.position = _newPosition;
            uint newHash = ComputeHash(ref _newPosition);

            if (newHash == _entry.hash)
            {
                return(true);                   // No change in hash...
            }

            // We must first retrieve the existing entry in the linked list of entries sharing that hash
            keyValue_t previous = null;
            keyValue_t current  = m_table[_entry.hash];

            while (current != null)
            {
                if (current != _entry)
                {
                    previous = current;
                    current  = current.next;
                    continue;
                }

                // Found it!

                // Link over that node to remove it from this hash's list of entries
                if (previous != null)
                {
                    previous.next = current.next;
                }
                else
                {
                    m_table[_entry.hash] = current.next;
                }

                // Update its hash
                _entry.hash = newHash;

                // Re-link it to its new position in the table
                _entry.next      = m_table[newHash];
                m_table[newHash] = _entry;

                return(true);
            }

            return(false);              // Not found...
        }
示例#5
0
        keyValue_t              Alloc()
        {
            if (m_freeNode == null)
            {
                throw new Exception("Table is full! Consider increasing _maxEntries!");
            }

            keyValue_t node = m_freeNode;

            m_freeNode = node.next;
            node.next  = null;
            node.hash  = ~0U;

            m_entriesCount++;

            return(node);
        }
示例#6
0
        void                    FindAllValuePointersInCell(int _cellX, int _cellY, int _cellZ, List <keyValue_t> _values)
        {
            uint hash = ComputeHash(_cellX, _cellY, _cellZ);

            keyValue_t current = m_table[hash];

            while (current != null)
            {
                int entryCellX, entryCellY, entryCellZ;
                GetCellIndices(ref current.position, out entryCellX, out entryCellY, out entryCellZ);
                if (entryCellX == _cellX && entryCellY == _cellY && entryCellZ == _cellZ)
                {
                    _values.Add(current);
                }
                current = current.next;
            }
        }
示例#7
0
        // Fills a list with all the values stored in a given cell
        public keyValue_t       FindFirstValueInCell(int _cellX, int _cellY, int _cellZ)
        {
            uint       hash    = ComputeHash(_cellX, _cellY, _cellZ);
            keyValue_t current = m_table[hash];

            while (current != null)
            {
                int entryCellX, entryCellY, entryCellZ;
                GetCellIndices(ref current.position, out entryCellX, out entryCellY, out entryCellZ);
                if (entryCellX == _cellX && entryCellY == _cellY && entryCellZ == _cellZ)
                {
                    return(current);
                }
                current = current.next;
            }
            return(null);
        }
示例#8
0
        // Retrieve the first entry by its position
        public keyValue_t       Find(ref float3 _position, float _epsilon)
        {
            uint hash = ComputeHash(ref _position);

            keyValue_t current = m_table[hash];

            while (current != null)
            {
                if (Compare(ref current.position, ref _position, _epsilon))
                {
                    return(current);                    // Found it!
                }
                current = current.next;
            }

            return(null);               // Not found...
        }
示例#9
0
        // Adds a new entry to the table
        // Returns the handle to the added entry
        public keyValue_t       Add(float3 _position, T _value)
        {
            uint hash = ComputeHash(ref _position);

            keyValue_t firstEntry = m_table[hash];

            keyValue_t newEntry = Alloc();

            if (newEntry != null)
            {
                newEntry.next     = firstEntry;
                newEntry.hash     = hash;
                newEntry.position = _position;
                newEntry.value    = _value;

                m_table[hash] = newEntry;                       // We're the new first entry
            }

            return(newEntry);
        }
示例#10
0
        // Removes an entry from the table
        public bool                     Remove(keyValue_t _entry)
        {
            keyValue_t previous = null;
            keyValue_t current  = m_table[_entry.hash];

            while (current != null)
            {
                if (current != _entry)
                {
                    previous = current;
                    current  = current.next;
                    continue;
                }

                // Found it!

                // Link over that node
                if (previous != null)
                {
                    previous.next = current.next;
                }
                else
                {
                    m_table[_entry.hash] = current.next;
                }

                // Add the node back to the free list
                current.next = m_freeNode;
                m_freeNode   = current;

                m_entriesCount--;

                return(true);
            }

            return(false);              // Not found...
        }