Пример #1
0
void readRotationElement(KFbxTypedProperty<fbxDouble3>& prop,
                         ERotationOrder fbxRotOrder,
                         bool quatInterpolate,
                         osgAnimation::UpdateMatrixTransform* pUpdate,
                         osg::Matrix& staticTransform)
{
    if (prop.GetKFCurve(KFCURVENODE_R_X) ||
        prop.GetKFCurve(KFCURVENODE_R_Y) ||
        prop.GetKFCurve(KFCURVENODE_R_Z))
    {
        if (quatInterpolate)
        {
            if (!staticTransform.isIdentity())
            {
                pUpdate->getStackedTransforms().push_back(
                    new osgAnimation::StackedMatrixElement(staticTransform));
                staticTransform.makeIdentity();
            }
            pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedQuaternionElement(
                "quaternion", makeQuat(prop.Get(), fbxRotOrder)));
        }
        else
        {
            char* curveNames[3] = {KFCURVENODE_R_X, KFCURVENODE_R_Y, KFCURVENODE_R_Z};
            osg::Vec3 axes[3] = {osg::Vec3(1,0,0), osg::Vec3(0,1,0), osg::Vec3(0,0,1)};

            fbxDouble3 fbxPropValue = prop.Get();
            fbxPropValue[0] = osg::DegreesToRadians(fbxPropValue[0]);
            fbxPropValue[1] = osg::DegreesToRadians(fbxPropValue[1]);
            fbxPropValue[2] = osg::DegreesToRadians(fbxPropValue[2]);

            int order[3] = {0, 1, 2};
            getRotationOrder(fbxRotOrder, order);

            for (int i = 0; i < 3; ++i)
            {
                int j = order[2-i];
                if (prop.GetKFCurve(curveNames[j]))
                {
                    if (!staticTransform.isIdentity())
                    {
                        pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedMatrixElement(staticTransform));
                        staticTransform.makeIdentity();
                    }

                    pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedRotateAxisElement(
                        std::string("rotate") + curveNames[j], axes[j], fbxPropValue[j]));
                }
                else
                {
                    staticTransform.preMultRotate(osg::Quat(fbxPropValue[j], axes[j]));
                }
            }
        }
    }
    else
    {
        staticTransform.preMultRotate(makeQuat(prop.Get(), fbxRotOrder));
    }
}
Пример #2
0
void readUpdateMatrixTransform(osgAnimation::UpdateMatrixTransform* pUpdate, FbxNode* pNode, FbxScene& fbxScene)
{
    osg::Matrix staticTransform;

    readTranslationElement(pNode->LclTranslation, pUpdate, staticTransform, fbxScene);

    FbxDouble3 fbxRotOffset = pNode->RotationOffset.Get();
    FbxDouble3 fbxRotPiv = pNode->RotationPivot.Get();
    staticTransform.preMultTranslate(osg::Vec3d(
                                         fbxRotPiv[0] + fbxRotOffset[0],
                                         fbxRotPiv[1] + fbxRotOffset[1],
                                         fbxRotPiv[2] + fbxRotOffset[2]));

    // When this flag is set to false, the RotationOrder, the Pre/Post rotation
    // values and the rotation limits should be ignored.
    bool rotationActive = pNode->RotationActive.Get();

    EFbxRotationOrder fbxRotOrder = (rotationActive && pNode->RotationOrder.IsValid()) ?
                                    pNode->RotationOrder.Get() : eEulerXYZ;

    if (rotationActive)
    {
        staticTransform.preMultRotate(makeQuat(pNode->PreRotation.Get(), fbxRotOrder));
    }

    readRotationElement(pNode->LclRotation, fbxRotOrder,
                        pNode->QuaternionInterpolate.IsValid() && pNode->QuaternionInterpolate.Get(),
                        pUpdate, staticTransform, fbxScene);

    if (rotationActive)
    {
        staticTransform.preMultRotate(makeQuat(pNode->PostRotation.Get(), fbxRotOrder));
    }

    FbxDouble3 fbxSclOffset = pNode->ScalingOffset.Get();
    FbxDouble3 fbxSclPiv = pNode->ScalingPivot.Get();
    staticTransform.preMultTranslate(osg::Vec3d(
                                         fbxSclOffset[0] + fbxSclPiv[0] - fbxRotPiv[0],
                                         fbxSclOffset[1] + fbxSclPiv[1] - fbxRotPiv[1],
                                         fbxSclOffset[2] + fbxSclPiv[2] - fbxRotPiv[2]));

    readScaleElement(pNode->LclScaling, pUpdate, staticTransform, fbxScene);

    staticTransform.preMultTranslate(osg::Vec3d(
                                         -fbxSclPiv[0],
                                         -fbxSclPiv[1],
                                         -fbxSclPiv[2]));

    if (!staticTransform.isIdentity())
    {
        pUpdate->getStackedTransforms().push_back(new osgAnimation::StackedMatrixElement(staticTransform));
    }
}
osgAnimation::Channel* readFbxChannelsQuat(
    KFbxAnimCurve* curveX, KFbxAnimCurve* curveY, KFbxAnimCurve* curveZ,
    const fbxDouble3& defaultValue,
    const char* targetName, ERotationOrder rotOrder)
{
    if (!(curveX && curveX->KeyGetCount()) &&
        !(curveY && curveY->KeyGetCount()) &&
        !(curveZ && curveZ->KeyGetCount()))
    {
        return 0;
    }

    osgAnimation::QuatSphericalLinearChannel* pChannel = new osgAnimation::QuatSphericalLinearChannel;
    pChannel->setTargetName(targetName);
    pChannel->setName("quaternion");
    typedef std::vector<osgAnimation::TemplateKeyframe<osg::Vec3> > KeyFrameCntr;
    KeyFrameCntr eulerFrameCntr;
    readKeys(curveX, curveY, curveZ, defaultValue, eulerFrameCntr, static_cast<float>(osg::PI / 180.0));

    osgAnimation::QuatSphericalLinearSampler::KeyframeContainerType& quatFrameCntr =
        *pChannel->getOrCreateSampler()->getOrCreateKeyframeContainer();
    quatFrameCntr.reserve(eulerFrameCntr.size());

    for (KeyFrameCntr::iterator it = eulerFrameCntr.begin(), end = eulerFrameCntr.end();
        it != end; ++it)
    {
        const osg::Vec3& euler = it->getValue();
        quatFrameCntr.push_back(osgAnimation::QuatKeyframe(
            it->getTime(), makeQuat(euler, rotOrder)));
    }

    return pChannel;
}
osg::Quat makeQuat(const osg::Vec3& radians, ERotationOrder fbxRotOrder)
{
    fbxDouble3 degrees(
        osg::RadiansToDegrees(radians.x()),
        osg::RadiansToDegrees(radians.y()),
        osg::RadiansToDegrees(radians.z()));
    return makeQuat(degrees, fbxRotOrder);
}
Пример #5
0
void makeLocalMatrix(const FbxNode* pNode, osg::Matrix& m)
{
    /*From http://area.autodesk.com/forum/autodesk-fbx/fbx-sdk/the-makeup-of-the-local-matrix-of-an-kfbxnode/

    Local Matrix = LclTranslation * RotationOffset * RotationPivot *
      PreRotation * LclRotation * PostRotation * RotationPivotInverse *
      ScalingOffset * ScalingPivot * LclScaling * ScalingPivotInverse

    LocalTranslation : translate (xform -query -translation)
    RotationOffset: translation compensates for the change in the rotate pivot point (xform -q -rotateTranslation)
    RotationPivot: current rotate pivot position (xform -q -rotatePivot)
    PreRotation : joint orientation(pre rotation)
    LocalRotation: rotate transform (xform -q -rotation & xform -q -rotateOrder)
    PostRotation : rotate axis (xform -q -rotateAxis)
    RotationPivotInverse: inverse of RotationPivot
    ScalingOffset: translation compensates for the change in the scale pivot point (xform -q -scaleTranslation)
    ScalingPivot: current scale pivot position (xform -q -scalePivot)
    LocalScaling: scale transform (xform -q -scale)
    ScalingPivotInverse: inverse of ScalingPivot
    */

    // When this flag is set to false, the RotationOrder, the Pre/Post rotation
    // values and the rotation limits should be ignored.
    bool rotationActive = pNode->RotationActive.Get();

    EFbxRotationOrder fbxRotOrder = rotationActive ? pNode->RotationOrder.Get() : eEulerXYZ;

    FbxDouble3 fbxLclPos = pNode->LclTranslation.Get();
    FbxDouble3 fbxRotOff = pNode->RotationOffset.Get();
    FbxDouble3 fbxRotPiv = pNode->RotationPivot.Get();
    FbxDouble3 fbxPreRot = pNode->PreRotation.Get();
    FbxDouble3 fbxLclRot = pNode->LclRotation.Get();
    FbxDouble3 fbxPostRot = pNode->PostRotation.Get();
    FbxDouble3 fbxSclOff = pNode->ScalingOffset.Get();
    FbxDouble3 fbxSclPiv = pNode->ScalingPivot.Get();
    FbxDouble3 fbxLclScl = pNode->LclScaling.Get();

    m.makeTranslate(osg::Vec3d(
                        fbxLclPos[0] + fbxRotOff[0] + fbxRotPiv[0],
                        fbxLclPos[1] + fbxRotOff[1] + fbxRotPiv[1],
                        fbxLclPos[2] + fbxRotOff[2] + fbxRotPiv[2]));
    if (rotationActive)
    {
        m.preMultRotate(
            makeQuat(fbxPostRot, fbxRotOrder) *
            makeQuat(fbxLclRot, fbxRotOrder) *
            makeQuat(fbxPreRot, fbxRotOrder));
    }
    else
    {
        m.preMultRotate(makeQuat(fbxLclRot, fbxRotOrder));
    }
    m.preMultTranslate(osg::Vec3d(
                           fbxSclOff[0] + fbxSclPiv[0] - fbxRotPiv[0],
                           fbxSclOff[1] + fbxSclPiv[1] - fbxRotPiv[1],
                           fbxSclOff[2] + fbxSclPiv[2] - fbxRotPiv[2]));
    m.preMultScale(osg::Vec3d(fbxLclScl[0], fbxLclScl[1], fbxLclScl[2]));
    m.preMultTranslate(osg::Vec3d(
                           -fbxSclPiv[0],
                           -fbxSclPiv[1],
                           -fbxSclPiv[2]));
}
Пример #6
0
#include "Camera.h"
#include "CommonDefs.h"
#include <GLES2/gl2.h>
#include "Log.h"
#include <algorithm>

static const Quatf makeQuat(const float hdg, const float pitch, const float roll)
{
    return Quatf::fromAxisRot(Vector3f(static_cast<float>(std::sin(DEG2RAD(hdg))), 0, static_cast<float>(std::cos(DEG2RAD(hdg)))), pitch) *
           Quatf::fromAxisRot(Vector3f(0, 1, 0), hdg) *
           Quatf::fromAxisRot(Vector3f(1, 0, 0), roll);
}

const Quatf sQuats[] =
{
    makeQuat(0,    -45, 0),
    makeQuat(45,   -45, 0),
    makeQuat(90,   -45, 0),
    makeQuat(135,  -45, 0),
    makeQuat(180,  -45, 0),
    makeQuat(-135, -45, 0),
    makeQuat(-90,  -45, 0),
    makeQuat(-45,  -45, 0),
    makeQuat(0,    -88, 0),
    makeQuat(0,    -88, -90),
    makeQuat(0,    -88, -180),
    makeQuat(0,    -88, 90)
};

const float Camera::sTransitionTime = 0.3f;
const float Camera::sFOVNarrow = 45.0f;