⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmlkeyframecontroller.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2003.  All Rights Reserved
//
// The Wild Magic Library (WML) source code is supplied under the terms of
// the license agreement http://www.magic-software.com/License/WildMagic.pdf
// and may not be copied or disclosed except in accordance with the terms of
// that agreement.

#include "WmlKeyframeController.h"
#include "WmlSpatial.h"
using namespace Wml;

WmlImplementRTTI(KeyframeController,Controller);
WmlImplementStream(KeyframeController);

//----------------------------------------------------------------------------
KeyframeController::KeyframeController ()
{
    m_iTQuantity = 0;
    m_afTTime = NULL;
    m_akTData = NULL;
    m_iTLastIndex = 0;

    m_iRQuantity = 0;
    m_afRTime = NULL;
    m_akRData = NULL;
    m_iRLastIndex = 0;

    m_iSQuantity = 0;
    m_afSTime = NULL;
    m_afSData = NULL;
    m_iSLastIndex = 0;

    m_iSharedQuantity = 0;
    m_afSharedTime = NULL;
    m_iSharedLastIndex = 0;
}
//----------------------------------------------------------------------------
KeyframeController::~KeyframeController ()
{
    delete[] m_akTData;
    delete[] m_akRData;
    delete[] m_afSData;

    if ( m_iSharedQuantity > 0 )
    {
        delete[] m_afSharedTime;
    }
    else
    {
        delete[] m_afTTime;
        delete[] m_afRTime;
        delete[] m_afSTime;
    }
}
//----------------------------------------------------------------------------
void KeyframeController::SetSharedQuantity (int iQuantity)
{
    m_iSharedQuantity = iQuantity;
    m_iTQuantity = iQuantity;
    m_iRQuantity = iQuantity;
    m_iSQuantity = iQuantity;
}
//----------------------------------------------------------------------------
void KeyframeController::SetSharedTimes (float* afTime)
{
    m_afSharedTime = afTime;
    m_afTTime = afTime;
    m_afRTime = afTime;
    m_afSTime = afTime;
}
//----------------------------------------------------------------------------
void KeyframeController::GetKeyInfo (float fCtrlTime, int iQuantity,
    float* afTime, int& riLastIndex, float& rfTime, int& ri0, int& ri1)
{
    if ( fCtrlTime <= afTime[0] )
    {
        rfTime = 0.0f;
        riLastIndex = 0;
        ri0 = 0;
        ri1 = 0;
        return;
    }

    if ( fCtrlTime >= afTime[iQuantity-1] )
    {
        rfTime = 0.0f;
        riLastIndex = iQuantity - 1;
        ri0 = riLastIndex;
        ri1 = riLastIndex;
        return;
    }

    int iNextIndex;
    if ( fCtrlTime > afTime[riLastIndex] )
    {
        iNextIndex = riLastIndex + 1;
        while ( fCtrlTime >= afTime[iNextIndex] )
        {
            riLastIndex = iNextIndex;
            iNextIndex++;
        }

        ri0 = riLastIndex;
        ri1 = iNextIndex;
        rfTime = (fCtrlTime - afTime[ri0])/(afTime[ri1] - afTime[ri0]);
    }
    else if ( fCtrlTime < afTime[riLastIndex] )
    {
        iNextIndex = riLastIndex - 1;
        while ( fCtrlTime <= afTime[iNextIndex] )
        {
            riLastIndex = iNextIndex;
            iNextIndex--;
        }

        ri0 = iNextIndex;
        ri1 = riLastIndex;
        rfTime = (fCtrlTime - afTime[ri0])/(afTime[ri1] - afTime[ri0]);
    }
    else
    {
        rfTime = 0.0f;
        ri0 = riLastIndex;
        ri1 = riLastIndex;
    }
}
//----------------------------------------------------------------------------
Vector3f KeyframeController::GetTranslation (float fNormTime, int i0, int i1)
{
    return m_akTData[i0] + fNormTime*(m_akTData[i1] - m_akTData[i0]);
}
//----------------------------------------------------------------------------
Matrix3f KeyframeController::GetRotation (float fNormTime, int i0, int i1)
{
    Quaternionf kQ = Quaternionf::Slerp(fNormTime,m_akRData[i0],
        m_akRData[i1]);

    Matrix3f kRot;
    kQ.ToRotationMatrix(kRot);
    return kRot;
}
//----------------------------------------------------------------------------
float KeyframeController::GetScale (float fNormTime, int i0, int i1)
{
    return m_afSData[i0] + fNormTime*(m_afSData[i1] - m_afSData[i0]);
}
//----------------------------------------------------------------------------
bool KeyframeController::Update (float fAppTime)
{
    if ( !Active() )
    {
        // controller does not compute world transform
        return false;
    }

    Spatial* pkSpatial = (Spatial*) m_pkObject;
    float fCtrlTime = GetControlTime(fAppTime);
    float fNormTime;
    int i0, i1;

    if ( m_iSharedQuantity > 0 )
    {
        GetKeyInfo(fCtrlTime,m_iSharedQuantity,m_afSharedTime,
            m_iSharedLastIndex,fNormTime,i0,i1);

        if ( m_iTQuantity > 0 )
            pkSpatial->Translate() = GetTranslation(fNormTime,i0,i1);

        if ( m_iRQuantity > 0 )
            pkSpatial->Rotate() = GetRotation(fNormTime,i0,i1);

        if ( m_iSQuantity > 0 )
            pkSpatial->Scale() = GetScale(fNormTime,i0,i1);
    }
    else
    {
        if ( m_iTQuantity > 0 )
        {
            GetKeyInfo(fCtrlTime,m_iTQuantity,m_afTTime,m_iTLastIndex,
                fNormTime,i0,i1);
            pkSpatial->Translate() = GetTranslation(fNormTime,i0,i1);
        }

        if ( m_iRQuantity > 0 )
        {
            GetKeyInfo(fCtrlTime,m_iRQuantity,m_afRTime,m_iRLastIndex,
                fNormTime,i0,i1);
            pkSpatial->Rotate() = GetRotation(fNormTime,i0,i1);
        }

        if ( m_iSQuantity > 0 )
        {
            GetKeyInfo(fCtrlTime,m_iSQuantity,m_afSTime,m_iSLastIndex,
                fNormTime,i0,i1);
            pkSpatial->Scale() = GetScale(fNormTime,i0,i1);
        }
    }

    // controller does not compute world transform
    return false;
}
//----------------------------------------------------------------------------

//----------------------------------------------------------------------------
// streaming
//----------------------------------------------------------------------------
Object* KeyframeController::Factory (Stream& rkStream)
{
    KeyframeController* pkObject = new KeyframeController;
    Stream::Link* pkLink = new Stream::Link(pkObject);
    pkObject->Load(rkStream,pkLink);
    return pkObject;
}
//----------------------------------------------------------------------------
void KeyframeController::Load (Stream& rkStream,
    Stream::Link* pkLink)
{
    Controller::Load(rkStream,pkLink);

    bool bShared;
    StreamReadBool(rkStream,bShared);

    if ( bShared )
    {
        StreamRead(rkStream,m_iSharedQuantity);
        if ( m_iSharedQuantity > 0 )
        {
            m_afSharedTime = new float[m_iSharedQuantity];
            m_akTData = new Vector3f[m_iSharedQuantity];
            m_akRData = new Quaternionf[m_iSharedQuantity];
            m_afSData = new float[m_iSharedQuantity];

            StreamRead(rkStream,m_afSharedTime,m_iSharedQuantity);
            StreamRead(rkStream,m_akTData,m_iSharedQuantity);
            StreamRead(rkStream,m_akRData,m_iSharedQuantity);
            StreamRead(rkStream,m_afSData,m_iSharedQuantity);

            SetSharedQuantity(m_iSharedQuantity);
        }
    }
    else
    {
        StreamRead(rkStream,m_iTQuantity);
        if ( m_iTQuantity > 0 )
        {
            m_afTTime = new float[m_iTQuantity];
            m_akTData = new Vector3f[m_iTQuantity];
            StreamRead(rkStream,m_afTTime,m_iTQuantity);
            StreamRead(rkStream,m_akTData,m_iTQuantity);
        }

        StreamRead(rkStream,m_iRQuantity);
        if ( m_iRQuantity > 0 )
        {
            m_afRTime = new float[m_iRQuantity];
            m_akRData = new Quaternionf[m_iRQuantity];
            StreamRead(rkStream,m_afRTime,m_iRQuantity);
            StreamRead(rkStream,m_akRData,m_iRQuantity);
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -