VelocityConstraint.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  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  * 1. The origin of this software must not be misrepresented; you must not
12  * claim that you wrote the original software. If you use this software
13  * in a product, an acknowledgment in the product documentation would be
14  * appreciated but is not required.
15  * 2. Altered source versions must be plainly marked as such, and must not be
16  * misrepresented as being the original software.
17  * 3. This notice may not be removed or altered from any source distribution.
18  */
19 
20 #ifndef PLAYRHO_DYNAMICS_CONTACTS_VELOCITYCONSTRAINT_HPP
21 #define PLAYRHO_DYNAMICS_CONTACTS_VELOCITYCONSTRAINT_HPP
22 
23 #include <PlayRho/Common/Math.hpp>
25 
26 namespace playrho {
27 
28 class StepConf;
29 
30 namespace d2 {
31 
32 class WorldManifold;
33 
46 {
47 public:
48 
50  using size_type = std::remove_const<decltype(MaxManifoldPoints)>::type;
51 
53  struct Conf
54  {
55  Real dtRatio = 1;
57  bool blockSolve = true;
58  };
59 
61  static PLAYRHO_CONSTEXPR inline Conf GetDefaultConf() noexcept
62  {
63  return Conf{};
64  }
65 
70  VelocityConstraint() = default;
71 
73  VelocityConstraint(const VelocityConstraint& copy) = default;
74 
76  VelocityConstraint& operator= (const VelocityConstraint& copy) = default;
77 
79  VelocityConstraint(Real friction, Real restitution, LinearVelocity tangentSpeed,
80  const WorldManifold& worldManifold,
81  BodyConstraint& bA,
82  BodyConstraint& bB,
83  Conf conf = GetDefaultConf());
84 
89  UnitVec GetNormal() const noexcept { return m_normal; }
90 
92  UnitVec GetTangent() const noexcept { return GetFwdPerpendicular(m_normal); }
93 
98  size_type GetPointCount() const noexcept { return m_pointCount; }
99 
103  InvMass22 GetK() const noexcept;
104 
108  Mass22 GetNormalMass() const noexcept;
109 
111  Real GetFriction() const noexcept { return m_friction; }
112 
114  Real GetRestitution() const noexcept { return m_restitution; }
115 
117  LinearVelocity GetTangentSpeed() const noexcept { return m_tangentSpeed; }
118 
120  BodyConstraint* GetBodyA() const noexcept { return m_bodyA; }
121 
123  BodyConstraint* GetBodyB() const noexcept { return m_bodyB; }
124 
130  Momentum GetNormalImpulseAtPoint(size_type index) const noexcept;
131 
137  Momentum GetTangentImpulseAtPoint(size_type index) const noexcept;
138 
142  LinearVelocity GetVelocityBiasAtPoint(size_type index) const noexcept;
143 
151  Mass GetNormalMassAtPoint(size_type index) const noexcept;
152 
160  Mass GetTangentMassAtPoint(size_type index) const noexcept;
161 
165  Length2 GetPointRelPosA(size_type index) const noexcept;
166 
170  Length2 GetPointRelPosB(size_type index) const noexcept;
171 
173  void SetNormalImpulseAtPoint(size_type index, Momentum value);
174 
176  void SetTangentImpulseAtPoint(size_type index, Momentum value);
177 
187  struct Point
188  {
191 
194 
197 
200 
204  Mass normalMass = 0_kg;
205 
210 
214  };
215 
224  const Point& GetPointAt(size_type index) const
225  {
226  assert(index < MaxManifoldPoints);
227  return m_points[index];
228  }
229 
230 private:
231 
238  void AddPoint(Momentum normalImpulse, Momentum tangentImpulse,
239  Length2 relA, Length2 relB, Conf conf);
240 
242  void RemovePoint() noexcept;
243 
245  Point GetPoint(Momentum normalImpulse, Momentum tangentImpulse,
246  Length2 relA, Length2 relB, Conf conf) const noexcept;
247 
256  Point& PointAt(size_type index)
257  {
258  assert(index < MaxManifoldPoints);
259  return m_points[index];
260  }
261 
262  Point m_points[MaxManifoldPoints];
263 
264  // K and normalMass fields are only used for the block solver.
265 
270  InvMass3 m_K = InvMass3{};
271 
277  Mass3 m_normalMass = Mass3{};
278 
279  BodyConstraint* m_bodyA = nullptr;
280  BodyConstraint* m_bodyB = nullptr;
281 
282  UnitVec m_normal = GetInvalid<UnitVec>();
283 
285  Real m_friction = GetInvalid<Real>();
286 
287  Real m_restitution = GetInvalid<Real>();
288 
289  LinearVelocity m_tangentSpeed = GetInvalid<decltype(m_tangentSpeed)>();
290 
291  size_type m_pointCount = 0;
292 };
293 
294 inline void VelocityConstraint::RemovePoint() noexcept
295 {
296  assert(m_pointCount > 0);
297  m_points[m_pointCount - 1] = Point{};
298  --m_pointCount;
299 }
300 
301 inline InvMass22 VelocityConstraint::GetK() const noexcept
302 {
303  return InvMass22{
304  InvMass2{get<0>(m_K), get<2>(m_K)},
305  InvMass2{get<2>(m_K), get<1>(m_K)}
306  };
307 }
308 
310 {
311  return Mass22{
312  Mass2{get<0>(m_normalMass), get<2>(m_normalMass)},
313  Mass2{get<2>(m_normalMass), get<1>(m_normalMass)}
314  };
315 }
316 
318 {
319  return GetPointAt(index).relA;
320 }
321 
323 {
324  return GetPointAt(index).relB;
325 }
326 
328 {
329  return GetPointAt(index).velocityBias;
330 }
331 
333 {
334  return GetPointAt(index).normalMass;
335 }
336 
338 {
339  return GetPointAt(index).tangentMass;
340 }
341 
343 {
344  return GetPointAt(index).normalImpulse;
345 }
346 
348 {
349  return GetPointAt(index).tangentImpulse;
350 }
351 
353 {
354  PointAt(index).normalImpulse = value;
355 }
356 
358 {
359  PointAt(index).tangentImpulse = value;
360 }
361 
362 // Free functions...
363 
367 
371 
376 inline UnitVec GetNormal(const VelocityConstraint& vc) noexcept
377 {
378  return vc.GetNormal();
379 }
380 
382 inline UnitVec GetTangent(const VelocityConstraint& vc) noexcept
383 {
384  return vc.GetTangent();
385 }
386 
388 inline InvMass GetInvMass(const VelocityConstraint& vc) noexcept
389 {
390  return vc.GetBodyA()->GetInvMass() + vc.GetBodyB()->GetInvMass();
391 }
392 
396 {
397  return vc.GetPointRelPosA(index);
398 }
399 
403 {
404  return vc.GetPointRelPosB(index);
405 }
406 
409 {
410  return vc.GetVelocityBiasAtPoint(index);
411 }
412 
416 {
417  return vc.GetNormalMassAtPoint(index);
418 }
419 
423 {
424  return vc.GetTangentMassAtPoint(index);
425 }
426 
430 {
431  return vc.GetNormalImpulseAtPoint(index);
432 }
433 
437 {
438  return vc.GetTangentImpulseAtPoint(index);
439 }
440 
443 {
445 }
446 
449 {
451 }
452 
455 {
456  vc.SetNormalImpulseAtPoint(index, value);
457 }
458 
461 {
462  vc.SetTangentImpulseAtPoint(index, value);
463 }
464 
466 inline void SetNormalImpulses(VelocityConstraint& vc, const Momentum2 impulses)
467 {
468  SetNormalImpulseAtPoint(vc, 0, impulses[0]);
469  SetNormalImpulseAtPoint(vc, 1, impulses[1]);
470 }
471 
473 inline void SetTangentImpulses(VelocityConstraint& vc, const Momentum2 impulses)
474 {
475  SetTangentImpulseAtPoint(vc, 0, impulses[0]);
476  SetTangentImpulseAtPoint(vc, 1, impulses[1]);
477 }
478 
479 } // namespace d2
480 } // namespace playrho
481 
482 #endif // PLAYRHO_DYNAMICS_CONTACTS_VELOCITYCONSTRAINT_HPP