| 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 | #ifndef BP_BROADPHASE_UPDATE_H |
| 31 | #define BP_BROADPHASE_UPDATE_H |
| 32 | |
| 33 | #include "foundation/PxAssert.h" |
| 34 | #include "foundation/PxUnionCast.h" |
| 35 | #include "CmPhysXCommon.h" |
| 36 | #include "PxBroadPhase.h" |
| 37 | #include "Ps.h" |
| 38 | |
| 39 | namespace physx |
| 40 | { |
| 41 | namespace Bp |
| 42 | { |
| 43 | typedef PxU32 ShapeHandle; |
| 44 | typedef PxU32 BpHandle; |
| 45 | #define BP_INVALID_BP_HANDLE 0x3fffffff |
| 46 | |
| 47 | #define ALIGN_SIZE_16(size) ((unsigned(size)+15)&(unsigned(~15))) |
| 48 | |
| 49 | #define BP_USE_AGGREGATE_GROUP_TAIL |
| 50 | #define BP_FILTERING_USES_TYPE_IN_GROUP |
| 51 | |
| 52 | /* |
| 53 | \brief AABBManager volumes with the same filter group value are guaranteed never to generate an overlap pair. |
| 54 | \note To ensure that static pairs never overlap, add static shapes with eSTATICS. |
| 55 | The value eDYNAMICS_BASE provides a minimum recommended group value for dynamic shapes. |
| 56 | If dynamics shapes are assigned group values greater than or equal to eDYNAMICS_BASE then |
| 57 | they are allowed to generate broadphase overlaps with statics, and other dynamic shapes provided |
| 58 | they have different group values. |
| 59 | @see AABBManager::createVolume |
| 60 | */ |
| 61 | struct FilterGroup |
| 62 | { |
| 63 | enum Enum |
| 64 | { |
| 65 | eSTATICS = 0, |
| 66 | eDYNAMICS_BASE = 1, |
| 67 | #ifdef BP_USE_AGGREGATE_GROUP_TAIL |
| 68 | eAGGREGATE_BASE = 0xfffffffe, |
| 69 | #endif |
| 70 | eINVALID = 0xffffffff |
| 71 | }; |
| 72 | }; |
| 73 | |
| 74 | #ifdef BP_FILTERING_USES_TYPE_IN_GROUP |
| 75 | struct FilterType |
| 76 | { |
| 77 | enum Enum |
| 78 | { |
| 79 | STATIC = 0, |
| 80 | KINEMATIC = 1, |
| 81 | DYNAMIC = 2, |
| 82 | AGGREGATE = 3, |
| 83 | |
| 84 | COUNT = 4 |
| 85 | }; |
| 86 | }; |
| 87 | #endif |
| 88 | |
| 89 | PX_FORCE_INLINE Bp::FilterGroup::Enum getFilterGroup_Statics() |
| 90 | { |
| 91 | return Bp::FilterGroup::eSTATICS; |
| 92 | } |
| 93 | |
| 94 | PX_FORCE_INLINE Bp::FilterGroup::Enum getFilterGroup_Dynamics(PxU32 rigidId, bool isKinematic) |
| 95 | { |
| 96 | const PxU32 group = rigidId + Bp::FilterGroup::eDYNAMICS_BASE; |
| 97 | #ifdef BP_FILTERING_USES_TYPE_IN_GROUP |
| 98 | const PxU32 type = isKinematic ? FilterType::KINEMATIC : FilterType::DYNAMIC; |
| 99 | return Bp::FilterGroup::Enum((group<<2)|type); |
| 100 | #else |
| 101 | PX_UNUSED(isKinematic); |
| 102 | return Bp::FilterGroup::Enum(group); |
| 103 | #endif |
| 104 | } |
| 105 | |
| 106 | PX_FORCE_INLINE Bp::FilterGroup::Enum getFilterGroup(bool isStatic, PxU32 rigidId, bool isKinematic) |
| 107 | { |
| 108 | return isStatic ? getFilterGroup_Statics() : getFilterGroup_Dynamics(rigidId, isKinematic); |
| 109 | } |
| 110 | |
| 111 | #ifdef BP_FILTERING_USES_TYPE_IN_GROUP |
| 112 | PX_FORCE_INLINE bool groupFiltering(const Bp::FilterGroup::Enum group0, const Bp::FilterGroup::Enum group1, const bool* PX_RESTRICT lut) |
| 113 | { |
| 114 | /* const int g0 = group0 & ~3; |
| 115 | const int g1 = group1 & ~3; |
| 116 | if(g0==g1) |
| 117 | return false;*/ |
| 118 | if(group0==group1) |
| 119 | { |
| 120 | PX_ASSERT((group0 & ~3)==(group1 & ~3)); |
| 121 | return false; |
| 122 | } |
| 123 | |
| 124 | const int type0 = group0 & 3; |
| 125 | const int type1 = group1 & 3; |
| 126 | return lut[type0*4+type1]; |
| 127 | } |
| 128 | #else |
| 129 | PX_FORCE_INLINE bool groupFiltering(const Bp::FilterGroup::Enum group0, const Bp::FilterGroup::Enum group1) |
| 130 | { |
| 131 | return group0!=group1; |
| 132 | } |
| 133 | #endif |
| 134 | |
| 135 | /* |
| 136 | \brief Encode a single float value with lossless encoding to integer |
| 137 | */ |
| 138 | PX_FORCE_INLINE PxU32 encodeFloat(PxU32 ir) |
| 139 | { |
| 140 | //we may need to check on -0 and 0 |
| 141 | //But it should make no practical difference. |
| 142 | if(ir & PX_SIGN_BITMASK) //negative? |
| 143 | return ~ir;//reverse sequence of negative numbers |
| 144 | else |
| 145 | return ir | PX_SIGN_BITMASK; // flip sign |
| 146 | } |
| 147 | |
| 148 | /* |
| 149 | \brief Encode a single float value with lossless encoding to integer |
| 150 | */ |
| 151 | PX_FORCE_INLINE PxU32 decodeFloat(PxU32 ir) |
| 152 | { |
| 153 | if(ir & PX_SIGN_BITMASK) //positive? |
| 154 | return ir & ~PX_SIGN_BITMASK; //flip sign |
| 155 | else |
| 156 | return ~ir; //undo reversal |
| 157 | } |
| 158 | |
| 159 | |
| 160 | /** |
| 161 | \brief Integer representation of PxBounds3 used by BroadPhase |
| 162 | @see BroadPhaseUpdateData |
| 163 | */ |
| 164 | |
| 165 | typedef PxU32 ValType; |
| 166 | |
| 167 | class IntegerAABB |
| 168 | { |
| 169 | public: |
| 170 | |
| 171 | enum |
| 172 | { |
| 173 | MIN_X = 0, |
| 174 | MIN_Y, |
| 175 | MIN_Z, |
| 176 | MAX_X, |
| 177 | MAX_Y, |
| 178 | MAX_Z |
| 179 | }; |
| 180 | |
| 181 | IntegerAABB(const PxBounds3& b, PxReal contactDistance) |
| 182 | { |
| 183 | const PxVec3 dist(contactDistance); |
| 184 | encode(bounds: PxBounds3(b.minimum - dist, b.maximum + dist)); |
| 185 | } |
| 186 | |
| 187 | /* |
| 188 | \brief Return the minimum along a specified axis |
| 189 | \param[in] i is the axis |
| 190 | */ |
| 191 | PX_FORCE_INLINE ValType getMin(PxU32 i) const { return (mMinMax)[MIN_X+i]; } |
| 192 | |
| 193 | /* |
| 194 | \brief Return the maximum along a specified axis |
| 195 | \param[in] i is the axis |
| 196 | */ |
| 197 | PX_FORCE_INLINE ValType getMax(PxU32 i) const { return (mMinMax)[MAX_X+i]; } |
| 198 | |
| 199 | /* |
| 200 | \brief Return one of the six min/max values of the bound |
| 201 | \param[in] isMax determines whether a min or max value is returned |
| 202 | \param[in] index is the axis |
| 203 | */ |
| 204 | PX_FORCE_INLINE ValType getExtent(PxU32 isMax, PxU32 index) const |
| 205 | { |
| 206 | PX_ASSERT(isMax<=1); |
| 207 | return (mMinMax)[3*isMax+index]; |
| 208 | } |
| 209 | |
| 210 | /* |
| 211 | \brief Return the minimum on the x axis |
| 212 | */ |
| 213 | PX_FORCE_INLINE ValType getMinX() const { return mMinMax[MIN_X]; } |
| 214 | |
| 215 | /* |
| 216 | \brief Return the minimum on the y axis |
| 217 | */ |
| 218 | PX_FORCE_INLINE ValType getMinY() const { return mMinMax[MIN_Y]; } |
| 219 | |
| 220 | /* |
| 221 | \brief Return the minimum on the z axis |
| 222 | */ |
| 223 | PX_FORCE_INLINE ValType getMinZ() const { return mMinMax[MIN_Z]; } |
| 224 | |
| 225 | /* |
| 226 | \brief Return the maximum on the x axis |
| 227 | */ |
| 228 | PX_FORCE_INLINE ValType getMaxX() const { return mMinMax[MAX_X]; } |
| 229 | |
| 230 | /* |
| 231 | \brief Return the maximum on the y axis |
| 232 | */ |
| 233 | PX_FORCE_INLINE ValType getMaxY() const { return mMinMax[MAX_Y]; } |
| 234 | |
| 235 | /* |
| 236 | \brief Return the maximum on the z axis |
| 237 | */ |
| 238 | PX_FORCE_INLINE ValType getMaxZ() const { return mMinMax[MAX_Z]; } |
| 239 | |
| 240 | /* |
| 241 | \brief Encode float bounds so they are stored as integer bounds |
| 242 | \param[in] bounds is the bounds to be encoded |
| 243 | \note The integer values of minima are always even, while the integer values of maxima are always odd |
| 244 | \note The encoding process masks off the last four bits for minima and masks on the last four bits for maxima. |
| 245 | This keeps the bounds constant when its shape is subjected to small global pose perturbations. In turn, this helps |
| 246 | reduce computational effort in the broadphase update by reducing the amount of sorting required on near-stationary |
| 247 | bodies that are aligned along one or more axis. |
| 248 | @see decode |
| 249 | */ |
| 250 | PX_FORCE_INLINE void encode(const PxBounds3& bounds) |
| 251 | { |
| 252 | const PxU32* PX_RESTRICT min = PxUnionCast<const PxU32*, const PxF32*>(b: &bounds.minimum.x); |
| 253 | const PxU32* PX_RESTRICT max = PxUnionCast<const PxU32*, const PxF32*>(b: &bounds.maximum.x); |
| 254 | //Avoid min=max by enforcing the rule that mins are even and maxs are odd. |
| 255 | mMinMax[MIN_X] = encodeFloatMin(source: min[0]); |
| 256 | mMinMax[MIN_Y] = encodeFloatMin(source: min[1]); |
| 257 | mMinMax[MIN_Z] = encodeFloatMin(source: min[2]); |
| 258 | mMinMax[MAX_X] = encodeFloatMax(source: max[0]) | (1<<2); |
| 259 | mMinMax[MAX_Y] = encodeFloatMax(source: max[1]) | (1<<2); |
| 260 | mMinMax[MAX_Z] = encodeFloatMax(source: max[2]) | (1<<2); |
| 261 | } |
| 262 | |
| 263 | /* |
| 264 | \brief Decode from integer bounds to float bounds |
| 265 | \param[out] bounds is the decoded float bounds |
| 266 | \note Encode followed by decode will produce a float bound larger than the original |
| 267 | due to the masking in encode. |
| 268 | @see encode |
| 269 | */ |
| 270 | PX_FORCE_INLINE void decode(PxBounds3& bounds) const |
| 271 | { |
| 272 | PxU32* PX_RESTRICT min = PxUnionCast<PxU32*, PxF32*>(b: &bounds.minimum.x); |
| 273 | PxU32* PX_RESTRICT max = PxUnionCast<PxU32*, PxF32*>(b: &bounds.maximum.x); |
| 274 | min[0] = decodeFloat(ir: mMinMax[MIN_X]); |
| 275 | min[1] = decodeFloat(ir: mMinMax[MIN_Y]); |
| 276 | min[2] = decodeFloat(ir: mMinMax[MIN_Z]); |
| 277 | max[0] = decodeFloat(ir: mMinMax[MAX_X]); |
| 278 | max[1] = decodeFloat(ir: mMinMax[MAX_Y]); |
| 279 | max[2] = decodeFloat(ir: mMinMax[MAX_Z]); |
| 280 | } |
| 281 | |
| 282 | /* |
| 283 | \brief Encode a single minimum value from integer bounds to float bounds |
| 284 | \note The encoding process masks off the last four bits for minima |
| 285 | @see encode |
| 286 | */ |
| 287 | static PX_FORCE_INLINE ValType encodeFloatMin(PxU32 source) |
| 288 | { |
| 289 | return ((encodeFloat(ir: source) >> eGRID_SNAP_VAL) - 1) << eGRID_SNAP_VAL; |
| 290 | } |
| 291 | |
| 292 | /* |
| 293 | \brief Encode a single maximum value from integer bounds to float bounds |
| 294 | \note The encoding process masks on the last four bits for maxima |
| 295 | @see encode |
| 296 | */ |
| 297 | static PX_FORCE_INLINE ValType encodeFloatMax(PxU32 source) |
| 298 | { |
| 299 | return ((encodeFloat(ir: source) >> eGRID_SNAP_VAL) + 1) << eGRID_SNAP_VAL; |
| 300 | } |
| 301 | |
| 302 | /* |
| 303 | \brief Shift the encoded bounds by a specified vector |
| 304 | \param[in] shift is the vector used to shift the bounds |
| 305 | */ |
| 306 | PX_FORCE_INLINE void shift(const PxVec3& shift) |
| 307 | { |
| 308 | ::physx::PxBounds3 elemBounds; |
| 309 | decode(bounds&: elemBounds); |
| 310 | elemBounds.minimum -= shift; |
| 311 | elemBounds.maximum -= shift; |
| 312 | encode(bounds: elemBounds); |
| 313 | } |
| 314 | |
| 315 | /* |
| 316 | \brief Test if this aabb lies entirely inside another aabb |
| 317 | \param[in] box is the other box |
| 318 | \return True if this aabb lies entirely inside box |
| 319 | */ |
| 320 | PX_INLINE bool isInside(const IntegerAABB& box) const |
| 321 | { |
| 322 | if(box.mMinMax[MIN_X]>mMinMax[MIN_X]) return false; |
| 323 | if(box.mMinMax[MIN_Y]>mMinMax[MIN_Y]) return false; |
| 324 | if(box.mMinMax[MIN_Z]>mMinMax[MIN_Z]) return false; |
| 325 | if(box.mMinMax[MAX_X]<mMinMax[MAX_X]) return false; |
| 326 | if(box.mMinMax[MAX_Y]<mMinMax[MAX_Y]) return false; |
| 327 | if(box.mMinMax[MAX_Z]<mMinMax[MAX_Z]) return false; |
| 328 | return true; |
| 329 | } |
| 330 | |
| 331 | /* |
| 332 | \brief Test if this aabb and another intersect |
| 333 | \param[in] b is the other box |
| 334 | \return True if this aabb and b intersect |
| 335 | */ |
| 336 | PX_FORCE_INLINE bool intersects(const IntegerAABB& b) const |
| 337 | { |
| 338 | return !(b.mMinMax[MIN_X] > mMinMax[MAX_X] || mMinMax[MIN_X] > b.mMinMax[MAX_X] || |
| 339 | b.mMinMax[MIN_Y] > mMinMax[MAX_Y] || mMinMax[MIN_Y] > b.mMinMax[MAX_Y] || |
| 340 | b.mMinMax[MIN_Z] > mMinMax[MAX_Z] || mMinMax[MIN_Z] > b.mMinMax[MAX_Z]); |
| 341 | } |
| 342 | |
| 343 | PX_FORCE_INLINE bool intersects1D(const IntegerAABB& b, const PxU32 axis) const |
| 344 | { |
| 345 | const PxU32 maxAxis = axis + 3; |
| 346 | return !(b.mMinMax[axis] > mMinMax[maxAxis] || mMinMax[axis] > b.mMinMax[maxAxis]); |
| 347 | } |
| 348 | |
| 349 | |
| 350 | /* |
| 351 | \brief Expand bounds to include another |
| 352 | \note This is used to compute the aggregate bounds of multiple shape bounds |
| 353 | \param[in] b is the bounds to be included |
| 354 | */ |
| 355 | PX_FORCE_INLINE void include(const IntegerAABB& b) |
| 356 | { |
| 357 | mMinMax[MIN_X] = PxMin(a: mMinMax[MIN_X], b: b.mMinMax[MIN_X]); |
| 358 | mMinMax[MIN_Y] = PxMin(a: mMinMax[MIN_Y], b: b.mMinMax[MIN_Y]); |
| 359 | mMinMax[MIN_Z] = PxMin(a: mMinMax[MIN_Z], b: b.mMinMax[MIN_Z]); |
| 360 | mMinMax[MAX_X] = PxMax(a: mMinMax[MAX_X], b: b.mMinMax[MAX_X]); |
| 361 | mMinMax[MAX_Y] = PxMax(a: mMinMax[MAX_Y], b: b.mMinMax[MAX_Y]); |
| 362 | mMinMax[MAX_Z] = PxMax(a: mMinMax[MAX_Z], b: b.mMinMax[MAX_Z]); |
| 363 | } |
| 364 | |
| 365 | /* |
| 366 | \brief Set the bounds to (max, max, max), (min, min, min) |
| 367 | */ |
| 368 | PX_INLINE void setEmpty() |
| 369 | { |
| 370 | mMinMax[MIN_X] = mMinMax[MIN_Y] = mMinMax[MIN_Z] = 0xff7fffff; //PX_IR(PX_MAX_F32); |
| 371 | mMinMax[MAX_X] = mMinMax[MAX_Y] = mMinMax[MAX_Z] = 0x00800000; ///PX_IR(0.0f); |
| 372 | } |
| 373 | |
| 374 | ValType mMinMax[6]; |
| 375 | |
| 376 | private: |
| 377 | |
| 378 | enum |
| 379 | { |
| 380 | eGRID_SNAP_VAL = 4 |
| 381 | }; |
| 382 | }; |
| 383 | |
| 384 | PX_FORCE_INLINE ValType encodeMin(const PxBounds3& bounds, PxU32 axis, PxReal contactDistance) |
| 385 | { |
| 386 | const PxReal val = bounds.minimum[axis] - contactDistance; |
| 387 | const PxU32 min = PxUnionCast<PxU32, PxF32>(b: val); |
| 388 | const PxU32 m = IntegerAABB::encodeFloatMin(source: min); |
| 389 | return m; |
| 390 | } |
| 391 | |
| 392 | PX_FORCE_INLINE ValType encodeMax(const PxBounds3& bounds, PxU32 axis, PxReal contactDistance) |
| 393 | { |
| 394 | const PxReal val = bounds.maximum[axis] + contactDistance; |
| 395 | const PxU32 max = PxUnionCast<PxU32, PxF32>(b: val); |
| 396 | const PxU32 m = IntegerAABB::encodeFloatMax(source: max) | (1<<2); |
| 397 | return m; |
| 398 | } |
| 399 | |
| 400 | class BroadPhase; |
| 401 | |
| 402 | class BroadPhaseUpdateData |
| 403 | { |
| 404 | public: |
| 405 | |
| 406 | /** |
| 407 | \brief A structure detailing the changes to the collection of aabbs, whose overlaps are computed in the broadphase. |
| 408 | The structure consists of per-object arrays of object bounds and object groups, and three arrays that index |
| 409 | into the per-object arrays, denoting the bounds which are to be created, updated and removed in the broad phase. |
| 410 | |
| 411 | * each entry in the object arrays represents the same shape or aggregate from frame to frame. |
| 412 | * each entry in an index array must be less than the capacity of the per-object arrays. |
| 413 | * no index value may appear in more than one index array, and may not occur more than once in that array. |
| 414 | |
| 415 | An index value is said to be "in use" if it has appeared in a created list in a previous update, and has not |
| 416 | since occurred in a removed list. |
| 417 | |
| 418 | \param[in] created an array of indices describing the bounds that must be inserted into the broadphase. |
| 419 | Each index in the array must not be in use. |
| 420 | |
| 421 | \param[in] updated an array of indices (referencing the boxBounds and boxGroups arrays) describing the bounds |
| 422 | that have moved since the last broadphase update. Each index in the array must be in use, and each object |
| 423 | whose index is in use and whose AABB has changed must appear in the update list. |
| 424 | |
| 425 | \param[in] removed an array of indices describing the bounds that must be removed from the broad phase. Each index in |
| 426 | the array must be in use. |
| 427 | |
| 428 | \param[in] boxBounds an array of bounds coordinates for the AABBs to be processed by the broadphase. |
| 429 | |
| 430 | An entry is valid if its values are integer bitwise representations of floating point numbers that satisfy max>min in each dimension, |
| 431 | along with a further rule that minima(maxima) must have even(odd) values. |
| 432 | |
| 433 | Each entry whose index is either in use or appears in the created array must be valid. An entry whose index is either not in use or |
| 434 | appears in the removed array need not be valid. |
| 435 | |
| 436 | \param[in] boxGroups an array of group ids, one for each bound, used for pair filtering. Bounds with the same group id will not be |
| 437 | reported as overlap pairs by the broad phase. Zero is reserved for static bounds. |
| 438 | |
| 439 | Entries in this array are immutable: the only way to change the group of an object is to remove it from the broad phase and reinsert |
| 440 | it at a different index (recall that each index must appear at most once in the created/updated/removed lists). |
| 441 | |
| 442 | \param[in] boxesCapacity the length of the boxBounds and boxGroups arrays. |
| 443 | |
| 444 | @see BroadPhase::update |
| 445 | */ |
| 446 | BroadPhaseUpdateData( |
| 447 | const ShapeHandle* created, const PxU32 createdSize, |
| 448 | const ShapeHandle* updated, const PxU32 updatedSize, |
| 449 | const ShapeHandle* removed, const PxU32 removedSize, |
| 450 | const PxBounds3* boxBounds, const Bp::FilterGroup::Enum* boxGroups, |
| 451 | #ifdef BP_FILTERING_USES_TYPE_IN_GROUP |
| 452 | const bool* lut, |
| 453 | #endif |
| 454 | const PxReal* boxContactDistances, const PxU32 boxesCapacity, |
| 455 | const bool stateChanged) : |
| 456 | mCreated (created), |
| 457 | mCreatedSize (createdSize), |
| 458 | mUpdated (updated), |
| 459 | mUpdatedSize (updatedSize), |
| 460 | mRemoved (removed), |
| 461 | mRemovedSize (removedSize), |
| 462 | mBoxBounds (boxBounds), |
| 463 | mBoxGroups (boxGroups), |
| 464 | #ifdef BP_FILTERING_USES_TYPE_IN_GROUP |
| 465 | mLUT (lut), |
| 466 | #endif |
| 467 | mContactDistance(boxContactDistances), |
| 468 | mBoxesCapacity (boxesCapacity), |
| 469 | mStateChanged (stateChanged) |
| 470 | { |
| 471 | } |
| 472 | |
| 473 | PX_FORCE_INLINE const ShapeHandle* getCreatedHandles() const { return mCreated; } |
| 474 | PX_FORCE_INLINE PxU32 getNumCreatedHandles() const { return mCreatedSize; } |
| 475 | |
| 476 | PX_FORCE_INLINE const ShapeHandle* getUpdatedHandles() const { return mUpdated; } |
| 477 | PX_FORCE_INLINE PxU32 getNumUpdatedHandles() const { return mUpdatedSize; } |
| 478 | |
| 479 | PX_FORCE_INLINE const ShapeHandle* getRemovedHandles() const { return mRemoved; } |
| 480 | PX_FORCE_INLINE PxU32 getNumRemovedHandles() const { return mRemovedSize; } |
| 481 | |
| 482 | PX_FORCE_INLINE const PxBounds3* getAABBs() const { return mBoxBounds; } |
| 483 | PX_FORCE_INLINE const Bp::FilterGroup::Enum* getGroups() const { return mBoxGroups; } |
| 484 | #ifdef BP_FILTERING_USES_TYPE_IN_GROUP |
| 485 | PX_FORCE_INLINE const bool* getLUT() const { return mLUT; } |
| 486 | #endif |
| 487 | PX_FORCE_INLINE PxU32 getCapacity() const { return mBoxesCapacity; } |
| 488 | |
| 489 | PX_FORCE_INLINE const PxReal* getContactDistance() const { return mContactDistance; } |
| 490 | |
| 491 | PX_FORCE_INLINE bool getStateChanged() const { return mStateChanged; } |
| 492 | |
| 493 | #if PX_CHECKED |
| 494 | static bool isValid(const BroadPhaseUpdateData& updateData, const BroadPhase& bp); |
| 495 | bool isValid() const; |
| 496 | #endif |
| 497 | |
| 498 | private: |
| 499 | |
| 500 | const ShapeHandle* mCreated; |
| 501 | PxU32 mCreatedSize; |
| 502 | |
| 503 | const ShapeHandle* mUpdated; |
| 504 | PxU32 mUpdatedSize; |
| 505 | |
| 506 | const ShapeHandle* mRemoved; |
| 507 | PxU32 mRemovedSize; |
| 508 | |
| 509 | const PxBounds3* mBoxBounds; |
| 510 | const Bp::FilterGroup::Enum* mBoxGroups; |
| 511 | #ifdef BP_FILTERING_USES_TYPE_IN_GROUP |
| 512 | const bool* mLUT; |
| 513 | #endif |
| 514 | const PxReal* mContactDistance; |
| 515 | PxU32 mBoxesCapacity; |
| 516 | bool mStateChanged; |
| 517 | }; |
| 518 | |
| 519 | } //namespace Bp |
| 520 | |
| 521 | } //namespace physx |
| 522 | |
| 523 | #endif //BP_BROADPHASE_UPDATE_H |
| 524 | |