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
86 _rig->updateJointState(i, rootTransform);86 _rig->updateJointState(i, rootTransform);
87 }87 }
88 88
89 buildShapes();89 computeBoundingShape();
90 90
91 Extents meshExtents = getMeshExtents();91 Extents meshExtents = getMeshExtents();
92 _headClipDistance = -(meshExtents.minimum.z / _scale.z - _defaultEyeModelPosition.z);92 _headClipDistance = -(meshExtents.minimum.z / _scale.z - _defaultEyeModelPosition.z);
@@ -248,6 +248,7 @@ void SkeletonModel::applyHandPosition(int jointIndex, const glm::vec3& position) · 155 unmodified lines
248 rotationBetween(handRotation * glm::vec3(-sign, 0.0f, 0.0f), forearmVector),248 rotationBetween(handRotation * glm::vec3(-sign, 0.0f, 0.0f), forearmVector),
249 true, PALM_PRIORITY);249 true, PALM_PRIORITY);
250}250}
251
251void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) {252void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) {
252 if (jointIndex == -1 || jointIndex >= _rig->getJointStateCount()) {253 if (jointIndex == -1 || jointIndex >= _rig->getJointStateCount()) {
253 return;254 return;
@@ -261,9 +262,7 @@ void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) { · 7 unmodified lines
261 // the palm's position must be transformed into the model-frame262 // the palm's position must be transformed into the model-frame
262 glm::quat inverseRotation = glm::inverse(_rotation);263 glm::quat inverseRotation = glm::inverse(_rotation);
263 glm::vec3 palmPosition = inverseRotation * (palm.getPosition() - _translation);264 glm::vec3 palmPosition = inverseRotation * (palm.getPosition() - _translation);
264 265 glm::quat palmRotation = inverseRotation * palm.getRotation();
265 // the palm's "raw" rotation is already in the model-frame
266 glm::quat palmRotation = palm.getRawRotation();
267 266
268 inverseKinematics(jointIndex, palmPosition, palmRotation, PALM_PRIORITY);267 inverseKinematics(jointIndex, palmPosition, palmRotation, PALM_PRIORITY);
269}268}
@@ -346,9 +345,9 @@ void SkeletonModel::renderOrientationDirections(gpu::Batch& batch, int jointInde · 76 unmodified lines
346 }345 }
347 OrientationLineIDs& jointLineIDs = _jointOrientationLines[jointIndex];346 OrientationLineIDs& jointLineIDs = _jointOrientationLines[jointIndex];
348 347
349 glm::vec3 pRight = position + orientation * IDENTITY_RIGHT * size;348 glm::vec3 pRight = position + orientation * IDENTITY_RIGHT * size;
350 glm::vec3 pUp = position + orientation * IDENTITY_UP * size;349 glm::vec3 pUp = position + orientation * IDENTITY_UP * size;
351 glm::vec3 pFront = position + orientation * IDENTITY_FRONT * size;350 glm::vec3 pFront = position + orientation * IDENTITY_FRONT * size;
352 351
353 glm::vec3 red(1.0f, 0.0f, 0.0f);352 glm::vec3 red(1.0f, 0.0f, 0.0f);
354 geometryCache->renderLine(batch, position, pRight, red, jointLineIDs._right);353 geometryCache->renderLine(batch, position, pRight, red, jointLineIDs._right);
@@ -466,7 +465,7 @@ float MIN_JOINT_MASS = 1.0f; · 111 unmodified lines
466float VERY_BIG_MASS = 1.0e6f;465float VERY_BIG_MASS = 1.0e6f;
467 466
468// virtual467// virtual
469void SkeletonModel::buildShapes() {468void SkeletonModel::computeBoundingShape() {
470 if (_geometry == NULL || _rig->jointStatesEmpty()) {469 if (_geometry == NULL || _rig->jointStatesEmpty()) {
471 return;470 return;
472 }471 }
@@ -476,36 +475,86 @@ void SkeletonModel::buildShapes() { · 3 unmodified lines
476 // rootJointIndex == -1 if the avatar model has no skeleton475 // rootJointIndex == -1 if the avatar model has no skeleton
477 return;476 return;
478 }477 }
479 computeBoundingShape(geometry);
480}
481 478
482void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) {479 // BOUNDING SHAPE HACK: before we measure the bounds of the joints we use IK to put the
483 // compute default joint transforms480 // hands and feet into positions that are more correct than the default pose.
484 int numStates = _rig->getJointStateCount();481
485 QVector<glm::mat4> transforms;482 // Measure limb lengths so we can specify IK targets that will pull hands and feet tight to body
486 transforms.fill(glm::mat4(), numStates);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
487 540
488 // compute bounding box that encloses all shapes541 // compute bounding box that encloses all shapes
489 Extents totalExtents;542 Extents totalExtents;
490 totalExtents.reset();543 totalExtents.reset();
491 totalExtents.addPoint(glm::vec3(0.0f));544 totalExtents.addPoint(glm::vec3(0.0f));
545 int numStates = _rig->getJointStateCount();
492 for (int i = 0; i < numStates; i++) {546 for (int i = 0; i < numStates; i++) {
493 // compute the default transform of this joint547 // compute the default transform of this joint
494 const JointState& state = _rig->getJointState(i);548 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 }
503 549
504 // Each joint contributes a sphere at its position550 // HACK WORKAROUND: ignore joints that may have bad translation (e.g. have been flagged as such with zero radius)
505 glm::vec3 axis(state.getBoneRadius());551 if (state.getBoneRadius() > 0.0f) {
506 glm::vec3 jointPosition = extractTranslation(transforms[i]);552 // Each joint contributes a sphere at its position
507 totalExtents.addPoint(jointPosition + axis);553 glm::vec3 axis(state.getBoneRadius());
508 totalExtents.addPoint(jointPosition - axis);554 glm::vec3 jointPosition = state.getPosition();
555 totalExtents.addPoint(jointPosition + axis);
556 totalExtents.addPoint(jointPosition - axis);
557 }
509 }558 }
510 559
511 // compute bounding shape parameters560 // compute bounding shape parameters
@@ -517,6 +566,11 @@ void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) { · 5 unmodified lines
517 566
518 glm::vec3 rootPosition = _rig->getJointState(geometry.rootJointIndex).getPosition();567 glm::vec3 rootPosition = _rig->getJointState(geometry.rootJointIndex).getPosition();
519 _boundingCapsuleLocalOffset = 0.5f * (totalExtents.maximum + totalExtents.minimum) - rootPosition;568 _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 }
520}574}
521 575
522void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) {576void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) {
@@ -535,7 +589,7 @@ void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha · 12 unmodified lines
535 glm::vec4(0.6f, 0.6f, 0.8f, alpha));589 glm::vec4(0.6f, 0.6f, 0.8f, alpha));
536 590
537 // draw a yellow sphere at the capsule bottom point591 // 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);
539 glm::vec3 axis = topPoint - bottomPoint;593 glm::vec3 axis = topPoint - bottomPoint;
540 transform.setTranslation(bottomPoint);594 transform.setTranslation(bottomPoint);
541 batch.setModelTransform(transform);595 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