Exemplo n.º 1
0
void SkeletonModel::initJointStates() {
    const FBXGeometry& geometry = getFBXGeometry();
    glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
    _rig->initJointStates(geometry, modelOffset);

    // Determine the default eye position for avatar scale = 1.0
    int headJointIndex = geometry.headJointIndex;
    if (0 > headJointIndex || headJointIndex >= _rig->getJointStateCount()) {
        qCWarning(interfaceapp) << "Bad head joint! Got:" << headJointIndex << "jointCount:" << _rig->getJointStateCount();
    }
    glm::vec3 leftEyePosition, rightEyePosition;
    getEyeModelPositions(leftEyePosition, rightEyePosition);
    glm::vec3 midEyePosition = (leftEyePosition + rightEyePosition) / 2.0f;

    int rootJointIndex = geometry.rootJointIndex;
    glm::vec3 rootModelPosition;
    getJointPosition(rootJointIndex, rootModelPosition);

    _defaultEyeModelPosition = midEyePosition - rootModelPosition;

    // Skeleton may have already been scaled so unscale it
    _defaultEyeModelPosition = _defaultEyeModelPosition / _scale;

    computeBoundingShape();

    Extents meshExtents = getMeshExtents();
    _headClipDistance = -(meshExtents.minimum.z / _scale.z - _defaultEyeModelPosition.z);
    _headClipDistance = std::max(_headClipDistance, DEFAULT_NEAR_CLIP);

    _owningAvatar->rebuildCollisionShape();
    emit skeletonLoaded();
}
Exemplo n.º 2
0
void SkeletonModel::resetShapePositionsToDefaultPose() {
    // DEBUG method.
    // Moves shapes to the joint default locations for debug visibility into
    // how the bounding shape is computed.

    if (!_geometry || _shapes.isEmpty()) {
        // geometry or joints have not yet been created
        return;
    }
    
    const FBXGeometry& geometry = _geometry->getFBXGeometry();
    if (geometry.joints.isEmpty()) {
        return;
    }

    // The shapes are moved to their default positions in computeBoundingShape().
    computeBoundingShape(geometry);

    // Then we move them into world frame for rendering at the Model's location.
    for (int i = 0; i < _shapes.size(); i++) {
        Shape* shape = _shapes[i];
        if (shape) {
            shape->setTranslation(_translation + _rotation * shape->getTranslation());
            shape->setRotation(_rotation * shape->getRotation());
        }
    }
    _boundingShape.setTranslation(_translation + _rotation * _boundingShapeLocalOffset);
    _boundingShape.setRotation(_rotation);
}
Exemplo n.º 3
0
// virtual
void SkeletonModel::buildShapes() {
    if (_geometry == NULL || _rig->jointStatesEmpty()) {
        return;
    }
    
    const FBXGeometry& geometry = _geometry->getFBXGeometry();
    if (geometry.joints.isEmpty() || geometry.rootJointIndex == -1) {
        // rootJointIndex == -1 if the avatar model has no skeleton
        return;
    }
    computeBoundingShape(geometry);
}
Exemplo n.º 4
0
// virtual
void SkeletonModel::buildShapes() {
    if (_geometry == NULL || _jointStates.isEmpty()) {
        return;
    }
    
    const FBXGeometry& geometry = _geometry->getFBXGeometry();
    if (geometry.joints.isEmpty() || geometry.rootJointIndex == -1) {
        // rootJointIndex == -1 if the avatar model has no skeleton
        return;
    }

    float uniformScale = extractUniformScale(_scale);
    const int numStates = _jointStates.size();
    for (int i = 0; i < numStates; i++) {
        JointState& state = _jointStates[i];
        const FBXJoint& joint = state.getFBXJoint();
        float radius = uniformScale * joint.boneRadius;
        float halfHeight = 0.5f * uniformScale * joint.distanceToParent;
        Shape::Type type = joint.shapeType;
        int parentIndex = joint.parentIndex;
        if (parentIndex == -1 || radius < EPSILON) {
            type = INVALID_SHAPE;
        } else if (type == CAPSULE_SHAPE && halfHeight < EPSILON) {
            // this shape is forced to be a sphere
            type = SPHERE_SHAPE;
        }
        Shape* shape = NULL;
        if (type == SPHERE_SHAPE) {
            shape = new SphereShape(radius);
            shape->setEntity(this);
        } else if (type == CAPSULE_SHAPE) {
            assert(parentIndex != -1);
            shape = new CapsuleShape(radius, halfHeight);
            shape->setEntity(this);
        } 
        if (shape && parentIndex != -1) {
            // always disable collisions between joint and its parent
            disableCollisions(i, parentIndex);
        } 
        _shapes.push_back(shape);
    }

    // This method moves the shapes to their default positions in Model frame.
    computeBoundingShape(geometry);
}
Exemplo n.º 5
0
void SkeletonModel::initJointStates() {
    const HFMModel& hfmModel = getHFMModel();
    glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
    _rig.initJointStates(hfmModel, modelOffset);

    {
        // initialize _jointData with proper values for default joints
        QVector<JointData> defaultJointData;
        _rig.copyJointsIntoJointData(defaultJointData);
        _owningAvatar->setRawJointData(defaultJointData);
    }

    // Determine the default eye position for avatar scale = 1.0
    int headJointIndex = _rig.indexOfJoint("Head");
    if (0 > headJointIndex || headJointIndex >= _rig.getJointStateCount()) {
        qCWarning(avatars_renderer) << "Bad head joint! Got:" << headJointIndex << "jointCount:" << _rig.getJointStateCount();
    }
    glm::vec3 leftEyePosition, rightEyePosition;
    getEyeModelPositions(leftEyePosition, rightEyePosition);
    glm::vec3 midEyePosition = (leftEyePosition + rightEyePosition) / 2.0f;

    int rootJointIndex = _rig.indexOfJoint("Hips");
    glm::vec3 rootModelPosition;
    getJointPosition(rootJointIndex, rootModelPosition);

    _defaultEyeModelPosition = midEyePosition - rootModelPosition;

    // Skeleton may have already been scaled so unscale it
    _defaultEyeModelPosition = _defaultEyeModelPosition / _scale;

    computeBoundingShape();

    Extents meshExtents = getMeshExtents();
    _headClipDistance = -(meshExtents.minimum.z / _scale.z - _defaultEyeModelPosition.z);
    _headClipDistance = std::max(_headClipDistance, DEFAULT_NEAR_CLIP);

    _owningAvatar->rebuildCollisionShape();
    emit skeletonLoaded();
}
Exemplo n.º 6
0
// virtual
void SkeletonModel::buildShapes() {
    if (_geometry == NULL || _jointStates.isEmpty()) {
        return;
    }
    
    const FBXGeometry& geometry = _geometry->getFBXGeometry();
    if (geometry.joints.isEmpty()) {
        return;
    }

    if (!_ragdoll) {
        _ragdoll = new SkeletonRagdoll(this);
    }
    _ragdoll->setRootIndex(geometry.rootJointIndex);
    _ragdoll->initPoints();
    QVector<VerletPoint>& points = _ragdoll->getPoints();

    float massScale = _ragdoll->getMassScale();

    float uniformScale = extractUniformScale(_scale);
    const int numStates = _jointStates.size();
    float totalMass = 0.0f;
    for (int i = 0; i < numStates; i++) {
        JointState& state = _jointStates[i];
        const FBXJoint& joint = state.getFBXJoint();
        float radius = uniformScale * joint.boneRadius;
        float halfHeight = 0.5f * uniformScale * joint.distanceToParent;
        Shape::Type type = joint.shapeType;
        int parentIndex = joint.parentIndex;
        if (parentIndex == -1 || radius < EPSILON) {
            type = SHAPE_TYPE_UNKNOWN;
        } else if (type == SHAPE_TYPE_CAPSULE && halfHeight < EPSILON) {
            // this shape is forced to be a sphere
            type = SHAPE_TYPE_SPHERE;
        }
        Shape* shape = NULL;
        if (type == SHAPE_TYPE_SPHERE) {
            shape = new VerletSphereShape(radius, &(points[i]));
            shape->setEntity(this);
            float mass = massScale * glm::max(MIN_JOINT_MASS, DENSITY_OF_WATER * shape->getVolume());
            points[i].setMass(mass);
            totalMass += mass;
        } else if (type == SHAPE_TYPE_CAPSULE) {
            assert(parentIndex != -1);
            shape = new VerletCapsuleShape(radius, &(points[parentIndex]), &(points[i]));
            shape->setEntity(this);
            float mass = massScale * glm::max(MIN_JOINT_MASS, DENSITY_OF_WATER * shape->getVolume());
            points[i].setMass(mass);
            totalMass += mass;
        } 
        if (shape && parentIndex != -1) {
            // always disable collisions between joint and its parent
            disableCollisions(i, parentIndex);
        } 
        _shapes.push_back(shape);
    }

    // set the mass of the root
    if (numStates > 0) {
        points[_ragdoll->getRootIndex()].setMass(totalMass);
    }

    // This method moves the shapes to their default positions in Model frame.
    computeBoundingShape(geometry);

    // While the shapes are in their default position we disable collisions between
    // joints that are currently colliding.
    disableCurrentSelfCollisions();

    _ragdoll->buildConstraints();

    // ... then move shapes back to current joint positions
    _ragdoll->slamPointPositions();
    _ragdoll->enforceConstraints();
}