CORGI
An open source project by FPL.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Groups Pages
transform.h
Go to the documentation of this file.
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef CORGI_COMPONENT_LIBRARY_TRANSFORM_H_
16 #define CORGI_COMPONENT_LIBRARY_TRANSFORM_H_
17 
18 #include <set>
19 #include <vector>
20 
21 #include "corgi/component.h"
22 #include "fplutil/intrusive_list.h"
23 #include "library_components_generated.h"
24 #include "mathfu/constants.h"
25 #include "mathfu/glsl_mappings.h"
26 #include "mathfu/matrix_4x4.h"
27 
28 namespace corgi {
29 namespace component_library {
30 
31 /// @file
32 /// @addtogroup corgi_component_library
33 /// @{
34 ///
35 /// @struct TransformData
36 ///
37 /// @brief Holds all transform data for Entities, such as
38 /// position, scale, and orientation.
39 struct TransformData {
40  /// @brief The default constructor for TransformData.
41  TransformData();
42 
43  /// @brief Move assignment operator for the TransformData.
44  ///
45  /// @param[in] other The other TransformData whose contents should be
46  /// moved into this TransformData.
47  ///
48  /// @return Returns a reference to the TransformData.
50  position = std::move(other.position);
51  scale = std::move(other.scale);
52  orientation = std::move(other.orientation);
53  world_transform = std::move(other.world_transform);
54  owner = std::move(other.owner);
55  parent = std::move(other.parent);
56  child_ids = std::move(other.child_ids);
57  pending_child_ids = std::move(other.pending_child_ids);
58  child_node = std::move(other.child_node);
59  children = std::move(other.children);
60  return *this;
61  }
62 
63  /// @brief Move constructor for the TransformData.
64  ///
65  /// @param[in] other The other TransformData whose contents should be
66  /// moved into this TransformData.
68  *this = std::move(other); // Calls the move assignment operator.
69  }
70 
71  /// @brief The position of this Entity.
72  mathfu::vec3 position;
73 
74  /// @brief The scale of the Entity.
75  mathfu::vec3 scale;
76 
77  /// @brief The orientation of the Entity.
78  mathfu::quat orientation;
79 
80  /// @brief The transform to place the Entity in world space.
81  mathfu::mat4 world_transform;
82 
83  /// @brief An EntityRef reference to the Entity that owns this
84  /// Component data.
86 
87  /// @brief An EntityRef reference to the parent Entity.
89 
90  /// @brief A set of std::string child IDs that will need to be exported.
91  std::set<std::string> child_ids;
92 
93  /// @brief Child IDs we will be linking up on the next update; we couldn't
94  /// link them before because they may not have been loaded.
95  std::vector<std::string> pending_child_ids;
96 
97  /// @brief The node inside the intrusive list for this Entity.
98  fplutil::intrusive_list_node child_node;
99 
100  /// @brief The intrusive list of this Entity's children.
101  fplutil::intrusive_list<TransformData> children;
102 
103  // We construct the matrix by hand here, because we know that it will
104  // always be a composition of rotation, scale, and translation, so we
105  // can do things a bit more cleanly than 3 4x4 matrix multiplications.
106  /// @brief Construct the transform matrix from the reotation, scale,
107  /// and translation.
108  ///
109  /// @return Returns a mathfu::mat4 containing the transform matrix.
110  mathfu::mat4 GetTransformMatrix() {
111  // Start with rotation:
112  mathfu::mat3 rot = orientation.ToMatrix();
113 
114  // Break it up into columns:
115  mathfu::vec4 c0 = mathfu::vec4(rot[0], rot[3], rot[6], 0);
116  mathfu::vec4 c1 = mathfu::vec4(rot[1], rot[4], rot[7], 0);
117  mathfu::vec4 c2 = mathfu::vec4(rot[2], rot[5], rot[8], 0);
118  mathfu::vec4 c3 = mathfu::vec4(0, 0, 0, 1);
119 
120  // Apply scale:
121  c0 *= scale.x;
122  c1 *= scale.y;
123  c2 *= scale.z;
124 
125  // Apply translation:
126  c3[0] = position.x;
127  c3[1] = position.y;
128  c3[2] = position.z;
129 
130  // Compose and return result:
131  return mathfu::mat4(c0, c1, c2, c3);
132  }
133 
134  private:
137 };
138 
139 /// @class TransformComponent
140 ///
141 /// @brief A Component that handles the transformations for every
142 /// Entity that registers with it.
143 class TransformComponent : public corgi::Component<TransformData> {
144  public:
145  /// @brief Destructor for TransformComponent.
146  virtual ~TransformComponent() {}
147 
148  /// @brief Get the world position for a given Entity
149  ///
150  /// @param[in] entity An EntityRef to the Entity whose world
151  /// position should be returned.
152  ///
153  /// @return Returns the world position of the Entity as a mathfu::vec3.
154  mathfu::vec3 WorldPosition(corgi::EntityRef entity);
155 
156  /// @brief Get the world orientation for a given Entity.
157  ///
158  /// @param[in] entity An EntityRef to the Entity whose world
159  /// orientation should be returned.
160  ///
161  /// @return Returns the world orientation for this Entity as a mathfu::quat.
162  mathfu::quat WorldOrientation(corgi::EntityRef entity);
163 
164  /// @brief Get the world transform for a given Entity.
165  ///
166  /// @param[in] entity An EntityRef to the Entity whose world
167  /// transform should be returned.
168  ///
169  /// @return Returns the world transform as a mathfu::mat4.
170  mathfu::mat4 WorldTransform(corgi::EntityRef entity);
171 
172  /// @brief Get the topmost parent of a given Entity.
173  ///
174  /// @param[in] entity An EntityRef to the Entity whose topmost parent
175  /// should be returned.
176  ///
177  /// @return Returns an EntityRef to the topmost parent of this Entity. If
178  /// not parents exist, then it returns the `entity` itself.
179  corgi::EntityRef GetRootParent(const corgi::EntityRef& entity) const;
180 
181  /// @brief Deserialize a flat binary buffer to create and populate an Entity
182  /// from raw data
183  ///
184  /// @param[in,out] entity An EntityRef reference that points to an Entity that
185  /// is being added from the raw data.
186  /// @param[in] raw_data A void pointer to the raw FlatBuffer data.
187  virtual void AddFromRawData(corgi::EntityRef& entity, const void* raw_data);
188 
189  /// @brief Serializes a TransformComponent's data for a given Entity.
190  ///
191  /// @param[in] entity An EntityRef reference to an Entity whose corresponding
192  /// TransformData will be serialized.
193  ///
194  /// @return Returns a RawDataUniquePtr to the start of the raw data in a
195  /// flat binary buffer.
196  virtual RawDataUniquePtr ExportRawData(const corgi::EntityRef& entity) const;
197 
198  /// @brief Initialize a new Entity and associate it with its TransformData.
199  ///
200  /// @param[in] entity An EntityRef to the Entity that should be associated
201  /// with its corresponding TransformData.
202  virtual void InitEntity(corgi::EntityRef& entity);
203 
204  /// @brief Remove the Entity and cleanup any children it may have.
205  ///
206  /// @param[in] entity An EntityRef reference to the Entity that should
207  /// have itself and any children removed.
208  virtual void CleanupEntity(corgi::EntityRef& entity);
209 
210  /// @brief Update the world position for all Entities registered with
211  /// this Component.
212  ///
213  /// @param[in] delta_time The delta time since the last call to this method.
214  virtual void UpdateAllEntities(corgi::WorldTime delta_time);
215 
216  /// @brief Add an Entity as a child to another Entity.
217  ///
218  /// @param[in] child An EntityRef to the Entity that should be added
219  /// as a child of `parent`.
220  /// @param[in] parent An EntityRef to the Entity that should have `child`
221  /// added as a child.
222  void AddChild(corgi::EntityRef& child, corgi::EntityRef& parent);
223 
224  /// @brief Remove an Entity from the intrusive list that it belongs to.
225  ///
226  /// @param[in] entity An EntityRef to the Entity that should be removed,
227  /// as a child, in the intrusive list.
228  void RemoveChild(corgi::EntityRef& entity);
229 
230  /// @brief After loading Entities, fix up any of their child links.
231  void PostLoadFixup();
232 
233  /// @brief Take any pending child IDs and set up the child links.
234  ///
235  /// @param[in] entity An EntityRef to the parent Entity whose child
236  /// links should be updated.
237  void UpdateChildLinks(corgi::EntityRef& entity);
238 
239  /// @brief Get the first Entity with a Component, given an ID.
240  ///
241  /// @note Searches in breadth-first order.
242  ///
243  /// @param[in] entity The EntityRef to the parent Entity whose children
244  /// should be searched.
245  /// @param[in] id The ComponentId to identify the Component that should
246  /// be checked during the search.
247  ///
248  /// @return Returns an EntityRef to the first Entity that has the
249  /// Component with ID `id`. Otherwise, it returns an invalid
250  /// EntityRef, if no such child exists.
252  corgi::ComponentId id) const {
253  return ChildWithComponents(entity, &id, 1);
254  }
255 
256  /// @brief Get the first Entity with all the Components given by an array
257  /// of IDs.
258  ///
259  /// @note Searches in breadth-first order.
260  ///
261  /// @param[in] entity The EntityRef to the parent Entity whose children
262  /// should be searched.
263  /// @param[in] ids An array of ComponentId to identify all the Components
264  /// that should be checked during the search.
265  /// @param[in] num_ids The length of the `ids` array.
266  ///
267  /// @return Returns an EntityRef to the first Entity that has all
268  /// the Components in the `ids` array. Otherwise, it returns an invalid
269  /// EntityRef, if no such child exists.
271  const corgi::ComponentId* ids,
272  size_t num_ids) const;
273 
274  private:
275  void UpdateWorldPosition(corgi::EntityRef& entity,
276  const mathfu::mat4& transform);
277 };
278 /// @}
279 
280 } // component_library
281 } // corgi
282 
285 
286 #endif // CORGI_COMPONENT_LIBRARY_TRANSFORM_H_
A Component that handles the transformations for every Entity that registers with it...
Definition: transform.h:143
std::unique_ptr< uint8_t, std::function< void(uint8_t *)> > RawDataUniquePtr
A pointer type for exported raw data.
Definition: component_interface.h:63
fplutil::intrusive_list< TransformData > children
The intrusive list of this Entity's children.
Definition: transform.h:101
virtual void AddFromRawData(corgi::EntityRef &entity, const void *raw_data)
Deserialize a flat binary buffer to create and populate an Entity from raw data.
A Component is an object that encapsulates all data and logic for Entities of a particular type...
Definition: component.h:43
virtual void UpdateAllEntities(corgi::WorldTime delta_time)
Update the world position for all Entities registered with this Component.
virtual RawDataUniquePtr ExportRawData(const corgi::EntityRef &entity) const
Serializes a TransformComponent's data for a given Entity.
mathfu::quat WorldOrientation(corgi::EntityRef entity)
Get the world orientation for a given Entity.
TransformData()
The default constructor for TransformData.
corgi::EntityRef ChildWithComponents(const corgi::EntityRef &entity, const corgi::ComponentId *ids, size_t num_ids) const
Get the first Entity with all the Components given by an array of IDs.
int WorldTime
A typedef that represents time in the game.
Definition: entity_common.h:49
corgi::EntityRef GetRootParent(const corgi::EntityRef &entity) const
Get the topmost parent of a given Entity.
virtual void CleanupEntity(corgi::EntityRef &entity)
Remove the Entity and cleanup any children it may have.
mathfu::mat4 GetTransformMatrix()
Construct the transform matrix from the reotation, scale, and translation.
Definition: transform.h:110
fplutil::intrusive_list_node child_node
The node inside the intrusive list for this Entity.
Definition: transform.h:98
std::set< std::string > child_ids
A set of std::string child IDs that will need to be exported.
Definition: transform.h:91
corgi::EntityRef owner
An EntityRef reference to the Entity that owns this Component data.
Definition: transform.h:85
virtual void InitEntity(corgi::EntityRef &entity)
Initialize a new Entity and associate it with its TransformData.
corgi::EntityRef parent
An EntityRef reference to the parent Entity.
Definition: transform.h:88
TransformData(TransformData &&other)
Move constructor for the TransformData.
Definition: transform.h:67
virtual ~TransformComponent()
Destructor for TransformComponent.
Definition: transform.h:146
std::vector< std::string > pending_child_ids
Child IDs we will be linking up on the next update; we couldn't link them before because they may not...
Definition: transform.h:95
TransformData & operator=(TransformData &&other)
Move assignment operator for the TransformData.
Definition: transform.h:49
A reference object for pointing into the vector pool. It acts as a pointer for vector pool elements a...
Definition: vector_pool.h:72
mathfu::vec3 position
The position of this Entity.
Definition: transform.h:72
mathfu::mat4 WorldTransform(corgi::EntityRef entity)
Get the world transform for a given Entity.
mathfu::vec3 WorldPosition(corgi::EntityRef entity)
Get the world position for a given Entity.
void PostLoadFixup()
After loading Entities, fix up any of their child links.
#define CORGI_REGISTER_COMPONENT(ComponentType, DataType)
Definition: component_id_lookup.h:48
mathfu::mat4 world_transform
The transform to place the Entity in world space.
Definition: transform.h:81
void RemoveChild(corgi::EntityRef &entity)
Remove an Entity from the intrusive list that it belongs to.
mathfu::quat orientation
The orientation of the Entity.
Definition: transform.h:78
Holds all transform data for Entities, such as position, scale, and orientation.
Definition: transform.h:39
void UpdateChildLinks(corgi::EntityRef &entity)
Take any pending child IDs and set up the child links.
uint16_t ComponentId
This represents the ID of a Component.
Definition: entity_common.h:36
void AddChild(corgi::EntityRef &child, corgi::EntityRef &parent)
Add an Entity as a child to another Entity.
corgi::EntityRef ChildWithComponent(const corgi::EntityRef &entity, corgi::ComponentId id) const
Get the first Entity with a Component, given an ID.
Definition: transform.h:251
mathfu::vec3 scale
The scale of the Entity.
Definition: transform.h:75