void OpenCloth::computeForces( float deltaTime ) { for( int i = 0; i < _totalPoints; ++i ) { _forces[i].x = _forces[i].y = _forces[i].z = 0.0f; const cc::Vec3f velocity = getVerletVelocity(_positions[i], _lastPositions[i], deltaTime); if( (i != 0) && (i != _divsX) ) { _forces[i] += _gravity * _mass; } _forces[i] += _damping * velocity; } for( int i = 0; i < _springCount; ++i ) { const cc::Vec3f& p1 = _positions[_springs[i].p1]; const cc::Vec3f& p1Last = _lastPositions[_springs[i].p1]; const cc::Vec3f& p2 = _positions[_springs[i].p2]; const cc::Vec3f& p2Last = _lastPositions[_springs[i].p2]; const cc::Vec3f v1 = getVerletVelocity(p1, p1Last, deltaTime); const cc::Vec3f v2 = getVerletVelocity(p2, p2Last, deltaTime); const cc::Vec3f deltaP = p1 - p2; const cc::Vec3f deltaV = v1 - v2; const float dist = deltaP.magnitude(); const float leftTerm = -_springs[i].ks * (dist - _springs[i].restLength); const float rightTerm = _springs[i].kd * (deltaV.dot(deltaP) / dist); const cc::Vec3f springForce = (leftTerm + rightTerm) * deltaP.normalized(); if( _springs[i].p1 != 0 && _springs[i].p1 != _divsX ) { _forces[_springs[i].p1] += springForce; } if( _springs[i].p2 != 0 && _springs[i].p2 != _divsX ) { _forces[_springs[i].p2] -= springForce; } } }
static void setVec3Length( cc::Vec3f& vec, float newLength ) { const float length = vec.magnitude(); if( length != 0.0f ) { const float factor = newLength / length; vec.x *= factor; vec.y *= factor; vec.z *= factor; } }