?? c3drenderer.cpp
字號(hào):
/*
*
============================================================================
* Name : C3DRenderer.cpp
* Part of : Example3D
* Created : 12/14/2003 by Forum Nokia
* Description:
* This is the project specification file for Example3D.
* Initial content was generated by Series 60 AppWizard.
*
* Version : 1.0.0
* Copyright: Forum Nokia
*
============================================================================
*/
// INCLUDES
#include "C3DRenderer.h"
#include "C3DBase.h"
#include "M3dObject.h"
#include <e32svr.h>
// MEMBER FUNCTIONS
C3DRenderer* C3DRenderer::NewL( C3DBase* a3DBase, TInt aMaxObjects )
{
C3DRenderer* self = new( ELeave )C3DRenderer( a3DBase, aMaxObjects );
CleanupStack::PushL( self );
self->ConstructL();
CleanupStack::Pop( self );
return self;
}
C3DRenderer::~C3DRenderer()
{
delete iObject;
delete iObjectPosition;
delete iObjectMatrix;
delete iObjectRotMatrix;
delete iObjectPriority;
delete iObjectZ;
delete iObjectN;
}
void C3DRenderer::ConstructL()
{
// make room for object parameters for all objects:
iObject = new( ELeave )M3dObject*[ iMaxObjects ];
iObjectPosition = new( ELeave )TVertex[ iMaxObjects ];
iObjectMatrix = new( ELeave )TMatrix[ iMaxObjects ];
iObjectRotMatrix = new( ELeave )TMatrix[ iMaxObjects ];
iObjectPriority = new( ELeave )TInt[ iMaxObjects ];
// and put default values where needed:
iObjectZ = new( ELeave )TInt[ iMaxObjects ];
iObjectN = new( ELeave )TInt[ iMaxObjects ];
TInt i;
for( i=0; i<iMaxObjects; i++ )
{
iObject[ i ] = NULL;
iObjectPriority[ i ] = NULL;
}
}
C3DRenderer::C3DRenderer( C3DBase* a3DBase, TInt aMaxObjects )
: i3DBase( a3DBase )
, iMaxObjects( aMaxObjects )
, iCos( a3DBase->CosTable() )
, iSin( a3DBase->SinTable() )
{
}
TInt C3DRenderer::AddObject( M3dObject* aObject )
{
// scan object list for empty position and put new object there.
TBool found = EFalse;
TInt i = 0;
while( ( i<iMaxObjects ) && ( !found ) )
{
if( iObject[ i ] == NULL )
{
found = ETrue;
}
else
{
i++;
}
}
if( found )
{
iObject[ i ] = aObject;
iObjectPosition[ i ] = TVertex( 0,0,0 );
SetObjectAngle( i, TVertex( 0,0,0 ) );
}
return i;
}
void C3DRenderer::RemoveObject( TInt aIndex )
{
iObject[ aIndex ] = NULL;
}
void C3DRenderer::SetObjectPosition( TInt aIndex, const TVertex& aPosition )
{
iObjectPosition[ aIndex ] = aPosition;
}
void C3DRenderer::SetObjectAngle( TInt aIndex, const TVertex& aAngle )
{
// when object has new angle, the rotate matrix must be updated:
TInt c1 = iCos[ aAngle.iZ & 4095 ];
TInt s1 = iSin[ aAngle.iZ & 4095 ];
TInt c2 = iCos[ aAngle.iX & 4095 ];
TInt s2 = iSin[ aAngle.iX & 4095 ];
TInt c3 = iCos[ aAngle.iY & 4095 ];
TInt s3 = iSin[ aAngle.iY & 4095 ];
TInt v1 = 1 << KShift;
// rotation order around axises: Z, X, Y
// order can be changed here ( order is backwards to definition )
TMatrix objRot( c3, 0, -s3, 0, // rotation matrix around Y-axis
0, v1, 0, 0,
s3, 0, c3, 0 );
objRot *= TMatrix( v1, 0, 0, 0, // rotation matrix around X-axis
0, c2, -s2, 0,
0, s2, c2, 0 );
objRot *= TMatrix( c1, -s1, 0, 0, // rotation matrix around Z-axis
s1, c1, 0, 0,
0, 0, v1, 0 );
iObjectMatrix[ aIndex ] = objRot;
}
void C3DRenderer::SetObjectPriority( TInt aIndex, TInt aPriority )
{
iObjectPriority[ aIndex ] = aPriority;
}
void C3DRenderer::SetCameraPosition( const TVertex& aPosition )
{
iCameraPosition = aPosition;
}
void C3DRenderer::SetCameraAngle( const TVertex& aAngle )
{
iCameraAngle = aAngle;
}
void C3DRenderer::Draw( const TBitmap& aScreen )
{
TInt i;
TInt v1 = 1 << KShift;
TInt c1 = iCos[ iCameraAngle.iY & 4095 ];
TInt s1 = iSin[ iCameraAngle.iY & 4095 ];
TInt c2 = iCos[ iCameraAngle.iX & 4095 ];
TInt s2 = iSin[ iCameraAngle.iX & 4095 ];
TInt c3 = iCos[ iCameraAngle.iZ & 4095 ];
TInt s3 = iSin[ iCameraAngle.iZ & 4095 ];
// Calculate camera rotation matrix:
TMatrix camRot( c3, -s3, 0, 0, // Z-axis
s3, c3, 0, 0,
0, 0, v1, 0 );
camRot *= TMatrix( v1, 0, 0, 0, // X-axis
0, c2, -s2, 0,
0, s2, c2, 0 );
camRot *= TMatrix( c1, 0, -s1, 0, // Y-axis
0,v1, 0, 0,
s1, 0, c1, 0 );
// and add camera position
camRot *= TMatrix ( v1, 0, 0, -iCameraPosition.iX,
0, v1, 0, -iCameraPosition.iY,
0, 0, v1, -iCameraPosition.iZ );
TFrustum frustum( i3DBase->ViewFrustum() );
// rotate all objects to their place in space
TInt numObjects = 0;
for( i=0; i<iMaxObjects; i++ )
{
if( iObject[ i ] != NULL ) // objectlist can contain empty indexes
{
iObjectMatrix[ i ][ 3 ] = iObjectPosition[ i ].iX;
iObjectMatrix[ i ][ 7 ] = iObjectPosition[ i ].iY;
iObjectMatrix[ i ][ 11] = iObjectPosition[ i ].iZ;
TMatrix& obj = iObjectRotMatrix[ numObjects ];
obj = camRot;
obj *= iObjectMatrix[ i ];
TVertex objPos( obj[ 3 ], obj[ 7 ], obj[ 11 ] );
// check if object is inside view frustum
TBool visible = ETrue;
for( TInt n=0; n<frustum.iNumPlanes; n++ )
{
TVertex& mv1 = frustum.iPlane[ n ].iNormal;
// calculate dot product to get point distance to plane:
TInt l = mv1.iX * objPos.iX + mv1.iY * objPos.iY + mv1.iZ * objPos.iZ;
l += frustum.iPlane[ n ].iDistance;
l >>= KShift;
l += iObject[ i ]->iBoundingRadius;
if( l < 0 )
{
visible = EFalse;
break;
}
}
if( visible )
{
// calculate object distance from camera
// used for object sorting
TInt d = objPos.iX*objPos.iX + objPos.iY*objPos.iY + objPos.iZ*objPos.iZ + iObjectPriority[ i ];
iObjectZ[ numObjects ] = d;
iObjectN[ numObjects ] = ( i << 16 ) + numObjects;
numObjects++;
}
}
}
// sort
i3DBase->QSort( iObjectZ, iObjectN, 0, numObjects-1 );
// draw sorted back to front
for( i=numObjects-1; i>=0; i-- )
{
TInt n1 = iObjectN[ i ] & 0xffff;
TInt n2 = iObjectN[ i ] >> 16;
iObject[ n2 ]->Draw( aScreen, &iObjectRotMatrix[ n1 ] );
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -