📄 mgcmorphcontroller.cpp
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement. The various license agreements may be found at
// the Magic Software web site. This file is subject to the license
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf
#include "MgcGeometry.h"
#include "MgcMorphController.h"
MgcImplementRTTI(MgcMorphController,MgcController);
MgcImplementStream(MgcMorphController);
//----------------------------------------------------------------------------
MgcMorphController::MgcMorphController (MgcGeometry* pkObject)
{
m_uiTargetQuantity = 0;
m_aakVertex = 0;
m_bUpdateNormals = false;
m_uiKeyQuantity = 0;
m_afTime = 0;
m_aafWeight = 0;
m_uiLastIndex = 0;
}
//----------------------------------------------------------------------------
MgcMorphController::~MgcMorphController ()
{
DeleteTargets();
DeleteTimes();
DeleteWeights();
}
//----------------------------------------------------------------------------
void MgcMorphController::DeleteTargets ()
{
if ( m_aakVertex )
{
for (unsigned int uiT = 0; uiT < m_uiTargetQuantity; uiT++)
delete[] m_aakVertex[uiT];
delete[] m_aakVertex;
m_aakVertex = 0;
}
}
//----------------------------------------------------------------------------
void MgcMorphController::DeleteTimes ()
{
delete[] m_afTime;
m_afTime = 0;
}
//----------------------------------------------------------------------------
void MgcMorphController::DeleteWeights ()
{
if ( m_aafWeight )
{
for (unsigned int uiK = 0; uiK < m_uiKeyQuantity; uiK++)
delete[] m_aafWeight[uiK];
delete[] m_aafWeight;
m_aafWeight = 0;
}
}
//----------------------------------------------------------------------------
void MgcMorphController::SetTargetQuantity (unsigned int uiTargetQuantity)
{
assert( uiTargetQuantity > 0 );
DeleteTargets();
m_uiTargetQuantity = uiTargetQuantity;
m_aakVertex = new MgcVector3*[m_uiTargetQuantity];
memset(m_aakVertex,0,m_uiTargetQuantity*sizeof(MgcVector3*));
}
//----------------------------------------------------------------------------
void MgcMorphController::SetKeyQuantity (unsigned int uiKeyQuantity)
{
assert( uiKeyQuantity > 0 );
DeleteTimes();
DeleteWeights();
m_uiKeyQuantity = uiKeyQuantity;
m_aafWeight = new MgcReal*[m_uiKeyQuantity];
memset(m_aafWeight,0,m_uiKeyQuantity*sizeof(MgcReal*));
}
//----------------------------------------------------------------------------
void MgcMorphController::GetKeyInfo (MgcReal fCtrlTime, MgcReal& rfTime,
MgcReal& rfOmTime, unsigned int& ruiI0, unsigned int& ruiI1)
{
if ( fCtrlTime <= m_afTime[0] )
{
rfTime = 0.0;
rfOmTime = 1.0;
m_uiLastIndex = 0;
ruiI0 = 0;
ruiI1 = 0;
return;
}
if ( fCtrlTime >= m_afTime[m_uiKeyQuantity-1] )
{
rfTime = 0.0;
rfOmTime = 1.0;
m_uiLastIndex = m_uiKeyQuantity - 1;
ruiI0 = m_uiLastIndex;
ruiI1 = m_uiLastIndex;
return;
}
unsigned int uiNextIndex;
if ( fCtrlTime > m_afTime[m_uiLastIndex] )
{
uiNextIndex = m_uiLastIndex + 1;
while ( fCtrlTime >= m_afTime[uiNextIndex] )
{
m_uiLastIndex = uiNextIndex;
uiNextIndex++;
}
ruiI0 = m_uiLastIndex;
ruiI1 = uiNextIndex;
rfTime = (fCtrlTime - m_afTime[ruiI0]) /
(m_afTime[ruiI1] - m_afTime[ruiI0]);
}
else if ( fCtrlTime < m_afTime[m_uiLastIndex] )
{
uiNextIndex = m_uiLastIndex - 1;
while ( fCtrlTime <= m_afTime[uiNextIndex] )
{
m_uiLastIndex = uiNextIndex;
uiNextIndex--;
}
ruiI0 = uiNextIndex;
ruiI1 = m_uiLastIndex;
rfTime = (fCtrlTime - m_afTime[ruiI0]) /
(m_afTime[ruiI1] - m_afTime[ruiI0]);
}
else
{
rfTime = 0.0;
ruiI0 = m_uiLastIndex;
ruiI1 = m_uiLastIndex;
}
rfOmTime = 1.0 - rfTime;
}
//----------------------------------------------------------------------------
bool MgcMorphController::Update (MgcReal fAppTime)
{
// The key interpolation uses linear interpolation. To get higher-order
// interpolation, you need to provide a more sophisticated key (Bezier
// cubic or TCB spline, for example).
if ( !Active() )
{
// controller does not compute world transform
return false;
}
// set vertices to target[0]
MgcGeometry* pkGeom = (MgcGeometry*) m_pkObject;
unsigned int uiVertexQuantity = pkGeom->GetVertexQuantity();
MgcVector3* akVertex = pkGeom->Vertices();
memcpy(akVertex,m_aakVertex[0],uiVertexQuantity*sizeof(MgcVector3));
// lookup the bounding keys
MgcReal fCtrlTime = GetControlTime(fAppTime);
MgcReal fNT, fOmNT;
unsigned int uiI0, uiI1;
GetKeyInfo(fCtrlTime,fNT,fOmNT,uiI0,uiI1);
// add the remaining components in the convex composition
for (unsigned int uiT = 1; uiT < m_uiTargetQuantity; uiT++)
{
MgcReal fCoeff = fOmNT*m_aafWeight[uiI0][uiT-1] +
fNT*m_aafWeight[uiI1][uiT-1];
for (unsigned int uiV = 0; uiV < uiVertexQuantity; uiV++)
akVertex[uiV] += fCoeff*m_aakVertex[uiT][uiV];
}
// controller does not compute world transform
return false;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// streaming
//----------------------------------------------------------------------------
MgcObject* MgcMorphController::Factory (MgcStream& rkStream)
{
MgcMorphController* pkObject = new MgcMorphController;
MgcStream::Link* pkLink = new MgcStream::Link(pkObject);
pkObject->Load(rkStream,pkLink);
return pkObject;
}
//----------------------------------------------------------------------------
void MgcMorphController::Load (MgcStream& rkStream, MgcStream::Link* pkLink)
{
MgcController::Load(rkStream,pkLink);
MgcStreamRead(rkStream,m_uiTargetQuantity);
SetTargetQuantity(m_uiTargetQuantity);
unsigned int uiVertexQuantity;
MgcStreamRead(rkStream,uiVertexQuantity);
for (unsigned int uiT = 0; uiT < m_uiTargetQuantity; uiT++)
{
MgcVector3* akVertex = new MgcVector3[uiVertexQuantity];
MgcStreamRead(rkStream,akVertex,uiVertexQuantity);
SetVertices(uiT,akVertex);
}
MgcStreamRead(rkStream,m_bUpdateNormals);
MgcStreamRead(rkStream,m_uiKeyQuantity);
SetKeyQuantity(m_uiKeyQuantity);
MgcReal* afTime = new MgcReal[m_uiKeyQuantity];
MgcStreamRead(rkStream,afTime,m_uiKeyQuantity);
SetTimes(afTime);
for (unsigned int uiK = 0; uiK < m_uiKeyQuantity; uiK++)
{
MgcReal* afWeight = new MgcReal[m_uiKeyQuantity-1];
MgcStreamRead(rkStream,afWeight,m_uiKeyQuantity-1);
SetWeights(uiK,afWeight);
}
}
//----------------------------------------------------------------------------
void MgcMorphController::Link (MgcStream& rkStream, MgcStream::Link* pkLink)
{
MgcController::Link(rkStream,pkLink);
}
//----------------------------------------------------------------------------
bool MgcMorphController::Register (MgcStream& rkStream)
{
return MgcController::Register(rkStream);
}
//----------------------------------------------------------------------------
void MgcMorphController::Save (MgcStream& rkStream)
{
MgcController::Save(rkStream);
MgcStreamWrite(rkStream,m_uiTargetQuantity);
MgcGeometry* pkGeom = (MgcGeometry*) m_pkObject;
unsigned int uiVertexQuantity = pkGeom->GetVertexQuantity();
MgcStreamWrite(rkStream,uiVertexQuantity);
for (unsigned int uiT = 0; uiT < m_uiTargetQuantity; uiT++)
MgcStreamWrite(rkStream,m_aakVertex[uiT],uiVertexQuantity);
MgcStreamWrite(rkStream,m_bUpdateNormals);
MgcStreamWrite(rkStream,m_uiKeyQuantity);
MgcStreamWrite(rkStream,m_afTime,m_uiKeyQuantity);
for (unsigned int uiK = 0; uiK < m_uiKeyQuantity; uiK++)
MgcStreamWrite(rkStream,m_aafWeight[uiK],m_uiKeyQuantity-1);
}
//----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -