Advertisement
Guest User

Untitled

a guest
Feb 8th, 2015
374
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.24 KB | None | 0 0
  1. #ifndef __CONTACT_CONSTRAINT_H__
  2. #define __CONTACT_CONSTRAINT_H__
  3.  
  4. #include "CRigidBody.h"
  5. #include "CContactManifold.h"
  6.  
  7. #define IRPL_BAUMGARTE 0.1f
  8. #define IRPL_ALLOWED_PENETRATION 0.01f
  9.  
  10. class CContactConstraint {
  11. friend class CContactManager;
  12. public:
  13. inline void PreStep(float _fInvDt) {
  14. for (unsigned int I = 0U; I < m_cmContactManifold.m_ui32TotalContacts; ++I) {
  15. CContactManifold::CM_MANIFOLD_CONTACT& cContact = m_cmContactManifold.m_cContacts[I];
  16.  
  17. CVector3 vR0 = cContact.vWorldPointOnA - m_prbRigidBody0->m_vPos;
  18. CVector3 vR1 = cContact.vWorldPointOnB - m_prbRigidBody1->m_vPos;
  19.  
  20. //Normal:
  21. {
  22. float fMassSum = m_prbRigidBody0->InvMass() + m_prbRigidBody1->InvMass();
  23. if (!m_prbRigidBody0->IsStatic()) {
  24. fMassSum += (m_prbRigidBody0->m_mWorldInvInertia * vR0.Cross(cContact.vWorldNormalOnB)).Cross(vR0).Dot(cContact.vWorldNormalOnB);
  25. }
  26. if (!m_prbRigidBody1->IsStatic()) {
  27. fMassSum += (m_prbRigidBody1->m_mWorldInvInertia * vR1.Cross(cContact.vWorldNormalOnB)).Cross(vR1).Dot(cContact.vWorldNormalOnB);
  28. }
  29. cContact.fNormalMass = ML_ONE / fMassSum;
  30. }
  31.  
  32. //Tangents (two).
  33. for (unsigned int J = 0U; J < 2U; ++J) {
  34. //Tangent:
  35. const CVector3& vWorldTangent = cContact.vWorldTangents[J];
  36. float fMassSum = m_prbRigidBody0->InvMass() + m_prbRigidBody1->InvMass();
  37. if (!m_prbRigidBody0->IsStatic()) {
  38. fMassSum += (m_prbRigidBody0->m_mWorldInvInertia * vR0.Cross(vWorldTangent)).Cross(vR0).Dot(vWorldTangent);
  39. }
  40. if (!m_prbRigidBody1->IsStatic()) {
  41. fMassSum += (m_prbRigidBody1->m_mWorldInvInertia * vR1.Cross(vWorldTangent)).Cross(vR1).Dot(vWorldTangent);
  42. }
  43. cContact.fTangentMasses[J] = ML_ONE / fMassSum;
  44. }
  45.  
  46. cContact.fBias = IRPL_BAUMGARTE * _fInvDt * CMathLib::Max(ML_ZERO, cContact.fDistance - IRPL_ALLOWED_PENETRATION);
  47. }
  48. }
  49.  
  50. inline void WarmStart() {
  51. for (unsigned int I = 0U; I < m_cmContactManifold.m_ui32TotalContacts; ++I) {
  52. CContactManifold::CM_MANIFOLD_CONTACT& cContact = m_cmContactManifold.m_cContacts[I];
  53.  
  54. CVector3 vR0 = cContact.vWorldPointOnA - m_prbRigidBody0->m_vPos;
  55. CVector3 vR1 = cContact.vWorldPointOnB - m_prbRigidBody1->m_vPos;
  56.  
  57. CVector3 vP = cContact.vWorldNormalOnB * cContact.fPN;
  58.  
  59. for (unsigned int J = 0U; J < 2U; ++J) {
  60. vP += cContact.vWorldTangents[J] * cContact.fPT[J];
  61. }
  62.  
  63. if (!m_prbRigidBody0->IsStatic()) {
  64. m_prbRigidBody0->m_vLinVel -= vP * m_prbRigidBody0->InvMass();
  65. m_prbRigidBody0->m_vAngVel -= m_prbRigidBody0->m_mWorldInvInertia * vR0.Cross(vP);
  66. }
  67.  
  68. if (!m_prbRigidBody1->IsStatic()) {
  69. m_prbRigidBody1->m_vLinVel += vP * m_prbRigidBody1->InvMass();
  70. m_prbRigidBody1->m_vAngVel += m_prbRigidBody1->m_mWorldInvInertia * vR1.Cross(vP);
  71. }
  72. }
  73. }
  74.  
  75.  
  76. inline void ApplyImpulse() {
  77. for (unsigned int I = 0U; I < m_cmContactManifold.m_ui32TotalContacts; ++I) {
  78. CContactManifold::CM_MANIFOLD_CONTACT& cContact = m_cmContactManifold.m_cContacts[I];
  79.  
  80. CVector3 vR0 = cContact.vWorldPointOnA - m_prbRigidBody0->m_vPos;
  81. CVector3 vR1 = cContact.vWorldPointOnB - m_prbRigidBody1->m_vPos;
  82.  
  83. //Tangents (two):
  84. {
  85. for (unsigned int J = 0U; J < 2U; ++J) {
  86. const CVector3& vTangent = cContact.vWorldTangents[J];
  87.  
  88. CVector3 vVR0 = m_prbRigidBody0->m_vLinVel + m_prbRigidBody0->m_vAngVel.Cross(vR0);
  89. CVector3 vVR1 = m_prbRigidBody1->m_vLinVel + m_prbRigidBody1->m_vAngVel.Cross(vR1);
  90. CVector3 vDV = vVR1 - vVR0;
  91.  
  92. float fLambda = cContact.fTangentMasses[J] * -vDV.Dot(vTangent);
  93. float fMaxLambda = 0.5f * cContact.fPN;
  94.  
  95. float fPT0 = cContact.fPT[J];
  96. cContact.fPT[J] = CMathLib::Clamp(fPT0 + fLambda, -fMaxLambda, fMaxLambda);
  97. fLambda = cContact.fPT[J] - fPT0;
  98. CVector3 vPT = vTangent * fLambda;
  99.  
  100. if (!m_prbRigidBody0->IsStatic()) {
  101. m_prbRigidBody0->m_vLinVel -= vPT * m_prbRigidBody0->InvMass();
  102. m_prbRigidBody0->m_vAngVel -= m_prbRigidBody0->m_mWorldInvInertia * vR0.Cross(vPT);
  103. }
  104.  
  105. if (!m_prbRigidBody1->IsStatic()) {
  106. m_prbRigidBody1->m_vLinVel += vPT * m_prbRigidBody1->InvMass();
  107. m_prbRigidBody1->m_vAngVel += m_prbRigidBody1->m_mWorldInvInertia * vR1.Cross(vPT);
  108. }
  109. }
  110. }
  111.  
  112. //Normal:
  113. {
  114. CVector3 vVR0 = m_prbRigidBody0->m_vLinVel + m_prbRigidBody0->m_vAngVel.Cross(vR0);
  115. CVector3 vVR1 = m_prbRigidBody1->m_vLinVel + m_prbRigidBody1->m_vAngVel.Cross(vR1);
  116. CVector3 vDV = vVR1 - vVR0;
  117. float fLambda = cContact.fNormalMass * -vDV.Dot(cContact.vWorldNormalOnB);
  118. float fPN0 = cContact.fPN;
  119. cContact.fPN = CMathLib::Max(fPN0 + fLambda, ML_ZERO);
  120. fLambda = cContact.fPN - fPN0;
  121. CVector3 vPN = cContact.vWorldNormalOnB * fLambda;
  122.  
  123. if (!m_prbRigidBody0->IsStatic()) {
  124. m_prbRigidBody0->m_vLinVel -= vPN * m_prbRigidBody0->InvMass();
  125. m_prbRigidBody0->m_vAngVel -= m_prbRigidBody0->m_mWorldInvInertia * vR0.Cross(vPN);
  126. }
  127.  
  128. if (!m_prbRigidBody1->IsStatic()) {
  129. m_prbRigidBody1->m_vLinVel += vPN * m_prbRigidBody1->InvMass();
  130. m_prbRigidBody1->m_vAngVel += m_prbRigidBody1->m_mWorldInvInertia * vR1.Cross(vPN);
  131. }
  132. }
  133.  
  134. //Biased Normal:
  135. {
  136. CVector3 vVR0 = m_prbRigidBody0->m_vBiasLinVel + m_prbRigidBody0->m_vBiasAngVel.Cross(vR0);
  137. CVector3 vVR1 = m_prbRigidBody1->m_vBiasLinVel + m_prbRigidBody1->m_vBiasAngVel.Cross(vR1);
  138. CVector3 vDV = vVR1 - vVR0;
  139. float fLambda = cContact.fNormalMass * (-vDV.Dot(cContact.vWorldNormalOnB) + cContact.fBias);
  140. float fPNB0 = cContact.fPNB;
  141. cContact.fPNB = CMathLib::Max(fPNB0 + fLambda, ML_ZERO);
  142. fLambda = cContact.fPNB - fPNB0;
  143.  
  144. CVector3 vPN = cContact.vWorldNormalOnB * fLambda;
  145.  
  146. if (!m_prbRigidBody0->IsStatic()) {
  147. m_prbRigidBody0->m_vBiasLinVel -= vPN * m_prbRigidBody0->InvMass();
  148. m_prbRigidBody0->m_vBiasAngVel -= m_prbRigidBody0->m_mWorldInvInertia * vR0.Cross(vPN);
  149. }
  150.  
  151. if (!m_prbRigidBody1->IsStatic()) {
  152. m_prbRigidBody1->m_vBiasLinVel += vPN * m_prbRigidBody1->InvMass();
  153. m_prbRigidBody1->m_vBiasAngVel += m_prbRigidBody1->m_mWorldInvInertia * vR1.Cross(vPN);
  154. }
  155. }
  156. }
  157. }
  158. //protected :
  159. CRigidBody* m_prbRigidBody0;
  160. CRigidBody* m_prbRigidBody1;
  161. CContactManifold m_cmContactManifold;
  162. };
  163.  
  164.  
  165. #endif //#ifndef __CONTACT_CONSTRAINT_H__
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement