Showing the changes to interface/src/avatar/SkeletonModel.cpp (1 of 8 files). Show all
Unified · Split
| @@ -163,41 +163,6 @@ void SkeletonModel::simulate(float deltaTime, bool fullUpdate) { · 162 unmodified lines | |||
| 163 | _boundingShape.setRotation(_rotation); | 163 | _boundingShape.setRotation(_rotation); |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | void SkeletonModel::getHandShapes(int jointIndex, QVector<const Shape*>& shapes) const { | ||
| 167 | if (jointIndex < 0 || jointIndex >= int(_shapes.size())) { | ||
| 168 | return; | ||
| 169 | } | ||
| 170 | if (jointIndex == getLeftHandJointIndex() | ||
| 171 | || jointIndex == getRightHandJointIndex()) { | ||
| 172 | // get all shapes that have this hand as an ancestor in the skeleton heirarchy | ||
| 173 | const FBXGeometry& geometry = _geometry->getFBXGeometry(); | ||
| 174 | for (int i = 0; i < _rig->getJointStateCount(); i++) { | ||
| 175 | const FBXJoint& joint = geometry.joints[i]; | ||
| 176 | int parentIndex = joint.parentIndex; | ||
| 177 | Shape* shape = _shapes[i]; | ||
| 178 | if (i == jointIndex) { | ||
| 179 | // this shape is the hand | ||
| 180 | if (shape) { | ||
| 181 | shapes.push_back(shape); | ||
| 182 | } | ||
| 183 | if (parentIndex != -1 && _shapes[parentIndex]) { | ||
| 184 | // also add the forearm | ||
| 185 | shapes.push_back(_shapes[parentIndex]); | ||
| 186 | } | ||
| 187 | } else if (shape) { | ||
| 188 | while (parentIndex != -1) { | ||
| 189 | if (parentIndex == jointIndex) { | ||
| 190 | // this shape is a child of the hand | ||
| 191 | shapes.push_back(shape); | ||
| 192 | break; | ||
| 193 | } | ||
| 194 | parentIndex = geometry.joints[parentIndex].parentIndex; | ||
| 195 | } | ||
| 196 | } | ||
| 197 | } | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | void SkeletonModel::renderIKConstraints(gpu::Batch& batch) { | 166 | void SkeletonModel::renderIKConstraints(gpu::Batch& batch) { |
| 202 | renderJointConstraints(batch, getRightHandJointIndex()); | 167 | renderJointConstraints(batch, getRightHandJointIndex()); |
| 203 | renderJointConstraints(batch, getLeftHandJointIndex()); | 168 | renderJointConstraints(batch, getLeftHandJointIndex()); |
| @@ -648,45 +613,12 @@ void SkeletonModel::buildShapes() { · 444 unmodified lines | |||
| 648 | // rootJointIndex == -1 if the avatar model has no skeleton | 613 | // rootJointIndex == -1 if the avatar model has no skeleton |
| 649 | return; | 614 | return; |
| 650 | } | 615 | } |
| 651 | |||
| 652 | float uniformScale = extractUniformScale(_scale); | ||
| 653 | for (int i = 0; i < _rig->getJointStateCount(); i++) { | ||
| 654 | const JointState& state = _rig->getJointState(i); | ||
| 655 | const FBXJoint& joint = state.getFBXJoint(); | ||
| 656 | float radius = uniformScale * joint.boneRadius; | ||
| 657 | float halfHeight = 0.5f * uniformScale * joint.distanceToParent; | ||
| 658 | Shape::Type type = joint.shapeType; | ||
| 659 | int parentIndex = joint.parentIndex; | ||
| 660 | if (parentIndex == -1 || radius < EPSILON) { | ||
| 661 | type = INVALID_SHAPE; | ||
| 662 | } else if (type == CAPSULE_SHAPE && halfHeight < EPSILON) { | ||
| 663 | // this shape is forced to be a sphere | ||
| 664 | type = SPHERE_SHAPE; | ||
| 665 | } | ||
| 666 | Shape* shape = NULL; | ||
| 667 | if (type == SPHERE_SHAPE) { | ||
| 668 | shape = new SphereShape(radius); | ||
| 669 | shape->setEntity(this); | ||
| 670 | } else if (type == CAPSULE_SHAPE) { | ||
| 671 | assert(parentIndex != -1); | ||
| 672 | shape = new CapsuleShape(radius, halfHeight); | ||
| 673 | shape->setEntity(this); | ||
| 674 | } | ||
| 675 | if (shape && parentIndex != -1) { | ||
| 676 | // always disable collisions between joint and its parent | ||
| 677 | disableCollisions(i, parentIndex); | ||
| 678 | } | ||
| 679 | _shapes.push_back(shape); | ||
| 680 | } | ||
| 681 | |||
| 682 | // This method moves the shapes to their default positions in Model frame. | ||
| 683 | computeBoundingShape(geometry); | 616 | computeBoundingShape(geometry); |
| 684 | } | 617 | } |
| 685 | 618 | ||
| 686 | void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) { | 619 | void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) { |
| 687 | // compute default joint transforms | 620 | // compute default joint transforms |
| 688 | int numStates = _rig->getJointStateCount(); | 621 | int numStates = _rig->getJointStateCount(); |
| 689 | assert(numStates == _shapes.size()); | ||
| 690 | QVector<glm::mat4> transforms; | 622 | QVector<glm::mat4> transforms; |
| 691 | transforms.fill(glm::mat4(), numStates); | 623 | transforms.fill(glm::mat4(), numStates); |
| 692 | 624 | ||
| @@ -707,39 +639,11 @@ void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) { · 14 unmodified lines | |||
| 707 | * joint.preTransform * glm::mat4_cast(modifiedRotation) * joint.postTransform; | 639 | * joint.preTransform * glm::mat4_cast(modifiedRotation) * joint.postTransform; |
| 708 | } | 640 | } |
| 709 | 641 | ||
| 710 | // Each joint contributes its point to the bounding box | 642 | // Each joint contributes a sphere at its position |
| 643 | glm::vec3 axis(joint.boneRadius); | ||
| 711 | glm::vec3 jointPosition = extractTranslation(transforms[i]); | 644 | glm::vec3 jointPosition = extractTranslation(transforms[i]); |
| 712 | totalExtents.addPoint(jointPosition); | 645 | totalExtents.addPoint(jointPosition + axis); |
| 713 | 646 | totalExtents.addPoint(jointPosition - axis); | |
| 714 | Shape* shape = _shapes[i]; | ||
| 715 | if (!shape) { | ||
| 716 | continue; | ||
| 717 | } | ||
| 718 | |||
| 719 | // Each joint with a shape contributes to the totalExtents: a box | ||
| 720 | // that contains the sphere centered at the end of the joint with radius of the bone. | ||
| 721 | |||
| 722 | // TODO: skip hand and arm shapes for bounding box calculation | ||
| 723 | int type = shape->getType(); | ||
| 724 | if (type == CAPSULE_SHAPE) { | ||
| 725 | // add the two furthest surface points of the capsule | ||
| 726 | CapsuleShape* capsule = static_cast<CapsuleShape*>(shape); | ||
| 727 | float radius = capsule->getRadius(); | ||
| 728 | glm::vec3 axis(radius); | ||
| 729 | Extents shapeExtents; | ||
| 730 | shapeExtents.reset(); | ||
| 731 | shapeExtents.addPoint(jointPosition + axis); | ||
| 732 | shapeExtents.addPoint(jointPosition - axis); | ||
| 733 | totalExtents.addExtents(shapeExtents); | ||
| 734 | } else if (type == SPHERE_SHAPE) { | ||
| 735 | float radius = shape->getBoundingRadius(); | ||
| 736 | glm::vec3 axis(radius); | ||
| 737 | Extents shapeExtents; | ||
| 738 | shapeExtents.reset(); | ||
| 739 | shapeExtents.addPoint(jointPosition + axis); | ||
| 740 | shapeExtents.addPoint(jointPosition - axis); | ||
| 741 | totalExtents.addExtents(shapeExtents); | ||
| 742 | } | ||
| 743 | } | 647 | } |
| 744 | 648 | ||
| 745 | // compute bounding shape parameters | 649 | // compute bounding shape parameters |
| @@ -755,43 +659,8 @@ void SkeletonModel::computeBoundingShape(const FBXGeometry& geometry) { · 9 unmodified lines | |||
| 755 | _boundingRadius = 0.5f * glm::length(diagonal); | 659 | _boundingRadius = 0.5f * glm::length(diagonal); |
| 756 | } | 660 | } |
| 757 | 661 | ||
| 758 | void SkeletonModel::resetShapePositionsToDefaultPose() { | ||
| 759 | // DEBUG method. | ||
| 760 | // Moves shapes to the joint default locations for debug visibility into | ||
| 761 | // how the bounding shape is computed. | ||
| 762 | |||
| 763 | if (!_geometry || _shapes.isEmpty()) { | ||
| 764 | // geometry or joints have not yet been created | ||
| 765 | return; | ||
| 766 | } | ||
| 767 | |||
| 768 | const FBXGeometry& geometry = _geometry->getFBXGeometry(); | ||
| 769 | if (geometry.joints.isEmpty()) { | ||
| 770 | return; | ||
| 771 | } | ||
| 772 | |||
| 773 | // The shapes are moved to their default positions in computeBoundingShape(). | ||
| 774 | computeBoundingShape(geometry); | ||
| 775 | |||
| 776 | // Then we move them into world frame for rendering at the Model's location. | ||
| 777 | for (int i = 0; i < _shapes.size(); i++) { | ||
| 778 | Shape* shape = _shapes[i]; | ||
| 779 | if (shape) { | ||
| 780 | shape->setTranslation(_translation + _rotation * shape->getTranslation()); | ||
| 781 | shape->setRotation(_rotation * shape->getRotation()); | ||
| 782 | } | ||
| 783 | } | ||
| 784 | _boundingShape.setTranslation(_translation + _rotation * _boundingShapeLocalOffset); | ||
| 785 | _boundingShape.setRotation(_rotation); | ||
| 786 | } | ||
| 787 | |||
| 788 | void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) { | 662 | void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float alpha) { |
| 789 | const int BALL_SUBDIVISIONS = 10; | 663 | const int BALL_SUBDIVISIONS = 10; |
| 790 | if (_shapes.isEmpty()) { | ||
| 791 | // the bounding shape has not been properly computed | ||
| 792 | // so no need to render it | ||
| 793 | return; | ||
| 794 | } | ||
| 795 | 664 | ||
| 796 | auto geometryCache = DependencyManager::get<GeometryCache>(); | 665 | auto geometryCache = DependencyManager::get<GeometryCache>(); |
| 797 | auto deferredLighting = DependencyManager::get<DeferredLightingEffect>(); | 666 | auto deferredLighting = DependencyManager::get<DeferredLightingEffect>(); |