Fixture.hpp
Go to the documentation of this file.
1 /*
2  * Original work Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
3  * Modified work Copyright (c) 2017 Louis Langholtz https://github.com/louis-langholtz/PlayRho
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  */
21 
22 #ifndef PLAYRHO_DYNAMICS_FIXTURE_HPP
23 #define PLAYRHO_DYNAMICS_FIXTURE_HPP
24 
27 
28 #include <PlayRho/Common/Math.hpp>
29 #include <PlayRho/Common/Span.hpp>
35 #include <limits>
36 #include <memory>
37 #include <vector>
38 #include <array>
39 
40 namespace playrho {
41 namespace d2 {
42 
43 class Body;
44 
61 class Fixture
62 {
63 public:
66  NonNull<Body*> GetBody() const noexcept;
67 
70  Shape GetShape() const noexcept;
71 
73  void SetSensor(bool sensor) noexcept;
74 
77  bool IsSensor() const noexcept;
78 
83  void SetFilterData(Filter filter);
84 
86  Filter GetFilterData() const noexcept;
87 
92  void Refilter();
93 
96  void* GetUserData() const noexcept;
97 
100  void SetUserData(void* data) noexcept;
101 
104  AreaDensity GetDensity() const noexcept;
105 
108  Real GetFriction() const noexcept;
109 
111  Real GetRestitution() const noexcept;
112 
116  ChildCounter GetProxyCount() const noexcept;
117 
121  FixtureProxy GetProxy(ChildCounter index) const noexcept;
122 
124  Span<const FixtureProxy> GetProxies() const noexcept;
125 
126 private:
127 
128  friend class FixtureAtty;
129 
130  Fixture() = delete; // explicitly deleted
131 
133  Fixture(const Fixture& other) = delete;
134 
146  Fixture(NonNull<Body*> body, const FixtureConf& def, const Shape& shape):
147  m_body{body},
148  m_userData{def.userData},
149  m_shape{shape},
150  m_filter{def.filter},
151  m_isSensor{def.isSensor}
152  {
153  // Intentionally empty.
154  }
155 
159  ~Fixture()
160  {
161  // Intentionally empty.
162  }
163 
165  union FixtureProxies {
166  FixtureProxies() noexcept: asArray{} {}
167  ~FixtureProxies() noexcept {}
168 
169  std::array<FixtureProxy, 2> asArray;
170  std::unique_ptr<FixtureProxy[]> asBuffer;
171  };
172 
174  void SetProxies(std::unique_ptr<FixtureProxy[]> value, std::size_t count) noexcept;
175 
177  void ResetProxies() noexcept;
178 
179  // Data ordered here for memory compaction.
180 
181  NonNull<Body*> const m_body;
182 
183  void* m_userData = nullptr;
184 
189  Shape m_shape;
190 
191  FixtureProxies m_proxies;
192 
195  ChildCounter m_proxyCount = 0;
196 
197  Filter m_filter;
198 
199  bool m_isSensor = false;
200 };
201 
202 inline Shape Fixture::GetShape() const noexcept
203 {
204  return m_shape;
205 }
206 
207 inline bool Fixture::IsSensor() const noexcept
208 {
209  return m_isSensor;
210 }
211 
212 inline Filter Fixture::GetFilterData() const noexcept
213 {
214  return m_filter;
215 }
216 
217 inline void* Fixture::GetUserData() const noexcept
218 {
219  return m_userData;
220 }
221 
222 inline void Fixture::SetUserData(void* data) noexcept
223 {
224  m_userData = data;
225 }
226 
227 inline NonNull<Body*> Fixture::GetBody() const noexcept
228 {
229  return m_body;
230 }
231 
232 inline ChildCounter Fixture::GetProxyCount() const noexcept
233 {
234  return m_proxyCount;
235 }
236 
237 inline void Fixture::SetFilterData(Filter filter)
238 {
239  m_filter = filter;
240  Refilter();
241 }
242 
244 {
245  const auto ptr = (m_proxyCount <= 2)? &(m_proxies.asArray[0]): m_proxies.asBuffer.get();
246  return Span<const FixtureProxy>(ptr, m_proxyCount);
247 }
248 
249 inline void Fixture::SetProxies(std::unique_ptr<FixtureProxy[]> value, std::size_t count) noexcept
250 {
251  assert(count < std::numeric_limits<ChildCounter>::max());
252  switch (count)
253  {
254  case 2:
255  m_proxies.asArray[1] = value[1];
256  [[fallthrough]];
257  case 1:
258  m_proxies.asArray[0] = value[0];
259  [[fallthrough]];
260  case 0:
261  break;
262  default:
263  m_proxies.asBuffer = std::move(value);
264  break;
265  }
266  m_proxyCount = static_cast<decltype(m_proxyCount)>(count);
267 }
268 
269 inline void Fixture::ResetProxies() noexcept
270 {
271  if (m_proxyCount > 2)
272  {
273  m_proxies.asBuffer.reset();
274  }
275  m_proxyCount = 0;
276 }
277 
278 inline Real Fixture::GetFriction() const noexcept
279 {
280  return playrho::d2::GetFriction(m_shape);
281 }
282 
283 inline Real Fixture::GetRestitution() const noexcept
284 {
285  return playrho::d2::GetRestitution(m_shape);
286 }
287 
288 inline AreaDensity Fixture::GetDensity() const noexcept
289 {
290  return playrho::d2::GetDensity(m_shape);
291 }
292 
293 // Free functions...
294 
300 bool TestPoint(const Fixture& f, Length2 p) noexcept;
301 
307 void SetAwake(const Fixture& f) noexcept;
308 
313 Transformation GetTransformation(const Fixture& f) noexcept;
314 
319 inline bool ShouldCollide(const Fixture& fixtureA, const Fixture& fixtureB) noexcept
320 {
321  return ShouldCollide(fixtureA.GetFilterData(), fixtureB.GetFilterData());
322 }
323 
324 } // namespace d2
325 } // namespace playrho
326 
327 #endif // PLAYRHO_DYNAMICS_FIXTURE_HPP