📄 mgcskincontroller.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 "MgcSkinController.h"
#include "MgcGeometry.h"
#include "MgcNode.h"
MgcImplementRTTI(MgcSkinController,MgcController);
MgcImplementStream(MgcSkinController);
//----------------------------------------------------------------------------
MgcSkinController::MgcSkinController (MgcGeometry* pkObject)
{
MgcController::SetObject(pkObject);
m_uiBoneQuantity = 0;
m_apkBone = 0;
m_auiSkinVertexQuantity = 0;
m_aakSkinVertex = 0;
}
//----------------------------------------------------------------------------
MgcSkinController::~MgcSkinController ()
{
delete[] m_apkBone;
delete[] m_auiSkinVertexQuantity;
for (unsigned int uiB = 0; uiB < m_uiBoneQuantity; uiB++)
delete[] m_aakSkinVertex[uiB];
delete[] m_aakSkinVertex;
}
//----------------------------------------------------------------------------
bool MgcSkinController::Update (MgcReal fAppTime)
{
// The skin vertices are calculated in the bone world coordinate system.
// The bone world coordinates already includes the world transform of the
// common parent, so the world transforms for the skin mesh should be
// the identity.
MgcGeometry* pkGeom = (MgcGeometry*) m_pkObject;
pkGeom->SetWorldTransformToIdentity();
if ( !Active() )
return true;
// set all vertices to the zero vector
MgcVector3* akVertex = pkGeom->Vertices();
memset(akVertex,0,pkGeom->GetVertexQuantity()*sizeof(MgcVector3));
// update dependent vertices for each bone
for (unsigned int uiB = 0; uiB < m_uiBoneQuantity; uiB++)
{
MgcNode* pkBone = m_apkBone[uiB];
MgcMatrix3 kSRot = pkBone->WorldScale()*pkBone->WorldRotate();
unsigned int uiVMax = m_auiSkinVertexQuantity[uiB];
SkinVertex* pkSV = m_aakSkinVertex[uiB];
for (unsigned int uiV = 0; uiV < uiVMax; uiV++, pkSV++)
{
MgcVector3 kVTrn = kSRot*pkSV->m_kOffset +
pkBone->WorldTranslate();
akVertex[pkSV->m_uiIndex] += pkSV->m_fWeight*kVTrn;
}
}
// update vertex normals if the skin has them
if ( pkGeom->Normals() )
pkGeom->UpdateModelNormals();
pkGeom->UpdateModelBound();
// controller computes world transform
return true;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
// streaming
//----------------------------------------------------------------------------
MgcObject* MgcSkinController::Factory (MgcStream& rkStream)
{
MgcSkinController* pkObject = new MgcSkinController;
MgcStream::Link* pkLink = new MgcStream::Link(pkObject);
pkObject->Load(rkStream,pkLink);
return pkObject;
}
//----------------------------------------------------------------------------
void MgcSkinController::Load (MgcStream& rkStream, MgcStream::Link* pkLink)
{
MgcController::Load(rkStream,pkLink);
MgcStreamRead(rkStream,m_uiBoneQuantity);
m_apkBone = new MgcNode*[m_uiBoneQuantity];
MgcStreamRead(rkStream,m_apkBone,m_uiBoneQuantity);
unsigned int uiB;
for (uiB = 0; uiB < m_uiBoneQuantity; uiB++)
pkLink->Add(m_apkBone[uiB]);
m_auiSkinVertexQuantity = new unsigned int[m_uiBoneQuantity];
MgcStreamRead(rkStream,m_auiSkinVertexQuantity,m_uiBoneQuantity);
m_aakSkinVertex = new SkinVertex*[m_uiBoneQuantity];
for (uiB = 0; uiB < m_uiBoneQuantity; uiB++)
{
unsigned int uiVMax = m_auiSkinVertexQuantity[uiB];
m_aakSkinVertex[uiB] = new SkinVertex[uiVMax];
SkinVertex* pkSV = m_aakSkinVertex[uiB];
for (unsigned int uiV = 0; uiV < uiVMax; uiV++, pkSV++)
MgcStreamRead(rkStream,*pkSV);
}
}
//----------------------------------------------------------------------------
void MgcSkinController::Link (MgcStream& rkStream, MgcStream::Link* pkLink)
{
MgcController::Link(rkStream,pkLink);
for (unsigned int uiB = 0; uiB < m_uiBoneQuantity; uiB++)
{
MgcObject* pkLinkID = pkLink->GetLinkID();
m_apkBone[uiB] = (MgcNode*)rkStream.GetFromMap(pkLinkID);
}
}
//----------------------------------------------------------------------------
bool MgcSkinController::Register (MgcStream& rkStream)
{
if ( !MgcController::Register(rkStream) )
return false;
for (unsigned int uiB = 0; uiB < m_uiBoneQuantity; uiB++)
m_apkBone[uiB]->Register(rkStream);
return true;
}
//----------------------------------------------------------------------------
void MgcSkinController::Save (MgcStream& rkStream)
{
MgcController::Save(rkStream);
MgcStreamWrite(rkStream,m_uiBoneQuantity);
MgcStreamWrite(rkStream,m_apkBone,m_uiBoneQuantity);
MgcStreamWrite(rkStream,m_auiSkinVertexQuantity,m_uiBoneQuantity);
for (unsigned int uiB = 0; uiB < m_uiBoneQuantity; uiB++)
{
unsigned int uiVMax = m_auiSkinVertexQuantity[uiB];
SkinVertex* pkSV = m_aakSkinVertex[uiB];
for (unsigned int uiV = 0; uiV < uiVMax; uiV++, pkSV++)
MgcStreamWrite(rkStream,*pkSV);
}
}
//----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -