RavEngine
Loading...
Searching...
No Matches
ExtRandomAccessHeap.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26
27#ifndef EXT_RANDOM_ACCESS_HEAP_H
28#define EXT_RANDOM_ACCESS_HEAP_H
29
30#include "foundation/PxArray.h"
31
32// MM: heap which allows the modification of the priorities of entries stored anywhere in the tree
33// for this, every entry gets an id via which it can be accessed
34
35// used in ExtMeshSimplificator to sort edges w.r.t. their error metric
36
37// ------------------------------------------------------------------------------
38
39namespace physx
40{
41 namespace Ext
42 {
43
44 template <class T> class RandomAccessHeap
45 {
46 public:
48 heap.resize(1); // dummy such that root is at 1 for faster parent child computation
49 ids.resize(1);
50 nextId = 0;
51 }
52
53 void resizeFast(PxArray<PxI32>& arr, PxU32 newSize, PxI32 value = 0)
54 {
55 if (newSize < arr.size())
56 arr.removeRange(newSize, arr.size() - newSize);
57 else
58 {
59 while (arr.size() < newSize)
60 arr.pushBack(value);
61 }
62 }
63
64 PxI32 insert(T elem, PxI32 id = -1) // id for ability to alter the entry later or to identify duplicates
65 {
66 if (id < 0) {
67 id = nextId;
68 nextId++;
69 }
70 else if (id >= nextId)
71 nextId = id + 1;
72
73 if (id >= 0 && id < PxI32(posOfId.size()) && posOfId[id] >= 0)
74 return id; // already in heap
75
76 heap.pushBack(elem);
77 ids.pushBack(id);
78
79 if (id >= PxI32(posOfId.size()))
80 resizeFast(posOfId, id + 1, -1);
81
82 posOfId[id] = heap.size() - 1;
83
84 percolate(PxI32(heap.size()) - 1);
85
86 return id;
87 }
88
89 bool remove(PxI32 id)
90 {
91 PxI32 i = posOfId[id];
92 if (i < 0)
93 return false;
94
95 posOfId[id] = -1;
96 T prev = heap[i];
97
98 heap[i] = heap.back();
99 heap.popBack();
100 ids[i] = ids.back();
101 ids.popBack();
102
103 if (i < PxI32(heap.size()))
104 {
105 posOfId[ids[i]] = i;
106
107 if (heap.size() > 1)
108 {
109 if (heap[i] < prev)
110 percolate(i);
111 else
112 siftDown(i);
113 }
114 }
115
116 return true;
117 }
118
119 T deleteMin()
120 {
121 T min(-1, -1, 0.0f);
122
123 if (heap.size() > 1)
124 {
125 min = heap[1];
126 posOfId[ids[1]] = -1;
127
128 heap[1] = heap.back();
129 heap.popBack();
130 ids[1] = ids.back();
131 ids.popBack();
132 posOfId[ids[1]] = 1;
133
134 siftDown(1);
135 }
136
137 return min;
138 }
139
140 void makeHeap(const PxArray<T> &elems) // O(n) instead of inserting one after the other O(n log n)
141 {
142 heap.resize(elems.size() + 1);
143 ids.resize(elems.size() + 1);
144 posOfId.resize(elems.size());
145
146 for (PxU32 i = 0; i < elems.size(); i++)
147 {
148 heap[i + 1] = elems[i];
149 ids[i + 1] = i;
150 posOfId[ids[i + 1]] = i + 1;
151 }
152
153 PxI32 n = (heap.size() - 1) >> 1;
154 for (PxI32 i = n; i >= 1; i--)
155 siftDown(i);
156 }
157
158 void clear()
159 {
160 heap.capacity() == 0 ? heap.resize(1) : heap.forceSize_Unsafe(1);
161 ids.capacity() == 0 ? ids.resize(1) : ids.forceSize_Unsafe(1);
162 posOfId.forceSize_Unsafe(0);
163 nextId = 0;
164 }
165 PX_FORCE_INLINE PxI32 size() { return heap.size() - 1; }
166 PX_FORCE_INLINE bool empty() { return heap.size() <= 1; }
167
168 private:
169 void siftDown(PxI32 i)
170 {
171 PxI32 n = PxI32(heap.size()) - 1;
172 PxI32 k = i;
173 PxI32 j;
174 do
175 {
176 j = k;
177 if (2 * j < n && heap[2 * j] < heap[k])
178 k = 2 * j;
179 if (2 * j < n && heap[2 * j + 1] < heap[k])
180 k = 2 * j + 1;
181 T temp = heap[j]; heap[j] = heap[k]; heap[k] = temp;
182 PxI32 id = ids[j]; ids[j] = ids[k]; ids[k] = id;
183
184 posOfId[ids[j]] = j;
185 posOfId[ids[k]] = k;
186
187 }
188 while (j != k);
189 }
190
191 void percolate(PxI32 i)
192 {
193 PxI32 k = i;
194 PxI32 j;
195 do
196 {
197 j = k;
198 if (j > 1 && !(heap[j >> 1] < heap[k]))
199 k = j >> 1;
200 T temp = heap[j]; heap[j] = heap[k]; heap[k] = temp;
201 PxI32 id = ids[j]; ids[j] = ids[k]; ids[k] = id;
202
203 posOfId[ids[j]] = j;
204 posOfId[ids[k]] = k;
205 }
206 while (j != k);
207 }
208
209 PxArray<T> heap;
210
211 PxArray<PxI32> ids;
212 PxArray<PxI32> posOfId;
213 PxI32 nextId;
214 };
215 }
216}
217
218#endif
Definition ExtRandomAccessHeap.h:45
Definition PxArray.h:53
PX_NOINLINE void resize(const uint32_t size, const T &a=T())
Definition PxArray.h:637
PX_FORCE_INLINE uint32_t size() const
Definition PxArray.h:242
PX_FORCE_INLINE void forceSize_Unsafe(uint32_t size)
Definition PxArray.h:507
PX_INLINE void removeRange(uint32_t begin, uint32_t count)
Definition PxArray.h:413
PX_FORCE_INLINE uint32_t capacity() const
Definition PxArray.h:497
PX_FORCE_INLINE T & pushBack(const T &a)
Definition PxArray.h:296
PX_INLINE T popBack()
Definition PxArray.h:311
PX_FORCE_INLINE const T & back() const
Definition PxArray.h:224
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39