History

Merge branch 'master' into ajt/new-anim-system

Anthony J. Thibault committed 11 years ago

Commit de31b922 parents 46b3a7f d55c92711 files · +177 −77Browse files

Showing the changes to interface/src/avatar/SkeletonModel.cpp (1 of 11 files). Show all

Unified · Split

interface/src/avatar/SkeletonModel.cpp+83−29
@@ -86,7 +86,7 @@ void SkeletonModel::initJointStates(QVector<JointState> states) { · 85 unmodified lines
8686 _rig->updateJointState(i, rootTransform);
8787 }
8888
89− buildShapes();
89+ computeBoundingShape();
9090
9191 Extents meshExtents = getMeshExtents();
9292 _headClipDistance = -(meshExtents.minimum.z / _scale.z - _defaultEyeModelPosition.z);
@@ -248,6 +248,7 @@ void SkeletonModel::applyHandPosition(int jointIndex, const glm::vec3& position) · 155 unmodified lines
248248 rotationBetween(handRotation * glm::vec3(-sign, 0.0f, 0.0f), forearmVector),
249249 true, PALM_PRIORITY);
250250 }
251+
251252 void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) {
252253 if (jointIndex == -1 || jointIndex >= _rig->getJointStateCount()) {
253254 return;
@@ -261,9 +262,7 @@ void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) { · 7 unmodified lines
261262 // the palm's position must be transformed into the model-frame
262263 glm::quat inverseRotation = glm::inverse(_rotation);
263264 glm::vec3 palmPosition = inverseRotation * (palm.getPosition() - _translation);
264−
265− // the palm's "raw" rotation is already in the model-frame
266− glm::quat palmRotation = palm.getRawRotation();
265+ glm::quat palmRotation = inverseRotation * palm.getRotation();
267266
268267 inverseKinematics(jointIndex, palmPosition, palmRotation, PALM_PRIORITY);
269268 }
@@ -346,9 +345,9 @@ void SkeletonModel::renderOrientationDirections(gpu::Batch& batch, int jointInde · 76 unmodified lines
346345 }
347346 OrientationLineIDs& jointLineIDs = _jointOrientationLines[jointIndex];
348347
349− glm::vec3 pRight = position + orientation * IDENTITY_RIGHT * size;
350− glm::vec3 pUp = position + orientation * IDENTITY_UP * size;
351− glm::vec3 pFront = position + orientation * IDENTITY_FRONT * size;
348+ glm::vec3 pRight = position + orientation * IDENTITY_RIGHT * size;
349+ glm::vec3 pUp = position + orientation * IDENTITY_UP * size;
350+ glm::vec3 pFront = position + orientation * IDENTITY_FRONT * size;
352351
353352 glm::vec3 red(1.0f, 0.0f, 0.0f);
354353 geometryCache->renderLine(batch, position, pRight, red, jointLineIDs._right);
@@ -466,7 +465,7 @@ float MIN_JOINT_MASS = 1.0f; · 111 unmodified lines
466465 float VERY_BIG_MASS = 1.0e6f;
467466
468467 // virtual
469−void SkeletonModel::buildShapes() {
468+void SkeletonModel::computeBoundingShape() {
470469 if (_geometry == NULL || _rig->jointStatesEmpty()) {
471470 return;
472471 }
@@ -476,36 +475,86 @@ void SkeletonModel::buildShapes() { · 3 unmodified lines
476475 // rootJointIndex == -1 if the avatar model has no skeleton
477476 return;
478477 }
479− computeBoundingShape(geometry);
480−}
481478
482−void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) {
483− // compute default joint transforms
484− int numStates = _rig->getJointStateCount();
485− QVector<glm::mat4> transforms;
486− transforms.fill(glm::mat4(), numStates);
479+ // BOUNDING SHAPE HACK: before we measure the bounds of the joints we use IK to put the
480+ // hands and feet into positions that are more correct than the default pose.
481+
482+ // Measure limb lengths so we can specify IK targets that will pull hands and feet tight to body
483+ QVector<QString> endEffectors;
484+ endEffectors.push_back("RightHand");
485+ endEffectors.push_back("LeftHand");
486+ endEffectors.push_back("RightFoot");
487+ endEffectors.push_back("LeftFoot");
488+
489+ QVector<QString> baseJoints;
490+ baseJoints.push_back("RightArm");
491+ baseJoints.push_back("LeftArm");
492+ baseJoints.push_back("RightUpLeg");
493+ baseJoints.push_back("LeftUpLeg");
494+
495+ for (int i = 0; i < endEffectors.size(); ++i) {
496+ QString tipName = endEffectors[i];
497+ QString baseName = baseJoints[i];
498+ float limbLength = 0.0f;
499+ int tipIndex = _rig->indexOfJoint(tipName);
500+ if (tipIndex == -1) {
501+ continue;
502+ }
503+ // save tip's relative rotation for later
504+ glm::quat tipRotation = _rig->getJointState(tipIndex).getRotationInConstrainedFrame();
505+
506+ // IK on each endpoint
507+ int jointIndex = tipIndex;
508+ QVector<int> freeLineage;
509+ float priority = 1.0f;
510+ while (jointIndex > -1) {
511+ JointState limbJoint = _rig->getJointState(jointIndex);
512+ freeLineage.push_back(jointIndex);
513+ if (limbJoint.getName() == baseName) {
514+ glm::vec3 targetPosition = limbJoint.getPosition() - glm::vec3(0.0f, 1.5f * limbLength, 0.0f);
515+ // do IK a few times to make sure the endpoint gets close to its target
516+ for (int j = 0; j < 5; ++j) {
517+ _rig->inverseKinematics(tipIndex,
518+ targetPosition,
519+ glm::quat(),
520+ priority,
521+ freeLineage,
522+ glm::mat4());
523+ }
524+ break;
525+ }
526+ limbLength += limbJoint.getDistanceToParent();
527+ jointIndex = limbJoint.getParentIndex();
528+ }
529+
530+ // since this IK target is totally bogus we restore the tip's relative rotation
531+ _rig->setJointRotationInConstrainedFrame(tipIndex, tipRotation, priority);
532+ }
533+
534+ // recompute all joint model-frame transforms
535+ glm::mat4 rootTransform = glm::scale(_scale) * glm::translate(_offset) * geometry.offset;
536+ for (int i = 0; i < _rig->getJointStateCount(); i++) {
537+ _rig->updateJointState(i, rootTransform);
538+ }
539+ // END BOUNDING SHAPE HACK
487540
488541 // compute bounding box that encloses all shapes
489542 Extents totalExtents;
490543 totalExtents.reset();
491544 totalExtents.addPoint(glm::vec3(0.0f));
545+ int numStates = _rig->getJointStateCount();
492546 for (int i = 0; i < numStates; i++) {
493547 // compute the default transform of this joint
494548 const JointState& state = _rig->getJointState(i);
495− int parentIndex = state.getParentIndex();
496− if (parentIndex == -1) {
497− transforms[i] = _rig->getJointTransform(i);
498− } else {
499− glm::quat modifiedRotation = state.getPreRotation() * state.getDefaultRotation() * state.getPostRotation();
500− transforms[i] = transforms[parentIndex] * glm::translate(state.getTranslation())
501− * state.getPreTransform() * glm::mat4_cast(modifiedRotation) * state.getPostTransform();
502− }
503549
504− // Each joint contributes a sphere at its position
505− glm::vec3 axis(state.getBoneRadius());
506− glm::vec3 jointPosition = extractTranslation(transforms[i]);
507− totalExtents.addPoint(jointPosition + axis);
508− totalExtents.addPoint(jointPosition - axis);
550+ // HACK WORKAROUND: ignore joints that may have bad translation (e.g. have been flagged as such with zero radius)
551+ if (state.getBoneRadius() > 0.0f) {
552+ // Each joint contributes a sphere at its position
553+ glm::vec3 axis(state.getBoneRadius());
554+ glm::vec3 jointPosition = state.getPosition();
555+ totalExtents.addPoint(jointPosition + axis);
556+ totalExtents.addPoint(jointPosition - axis);
557+ }
509558 }
510559
511560 // compute bounding shape parameters
@@ -517,6 +566,11 @@ void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) { · 5 unmodified lines
517566
518567 glm::vec3 rootPosition = _rig->getJointState(geometry.rootJointIndex).getPosition();
519568 _boundingCapsuleLocalOffset = 0.5f * (totalExtents.maximum + totalExtents.minimum) - rootPosition;
569+
570+ // RECOVER FROM BOUNINDG SHAPE HACK: now that we're all done, restore the default pose
571+ for (int i = 0; i < numStates; i++) {
572+ _rig->restoreJointRotation(i, 1.0f, 1.0f);
573+ }
520574 }
521575
522576 void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) {
@@ -535,7 +589,7 @@ void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha · 12 unmodified lines
535589 glm::vec4(0.6f, 0.6f, 0.8f, alpha));
536590
537591 // draw a yellow sphere at the capsule bottom point
538− glm::vec3 bottomPoint = topPoint - glm::vec3(0.0f, -_boundingCapsuleHeight, 0.0f);
592+ glm::vec3 bottomPoint = topPoint - glm::vec3(0.0f, _boundingCapsuleHeight, 0.0f);
539593 glm::vec3 axis = topPoint - bottomPoint;
540594 transform.setTranslation(bottomPoint);
541595 batch.setModelTransform(transform);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t