Merge pull request #5881 from AndrewMeadows/ik-repairs-004

remove underpose attenuation from IK relaxation step
This commit is contained in:
Howard Stearns 2015-09-22 19:45:40 -07:00
commit a9460b9b41
7 changed files with 34 additions and 35 deletions

View file

@ -635,8 +635,6 @@ void SkeletonModel::computeBoundingShape() {
}
void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) {
const int BALL_SUBDIVISIONS = 10;
auto geometryCache = DependencyManager::get<GeometryCache>();
auto deferredLighting = DependencyManager::get<DeferredLightingEffect>();
// draw a blue sphere at the capsule top point

View file

@ -33,8 +33,10 @@ void AnimInverseKinematics::loadPoses(const AnimPoseVec& poses) {
assert(_skeleton && ((poses.size() == 0) || (_skeleton->getNumJoints() == (int)poses.size())));
if (_skeleton->getNumJoints() == (int)poses.size()) {
_relativePoses = poses;
_accumulators.resize(_relativePoses.size());
} else {
_relativePoses.clear();
_accumulators.clear();
}
}
@ -133,8 +135,8 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(std::vector<IKTarge
computeAbsolutePoses(absolutePoses);
// clear the accumulators before we start the IK solver
for (auto& accumulatorPair: _accumulators) {
accumulatorPair.second.clear();
for (auto& accumulator: _accumulators) {
accumulator.clearAndClean();
}
float largestError = 0.0f;
@ -221,11 +223,11 @@ void AnimInverseKinematics::solveWithCyclicCoordinateDescent(std::vector<IKTarge
++numLoops;
// harvest accumulated rotations and apply the average
for (auto& accumulatorPair: _accumulators) {
RotationAccumulator& accumulator = accumulatorPair.second;
if (accumulator.size() > 0) {
_relativePoses[accumulatorPair.first].rot = accumulator.getAverage();
accumulator.clear();
const int numJoints = (int)_accumulators.size();
for (int i = 0; i < numJoints; ++i) {
if (_accumulators[i].size() > 0) {
_relativePoses[i].rot = _accumulators[i].getAverage();
_accumulators[i].clear();
}
}
@ -299,7 +301,11 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
int numJoints = (int)_relativePoses.size();
for (int i = 0; i < numJoints; ++i) {
float dotSign = copysignf(1.0f, glm::dot(_relativePoses[i].rot, underPoses[i].rot));
_relativePoses[i].rot = glm::normalize(glm::lerp(_relativePoses[i].rot, dotSign * underPoses[i].rot, blend));
if (_accumulators[i].isDirty()) {
_relativePoses[i].rot = glm::normalize(glm::lerp(_relativePoses[i].rot, dotSign * underPoses[i].rot, blend));
} else {
_relativePoses[i].rot = underPoses[i].rot;
}
}
}
return evaluate(animVars, dt, triggersOut);
@ -642,18 +648,3 @@ void AnimInverseKinematics::setSkeletonInternal(AnimSkeleton::ConstPointer skele
clearConstraints();
}
}
void AnimInverseKinematics::relaxTowardDefaults(float dt) {
// NOTE: for now we just use a single relaxation timescale for all joints, but in the future
// we could vary the timescale on a per-joint basis or do other fancy things.
// for each joint: lerp towards the default pose
const float RELAXATION_TIMESCALE = 0.25f;
const float alpha = glm::clamp(dt / RELAXATION_TIMESCALE, 0.0f, 1.0f);
int numJoints = (int)_relativePoses.size();
for (int i = 0; i < numJoints; ++i) {
float dotSign = copysignf(1.0f, glm::dot(_relativePoses[i].rot, _defaultRelativePoses[i].rot));
_relativePoses[i].rot = glm::normalize(glm::lerp(_relativePoses[i].rot, dotSign * _defaultRelativePoses[i].rot, alpha));
}
}

View file

@ -50,8 +50,6 @@ protected:
// for AnimDebugDraw rendering
virtual const AnimPoseVec& getPosesInternal() const override { return _relativePoses; }
void relaxTowardDefaults(float dt);
RotationConstraint* getConstraint(int index);
void clearConstraints();
void initConstraints();
@ -72,7 +70,7 @@ protected:
};
std::map<int, RotationConstraint*> _constraints;
std::map<int, RotationAccumulator> _accumulators; // class-member to exploit temporal coherency
std::vector<RotationAccumulator> _accumulators;
std::vector<IKTargetVar> _targetVarVec;
AnimPoseVec _defaultRelativePoses; // poses of the relaxed state
AnimPoseVec _relativePoses; // current relative poses

View file

@ -11,17 +11,23 @@
#include <glm/gtx/quaternion.hpp>
void RotationAccumulator::add(glm::quat rotation) {
void RotationAccumulator::add(const glm::quat& rotation) {
// make sure both quaternions are on the same hyper-hemisphere before we add them linearly (lerp)
_rotationSum += copysignf(1.0f, glm::dot(_rotationSum, rotation)) * rotation;
++_numRotations;
_isDirty = true;
}
glm::quat RotationAccumulator::getAverage() {
return (_numRotations > 0) ? glm::normalize(_rotationSum) : glm::quat();
}
void RotationAccumulator::clear() {
void RotationAccumulator::clear() {
_rotationSum *= 0.0f;
_numRotations = 0;
}
void RotationAccumulator::clearAndClean() {
clear();
_isDirty = false;
}

View file

@ -14,19 +14,27 @@
class RotationAccumulator {
public:
RotationAccumulator() : _rotationSum(0.0f, 0.0f, 0.0f, 0.0f), _numRotations(0) { }
RotationAccumulator() : _rotationSum(0.0f, 0.0f, 0.0f, 0.0f), _numRotations(0), _isDirty(false) { }
int size() const { return _numRotations; }
void add(glm::quat rotation);
void add(const glm::quat& rotation);
glm::quat getAverage();
/// \return true if any rotations were accumulated
bool isDirty() const { return _isDirty; }
/// \brief clear accumulated rotation but don't change _isDirty
void clear();
/// \brief clear accumulated rotation and set _isDirty to false
void clearAndClean();
private:
glm::quat _rotationSum;
int _numRotations;
bool _isDirty;
};
#endif // hifi_RotationAccumulator_h

View file

@ -1727,9 +1727,7 @@ void Model::segregateMeshGroups() {
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
int shapeID = 0;
for (int i = 0; i < (int)networkMeshes.size(); i++) {
const NetworkMesh& networkMesh = *(networkMeshes.at(i).get());
const FBXMesh& mesh = geometry.meshes.at(i);
const MeshState& state = _meshStates.at(i);
// Create the render payloads
int totalParts = mesh.parts.size();

View file

@ -193,7 +193,7 @@ public:
int getBlendshapeCoefficientsNum() const { return _blendshapeCoefficients.size(); }
float getBlendshapeCoefficient(unsigned int index) const {
return index >= _blendshapeCoefficients.size() ? 0.0f : _blendshapeCoefficients.at(index);
return index >= (unsigned int)_blendshapeCoefficients.size() ? 0.0f : _blendshapeCoefficients.at(index);
}
protected: