📄 c3dbase.cpp
字号:
/*
============================================================================
* Name : C3DBase.cpp
* Part of : Example3D
* Description : Definition of C3DBase
* Copyright (c) 2007 Nokia Corporation
============================================================================
*/
// INCLUDES
#include "C3DBase.h"
#include <e32math.h>
#include <f32file.h>
// MEMBER FUNCTIONS
C3DBase* C3DBase::NewL( const TSize& aScreenSize )
{
C3DBase* self = new( ELeave )C3DBase( aScreenSize );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
C3DBase::~C3DBase()
{
delete[] iCos;
delete[] iSin;
}
C3DBase::C3DBase( const TSize& aScreenSize )
: iScreenSize( aScreenSize )
{
}
void C3DBase::ConstructL()
{
//
// generate sin & cos tables
//
iCos = new( ELeave )TInt16[ KSinTableSize ];
iSin = new( ELeave )TInt16[ KSinTableSize ];
TInt max = 1 << KShift;
TInt i;
for( i=0; i<KSinTableSize; i++ )
{
TReal r;
Math::Cos( r, KPi * i / (KSinTableSize/2) );
r *= max;
Math::Int( iCos[ i ], r );
Math::Sin( r, KPi * i / (KSinTableSize/2) );
r *= max;
Math::Int( iSin[ i ], r );
}
InitFrustum( iScreenSize );
}
void C3DBase::InitFrustum( const TSize& aScreenSize )
{
iScreenSize = aScreenSize;
TRect rect(aScreenSize);
//
// create view frustum
//
// calculate angles from screen size
// -1 because of rounding errors
// so we wouldn't draw outside visible screen
TReal r;
TInt lens = 512;
TInt32 xangle;
TInt32 yangle;
Math::ATan( r, 0.5 * iScreenSize.iWidth / lens );
r = r / KPi * KSinTableSize / 2 - 1;
Math::Int( xangle, r );
Math::ATan( r, 0.5 * iScreenSize.iHeight / lens );
r = r / KPi * KSinTableSize / 2 - 1;
Math::Int( yangle, r );
iViewFrustum.iNumPlanes = 5;
TInt a;
// near clipping plane
iViewFrustum.iPlane[ 0 ].iNormal = TVertex ( 0, 0, 1 << KShift );
iViewFrustum.iPlane[ 0 ].iDistance = -500 << KShift;
// left clipping plane
a = (TInt)( xangle ) & ( KSinTableSize-1 );
iViewFrustum.iPlane[ 1 ].iNormal = TVertex ( iCos[ a ], 0, iSin[ a ] );
iViewFrustum.iPlane[ 1 ].iDistance = 0;
// bottom clipping plane
a = ( ( KSinTableSize/2 )-yangle ) & ( KSinTableSize-1 );
iViewFrustum.iPlane[ 2 ].iNormal = TVertex ( 0, iCos[ a ], iSin[ a ] );
iViewFrustum.iPlane[ 2 ].iDistance = 0;
// right clipping plane
a = (TInt)( ( KSinTableSize/2 )-xangle ) & ( KSinTableSize-1 );
iViewFrustum.iPlane[ 3 ].iNormal = TVertex ( iCos[ a ], 0, iSin[ a ] );
iViewFrustum.iPlane[ 3 ].iDistance = 0;
// top clipping plane
a = ( yangle ) & ( KSinTableSize-1 );
iViewFrustum.iPlane[ 4 ].iNormal = TVertex ( 0, iCos[ a ], iSin[ a ] );
iViewFrustum.iPlane[ 4 ].iDistance = 0;
}
TInt16* C3DBase::CosTable()
{
return iCos;
}
TInt16* C3DBase::SinTable()
{
return iSin;
}
TFrustum& C3DBase::ViewFrustum()
{
return iViewFrustum;
}
TVertex C3DBase::RotateX( const TVertex& aVertex, TInt aAngle )
{
TInt c = iCos[ aAngle & ( KSinTableSize-1 ) ];
TInt s = iSin[ aAngle & ( KSinTableSize-1 ) ];
TVertex v;
v.iX = aVertex.iX;
v.iY = ( aVertex.iY * c - aVertex.iZ * s ) >> KShift;
v.iZ = ( aVertex.iY * s + aVertex.iZ * c ) >> KShift;
return v;
}
TVertex C3DBase::RotateY( const TVertex& aVertex, TInt aAngle )
{
TInt c = iCos[ aAngle & ( KSinTableSize-1 ) ];
TInt s = iSin[ aAngle & ( KSinTableSize-1 ) ];
TVertex v;
v.iX = ( aVertex.iX * c - aVertex.iZ * s ) >> KShift;
v.iY = aVertex.iY;
v.iZ = ( aVertex.iX * s + aVertex.iZ * c ) >> KShift;
return v;
}
TVertex C3DBase::RotateZ( const TVertex& aVertex, TInt aAngle )
{
TInt c = iCos[ aAngle & ( KSinTableSize-1 ) ];
TInt s = iSin[ aAngle & ( KSinTableSize-1 ) ];
TVertex v;
v.iX = ( aVertex.iX * c - aVertex.iY * s ) >> KShift;
v.iY = ( aVertex.iX * s + aVertex.iY * c ) >> KShift;
v.iZ = aVertex.iZ;
return v;
}
void C3DBase::QSort( TInt* aZ, TInt* aN, TInt aLow, TInt aHigh )
{
// the table aZ from range aLow..aHigh is sorted here
// the table aN is an index table for aZ table entries
// sorting method is a standard "quick sort"
if( aHigh <= aLow ) return;
TInt vz = aZ[ aLow ];
TInt vn = aN[ aLow ];
TInt lo = aLow;
TInt hi = aHigh;
TInt rPos = lo+1;
TInt z = aZ[ rPos ];
TInt n = aN[ rPos++ ];
TInt t;
for( TInt i=aLow+1; i<=aHigh; i++ )
{
if( z<vz )
{
aZ[ lo ] = z;
z = aZ[ rPos ];
aN[ lo++ ] = n;
n = aN[ rPos++ ];
}
else
{
t = aZ[ hi ];
aZ[ hi ] = z;
z = t;
t = aN[ hi ];
aN[ hi-- ] = n;
n = t;
}
}
aZ[ lo ] = vz;
aN[ lo ] = vn;
// this function will recursively call itself to arrange
// everything that wasn't arranged on this run.
QSort( aZ, aN, aLow, lo-1 );
QSort( aZ, aN, lo+1, aHigh );
}
TInt C3DBase::PolygonCount()
{
return iPolygonCount;
}
void C3DBase::ResetPolygonCount()
{
iPolygonCount = 0;
}
void C3DBase::AddPolygonCount( TInt aCount )
{
iPolygonCount += aCount;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -