wmllattice.cpp
来自「3D Game Engine Design Source Code非常棒」· C++ 代码 · 共 275 行
CPP
275 行
// 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 "WmlLattice.h"
using namespace Wml;
using namespace std;
const char* Lattice::ms_acHeader = "Magic Image";
//----------------------------------------------------------------------------
Lattice::Lattice (int iDimensions, int* aiBound)
{
#ifdef _DEBUG
assert( iDimensions > 0 && aiBound );
for (int i = 0; i < iDimensions; i++)
{
assert( aiBound[i] > 0 );
}
#endif
m_iDimensions = iDimensions;
m_aiBound = aiBound;
m_aiOffset = new int[iDimensions];
ComputeQuantityAndOffsets();
}
//----------------------------------------------------------------------------
Lattice::Lattice (const Lattice& rkLattice)
{
m_iDimensions = rkLattice.m_iDimensions;
m_iQuantity = rkLattice.m_iQuantity;
m_aiBound = new int[m_iDimensions];
m_aiOffset = new int[m_iDimensions];
int iCopySize = m_iDimensions*sizeof(int);
memcpy(m_aiBound,rkLattice.m_aiBound,iCopySize);
memcpy(m_aiOffset,rkLattice.m_aiOffset,iCopySize);
}
//----------------------------------------------------------------------------
Lattice::Lattice (int iDimensions)
{
assert( iDimensions > 0 );
m_iDimensions = iDimensions;
m_aiBound = NULL;
m_aiOffset = new int[iDimensions];
memset(m_aiOffset,0,iDimensions*sizeof(int));
m_iQuantity = 0;
}
//----------------------------------------------------------------------------
Lattice::Lattice ()
{
m_iDimensions = 0;
m_aiBound = NULL;
m_aiOffset = NULL;
m_iQuantity = 0;
}
//----------------------------------------------------------------------------
Lattice::~Lattice ()
{
delete[] m_aiBound;
delete[] m_aiOffset;
}
//----------------------------------------------------------------------------
void Lattice::SetBounds (int* aiBound)
{
#ifdef _DEBUG
assert( aiBound );
for (int i = 0; i < m_iDimensions; i++)
{
assert( aiBound[i] > 0 );
}
#endif
m_aiBound = aiBound;
ComputeQuantityAndOffsets();
}
//----------------------------------------------------------------------------
void Lattice::ComputeQuantityAndOffsets ()
{
int i;
// calculate number of lattice points
m_iQuantity = 1;
for (i = 0; i < m_iDimensions; i++)
m_iQuantity *= m_aiBound[i];
// calculate offset indices of neighboring lattice points
m_aiOffset[0] = 1;
for (i = 1; i < m_iDimensions; i++)
m_aiOffset[i] = m_aiBound[i-1]*m_aiOffset[i-1];
}
//----------------------------------------------------------------------------
Lattice& Lattice::operator= (const Lattice& rkLattice)
{
if ( m_iDimensions != rkLattice.m_iDimensions )
{
delete[] m_aiBound;
delete[] m_aiOffset;
m_iDimensions = rkLattice.m_iDimensions;
m_iQuantity = rkLattice.m_iQuantity;
m_aiBound = new int[m_iDimensions];
m_aiOffset = new int[m_iDimensions];
}
int iCopySize = m_iDimensions*sizeof(int);
memcpy(m_aiBound,rkLattice.m_aiBound,iCopySize);
memcpy(m_aiOffset,rkLattice.m_aiOffset,iCopySize);
return *this;
}
//----------------------------------------------------------------------------
bool Lattice::operator== (const Lattice& rkLattice) const
{
if ( m_iDimensions != rkLattice.m_iDimensions )
return false;
int iCompareSize = m_iDimensions*sizeof(int);
return memcmp(m_aiBound,rkLattice.m_aiBound,iCompareSize) == 0;
}
//----------------------------------------------------------------------------
bool Lattice::operator!= (const Lattice& rkLattice) const
{
return !operator==(rkLattice);
}
//----------------------------------------------------------------------------
int Lattice::GetIndex (const int* aiCoord) const
{
// assert: auiCoord is array of m_iDimensions elements
int iIndex = aiCoord[0];
for (int i = 1; i < m_iDimensions; i++)
iIndex += m_aiOffset[i]*aiCoord[i];
return iIndex;
}
//----------------------------------------------------------------------------
void Lattice::GetCoordinates (int iIndex, int* aiCoord) const
{
// assert: aiCoord is array of m_iDimensions elements
for (int i = 0; i < m_iDimensions; i++)
{
aiCoord[i] = iIndex % m_aiBound[i];
iIndex /= m_aiBound[i];
}
}
//----------------------------------------------------------------------------
bool Lattice::Load (ifstream& rkIStr)
{
// Header is an ASCII string of 'char'. No need to swap bytes on big
// endian platforms.
int iSize = (int)strlen(ms_acHeader) + 1;
char* acBuffer = new char[iSize];
rkIStr.read(acBuffer,iSize);
acBuffer[iSize-1] = 0;
if ( strncmp(acBuffer,ms_acHeader,iSize) != 0 )
{
delete[] acBuffer;
m_iDimensions = 0;
m_iQuantity = 0;
m_aiBound = NULL;
m_aiOffset = NULL;
return false;
}
delete[] acBuffer;
rkIStr.read((char*)&m_iDimensions,sizeof(int));
#ifdef WML_BIG_ENDIAN
System::SwapBytes(sizeof(int),&m_iDimensions);
#endif
delete[] m_aiBound;
m_aiBound = new int[m_iDimensions];
rkIStr.read((char*)m_aiBound,m_iDimensions*sizeof(int));
#ifdef WML_BIG_ENDIAN
System::SwapBytes(sizeof(int),m_iDimensions,m_aiBound);
#endif
delete[] m_aiOffset;
m_aiOffset = new int[m_iDimensions];
ComputeQuantityAndOffsets();
return true;
}
//----------------------------------------------------------------------------
bool Lattice::Save (ofstream& rkOStr) const
{
// Header is an ASCII string of 'char'. No need to swap bytes on big
// endian platforms.
rkOStr.write(ms_acHeader,(int)strlen(ms_acHeader)+1);
#ifdef WML_BIG_ENDIAN
int iDummy = m_iDimensions;
System::SwapBytes(sizeof(int),&iDummy);
rkOStr.write((const char*)&iDummy,sizeof(int));
#else
rkOStr.write((const char*)&m_iDimensions,sizeof(int));
#endif
#ifdef WML_BIG_ENDIAN
for (int i = 0; i < m_iDimensions; i++)
{
iDummy = m_aiBound[i];
System::SwapBytes(sizeof(int),&iDummy);
rkOStr.write((const char*)&iDummy,sizeof(int));
}
#else
rkOStr.write((const char*)m_aiBound,m_iDimensions*sizeof(int));
#endif
return true;
}
//----------------------------------------------------------------------------
bool Lattice::LoadRaw (const char* acFilename, int& riDimensions,
int*& raiBound, int& riQuantity, int& riRTTI, int& riSizeOf,
char*& racData)
{
ifstream kIStr(acFilename,ios::in|ios::binary);
if ( !kIStr )
return false;
// Header is an ASCII string of 'char'. No need to swap bytes on big
// endian platforms.
int iSize = (int)strlen(ms_acHeader) + 1;
char* acBuffer = new char[iSize];
kIStr.read(acBuffer,iSize);
acBuffer[iSize-1] = 0;
if ( strncmp(acBuffer,ms_acHeader,iSize) != 0 )
{
delete[] acBuffer;
return false;
}
delete[] acBuffer;
kIStr.read((char*)&riDimensions,sizeof(int));
#ifdef WML_BIG_ENDIAN
System::SwapBytes(sizeof(int),&riDimensions);
#endif
raiBound = new int[riDimensions];
kIStr.read((char*)raiBound,riDimensions*sizeof(int));
#ifdef WML_BIG_ENDIAN
System::SwapBytes(sizeof(int),riDimensions,raiBound);
#endif
riQuantity = 1;
for (int i = 0; i < riDimensions; i++)
riQuantity *= raiBound[i];
kIStr.read((char*)&riRTTI,sizeof(int));
#ifdef WML_BIG_ENDIAN
System::SwapBytes(sizeof(int),&riRTTI);
#endif
kIStr.read((char*)&riSizeOf,sizeof(int));
#ifdef WML_BIG_ENDIAN
System::SwapBytes(sizeof(int),&riSizeOf);
#endif
racData = new char[riQuantity*riSizeOf];
kIStr.read(racData,riQuantity*riSizeOf);
#ifdef WML_BIG_ENDIAN
System::SwapBytes(riSizeOf,riQuantity,racData);
#endif
return true;
}
//----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?