示例#1
0
void Flow::updateJoints(AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses) {
    updateAbsolutePoses(relativePoses, absolutePoses);
    for (auto &jointData : _flowJointData) {
        int jointIndex = jointData.first;
        glm::vec3 jointPosition, parentPosition, jointTranslation;
        glm::quat jointRotation, parentWorldRotation;
        if (!jointData.second.isHelper()) {
            getJointPositionInWorldFrame(absolutePoses, jointIndex, jointPosition, _entityPosition, _entityRotation);
            getJointTranslation(relativePoses, jointIndex, jointTranslation);
            getJointRotation(relativePoses, jointIndex, jointRotation);
        } else {
            jointPosition = jointData.second.getCurrentPosition();
            jointTranslation = jointData.second.getCurrentTranslation();
            jointRotation = jointData.second.getCurrentRotation();
        }
        getJointPositionInWorldFrame(absolutePoses, jointData.second.getParentIndex(), parentPosition, _entityPosition, _entityRotation);
        getJointRotationInWorldFrame(absolutePoses, jointData.second.getParentIndex(), parentWorldRotation, _entityRotation);
        jointData.second.setUpdatedData(jointPosition, jointTranslation, jointRotation, parentPosition, parentWorldRotation);
    }
    auto &selfCollisions = _collisionSystem.getSelfCollisions();
    for (auto &collision : selfCollisions) {
        updateCollisionJoint(collision, absolutePoses);
    }
    auto &selfTouchCollisions = _collisionSystem.getSelfTouchCollisions();
    for (auto &collision : selfTouchCollisions) {
        updateCollisionJoint(collision, absolutePoses);
    }
    _collisionSystem.prepareCollisions();
}
示例#2
0
bool FaceModel::getEyePositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const {
    if (!isActive()) {
        return false;
    }
    const FBXGeometry& geometry = _geometry->getFBXGeometry();
    return getJointPositionInWorldFrame(geometry.leftEyeJointIndex, firstEyePosition) &&
        getJointPositionInWorldFrame(geometry.rightEyeJointIndex, secondEyePosition);
}
示例#3
0
bool SkeletonModel::getNeckPosition(glm::vec3& neckPosition) const {
    if (_owningAvatar->isMyAvatar() &&
            Menu::getInstance()->isOptionChecked(MenuOption::CollideAsRagdoll)) {
        return isActive() && getVisibleJointPositionInWorldFrame(_geometry->getFBXGeometry().neckJointIndex, neckPosition);
    }
    return isActive() && getJointPositionInWorldFrame(_geometry->getFBXGeometry().neckJointIndex, neckPosition);
}
示例#4
0
void Flow::updateCollisionJoint(FlowCollisionSphere& collision, AnimPoseVec& absolutePoses) {
    glm::quat jointRotation;
    getJointPositionInWorldFrame(absolutePoses, collision._jointIndex, collision._position, _entityPosition, _entityRotation);
    getJointRotationInWorldFrame(absolutePoses, collision._jointIndex, jointRotation, _entityRotation);
    glm::vec3 worldOffset = jointRotation * collision._offset;
    collision._position = collision._position + worldOffset;
}
示例#5
0
bool Flow::worldToJointPoint(const AnimPoseVec& absolutePoses, const glm::vec3& position, const int jointIndex, glm::vec3& jointSpacePosition) const {
    glm::vec3 jointPos;
    glm::quat jointRot;
    if (getJointPositionInWorldFrame(absolutePoses, jointIndex, jointPos, _entityPosition, _entityRotation) && 
        getJointRotationInWorldFrame(absolutePoses, jointIndex, jointRot, _entityRotation)) {
        glm::vec3 modelOffset = position - jointPos;
        jointSpacePosition = glm::inverse(jointRot) * modelOffset;
        return true;
    }
    return false;
}
示例#6
0
bool SkeletonModel::getRightGrabPosition(glm::vec3& position) const {
    int knuckleIndex = _rig->indexOfJoint("RightHandMiddle1");
    int handIndex = _rig->indexOfJoint("RightHand");
    if (knuckleIndex >= 0 && handIndex >= 0) {
        glm::quat handRotation;
        glm::vec3 knucklePosition;
        glm::vec3 handPosition;
        if (!getJointPositionInWorldFrame(knuckleIndex, knucklePosition)) {
            return false;
        }
        if (!getJointPositionInWorldFrame(handIndex, handPosition)) {
            return false;
        }
        if (!getJointRotationInWorldFrame(handIndex, handRotation)) {
            return false;
        }
        float halfPalmLength = glm::distance(knucklePosition, handPosition) * 0.5f;
        // z azis is standardized to be out of the palm.  move from the knuckle-joint away from the palm
        // by 1/2 the palm length.
        position = knucklePosition + handRotation * (glm::vec3(0.0f, 0.0f, 1.0f) * halfPalmLength);
        return true;
    }
    return false;
}
示例#7
0
bool SkeletonModel::getNeckPosition(glm::vec3& neckPosition) const {
    return isActive() && getJointPositionInWorldFrame(getFBXGeometry().neckJointIndex, neckPosition);
}
示例#8
0
bool SkeletonModel::getHeadPosition(glm::vec3& headPosition) const {
    return isActive() && getJointPositionInWorldFrame(getFBXGeometry().headJointIndex, headPosition);
}
示例#9
0
bool SkeletonModel::getRightShoulderPosition(glm::vec3& position) const {
    return getJointPositionInWorldFrame(getLastFreeJointIndex(getRightHandJointIndex()), position);
}
示例#10
0
bool SkeletonModel::getRightHandPosition(glm::vec3& position) const {
    return getJointPositionInWorldFrame(getRightHandJointIndex(), position);
}
示例#11
0
bool SkeletonModel::getNeckPosition(glm::vec3& neckPosition) const {
    return isActive() && getJointPositionInWorldFrame(_rig.indexOfJoint("Neck"), neckPosition);
}
示例#12
0
bool SkeletonModel::getHeadPosition(glm::vec3& headPosition) const {
    return isActive() && getJointPositionInWorldFrame(_rig.indexOfJoint("Head"), headPosition);
}
示例#13
0
void Flow::calculateConstraints(const std::shared_ptr<AnimSkeleton>& skeleton, 
                                AnimPoseVec& relativePoses, AnimPoseVec& absolutePoses) {
    cleanUp();
    if (!skeleton) {
        return;
    }
    auto flowPrefix = FLOW_JOINT_PREFIX.toUpper();
    auto simPrefix = SIM_JOINT_PREFIX.toUpper();
    std::vector<int> handsIndices;
    _groupSettings.clear();

    for (int i = 0; i < skeleton->getNumJoints(); i++) {
        auto name = skeleton->getJointName(i);
        if (std::find(HAND_COLLISION_JOINTS.begin(), HAND_COLLISION_JOINTS.end(), name) != HAND_COLLISION_JOINTS.end()) {
            handsIndices.push_back(i);
        }
        auto parentIndex = skeleton->getParentIndex(i);
        if (parentIndex == -1) {
            continue;
        }
        auto jointChildren = skeleton->getChildrenOfJoint(i);
        // auto childIndex = jointChildren.size() > 0 ? jointChildren[0] : -1;
        auto group = QStringRef(&name, 0, 3).toString().toUpper();
        auto split = name.split("_");
        bool isSimJoint = (group == simPrefix);
        bool isFlowJoint = split.size() > 2 && split[0].toUpper() == flowPrefix;
        if (isFlowJoint || isSimJoint) {
            group = "";
            if (isSimJoint) {
                for (int j = 1; j < name.size() - 1; j++) {
                    bool toFloatSuccess;
                    QStringRef(&name, (int)(name.size() - j), 1).toString().toFloat(&toFloatSuccess);
                    if (!toFloatSuccess && (name.size() - j) > (int)simPrefix.size()) {
                        group = QStringRef(&name, (int)simPrefix.size(), (int)(name.size() - j + 1) - (int)simPrefix.size()).toString();
                        break;
                    }
                }
                if (group.isEmpty()) {
                    group = QStringRef(&name, (int)simPrefix.size(), name.size() - (int)simPrefix.size()).toString();
                }
                qCDebug(animation) << "Sim joint added to flow: " << name;
            } else {
                group = split[1];
            }
            if (!group.isEmpty()) {
                _flowJointKeywords.push_back(group);
                FlowPhysicsSettings jointSettings;
                if (PRESET_FLOW_DATA.find(group) != PRESET_FLOW_DATA.end()) {
                    jointSettings = PRESET_FLOW_DATA.at(group);
                } else {
                    jointSettings = DEFAULT_JOINT_SETTINGS;
                }
                if (_flowJointData.find(i) ==  _flowJointData.end()) {
                    auto flowJoint = FlowJoint(i, parentIndex, -1, name, group, jointSettings);
                    _flowJointData.insert(std::pair<int, FlowJoint>(i, flowJoint));
                }
                updateGroupSettings(group, jointSettings);
            }
        } else {
            if (PRESET_COLLISION_DATA.find(name) != PRESET_COLLISION_DATA.end()) {
                _collisionSystem.addCollisionSphere(i, PRESET_COLLISION_DATA.at(name));
            }
        }
    }

    for (auto &jointData : _flowJointData) {
        int jointIndex = jointData.first;
        glm::vec3 jointPosition, parentPosition, jointTranslation;
        glm::quat jointRotation;
        getJointPositionInWorldFrame(absolutePoses, jointIndex, jointPosition, _entityPosition, _entityRotation);
        getJointTranslation(relativePoses, jointIndex, jointTranslation);
        getJointRotation(relativePoses, jointIndex, jointRotation);
        getJointPositionInWorldFrame(absolutePoses, jointData.second.getParentIndex(), parentPosition, _entityPosition, _entityRotation);

        jointData.second.setInitialData(jointPosition, jointTranslation, jointRotation, parentPosition);
    }

    std::vector<int> roots;

    for (auto &joint :_flowJointData) {
        if (_flowJointData.find(joint.second.getParentIndex()) == _flowJointData.end()) {
            joint.second.setAnchored(true);
            roots.push_back(joint.first);
        } else {
            _flowJointData[joint.second.getParentIndex()].setChildIndex(joint.first);
        }
    }
    int extraIndex = -1;
    for (size_t i = 0; i < roots.size(); i++) {
        FlowThread thread = FlowThread(roots[i], &_flowJointData);
        // add threads with at least 2 joints
        if (thread._joints.size() > 0) {
            if (thread._joints.size() == 1) {
                int jointIndex = roots[i];
                auto &joint = _flowJointData[jointIndex];
                auto &jointPosition = joint.getUpdatedPosition();
                auto newSettings = joint.getSettings();
                extraIndex = extraIndex > -1 ? extraIndex + 1 : skeleton->getNumJoints();
                joint.setChildIndex(extraIndex);
                auto newJoint = FlowJoint(extraIndex, jointIndex, -1, joint.getName(), joint.getGroup(), newSettings);
                newJoint.toHelperJoint(jointPosition, HELPER_JOINT_LENGTH);
                glm::vec3 translation = glm::vec3(0.0f, HELPER_JOINT_LENGTH, 0.0f);
                newJoint.setInitialData(jointPosition + translation, 100.0f * translation , Quaternions::IDENTITY, jointPosition);
                _flowJointData.insert(std::pair<int, FlowJoint>(extraIndex, newJoint));
                FlowThread newThread = FlowThread(jointIndex, &_flowJointData);
                if (newThread._joints.size() > 1) {
                    _jointThreads.push_back(newThread);
                }
            } else {
                _jointThreads.push_back(thread);
            }
        }
    }
    
    if (_jointThreads.size() == 0) {
        onCleanup();
    }
    if (handsIndices.size() > 0) {
        FlowCollisionSettings handSettings;
        handSettings._radius = HAND_COLLISION_RADIUS;
        for (size_t i = 0; i < handsIndices.size(); i++) {
            _collisionSystem.addCollisionSphere(handsIndices[i], handSettings, glm::vec3(), true, true);
        }
    }
    _initialized = _jointThreads.size() > 0;
}