mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 22:56:29 +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 <VerletCapsuleShape.h>
|
||||||
#include <VerletSphereShape.h>
|
#include <VerletSphereShape.h>
|
||||||
#include <DistanceConstraint.h>
|
|
||||||
#include <FixedConstraint.h>
|
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "Avatar.h"
|
#include "Avatar.h"
|
||||||
#include "Hand.h"
|
#include "Hand.h"
|
||||||
#include "Menu.h"
|
#include "Menu.h"
|
||||||
#include "MuscleConstraint.h"
|
|
||||||
#include "SkeletonModel.h"
|
#include "SkeletonModel.h"
|
||||||
#include "SkeletonRagdoll.h"
|
#include "SkeletonRagdoll.h"
|
||||||
|
|
||||||
|
@ -606,6 +603,7 @@ void SkeletonModel::buildShapes() {
|
||||||
|
|
||||||
float uniformScale = extractUniformScale(_scale);
|
float uniformScale = extractUniformScale(_scale);
|
||||||
const int numStates = _jointStates.size();
|
const int numStates = _jointStates.size();
|
||||||
|
float totalMass = 0.0f;
|
||||||
for (int i = 0; i < numStates; i++) {
|
for (int i = 0; i < numStates; i++) {
|
||||||
JointState& state = _jointStates[i];
|
JointState& state = _jointStates[i];
|
||||||
const FBXJoint& joint = state.getFBXJoint();
|
const FBXJoint& joint = state.getFBXJoint();
|
||||||
|
@ -624,26 +622,31 @@ void SkeletonModel::buildShapes() {
|
||||||
if (type == Shape::SPHERE_SHAPE) {
|
if (type == Shape::SPHERE_SHAPE) {
|
||||||
shape = new VerletSphereShape(radius, &(points[i]));
|
shape = new VerletSphereShape(radius, &(points[i]));
|
||||||
shape->setEntity(this);
|
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) {
|
} else if (type == Shape::CAPSULE_SHAPE) {
|
||||||
assert(parentIndex != -1);
|
assert(parentIndex != -1);
|
||||||
shape = new VerletCapsuleShape(radius, &(points[parentIndex]), &(points[i]));
|
shape = new VerletCapsuleShape(radius, &(points[parentIndex]), &(points[i]));
|
||||||
shape->setEntity(this);
|
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) {
|
if (parentIndex != -1) {
|
||||||
// always disable collisions between joint and its parent
|
// always disable collisions between joint and its parent
|
||||||
if (shape) {
|
if (shape) {
|
||||||
disableCollisions(i, parentIndex);
|
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);
|
_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.
|
// This method moves the shapes to their default positions in Model frame.
|
||||||
computeBoundingShape(geometry);
|
computeBoundingShape(geometry);
|
||||||
|
|
||||||
|
|
|
@ -70,10 +70,7 @@ void SkeletonRagdoll::buildConstraints() {
|
||||||
for (int i = 0; i < numPoints; ++i) {
|
for (int i = 0; i < numPoints; ++i) {
|
||||||
const JointState& state = jointStates.at(i);
|
const JointState& state = jointStates.at(i);
|
||||||
int parentIndex = state.getParentIndex();
|
int parentIndex = state.getParentIndex();
|
||||||
if (parentIndex == -1) {
|
if (parentIndex != -1) {
|
||||||
FixedConstraint* anchor = new FixedConstraint(&_translationInSimulationFrame, &(_points[i]));
|
|
||||||
_fixedConstraints.push_back(anchor);
|
|
||||||
} else {
|
|
||||||
DistanceConstraint* bone = new DistanceConstraint(&(_points[i]), &(_points[parentIndex]));
|
DistanceConstraint* bone = new DistanceConstraint(&(_points[i]), &(_points[parentIndex]));
|
||||||
bone->setDistance(state.getDistanceToParent());
|
bone->setDistance(state.getDistanceToParent());
|
||||||
_boneConstraints.push_back(bone);
|
_boneConstraints.push_back(bone);
|
||||||
|
|
|
@ -163,10 +163,10 @@ bool PhysicsSimulation::addRagdoll(Ragdoll* doll) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSimulation::removeRagdoll(Ragdoll* doll) {
|
void PhysicsSimulation::removeRagdoll(Ragdoll* doll) {
|
||||||
int numDolls = _otherRagdolls.size();
|
if (!doll || doll->_simulation != this) {
|
||||||
if (doll->_simulation != this) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int numDolls = _otherRagdolls.size();
|
||||||
for (int i = 0; i < numDolls; ++i) {
|
for (int i = 0; i < numDolls; ++i) {
|
||||||
if (doll == _otherRagdolls[i]) {
|
if (doll == _otherRagdolls[i]) {
|
||||||
if (i == numDolls - 1) {
|
if (i == numDolls - 1) {
|
||||||
|
@ -205,10 +205,11 @@ void PhysicsSimulation::stepForward(float deltaTime, float minError, int maxIter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool collidedWithOtherRagdoll = false;
|
||||||
int iterations = 0;
|
int iterations = 0;
|
||||||
float error = 0.0f;
|
float error = 0.0f;
|
||||||
do {
|
do {
|
||||||
computeCollisions();
|
collidedWithOtherRagdoll = computeCollisions() || collidedWithOtherRagdoll;
|
||||||
updateContacts();
|
updateContacts();
|
||||||
resolveCollisions();
|
resolveCollisions();
|
||||||
|
|
||||||
|
@ -225,6 +226,14 @@ void PhysicsSimulation::stepForward(float deltaTime, float minError, int maxIter
|
||||||
now = usecTimestampNow();
|
now = usecTimestampNow();
|
||||||
} while (_collisions.size() != 0 && (iterations < maxIterations) && (error > minError) && (now < expiry));
|
} 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();
|
pruneContacts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +246,7 @@ void PhysicsSimulation::moveRagdolls(float deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSimulation::computeCollisions() {
|
bool PhysicsSimulation::computeCollisions() {
|
||||||
PerformanceTimer perfTimer("collide");
|
PerformanceTimer perfTimer("collide");
|
||||||
_collisions.clear();
|
_collisions.clear();
|
||||||
|
|
||||||
|
@ -258,11 +267,13 @@ void PhysicsSimulation::computeCollisions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// collide main ragdoll with others
|
// collide main ragdoll with others
|
||||||
|
bool otherCollisions = false;
|
||||||
int numEntities = _otherEntities.size();
|
int numEntities = _otherEntities.size();
|
||||||
for (int i = 0; i < numEntities; ++i) {
|
for (int i = 0; i < numEntities; ++i) {
|
||||||
const QVector<Shape*> otherShapes = _otherEntities.at(i)->getShapes();
|
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() {
|
void PhysicsSimulation::resolveCollisions() {
|
||||||
|
|
|
@ -53,9 +53,11 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void moveRagdolls(float deltaTime);
|
void moveRagdolls(float deltaTime);
|
||||||
void computeCollisions();
|
|
||||||
void resolveCollisions();
|
|
||||||
|
|
||||||
|
/// \return true if main ragdoll collides with other avatar
|
||||||
|
bool computeCollisions();
|
||||||
|
|
||||||
|
void resolveCollisions();
|
||||||
void enforceContacts();
|
void enforceContacts();
|
||||||
void applyContactFriction();
|
void applyContactFriction();
|
||||||
void updateContacts();
|
void updateContacts();
|
||||||
|
|
Loading…
Reference in a new issue