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 #ifndef REACTPHYSICS3D_COLLISION_BODY_COMPONENTS_H
27 #define REACTPHYSICS3D_COLLISION_BODY_COMPONENTS_H
28 
29 // Libraries
30 #include <reactphysics3d/mathematics/Transform.h>
31 #include <reactphysics3d/engine/Entity.h>
32 #include <reactphysics3d/components/Components.h>
33 #include <reactphysics3d/containers/Map.h>
34 
35 // ReactPhysics3D namespace
36 namespace reactphysics3d {
37 
38 // Class declarations
39 class MemoryAllocator;
40 class EntityManager;
41 class CollisionBody;
42 
43 // Class CollisionBodyComponents
44 /**
45  * This class represent the component of the ECS that contains data about a collision body.
46  * The components of the sleeping entities (bodies) are always stored at the end of the array.
47  */
48 class CollisionBodyComponents : public Components {
49 
50     private:
51 
52         // -------------------- Attributes -------------------- //
53 
54         /// Array of body entities of each component
55         Entity* mBodiesEntities;
56 
57         /// Array of pointers to the corresponding bodies
58         CollisionBody** mBodies;
59 
60         /// Array with the list of colliders of each body
61         List<Entity>* mColliders;
62 
63         /// Array of boolean values to know if the body is active.
64         bool* mIsActive;
65 
66         /// Array of pointers that can be used to attach user data to the body
67         void** mUserData;
68 
69         // -------------------- Methods -------------------- //
70 
71         /// Allocate memory for a given number of components
72         virtual void allocate(uint32 nbComponentsToAllocate) override;
73 
74         /// Destroy a component at a given index
75         virtual void destroyComponent(uint32 index) override;
76 
77         /// Move a component from a source to a destination index in the components array
78         virtual void moveComponentToIndex(uint32 srcIndex, uint32 destIndex) override;
79 
80         /// Swap two components in the array
81         virtual void swapComponents(uint32 index1, uint32 index2) override;
82 
83     public:
84 
85         /// Structure for the data of a collision body component
86         struct CollisionBodyComponent {
87 
88             CollisionBody* body;
89 
90             /// Constructor
CollisionBodyComponentCollisionBodyComponent91             CollisionBodyComponent(CollisionBody* body) : body(body) {
92 
93             }
94         };
95 
96         // -------------------- Methods -------------------- //
97 
98         /// Constructor
99         CollisionBodyComponents(MemoryAllocator& allocator);
100 
101         /// Destructor
102         virtual ~CollisionBodyComponents() override = default;
103 
104         /// Add a component
105         void addComponent(Entity bodyEntity, bool isSleeping, const CollisionBodyComponent& component);
106 
107         /// Add a collider to a body component
108         void addColliderToBody(Entity bodyEntity, Entity colliderEntity);
109 
110         /// Remove a collider from a body component
111         void removeColliderFromBody(Entity bodyEntity, Entity colliderEntity);
112 
113         /// Return a pointer to a body
114         CollisionBody* getBody(Entity bodyEntity);
115 
116         /// Return the list of colliders of a body
117         const List<Entity>& getColliders(Entity bodyEntity) const;
118 
119         /// Return true if the body is active
120         bool getIsActive(Entity bodyEntity) const;
121 
122         /// Set the value to know if the body is active
123         void setIsActive(Entity bodyEntity, bool isActive) const;
124 
125         /// Return the user data associated with the body
126         void* getUserData(Entity bodyEntity) const;
127 
128         /// Set the user data associated with the body
129         void setUserData(Entity bodyEntity, void* userData) const;
130 };
131 
132 // Add a collider to a body component
addColliderToBody(Entity bodyEntity,Entity colliderEntity)133 inline void CollisionBodyComponents::addColliderToBody(Entity bodyEntity, Entity colliderEntity) {
134 
135     assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
136 
137     mColliders[mMapEntityToComponentIndex[bodyEntity]].add(colliderEntity);
138 }
139 
140 // Remove a collider from a body component
removeColliderFromBody(Entity bodyEntity,Entity colliderEntity)141 inline void CollisionBodyComponents::removeColliderFromBody(Entity bodyEntity, Entity colliderEntity) {
142 
143     assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
144 
145     mColliders[mMapEntityToComponentIndex[bodyEntity]].remove(colliderEntity);
146 }
147 
148 // Return a pointer to a body
getBody(Entity bodyEntity)149 inline CollisionBody *CollisionBodyComponents::getBody(Entity bodyEntity) {
150 
151     assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
152 
153     return mBodies[mMapEntityToComponentIndex[bodyEntity]];
154 }
155 
156 // Return the list of colliders of a body
getColliders(Entity bodyEntity)157 inline const List<Entity>& CollisionBodyComponents::getColliders(Entity bodyEntity) const {
158 
159     assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
160 
161     return mColliders[mMapEntityToComponentIndex[bodyEntity]];
162 }
163 
164 // Return true if the body is active
getIsActive(Entity bodyEntity)165 inline bool CollisionBodyComponents::getIsActive(Entity bodyEntity) const {
166 
167     assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
168 
169     return mIsActive[mMapEntityToComponentIndex[bodyEntity]];
170 }
171 
172 // Set the value to know if the body is active
setIsActive(Entity bodyEntity,bool isActive)173 inline void CollisionBodyComponents::setIsActive(Entity bodyEntity, bool isActive) const {
174 
175     assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
176 
177     mIsActive[mMapEntityToComponentIndex[bodyEntity]] = isActive;
178 }
179 
180 // Return the user data associated with the body
getUserData(Entity bodyEntity)181 inline void* CollisionBodyComponents::getUserData(Entity bodyEntity) const {
182 
183     assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
184 
185     return mUserData[mMapEntityToComponentIndex[bodyEntity]];
186 }
187 
188 // Set the user data associated with the body
setUserData(Entity bodyEntity,void * userData)189 inline void CollisionBodyComponents::setUserData(Entity bodyEntity, void* userData) const {
190 
191     assert(mMapEntityToComponentIndex.containsKey(bodyEntity));
192 
193     mUserData[mMapEntityToComponentIndex[bodyEntity]] = userData;
194 }
195 
196 }
197 
198 #endif
199