void Solver::setUpBodyMatricies(DMatrix& s, DMatrix& u, DMatrix& s_next, DMatrix& u_next, DMatrix& S, DMatrix& MInverse, DMatrix& Fext) { for (int i = 0; i<m_rigidBodies.size(); i++) { const RigidBody_c* rb = m_rigidBodies[i]; s.Set(i * 7 + 0) = rb->m_position.x; s.Set(i * 7 + 1) = rb->m_position.y; s.Set(i * 7 + 2) = rb->m_position.z; s.Set(i * 7 + 3) = rb->m_orientation.w; s.Set(i * 7 + 4) = rb->m_orientation.x; s.Set(i * 7 + 5) = rb->m_orientation.y; s.Set(i * 7 + 6) = rb->m_orientation.z; u.Set(i * 6 + 0) = rb->m_linearVelocity.x; u.Set(i * 6 + 1) = rb->m_linearVelocity.y; u.Set(i * 6 + 2) = rb->m_linearVelocity.z; u.Set(i * 6 + 3) = rb->m_angularVelocity.x; u.Set(i * 6 + 4) = rb->m_angularVelocity.y; u.Set(i * 6 + 5) = rb->m_angularVelocity.z; const XMFLOAT4& q = rb->m_orientation; DMatrix Q(4, 3); Q.Set(0, 0) = -q.x; Q.Set(0, 1) = -q.y; Q.Set(0, 2) = -q.z; Q.Set(1, 0) = q.w; Q.Set(1, 1) = q.z; Q.Set(1, 2) = -q.y; Q.Set(2, 0) = -q.z; Q.Set(2, 1) = q.w; Q.Set(2, 2) = q.x; Q.Set(3, 0) = q.y; Q.Set(3, 1) = -q.x; Q.Set(3, 2) = q.w; Q = Q * 0.5f; DMatrix Idenity(3, 3); Idenity.SetToZero(); Idenity.Set(0, 0) = Idenity.Set(1, 1) = Idenity.Set(2, 2) = 1.0f; S.SetSubMatrix(i * 7 + 0, i * 6 + 0, Idenity); S.SetSubMatrix(i * 7 + 3, i * 6 + 3, Q); DMatrix M(3, 3); M.Set(0, 0) = M.Set(1, 1) = M.Set(2, 2) = rb->m_invMass; const XMFLOAT3X3& dxm = rb->CreateWorldII(); DMatrix I(3, 3); I.Set(0, 0) = dxm._11; I.Set(1, 0) = dxm._12; I.Set(2, 0) = dxm._13; I.Set(0, 1) = dxm._21; I.Set(1, 1) = dxm._22; I.Set(2, 1) = dxm._23; I.Set(0, 2) = dxm._31; I.Set(1, 2) = dxm._32; I.Set(2, 2) = dxm._33; /*if (rb->m_invMass == 0.0f) { M.Set(0, 0) = M.Set(1, 1) = M.Set(2, 2) = 0.01f; I.Set(0, 0) = 0.01f; I.Set(1, 0) = dxm._12; I.Set(2, 0) = dxm._13; I.Set(0, 1) = dxm._21; I.Set(1, 1) = 0.01f ; I.Set(2, 1) = dxm._23; I.Set(0, 2) = dxm._31; I.Set(1, 2) = dxm._32; I.Set(2, 2) = 0.01f; }*/ MInverse.SetSubMatrix(i * 6, i * 6, M); MInverse.SetSubMatrix(i * 6 + 3, i * 6 + 3, I); DMatrix F(3, 1); F.Set(0, 0) = rb->m_force.x; F.Set(1, 0) = rb->m_force.y; F.Set(2, 0) = rb->m_force.z; XMFLOAT3 rF = rb->m_torque; DMatrix T(3, 1); T.Set(0, 0) = rF.x; T.Set(1, 0) = rF.y; T.Set(2, 0) = rF.z; Fext.SetSubMatrix(i * 6, 0, F); Fext.SetSubMatrix(i * 6 + 3, 0, T); } }
void Solver::GaussSeidelLCP(const DMatrix& J, const DMatrix& W_Jt, const DMatrix& b, DMatrix& V, DMatrix& x, const DMatrix* lo, const DMatrix* hi) { int maxIterations = 20; x.SetToZero(); const int n = x.GetNumRows(); DMatrix aDiag = J.diagonalProduct(W_Jt); float xi_prime; float xi; float delta_xi; while (maxIterations--) { for (int i = 0; i < n; i++) { // xi' = xi + 1/Aii (bi - Ai*x) // xi' = xi + 1/Aii (bi - J*Vi) xi = x.Get(i); xi_prime = xi; assert(aDiag.Get(i) != 0.0f); xi_prime += 1 / aDiag.Get(i) * (b.Get(i) - J.rowProduct(V, i).Get(0));// A.rowProduct(x, i).Get(0));// if (lo && (xi_prime < lo->Get(i))) { xi_prime = lo->Get(i); } if (hi && xi_prime > hi->Get(i)) { xi_prime = hi->Get(i); } // Update X-component with new result x.Set(i) = xi_prime; // Fix V component with latest X result by using delta between current // and previous result for the X component. // V' = V + W*Jt * delta_x float delta_xi = xi_prime - xi; const DMatrix& V_adjust = W_Jt.colProduct(delta_xi, i); V.AddSubMatrix(0, 0, V_adjust); } } }