123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
- // SPDX-FileCopyrightText: 2023 Jorrit Rouwe
- // SPDX-License-Identifier: MIT
- #pragma once
- #include <Jolt/Physics/Collision/ObjectLayer.h>
- JPH_NAMESPACE_BEGIN
- /// Filter class to test if two objects can collide based on their object layer. Used while finding collision pairs.
- /// This implementation uses a table to determine if two layers can collide.
- class ObjectLayerPairFilterTable : public ObjectLayerPairFilter
- {
- private:
- /// Get which bit corresponds to the pair (inLayer1, inLayer2)
- uint GetBit(ObjectLayer inLayer1, ObjectLayer inLayer2) const
- {
- // We store the lower left half only, so swap the inputs when trying to access the top right half
- if (inLayer1 > inLayer2)
- swap(inLayer1, inLayer2);
- JPH_ASSERT(inLayer2 < mNumObjectLayers);
- // Calculate at which bit the entry for this pair resides
- // We use the fact that a row always starts at inLayer2 * (inLayer2 + 1) / 2
- // (this is the amount of bits needed to store a table of inLayer2 entries)
- return (inLayer2 * (inLayer2 + 1)) / 2 + inLayer1;
- }
- public:
- JPH_OVERRIDE_NEW_DELETE
- /// Constructs the table with inNumObjectLayers Layers, initially all layer pairs are disabled
- explicit ObjectLayerPairFilterTable(uint inNumObjectLayers) :
- mNumObjectLayers(inNumObjectLayers)
- {
- // By default nothing collides
- // For the first layer we only need to store 1 bit, for the second 2 bits, for the third 3 bits, etc.
- // We use the formula Sum_i=1^N i = N * (N + 1) / 2 to calculate the size of the table
- int table_size = (inNumObjectLayers * (inNumObjectLayers + 1) / 2 + 7) / 8;
- mTable.resize(table_size, 0);
- }
- /// Get the number of object layers
- uint GetNumObjectLayers() const
- {
- return mNumObjectLayers;
- }
- /// Disable collision between two object layers
- void DisableCollision(ObjectLayer inLayer1, ObjectLayer inLayer2)
- {
- uint bit = GetBit(inLayer1, inLayer2);
- mTable[bit >> 3] &= (0xff ^ (1 << (bit & 0b111)));
- }
- /// Enable collision between two object layers
- void EnableCollision(ObjectLayer inLayer1, ObjectLayer inLayer2)
- {
- uint bit = GetBit(inLayer1, inLayer2);
- mTable[bit >> 3] |= 1 << (bit & 0b111);
- }
- /// Returns true if two layers can collide
- virtual bool ShouldCollide(ObjectLayer inObject1, ObjectLayer inObject2) const override
- {
- // Test if the bit is set for this group pair
- uint bit = GetBit(inObject1, inObject2);
- return (mTable[bit >> 3] & (1 << (bit & 0b111))) != 0;
- }
- private:
- uint mNumObjectLayers; ///< The number of layers that this table supports
- Array<uint8> mTable; ///< The table of bits that indicates which layers collide
- };
- JPH_NAMESPACE_END
|