RavEngine
Loading...
Searching...
No Matches
BpBroadPhaseShared.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// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29#ifndef BP_BROADPHASE_SHARED_H
30#define BP_BROADPHASE_SHARED_H
31
32#include "BpBroadPhaseIntegerAABB.h"
33#include "foundation/PxUserAllocated.h"
34#include "foundation/PxHash.h"
35#include "foundation/PxVecMath.h"
36
37namespace physx
38{
39namespace Bp
40{
41 #define INVALID_ID 0xffffffff
42 #define INVALID_USER_ID 0xffffffff
43
45 {
46 PX_FORCE_INLINE PxU32 getId0() const { return id0_isNew & ~PX_SIGN_BITMASK; }
47 PX_FORCE_INLINE PxU32 getId1() const { return id1_isUpdated & ~PX_SIGN_BITMASK; }
48
49 PX_FORCE_INLINE PxU32 isNew() const { return id0_isNew & PX_SIGN_BITMASK; }
50 PX_FORCE_INLINE PxU32 isUpdated() const { return id1_isUpdated & PX_SIGN_BITMASK; }
51
52 PX_FORCE_INLINE void setNewPair(PxU32 id0, PxU32 id1)
53 {
54 PX_ASSERT(!(id0 & PX_SIGN_BITMASK));
55 PX_ASSERT(!(id1 & PX_SIGN_BITMASK));
56 id0_isNew = id0 | PX_SIGN_BITMASK;
57 id1_isUpdated = id1;
58 }
59
60 PX_FORCE_INLINE void setNewPair2(PxU32 id0, PxU32 id1)
61 {
62 PX_ASSERT(!(id0 & PX_SIGN_BITMASK));
63 PX_ASSERT(!(id1 & PX_SIGN_BITMASK));
64 id0_isNew = id0;
65 id1_isUpdated = id1;
66 }
67
68 PX_FORCE_INLINE void setUpdated() { id1_isUpdated |= PX_SIGN_BITMASK; }
69 PX_FORCE_INLINE void clearUpdated() { id1_isUpdated &= ~PX_SIGN_BITMASK; }
70 PX_FORCE_INLINE void clearNew() { id0_isNew &= ~PX_SIGN_BITMASK; }
71
72 protected:
73 PxU32 id0_isNew;
74 PxU32 id1_isUpdated;
75 };
76
77 PX_FORCE_INLINE bool differentPair(const InternalPair& p, PxU32 id0, PxU32 id1) { return (id0!=p.getId0()) || (id1!=p.getId1()); }
78 PX_FORCE_INLINE PxU32 hash(PxU32 id0, PxU32 id1) { return PxComputeHash( (id0&0xffff)|(id1<<16)); }
79 //PX_FORCE_INLINE PxU32 hash(PxU32 id0, PxU32 id1) { return PxComputeHash(PxU64(id0)|(PxU64(id1)<<32)) ; }
80 PX_FORCE_INLINE void sort(PxU32& id0, PxU32& id1) { if(id0>id1) PxSwap(id0, id1); }
81
83 {
84 public:
87
88 PX_FORCE_INLINE PxU32 getPairIndex(const InternalPair* pair) const
89 {
90 return (PxU32((size_t(pair) - size_t(mActivePairs)))/sizeof(InternalPair));
91 }
92
93 // Internal version saving hash computation
94 PX_FORCE_INLINE InternalPair* findPair(PxU32 id0, PxU32 id1, PxU32 hashValue) const
95 {
96 if(!mHashTable)
97 return NULL; // Nothing has been allocated yet
98
99 InternalPair* PX_RESTRICT activePairs = mActivePairs;
100 const PxU32* PX_RESTRICT next = mNext;
101
102 // Look for it in the table
103 PxU32 offset = mHashTable[hashValue];
104 while(offset!=INVALID_ID && differentPair(activePairs[offset], id0, id1))
105 {
106 PX_ASSERT(activePairs[offset].getId0()!=INVALID_USER_ID);
107 offset = next[offset]; // Better to have a separate array for this
108 }
109 if(offset==INVALID_ID)
110 return NULL;
111 PX_ASSERT(offset<mNbActivePairs);
112 // Match mActivePairs[offset] => the pair is persistent
113
114 return &activePairs[offset];
115 }
116
117 PX_FORCE_INLINE InternalPair* addPairInternal(PxU32 id0, PxU32 id1)
118 {
119 // Order the ids
120 sort(id0, id1);
121
122 const PxU32 fullHashValue = hash(id0, id1);
123 PxU32 hashValue = fullHashValue & mMask;
124
125 {
126 InternalPair* PX_RESTRICT p = findPair(id0, id1, hashValue);
127 if(p)
128 {
129 p->setUpdated();
130 return p; // Persistent pair
131 }
132 }
133
134 // This is a new pair
135 if(mNbActivePairs >= mHashSize)
136 hashValue = growPairs(fullHashValue);
137
138 const PxU32 pairIndex = mNbActivePairs++;
139
140 InternalPair* PX_RESTRICT p = &mActivePairs[pairIndex];
141 p->setNewPair(id0, id1);
142 mNext[pairIndex] = mHashTable[hashValue];
143 mHashTable[hashValue] = pairIndex;
144 return p;
145 }
146
147 PxU32 mHashSize;
148 PxU32 mMask;
149 PxU32 mNbActivePairs;
150 PxU32* mHashTable;
151 PxU32* mNext;
152 InternalPair* mActivePairs;
153 PxU32 mReservedMemory;
154
155 void purge();
156 void reallocPairs();
157 void shrinkMemory();
158 void reserveMemory(PxU32 memSize);
159 PX_NOINLINE PxU32 growPairs(PxU32 fullHashValue);
160 void removePair(PxU32 id0, PxU32 id1, PxU32 hashValue, PxU32 pairIndex);
161 };
162
163 struct AABB_Xi
164 {
167
168 PX_FORCE_INLINE void initFromFloats(const void* PX_RESTRICT minX, const void* PX_RESTRICT maxX)
169 {
170 mMinX = encodeFloat(*reinterpret_cast<const PxU32*>(minX));
171 mMaxX = encodeFloat(*reinterpret_cast<const PxU32*>(maxX));
172 }
173
174 PX_FORCE_INLINE void initFromPxVec4(const PxVec4& min, const PxVec4& max)
175 {
176 initFromFloats(&min.x, &max.x);
177 }
178
179 PX_FORCE_INLINE void operator = (const AABB_Xi& box)
180 {
181 mMinX = box.mMinX;
182 mMaxX = box.mMaxX;
183 }
184
185 PX_FORCE_INLINE void initSentinel()
186 {
187 mMinX = 0xffffffff;
188 }
189
190 PX_FORCE_INLINE bool isSentinel() const
191 {
192 return mMinX == 0xffffffff;
193 }
194
195 PxU32 mMinX;
196 PxU32 mMaxX;
197 };
198
199 struct AABB_YZn
200 {
203
204 PX_FORCE_INLINE void initFromPxVec4(const PxVec4& min, const PxVec4& max)
205 {
206 mMinY = -min.y;
207 mMinZ = -min.z;
208 mMaxY = max.y;
209 mMaxZ = max.z;
210 }
211
212 PX_FORCE_INLINE void operator = (const AABB_YZn& box)
213 {
214 using namespace physx::aos;
215 V4StoreA(V4LoadA(&box.mMinY), &mMinY);
216 }
217
218 float mMinY;
219 float mMinZ;
220 float mMaxY;
221 float mMaxZ;
222 };
223
224 struct AABB_YZr
225 {
228
229 PX_FORCE_INLINE void initFromPxVec4(const PxVec4& min, const PxVec4& max)
230 {
231 mMinY = min.y;
232 mMinZ = min.z;
233 mMaxY = max.y;
234 mMaxZ = max.z;
235 }
236
237 PX_FORCE_INLINE void operator = (const AABB_YZr& box)
238 {
239 using namespace physx::aos;
240 V4StoreA(V4LoadA(&box.mMinY), &mMinY);
241 }
242
243 float mMinY;
244 float mMinZ;
245 float mMaxY;
246 float mMaxZ;
247 };
248
249} //namespace Bp
250} //namespace physx
251
252#endif // BP_BROADPHASE_SHARED_H
Definition BpBroadPhaseShared.h:83
Definition PxUserAllocated.h:43
Definition PxVec4.h:50
#define PX_RESTRICT
Definition PxPreprocessor.h:355
#define PX_NOINLINE
Definition PxPreprocessor.h:346
#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
Definition BpBroadPhaseShared.h:164
Definition BpBroadPhaseShared.h:200
Definition BpBroadPhaseShared.h:225
Definition BpBroadPhaseShared.h:45