Esempio n. 1
0
bool
UsdSkelSkeletonQuery::_ComputeSkinningTransforms(VtMatrix4dArray* xforms,
                                                 UsdTimeCode time) const
{
    if (ComputeJointSkelTransforms(xforms, time)) {

        // XXX: Since this is a fairly frequent computation request,
        // skel-space inverse rest transforms are cached on-demand
        // on the definition
        
        VtMatrix4dArray inverseBindXforms;
        if (!_definition->GetJointWorldInverseBindTransforms(
                &inverseBindXforms)) {
            TF_WARN("%s -- Failed fetching bind transforms. The "
                    "'bindTransforms' attribute may be unauthored, "
                    "or may not match the number of joints.",
                    GetSkeleton().GetPrim().GetPath().GetText());
            return false;
        }

        if(xforms->size() == inverseBindXforms.size()) {
            // xforms = inverseBindXforms * xforms
            _PreMultXforms(inverseBindXforms, xforms);
            return true;
        } else {
            TF_WARN("%s -- Size of computed joints transforms [%zu] does not "
                    "match the number of elements in the 'bindTransforms' "
                    "attr [%zu].", GetSkeleton().GetPrim().GetPath().GetText(),
                    xforms->size(), inverseBindXforms.size());
        }
    }
    return false;
}
Esempio n. 2
0
bool
UsdSkelSkeletonQuery::ComputeJointRestRelativeTransforms(
    VtMatrix4dArray* xforms, UsdTimeCode time) const
{
    TRACE_FUNCTION();

    if (!xforms) {
        TF_CODING_ERROR("'xforms' pointer is null.");
        return false;
    }

    if(TF_VERIFY(IsValid(), "invalid skeleton query.")) {
        if (_HasMappableAnim()) {
            // jointLocalXf = restRelativeXf * restXf
            // restRelativeXf = jointLocalXf * inv(restXf)

            // Pull inverse rest transforms first
            // They are cached on the definition.
            VtMatrix4dArray invRestXforms;
            if (_definition->GetJointLocalInverseRestTransforms(
                    &invRestXforms)) {

                VtMatrix4dArray localXforms;
                if (_ComputeJointLocalTransforms(
                        &localXforms, time, /*atRest*/ false)) {
                    if (TF_VERIFY(localXforms.size() == invRestXforms.size())) {
                        
                        xforms->resize(localXforms.size());

                        _MultTransforms(localXforms.cdata(),
                                        invRestXforms.cdata(),
                                        xforms->data(), xforms->size());
                        return true;
                    }
                }
            } else {
                TF_WARN("%s -- Failed computing rest-relative transforms: "
                        "the 'restTransforms' of the Skeleton are either unset, "
                        "or do not have a matching number of joints.",
                        GetSkeleton().GetPrim().GetPath().GetText());
            }
        } else {
            // No bound animation, so rest relative transforms are identity.
            xforms->assign(GetTopology().GetNumJoints(), GfMatrix4d(1));
            return true;
        }
    }
    return false;
}
Esempio n. 3
0
File: rprim.cpp Progetto: MWDD/USD
void
HdRprim::_PopulateConstantPrimVars(HdSceneDelegate* delegate,
                                   HdDrawItem *drawItem,
                                   HdDirtyBits *dirtyBits)
{
    HD_TRACE_FUNCTION();
    HF_MALLOC_TAG_FUNCTION();

    SdfPath const& id = GetId();
    HdRenderIndex &renderIndex = delegate->GetRenderIndex();
    HdResourceRegistry *resourceRegistry = &HdResourceRegistry::GetInstance();


    // XXX: this should be in a different method
    // XXX: This should be in HdSt getting the HdSt Shader
    const HdShader *shader = static_cast<const HdShader *>(
                                  renderIndex.GetSprim(HdPrimTypeTokens->shader,
                                                       _surfaceShaderID));

    if (shader == nullptr) {
        shader = static_cast<const HdShader *>(
                        renderIndex.GetFallbackSprim(HdPrimTypeTokens->shader));
    }

    _sharedData.surfaceShader = shader->GetShaderCode();


    // update uniforms
    HdBufferSourceVector sources;
    if (HdChangeTracker::IsTransformDirty(*dirtyBits, id)) {
        GfMatrix4d transform = delegate->GetTransform(id);
        _sharedData.bounds.SetMatrix(transform); // for CPU frustum culling

        HdBufferSourceSharedPtr source(new HdVtBufferSource(
                                           HdTokens->transform,
                                           transform));
        sources.push_back(source);
        source.reset(new HdVtBufferSource(HdTokens->transformInverse,
                                          transform.GetInverse()));
        sources.push_back(source);

        // if this is a prototype (has instancer),
        // also push the instancer transform separately.
        if (!_instancerID.IsEmpty()) {
            // gather all instancer transforms in the instancing hierarchy
            VtMatrix4dArray rootTransforms = _GetInstancerTransforms(delegate);
            VtMatrix4dArray rootInverseTransforms(rootTransforms.size());
            bool leftHanded = transform.IsLeftHanded();
            for (size_t i = 0; i < rootTransforms.size(); ++i) {
                rootInverseTransforms[i] = rootTransforms[i].GetInverse();
                // flip the handedness if necessary
                leftHanded ^= rootTransforms[i].IsLeftHanded();
            }

            source.reset(new HdVtBufferSource(
                             HdTokens->instancerTransform,
                             rootTransforms, /*staticArray=*/true));
            sources.push_back(source);
            source.reset(new HdVtBufferSource(
                             HdTokens->instancerTransformInverse,
                             rootInverseTransforms, /*staticArray=*/true));
            sources.push_back(source);

            // XXX: It might be worth to consider to have isFlipped
            // for non-instanced prims as well. It can improve
            // the drawing performance on older-GPUs by reducing
            // fragment shader cost, although it needs more GPU memory.

            // set as int (GLSL needs 32-bit align for bool)
            source.reset(new HdVtBufferSource(
                             HdTokens->isFlipped, VtValue(int(leftHanded))));
            sources.push_back(source);
        }
    }
    if (HdChangeTracker::IsExtentDirty(*dirtyBits, id)) {
        _sharedData.bounds.SetRange(GetExtent(delegate));

        GfVec3d const & localMin = drawItem->GetBounds().GetBox().GetMin();
        HdBufferSourceSharedPtr sourceMin(new HdVtBufferSource(
                                           HdTokens->bboxLocalMin,
                                           VtValue(GfVec4f(
                                               localMin[0],
                                               localMin[1],
                                               localMin[2], 0))));
        sources.push_back(sourceMin);

        GfVec3d const & localMax = drawItem->GetBounds().GetBox().GetMax();
        HdBufferSourceSharedPtr sourceMax(new HdVtBufferSource(
                                           HdTokens->bboxLocalMax,
                                           VtValue(GfVec4f(
                                               localMax[0],
                                               localMax[1],
                                               localMax[2], 0))));
        sources.push_back(sourceMax);
    }

    if (HdChangeTracker::IsPrimIdDirty(*dirtyBits, id)) {
        GfVec4f primIdColor;
        int32_t primId = GetPrimId();
        HdBufferSourceSharedPtr source(new HdVtBufferSource(
                                           HdTokens->primID,
                                           VtValue(primId)));
        sources.push_back(source);
    }

    if (HdChangeTracker::IsAnyPrimVarDirty(*dirtyBits, id)) {
        TfTokenVector primVarNames = delegate->GetPrimVarConstantNames(id);
        sources.reserve(sources.size()+primVarNames.size());
        TF_FOR_ALL(nameIt, primVarNames) {
            if (HdChangeTracker::IsPrimVarDirty(*dirtyBits, id, *nameIt)) {
                VtValue value = delegate->Get(id, *nameIt);

                // XXX Hydra doesn't support string primvar yet
                if (value.IsHolding<std::string>()) continue;

                if (!value.IsEmpty()) {
                    HdBufferSourceSharedPtr source(
                        new HdVtBufferSource(*nameIt, value));

                    // if it's an unacceptable type, skip it (e.g. std::string)
                    if (source->GetNumComponents() > 0) {
                        sources.push_back(source);
                    }
                }
            }
        }
    }