1 | // |
2 | // Redistribution and use in source and binary forms, with or without |
3 | // modification, are permitted provided that the following conditions |
4 | // are met: |
5 | // * Redistributions of source code must retain the above copyright |
6 | // notice, this list of conditions and the following disclaimer. |
7 | // * Redistributions in binary form must reproduce the above copyright |
8 | // notice, this list of conditions and the following disclaimer in the |
9 | // documentation and/or other materials provided with the distribution. |
10 | // * Neither the name of NVIDIA CORPORATION nor the names of its |
11 | // contributors may be used to endorse or promote products derived |
12 | // from this software without specific prior written permission. |
13 | // |
14 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY |
15 | // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
17 | // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
18 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
19 | // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
20 | // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
21 | // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
22 | // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
24 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | // |
26 | // Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved. |
27 | // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. |
28 | // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. |
29 | |
30 | |
31 | #ifndef PX_PHYSICS_SCENEQUERYMANAGER |
32 | #define PX_PHYSICS_SCENEQUERYMANAGER |
33 | /** \addtogroup physics |
34 | @{ */ |
35 | |
36 | #include "PxSceneDesc.h" |
37 | #include "CmBitMap.h" |
38 | #include "PsArray.h" |
39 | #include "SqPruner.h" |
40 | #include "PsMutex.h" |
41 | #include "PxActor.h" // needed for offset table |
42 | #include "ScScene.h" |
43 | // threading |
44 | #include "PsSync.h" |
45 | |
46 | namespace physx |
47 | { |
48 | namespace Scb |
49 | { |
50 | class Scene; |
51 | class Shape; |
52 | class Actor; |
53 | } |
54 | |
55 | namespace Gu |
56 | { |
57 | class BVHStructure; |
58 | } |
59 | |
60 | namespace Sq |
61 | { |
62 | typedef size_t PrunerData; |
63 | #define SQ_INVALID_PRUNER_DATA 0xffffffff |
64 | |
65 | struct PrunerPayload; |
66 | class Pruner; |
67 | class CompoundPruner; |
68 | |
69 | // PT: extended pruner structure. We might want to move the additional data to the pruner itself later. |
70 | struct PrunerExt |
71 | { |
72 | PrunerExt(); |
73 | ~PrunerExt(); |
74 | |
75 | void init(PxPruningStructureType::Enum type, PxU64 contextID, PxU32 sceneLimit); |
76 | void flushMemory(); |
77 | void preallocate(PxU32 nbShapes); |
78 | void flushShapes(PxU32 index); |
79 | |
80 | void addToDirtyList(PrunerHandle handle); |
81 | Ps::IntBool isDirty(PrunerHandle handle) const; |
82 | void removeFromDirtyList(PrunerHandle handle); |
83 | void growDirtyList(PrunerHandle handle); |
84 | |
85 | PX_FORCE_INLINE PxPruningStructureType::Enum type() const { return mPrunerType; } |
86 | PX_FORCE_INLINE const Pruner* pruner() const { return mPruner; } |
87 | PX_FORCE_INLINE Pruner* pruner() { return mPruner; } |
88 | PX_FORCE_INLINE PxU32 timestamp() const { return mTimestamp; } |
89 | PX_FORCE_INLINE void invalidateTimestamp() { mTimestamp++; } |
90 | |
91 | private: |
92 | Pruner* mPruner; |
93 | Cm::BitMap mDirtyMap; |
94 | Ps::Array<PrunerHandle> mDirtyList; |
95 | PxPruningStructureType::Enum mPrunerType; |
96 | PxU32 mTimestamp; |
97 | |
98 | PX_NOCOPY(PrunerExt) |
99 | |
100 | friend class SceneQueryManager; |
101 | }; |
102 | |
103 | typedef Ps::Pair<PrunerCompoundId, PrunerHandle> CompoundPair; |
104 | typedef Ps::CoalescedHashSet<CompoundPair > CompoundPrunerSet; |
105 | // AB: extended compoud pruner structure, buffers compound shape changes and flushes them. |
106 | struct CompoundPrunerExt |
107 | { |
108 | CompoundPrunerExt(); |
109 | ~CompoundPrunerExt(); |
110 | |
111 | void flushMemory(); |
112 | void preallocate(PxU32 nbShapes); |
113 | void flushShapes(); |
114 | |
115 | void addToDirtyList(PrunerCompoundId compoundId, PrunerHandle handle); |
116 | Ps::IntBool isDirty(PrunerCompoundId compoundId, PrunerHandle handle) const; |
117 | void removeFromDirtyList(PrunerCompoundId compoundId, PrunerHandle handle); |
118 | |
119 | PX_FORCE_INLINE const CompoundPruner* pruner() const { return mPruner; } |
120 | PX_FORCE_INLINE CompoundPruner* pruner() { return mPruner; } |
121 | |
122 | private: |
123 | CompoundPruner* mPruner; |
124 | CompoundPrunerSet mDirtyList; |
125 | |
126 | PX_NOCOPY(CompoundPrunerExt) |
127 | |
128 | friend class SceneQueryManager; |
129 | }; |
130 | |
131 | |
132 | struct DynamicBoundsSync : public Sc::SqBoundsSync |
133 | { |
134 | virtual void sync(const PrunerHandle* handles, const PxU32* indices, const PxBounds3* bounds, PxU32 count, const Cm::BitMap& dirtyShapeSimMap); |
135 | |
136 | Pruner* mPruner; |
137 | PxU32* mTimestamp; |
138 | }; |
139 | |
140 | class SceneQueryManager : public Ps::UserAllocated |
141 | { |
142 | PX_NOCOPY(SceneQueryManager) |
143 | public: |
144 | SceneQueryManager(Scb::Scene& scene, PxPruningStructureType::Enum staticStructure, |
145 | PxPruningStructureType::Enum dynamicStructure, PxU32 dynamicTreeRebuildRateHint, |
146 | const PxSceneLimits& limits); |
147 | ~SceneQueryManager(); |
148 | |
149 | PrunerData addPrunerShape(const Scb::Shape& scbShape, const Scb::Actor& scbActor, bool dynamic, PrunerCompoundId compoundId, const PxBounds3* bounds=NULL, bool hasPrunerStructure = false); |
150 | void removePrunerShape(PrunerCompoundId compoundId, PrunerData shapeData); |
151 | const PrunerPayload& getPayload(PrunerCompoundId compoundId, PrunerData shapeData) const; |
152 | |
153 | void addPruningStructure(const Sq::PruningStructure& ps); |
154 | void addCompoundShape(const Gu::BVHStructure& bvhStructure, PrunerCompoundId compoundId, const PxTransform& compoundTransform, PrunerData* prunerData, const Scb::Shape** scbShapes, const Scb::Actor& scbActor); |
155 | |
156 | public: |
157 | PX_FORCE_INLINE Scb::Scene& getScene() const { return mScene; } |
158 | PX_FORCE_INLINE PxU32 getDynamicTreeRebuildRateHint() const { return mRebuildRateHint; } |
159 | |
160 | PX_FORCE_INLINE const PrunerExt& get(PruningIndex::Enum index) const { return mPrunerExt[index]; } |
161 | PX_FORCE_INLINE PrunerExt& get(PruningIndex::Enum index) { return mPrunerExt[index]; } |
162 | |
163 | PX_FORCE_INLINE const CompoundPrunerExt& getCompoundPruner() const { return mCompoundPrunerExt; } |
164 | |
165 | void preallocate(PxU32 staticShapes, PxU32 dynamicShapes); |
166 | void markForUpdate(PrunerCompoundId compoundId, PrunerData s); |
167 | void setDynamicTreeRebuildRateHint(PxU32 dynTreeRebuildRateHint); |
168 | |
169 | void flushUpdates(); |
170 | void forceDynamicTreeRebuild(bool rebuildStaticStructure, bool rebuildDynamicStructure); |
171 | void sceneQueryBuildStep(PruningIndex::Enum index); |
172 | |
173 | void updateCompoundActors(Sc::BodyCore*const* bodies, PxU32 numBodies); |
174 | void updateCompoundActor(PrunerCompoundId compoundId, const PxTransform& compoundTransform, bool dynamic); |
175 | void removeCompoundActor(PrunerCompoundId compoundId, bool dynamic); |
176 | |
177 | DynamicBoundsSync& getDynamicBoundsSync() { return mDynamicBoundsSync; } |
178 | |
179 | bool prepareSceneQueriesUpdate(PruningIndex::Enum index); |
180 | |
181 | // Force a rebuild of the aabb/loose octree etc to allow raycasting on multiple threads. |
182 | void afterSync(PxSceneQueryUpdateMode::Enum updateMode); |
183 | void shiftOrigin(const PxVec3& shift); |
184 | |
185 | void flushMemory(); |
186 | private: |
187 | PrunerExt mPrunerExt[PruningIndex::eCOUNT]; |
188 | CompoundPrunerExt mCompoundPrunerExt; |
189 | |
190 | PxU32 mRebuildRateHint; |
191 | |
192 | Scb::Scene& mScene; |
193 | |
194 | // threading |
195 | shdfnd::Mutex mSceneQueryLock; // to make sure only one query updates the dirty pruner structure if multiple queries run in parallel |
196 | |
197 | DynamicBoundsSync mDynamicBoundsSync; |
198 | |
199 | volatile bool mPrunerNeedsUpdating; |
200 | |
201 | void flushShapes(); |
202 | }; |
203 | |
204 | /////////////////////////////////////////////////////////////////////////////// |
205 | |
206 | // PT: TODO: replace PrunerData with just PxU32 to save memory on Win64. Breaks binary compatibility though. |
207 | // PT: was previously called 'ActorShape' but does not contain an actor or shape pointer, contrary to the Np-level struct with the same name. |
208 | // PT: it only contains a pruner index (0 or 1) and a pruner handle. Hence the new name. |
209 | PX_FORCE_INLINE PrunerData createPrunerData(PxU32 index, PrunerHandle h) { return PrunerData((h << 1) | index); } |
210 | PX_FORCE_INLINE PxU32 getPrunerIndex(PrunerData data) { return PxU32(data & 1); } |
211 | PX_FORCE_INLINE PrunerHandle getPrunerHandle(PrunerData data) { return PrunerHandle(data >> 1); } |
212 | |
213 | /////////////////////////////////////////////////////////////////////////////// |
214 | |
215 | |
216 | } // namespace Sq |
217 | |
218 | } |
219 | |
220 | /** @} */ |
221 | #endif |
222 | |