1 /********************************************************************************
2 * ReactPhysics3D physics library, http://www.reactphysics3d.com *
3 * Copyright (c) 2010-2020 Daniel Chappuis *
4 *********************************************************************************
5 * *
6 * This software is provided 'as-is', without any express or implied warranty. *
7 * In no event will the authors be held liable for any damages arising from the *
8 * use of this software. *
9 * *
10 * Permission is granted to anyone to use this software for any purpose, *
11 * including commercial applications, and to alter it and redistribute it *
12 * freely, subject to the following restrictions: *
13 * *
14 * 1. The origin of this software must not be misrepresented; you must not claim *
15 * that you wrote the original software. If you use this software in a *
16 * product, an acknowledgment in the product documentation would be *
17 * appreciated but is not required. *
18 * *
19 * 2. Altered source versions must be plainly marked as such, and must not be *
20 * misrepresented as being the original software. *
21 * *
22 * 3. This notice may not be removed or altered from any source distribution. *
23 * *
24 ********************************************************************************/
25
26 // Libraries
27 #include <reactphysics3d/components/BallAndSocketJointComponents.h>
28 #include <reactphysics3d/engine/EntityManager.h>
29 #include <reactphysics3d/mathematics/Matrix3x3.h>
30 #include <cassert>
31
32 // We want to use the ReactPhysics3D namespace
33 using namespace reactphysics3d;
34
35 // Constructor
BallAndSocketJointComponents(MemoryAllocator & allocator)36 BallAndSocketJointComponents::BallAndSocketJointComponents(MemoryAllocator& allocator)
37 :Components(allocator, sizeof(Entity) + sizeof(BallAndSocketJoint*) + sizeof(Vector3) +
38 sizeof(Vector3) + sizeof(Vector3) + sizeof(Vector3) +
39 sizeof(Matrix3x3) + sizeof(Matrix3x3) + sizeof(Vector3) +
40 sizeof(Matrix3x3) + sizeof(Vector3)) {
41
42 // Allocate memory for the components data
43 allocate(INIT_NB_ALLOCATED_COMPONENTS);
44 }
45
46 // Allocate memory for a given number of components
allocate(uint32 nbComponentsToAllocate)47 void BallAndSocketJointComponents::allocate(uint32 nbComponentsToAllocate) {
48
49 assert(nbComponentsToAllocate > mNbAllocatedComponents);
50
51 // Size for the data of a single component (in bytes)
52 const size_t totalSizeBytes = nbComponentsToAllocate * mComponentDataSize;
53
54 // Allocate memory
55 void* newBuffer = mMemoryAllocator.allocate(totalSizeBytes);
56 assert(newBuffer != nullptr);
57
58 // New pointers to components data
59 Entity* newJointEntities = static_cast<Entity*>(newBuffer);
60 BallAndSocketJoint** newJoints = reinterpret_cast<BallAndSocketJoint**>(newJointEntities + nbComponentsToAllocate);
61 Vector3* newLocalAnchorPointBody1 = reinterpret_cast<Vector3*>(newJoints + nbComponentsToAllocate);
62 Vector3* newLocalAnchorPointBody2 = reinterpret_cast<Vector3*>(newLocalAnchorPointBody1 + nbComponentsToAllocate);
63 Vector3* newR1World = reinterpret_cast<Vector3*>(newLocalAnchorPointBody2 + nbComponentsToAllocate);
64 Vector3* newR2World = reinterpret_cast<Vector3*>(newR1World + nbComponentsToAllocate);
65 Matrix3x3* newI1 = reinterpret_cast<Matrix3x3*>(newR2World + nbComponentsToAllocate);
66 Matrix3x3* newI2 = reinterpret_cast<Matrix3x3*>(newI1 + nbComponentsToAllocate);
67 Vector3* newBiasVector = reinterpret_cast<Vector3*>(newI2 + nbComponentsToAllocate);
68 Matrix3x3* newInverseMassMatrix = reinterpret_cast<Matrix3x3*>(newBiasVector + nbComponentsToAllocate);
69 Vector3* newImpulse = reinterpret_cast<Vector3*>(newInverseMassMatrix + nbComponentsToAllocate);
70
71 // If there was already components before
72 if (mNbComponents > 0) {
73
74 // Copy component data from the previous buffer to the new one
75 memcpy(newJointEntities, mJointEntities, mNbComponents * sizeof(Entity));
76 memcpy(newJoints, mJoints, mNbComponents * sizeof(BallAndSocketJoint*));
77 memcpy(newLocalAnchorPointBody1, mLocalAnchorPointBody1, mNbComponents * sizeof(Vector3));
78 memcpy(newLocalAnchorPointBody2, mLocalAnchorPointBody2, mNbComponents * sizeof(Vector3));
79 memcpy(newR1World, mR1World, mNbComponents * sizeof(Vector3));
80 memcpy(newR2World, mR2World, mNbComponents * sizeof(Vector3));
81 memcpy(newI1, mI1, mNbComponents * sizeof(Matrix3x3));
82 memcpy(newI2, mI2, mNbComponents * sizeof(Matrix3x3));
83 memcpy(newBiasVector, mBiasVector, mNbComponents * sizeof(Vector3));
84 memcpy(newInverseMassMatrix, mInverseMassMatrix, mNbComponents * sizeof(Matrix3x3));
85 memcpy(newImpulse, mImpulse, mNbComponents * sizeof(Vector3));
86
87 // Deallocate previous memory
88 mMemoryAllocator.release(mBuffer, mNbAllocatedComponents * mComponentDataSize);
89 }
90
91 mBuffer = newBuffer;
92 mJointEntities = newJointEntities;
93 mJoints = newJoints;
94 mNbAllocatedComponents = nbComponentsToAllocate;
95 mLocalAnchorPointBody1 = newLocalAnchorPointBody1;
96 mLocalAnchorPointBody2 = newLocalAnchorPointBody2;
97 mR1World = newR1World;
98 mR2World = newR2World;
99 mI1 = newI1;
100 mI2 = newI2;
101 mBiasVector = newBiasVector;
102 mInverseMassMatrix = newInverseMassMatrix;
103 mImpulse = newImpulse;
104 }
105
106 // Add a component
addComponent(Entity jointEntity,bool isSleeping,const BallAndSocketJointComponent & component)107 void BallAndSocketJointComponents::addComponent(Entity jointEntity, bool isSleeping, const BallAndSocketJointComponent& component) {
108
109 // Prepare to add new component (allocate memory if necessary and compute insertion index)
110 uint32 index = prepareAddComponent(isSleeping);
111
112 // Insert the new component data
113 new (mJointEntities + index) Entity(jointEntity);
114 mJoints[index] = nullptr;
115 new (mLocalAnchorPointBody1 + index) Vector3(0, 0, 0);
116 new (mLocalAnchorPointBody2 + index) Vector3(0, 0, 0);
117 new (mR1World + index) Vector3(0, 0, 0);
118 new (mR2World + index) Vector3(0, 0, 0);
119 new (mI1 + index) Matrix3x3();
120 new (mI2 + index) Matrix3x3();
121 new (mBiasVector + index) Vector3(0, 0, 0);
122 new (mInverseMassMatrix + index) Matrix3x3();
123 new (mImpulse + index) Vector3(0, 0, 0);
124
125 // Map the entity with the new component lookup index
126 mMapEntityToComponentIndex.add(Pair<Entity, uint32>(jointEntity, index));
127
128 mNbComponents++;
129
130 assert(mDisabledStartIndex <= mNbComponents);
131 assert(mNbComponents == static_cast<uint32>(mMapEntityToComponentIndex.size()));
132 }
133
134 // Move a component from a source to a destination index in the components array
135 // The destination location must contain a constructed object
moveComponentToIndex(uint32 srcIndex,uint32 destIndex)136 void BallAndSocketJointComponents::moveComponentToIndex(uint32 srcIndex, uint32 destIndex) {
137
138 const Entity entity = mJointEntities[srcIndex];
139
140 // Copy the data of the source component to the destination location
141 new (mJointEntities + destIndex) Entity(mJointEntities[srcIndex]);
142 mJoints[destIndex] = mJoints[srcIndex];
143 new (mLocalAnchorPointBody1 + destIndex) Vector3(mLocalAnchorPointBody1[srcIndex]);
144 new (mLocalAnchorPointBody2 + destIndex) Vector3(mLocalAnchorPointBody2[srcIndex]);
145 new (mR1World + destIndex) Vector3(mR1World[srcIndex]);
146 new (mR2World + destIndex) Vector3(mR2World[srcIndex]);
147 new (mI1 + destIndex) Matrix3x3(mI1[srcIndex]);
148 new (mI2 + destIndex) Matrix3x3(mI2[srcIndex]);
149 new (mBiasVector + destIndex) Vector3(mBiasVector[srcIndex]);
150 new (mInverseMassMatrix + destIndex) Matrix3x3(mInverseMassMatrix[srcIndex]);
151 new (mImpulse + destIndex) Vector3(mImpulse[srcIndex]);
152
153 // Destroy the source component
154 destroyComponent(srcIndex);
155
156 assert(!mMapEntityToComponentIndex.containsKey(entity));
157
158 // Update the entity to component index mapping
159 mMapEntityToComponentIndex.add(Pair<Entity, uint32>(entity, destIndex));
160
161 assert(mMapEntityToComponentIndex[mJointEntities[destIndex]] == destIndex);
162 }
163
164 // Swap two components in the array
swapComponents(uint32 index1,uint32 index2)165 void BallAndSocketJointComponents::swapComponents(uint32 index1, uint32 index2) {
166
167 // Copy component 1 data
168 Entity jointEntity1(mJointEntities[index1]);
169 BallAndSocketJoint* joint1 = mJoints[index1];
170 Vector3 localAnchorPointBody1(mLocalAnchorPointBody1[index1]);
171 Vector3 localAnchorPointBody2(mLocalAnchorPointBody2[index1]);
172 Vector3 r1World1(mR1World[index1]);
173 Vector3 r2World1(mR2World[index1]);
174 Matrix3x3 i11(mI1[index1]);
175 Matrix3x3 i21(mI2[index1]);
176 Vector3 biasVector1(mBiasVector[index1]);
177 Matrix3x3 inverseMassMatrix1(mInverseMassMatrix[index1]);
178 Vector3 impulse1(mImpulse[index1]);
179
180 // Destroy component 1
181 destroyComponent(index1);
182
183 moveComponentToIndex(index2, index1);
184
185 // Reconstruct component 1 at component 2 location
186 new (mJointEntities + index2) Entity(jointEntity1);
187 mJoints[index2] = joint1;
188 new (mLocalAnchorPointBody1 + index2) Vector3(localAnchorPointBody1);
189 new (mLocalAnchorPointBody2 + index2) Vector3(localAnchorPointBody2);
190 new (mR1World + index2) Vector3(r1World1);
191 new (mR2World + index2) Vector3(r2World1);
192 new (mI1 + index2) Matrix3x3(i11);
193 new (mI2 + index2) Matrix3x3(i21);
194 new (mBiasVector + index2) Vector3(biasVector1);
195 new (mInverseMassMatrix + index2) Matrix3x3(inverseMassMatrix1);
196 new (mImpulse + index2) Vector3(impulse1);
197
198 // Update the entity to component index mapping
199 mMapEntityToComponentIndex.add(Pair<Entity, uint32>(jointEntity1, index2));
200
201 assert(mMapEntityToComponentIndex[mJointEntities[index1]] == index1);
202 assert(mMapEntityToComponentIndex[mJointEntities[index2]] == index2);
203 assert(mNbComponents == static_cast<uint32>(mMapEntityToComponentIndex.size()));
204 }
205
206 // Destroy a component at a given index
destroyComponent(uint32 index)207 void BallAndSocketJointComponents::destroyComponent(uint32 index) {
208
209 Components::destroyComponent(index);
210
211 assert(mMapEntityToComponentIndex[mJointEntities[index]] == index);
212
213 mMapEntityToComponentIndex.remove(mJointEntities[index]);
214
215 mJointEntities[index].~Entity();
216 mJoints[index] = nullptr;
217 mLocalAnchorPointBody1[index].~Vector3();
218 mLocalAnchorPointBody2[index].~Vector3();
219 mR1World[index].~Vector3();
220 mR2World[index].~Vector3();
221 mI1[index].~Matrix3x3();
222 mI2[index].~Matrix3x3();
223 mBiasVector[index].~Vector3();
224 mInverseMassMatrix[index].~Matrix3x3();
225 mImpulse[index].~Vector3();
226 }
227