mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 18:35:32 +02:00
compute and store Ragdoll::_accumulatedMovement
This commit is contained in:
parent
3e2095332f
commit
7e7978de1a
4 changed files with 34 additions and 21 deletions
|
@ -14,14 +14,11 @@
|
|||
|
||||
#include <VerletCapsuleShape.h>
|
||||
#include <VerletSphereShape.h>
|
||||
#include <DistanceConstraint.h>
|
||||
#include <FixedConstraint.h>
|
||||
|
||||
#include "Application.h"
|
||||
#include "Avatar.h"
|
||||
#include "Hand.h"
|
||||
#include "Menu.h"
|
||||
#include "MuscleConstraint.h"
|
||||
#include "SkeletonModel.h"
|
||||
#include "SkeletonRagdoll.h"
|
||||
|
||||
|
@ -606,6 +603,7 @@ void SkeletonModel::buildShapes() {
|
|||
|
||||
float uniformScale = extractUniformScale(_scale);
|
||||
const int numStates = _jointStates.size();
|
||||
float totalMass = 0.0f;
|
||||
for (int i = 0; i < numStates; i++) {
|
||||
JointState& state = _jointStates[i];
|
||||
const FBXJoint& joint = state.getFBXJoint();
|
||||
|
@ -624,26 +622,31 @@ void SkeletonModel::buildShapes() {
|
|||
if (type == Shape::SPHERE_SHAPE) {
|
||||
shape = new VerletSphereShape(radius, &(points[i]));
|
||||
shape->setEntity(this);
|
||||
points[i].setMass(massScale * glm::max(MIN_JOINT_MASS, DENSITY_OF_WATER * shape->getVolume()));
|
||||
float mass = massScale * glm::max(MIN_JOINT_MASS, DENSITY_OF_WATER * shape->getVolume());
|
||||
points[i].setMass(mass);
|
||||
totalMass += mass;
|
||||
} else if (type == Shape::CAPSULE_SHAPE) {
|
||||
assert(parentIndex != -1);
|
||||
shape = new VerletCapsuleShape(radius, &(points[parentIndex]), &(points[i]));
|
||||
shape->setEntity(this);
|
||||
points[i].setMass(massScale * glm::max(MIN_JOINT_MASS, DENSITY_OF_WATER * shape->getVolume()));
|
||||
float mass = massScale * glm::max(MIN_JOINT_MASS, DENSITY_OF_WATER * shape->getVolume());
|
||||
points[i].setMass(mass);
|
||||
totalMass += mass;
|
||||
}
|
||||
if (parentIndex != -1) {
|
||||
// always disable collisions between joint and its parent
|
||||
if (shape) {
|
||||
disableCollisions(i, parentIndex);
|
||||
}
|
||||
} else {
|
||||
// give the base joint a very large mass since it doesn't actually move
|
||||
// in the local-frame simulation (it defines the origin)
|
||||
points[i].setMass(VERY_BIG_MASS);
|
||||
}
|
||||
}
|
||||
_shapes.push_back(shape);
|
||||
}
|
||||
|
||||
// set the mass of the root
|
||||
if (numStates > 0) {
|
||||
points[0].setMass(totalMass);
|
||||
}
|
||||
|
||||
// This method moves the shapes to their default positions in Model frame.
|
||||
computeBoundingShape(geometry);
|
||||
|
||||
|
|
|
@ -70,10 +70,7 @@ void SkeletonRagdoll::buildConstraints() {
|
|||
for (int i = 0; i < numPoints; ++i) {
|
||||
const JointState& state = jointStates.at(i);
|
||||
int parentIndex = state.getParentIndex();
|
||||
if (parentIndex == -1) {
|
||||
FixedConstraint* anchor = new FixedConstraint(&_translationInSimulationFrame, &(_points[i]));
|
||||
_fixedConstraints.push_back(anchor);
|
||||
} else {
|
||||
if (parentIndex != -1) {
|
||||
DistanceConstraint* bone = new DistanceConstraint(&(_points[i]), &(_points[parentIndex]));
|
||||
bone->setDistance(state.getDistanceToParent());
|
||||
_boneConstraints.push_back(bone);
|
||||
|
|
|
@ -163,10 +163,10 @@ bool PhysicsSimulation::addRagdoll(Ragdoll* doll) {
|
|||
}
|
||||
|
||||
void PhysicsSimulation::removeRagdoll(Ragdoll* doll) {
|
||||
int numDolls = _otherRagdolls.size();
|
||||
if (doll->_simulation != this) {
|
||||
if (!doll || doll->_simulation != this) {
|
||||
return;
|
||||
}
|
||||
int numDolls = _otherRagdolls.size();
|
||||
for (int i = 0; i < numDolls; ++i) {
|
||||
if (doll == _otherRagdolls[i]) {
|
||||
if (i == numDolls - 1) {
|
||||
|
@ -205,10 +205,11 @@ void PhysicsSimulation::stepForward(float deltaTime, float minError, int maxIter
|
|||
}
|
||||
}
|
||||
|
||||
bool collidedWithOtherRagdoll = false;
|
||||
int iterations = 0;
|
||||
float error = 0.0f;
|
||||
do {
|
||||
computeCollisions();
|
||||
collidedWithOtherRagdoll = computeCollisions() || collidedWithOtherRagdoll;
|
||||
updateContacts();
|
||||
resolveCollisions();
|
||||
|
||||
|
@ -225,6 +226,14 @@ void PhysicsSimulation::stepForward(float deltaTime, float minError, int maxIter
|
|||
now = usecTimestampNow();
|
||||
} while (_collisions.size() != 0 && (iterations < maxIterations) && (error > minError) && (now < expiry));
|
||||
|
||||
// the collisions may have moved the main ragdoll from the simulation center
|
||||
// so we remove this offset (potentially storing it as movement of the Ragdoll owner)
|
||||
_ragdoll->removeRootOffset(collidedWithOtherRagdoll);
|
||||
|
||||
// also remove any offsets from the other ragdolls
|
||||
for (int i = 0; i < numDolls; ++i) {
|
||||
_otherRagdolls[i]->removeRootOffset(false);
|
||||
}
|
||||
pruneContacts();
|
||||
}
|
||||
|
||||
|
@ -237,7 +246,7 @@ void PhysicsSimulation::moveRagdolls(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
void PhysicsSimulation::computeCollisions() {
|
||||
bool PhysicsSimulation::computeCollisions() {
|
||||
PerformanceTimer perfTimer("collide");
|
||||
_collisions.clear();
|
||||
|
||||
|
@ -258,11 +267,13 @@ void PhysicsSimulation::computeCollisions() {
|
|||
}
|
||||
|
||||
// collide main ragdoll with others
|
||||
bool otherCollisions = false;
|
||||
int numEntities = _otherEntities.size();
|
||||
for (int i = 0; i < numEntities; ++i) {
|
||||
const QVector<Shape*> otherShapes = _otherEntities.at(i)->getShapes();
|
||||
ShapeCollider::collideShapesWithShapes(shapes, otherShapes, _collisions);
|
||||
otherCollisions = ShapeCollider::collideShapesWithShapes(shapes, otherShapes, _collisions) || otherCollisions;
|
||||
}
|
||||
return otherCollisions;
|
||||
}
|
||||
|
||||
void PhysicsSimulation::resolveCollisions() {
|
||||
|
|
|
@ -53,9 +53,11 @@ public:
|
|||
|
||||
protected:
|
||||
void moveRagdolls(float deltaTime);
|
||||
void computeCollisions();
|
||||
void resolveCollisions();
|
||||
|
||||
/// \return true if main ragdoll collides with other avatar
|
||||
bool computeCollisions();
|
||||
|
||||
void resolveCollisions();
|
||||
void enforceContacts();
|
||||
void applyContactFriction();
|
||||
void updateContacts();
|
||||
|
|
Loading…
Reference in a new issue