Allocate memory for a given number of components
| 44 | |
| 45 | // Allocate memory for a given number of components |
| 46 | void ColliderComponents::allocate(uint32 nbComponentsToAllocate) { |
| 47 | |
| 48 | assert(nbComponentsToAllocate > mNbAllocatedComponents); |
| 49 | |
| 50 | // Make sure capacity is an integral multiple of alignment |
| 51 | nbComponentsToAllocate = std::ceil(nbComponentsToAllocate / float(GLOBAL_ALIGNMENT)) * GLOBAL_ALIGNMENT; |
| 52 | |
| 53 | // Size for the data of a single component (in bytes) |
| 54 | const size_t totalSizeBytes = nbComponentsToAllocate * mComponentDataSize + mAlignmentMarginSize; |
| 55 | |
| 56 | // Allocate memory |
| 57 | void* newBuffer = mMemoryAllocator.allocate(totalSizeBytes); |
| 58 | assert(newBuffer != nullptr); |
| 59 | assert(reinterpret_cast<uintptr_t>(newBuffer) % GLOBAL_ALIGNMENT == 0); |
| 60 | |
| 61 | // New pointers to components data |
| 62 | Entity* newCollidersEntities = static_cast<Entity*>(newBuffer); |
| 63 | Entity* newBodiesEntities = reinterpret_cast<Entity*>(MemoryAllocator::alignAddress(newCollidersEntities + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 64 | assert(reinterpret_cast<uintptr_t>(newBodiesEntities) % GLOBAL_ALIGNMENT == 0); |
| 65 | Collider** newColliders = reinterpret_cast<Collider**>(MemoryAllocator::alignAddress(newBodiesEntities + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 66 | assert(reinterpret_cast<uintptr_t>(newColliders) % GLOBAL_ALIGNMENT == 0); |
| 67 | int32* newBroadPhaseIds = reinterpret_cast<int32*>(MemoryAllocator::alignAddress(newColliders + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 68 | assert(reinterpret_cast<uintptr_t>(newBroadPhaseIds) % GLOBAL_ALIGNMENT == 0); |
| 69 | Transform* newLocalToBodyTransforms = reinterpret_cast<Transform*>(MemoryAllocator::alignAddress(newBroadPhaseIds + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 70 | assert(reinterpret_cast<uintptr_t>(newLocalToBodyTransforms) % GLOBAL_ALIGNMENT == 0); |
| 71 | CollisionShape** newCollisionShapes = reinterpret_cast<CollisionShape**>(MemoryAllocator::alignAddress(newLocalToBodyTransforms + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 72 | assert(reinterpret_cast<uintptr_t>(newCollisionShapes) % GLOBAL_ALIGNMENT == 0); |
| 73 | unsigned short* newCollisionCategoryBits = reinterpret_cast<unsigned short*>(MemoryAllocator::alignAddress(newCollisionShapes + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 74 | assert(reinterpret_cast<uintptr_t>(newCollisionCategoryBits) % GLOBAL_ALIGNMENT == 0); |
| 75 | unsigned short* newCollideWithMaskBits = reinterpret_cast<unsigned short*>(MemoryAllocator::alignAddress(newCollisionCategoryBits + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 76 | assert(reinterpret_cast<uintptr_t>(newCollideWithMaskBits) % GLOBAL_ALIGNMENT == 0); |
| 77 | Transform* newLocalToWorldTransforms = reinterpret_cast<Transform*>(MemoryAllocator::alignAddress(newCollideWithMaskBits + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 78 | assert(reinterpret_cast<uintptr_t>(newLocalToWorldTransforms) % GLOBAL_ALIGNMENT == 0); |
| 79 | Array<uint64>* newOverlappingPairs = reinterpret_cast<Array<uint64>*>(MemoryAllocator::alignAddress(newLocalToWorldTransforms + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 80 | assert(reinterpret_cast<uintptr_t>(newOverlappingPairs) % GLOBAL_ALIGNMENT == 0); |
| 81 | bool* hasCollisionShapeChangedSize = reinterpret_cast<bool*>(MemoryAllocator::alignAddress(newOverlappingPairs + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 82 | assert(reinterpret_cast<uintptr_t>(hasCollisionShapeChangedSize) % GLOBAL_ALIGNMENT == 0); |
| 83 | bool* isTrigger = reinterpret_cast<bool*>(MemoryAllocator::alignAddress(hasCollisionShapeChangedSize + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 84 | assert(reinterpret_cast<uintptr_t>(isTrigger) % GLOBAL_ALIGNMENT == 0); |
| 85 | bool* isSimulationCollider = reinterpret_cast<bool*>(MemoryAllocator::alignAddress(isTrigger + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 86 | assert(reinterpret_cast<uintptr_t>(isSimulationCollider) % GLOBAL_ALIGNMENT == 0); |
| 87 | bool* isWorldQueryCollider = reinterpret_cast<bool*>(MemoryAllocator::alignAddress(isSimulationCollider + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 88 | assert(reinterpret_cast<uintptr_t>(isWorldQueryCollider) % GLOBAL_ALIGNMENT == 0); |
| 89 | Material* materials = reinterpret_cast<Material*>(MemoryAllocator::alignAddress(isWorldQueryCollider + nbComponentsToAllocate, GLOBAL_ALIGNMENT)); |
| 90 | assert(reinterpret_cast<uintptr_t>(materials) % GLOBAL_ALIGNMENT == 0); |
| 91 | assert(reinterpret_cast<uintptr_t>(materials + nbComponentsToAllocate) <= reinterpret_cast<uintptr_t>(newBuffer) + totalSizeBytes); |
| 92 | |
| 93 | // If there was already components before |
| 94 | if (mNbComponents > 0) { |
| 95 | |
| 96 | // Copy component data from the previous buffer to the new one |
| 97 | memcpy(newCollidersEntities, mCollidersEntities, mNbComponents * sizeof(Entity)); |
| 98 | memcpy(newBodiesEntities, mBodiesEntities, mNbComponents * sizeof(Entity)); |
| 99 | memcpy(newColliders, mColliders, mNbComponents * sizeof(Collider*)); |
| 100 | memcpy(newBroadPhaseIds, mBroadPhaseIds, mNbComponents * sizeof(int32)); |
| 101 | memcpy(newLocalToBodyTransforms, mLocalToBodyTransforms, mNbComponents * sizeof(Transform)); |
| 102 | memcpy(newCollisionShapes, mCollisionShapes, mNbComponents * sizeof(CollisionShape*)); |
| 103 | memcpy(newCollisionCategoryBits, mCollisionCategoryBits, mNbComponents * sizeof(unsigned short)); |