mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 18:13:29 +02:00
parent-relative linear slaving of verlet shapes
This commit is contained in:
parent
72c7498454
commit
559188cace
1 changed files with 44 additions and 13 deletions
|
@ -533,6 +533,7 @@ void SkeletonModel::buildRagdollConstraints() {
|
|||
_ragdollConstraints.push_back(anchor);
|
||||
} else {
|
||||
DistanceConstraint* bone = new DistanceConstraint(&(_ragdollPoints[i]), &(_ragdollPoints[parentIndex]));
|
||||
bone->setDistance(state.getDistanceToParent());
|
||||
_ragdollConstraints.push_back(bone);
|
||||
families.insert(parentIndex, i);
|
||||
}
|
||||
|
@ -597,11 +598,7 @@ void SkeletonModel::updateVisibleJointStates() {
|
|||
|
||||
// virtual
|
||||
void SkeletonModel::stepRagdollForward(float deltaTime) {
|
||||
// NOTE: increasing this timescale reduces vibrations in the ragdoll solution and reduces tunneling
|
||||
// but makes the shapes slower to follow the body (introduces lag).
|
||||
const float RAGDOLL_FOLLOWS_JOINTS_TIMESCALE = 0.05f;
|
||||
float fraction = glm::clamp(deltaTime / RAGDOLL_FOLLOWS_JOINTS_TIMESCALE, 0.0f, 1.0f);
|
||||
moveShapesTowardJoints(fraction);
|
||||
moveShapesTowardJoints(deltaTime);
|
||||
}
|
||||
|
||||
float DENSITY_OF_WATER = 1000.0f; // kg/m^3
|
||||
|
@ -676,17 +673,51 @@ void SkeletonModel::buildShapes() {
|
|||
enforceRagdollConstraints();
|
||||
}
|
||||
|
||||
void SkeletonModel::moveShapesTowardJoints(float fraction) {
|
||||
void SkeletonModel::moveShapesTowardJoints(float deltaTime) {
|
||||
const int numStates = _jointStates.size();
|
||||
assert(_jointStates.size() == _ragdollPoints.size());
|
||||
assert(fraction >= 0.0f && fraction <= 1.0f);
|
||||
if (_ragdollPoints.size() == numStates) {
|
||||
float oneMinusFraction = 1.0f - fraction;
|
||||
int numJoints = _jointStates.size();
|
||||
for (int i = 0; i < numJoints; ++i) {
|
||||
_ragdollPoints[i]._lastPosition = _ragdollPoints[i]._position;
|
||||
_ragdollPoints[i]._position = oneMinusFraction * _ragdollPoints[i]._position + fraction * _jointStates.at(i).getPosition();
|
||||
if (_ragdollPoints.size() != numStates) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float RAGDOLL_FOLLOWS_JOINTS_TIMESCALE = 0.05f;
|
||||
float fraction = glm::clamp(deltaTime / RAGDOLL_FOLLOWS_JOINTS_TIMESCALE, 0.0f, 1.0f);
|
||||
|
||||
// SIMPLE LINEAR_SLAVING -- KEEP this implementation for reference
|
||||
//float oneMinusFraction = 1.0f - fraction;
|
||||
//for (int i = 0; i < numStates; ++i) {
|
||||
// _ragdollPoints[i]._lastPosition = _ragdollPoints[i]._position;
|
||||
// _ragdollPoints[i]._position = oneMinusFraction * _ragdollPoints[i]._position + fraction * _jointStates.at(i).getPosition();
|
||||
//}
|
||||
// LINEAR_SLAVING -- KEEP
|
||||
|
||||
// parent-relative linear slaving
|
||||
for (int i = 0; i < numStates; ++i) {
|
||||
JointState& state = _jointStates[i];
|
||||
_ragdollPoints[i]._lastPosition = _ragdollPoints.at(i)._position;
|
||||
|
||||
int p = state.getParentIndex();
|
||||
if (p == -1) {
|
||||
_ragdollPoints[i]._position = glm::vec3(0.0f);
|
||||
continue;
|
||||
}
|
||||
if (state.getDistanceToParent() < EPSILON) {
|
||||
_ragdollPoints[i]._position = _ragdollPoints.at(p)._position;
|
||||
continue;
|
||||
}
|
||||
|
||||
const JointState& parentState = _jointStates.at(p);
|
||||
glm::vec3 targetBone = state.getPosition() - parentState.getPosition();
|
||||
glm::vec3 bone = _ragdollPoints.at(i)._lastPosition - _ragdollPoints.at(p)._lastPosition;
|
||||
|
||||
glm::vec3 newBone = (1.0f - fraction) * bone + fraction * targetBone;
|
||||
float boneLength = glm::length(newBone);
|
||||
if (boneLength > EPSILON) {
|
||||
// slam newBone's lenght to that of the joint, which helps maintain distance constraints
|
||||
newBone *= state.getDistanceToParent() / boneLength;
|
||||
}
|
||||
// we set the new position relative to parent
|
||||
_ragdollPoints[i]._position = _ragdollPoints.at(p)._position + newBone;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue