📄 wmlkeyframecontroller.cpp
字号:
// 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 + -