port from perforce
This commit is contained in:
331
evoke-64k/bp10/blocktree.cpp
Normal file
331
evoke-64k/bp10/blocktree.cpp
Normal file
@@ -0,0 +1,331 @@
|
||||
#include "blocktree.h"
|
||||
#include "globals.h"
|
||||
#include "intrin.h"
|
||||
|
||||
static const int m_iMaxBlockTrees= 16;
|
||||
BlockTree g_BlockTrees[ m_iMaxBlockTrees ];
|
||||
|
||||
static const int m_iMaxTreeElements= 2 * 1024 * 128;
|
||||
BlockTreeElement g_BlockElements[ m_iMaxTreeElements ];
|
||||
int g_iBlockElementsUsed= 0;
|
||||
|
||||
static const int m_iMaxTreeBuilderElements= 512;
|
||||
BlockTreeBuilder g_BuilderStack[ m_iMaxTreeBuilderElements ];
|
||||
int g_iLastBuilderElement= 0;
|
||||
|
||||
static const int g_iMaxBlocksPerTree= 1024 * 2;
|
||||
|
||||
static float fMinSize;
|
||||
|
||||
void CreateBlockTree();
|
||||
void MoveBTB( BlockTreeBuilder& btb, float fStep );
|
||||
void ProcessTree( BlockTree* t );
|
||||
BlockTreeElement* AddTreeBox( BlockTree* t, BlockTreeBuilder& btb );
|
||||
void AddBuilderStack( BlockTreeBuilder& btb, int iLeafMode );
|
||||
|
||||
void BlockTree::Init()
|
||||
{
|
||||
m_pElements= NULL;
|
||||
m_iElementcount= 0;
|
||||
m_fBaseTime= 0.0f;
|
||||
m_fLastChangeTime= -1.0f;
|
||||
}
|
||||
|
||||
bool BlockTree::IsActive( float fTime )
|
||||
{
|
||||
if( fTime > m_fBaseTime )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void BlockTree::AddToScene( float fTime, int iObject )
|
||||
{
|
||||
if( fTime > m_fLastChangeTime )
|
||||
{
|
||||
return;
|
||||
}
|
||||
fTime-= m_fBaseTime;
|
||||
|
||||
g_Objects[ iObject ].Lock();
|
||||
for( int i= 0; i < m_iElementcount; ++i )
|
||||
{
|
||||
BlockTreeElement& b= m_pElements[ i ];
|
||||
float fElemTime= fTime - b.m_fTimeOffset;
|
||||
if( fElemTime > 0.0f )
|
||||
{
|
||||
D3DXVECTOR3 Pos( b.m_v3Pos );
|
||||
D3DXVECTOR3 Rot( b.m_v3Rot );
|
||||
float fSize= b.m_fSize;
|
||||
if( fElemTime < m_fTimeStep )
|
||||
{
|
||||
float fLerp= fElemTime / m_fTimeStep;
|
||||
fSize*= fLerp;
|
||||
if( b.m_ParentObject != NULL )
|
||||
{
|
||||
D3DXVec3Lerp( &Rot, &(b.m_ParentObject->m_v3Rot), &Rot, fLerp );
|
||||
fLerp= 0.5f + 0.5f * fLerp;
|
||||
D3DXVec3Lerp( &Pos, &(b.m_ParentObject->m_v3Pos), &Pos, fLerp );
|
||||
}
|
||||
}
|
||||
D3DXVECTOR3 Size( fSize, fSize, fSize );
|
||||
|
||||
g_Objects[ iObject ].AddBox(
|
||||
Pos,
|
||||
Size,
|
||||
Rot,
|
||||
0xffffffff,
|
||||
b.m_fColor, 0.0f );
|
||||
}
|
||||
}
|
||||
g_Objects[ iObject ].Unlock();
|
||||
}
|
||||
|
||||
void PrepareBlockTrees()
|
||||
{
|
||||
for( int i= OI_BlockTreeFirst; i <= OI_BlockTreeLast; ++i )
|
||||
{
|
||||
g_Objects[ i ].Create( 4 * 6 * g_iMaxBlocksPerTree, 6 * 6 * g_iMaxBlocksPerTree, true );
|
||||
g_Objects[ i ].m_iUsedShader[ 0 ]= Rainbow;
|
||||
g_Objects[ i ].m_iUsedPreShader= PreDepth;
|
||||
}
|
||||
for( int i= 0; i < m_iMaxBlockTrees; ++i )
|
||||
{
|
||||
g_BlockTrees[ i ].Init();
|
||||
}
|
||||
|
||||
CreateBlockTree();
|
||||
}
|
||||
|
||||
void AddBlockTreesToScene( float fTime )
|
||||
{
|
||||
for( int i= 0; i < m_iMaxBlockTrees; ++i )
|
||||
{
|
||||
if( g_BlockTrees[ i ].IsActive( fTime ) )
|
||||
{
|
||||
assert( OI_BlockTreeFirst + i < OI_BlockTreeLast );
|
||||
g_BlockTrees[ i ].AddToScene( fTime, OI_BlockTreeFirst + i );
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Objects[ OI_BlockTreeFirst + i ].HideVertexData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CreateBlockTree()
|
||||
{
|
||||
g_Random.setSeed( 17 );
|
||||
fMinSize= 0.25f;
|
||||
{
|
||||
BlockTree* t= g_BlockTrees;
|
||||
|
||||
t->m_iElementcount= 0;
|
||||
t->m_pElements= g_BlockElements + g_iBlockElementsUsed;
|
||||
t->m_fTimeStep= 0.125f;
|
||||
|
||||
g_iLastBuilderElement= 1;
|
||||
BlockTreeBuilder* btb= g_BuilderStack;
|
||||
btb->m_v3Pos=D3DXVECTOR3( 0.0f,
|
||||
-2.5f,
|
||||
0.0f );
|
||||
|
||||
btb->m_v3Rot=D3DXVECTOR3( 0, 0, 0 );
|
||||
btb->m_iWalkAxis= 2;
|
||||
btb->m_fSize= 1.75f;
|
||||
btb->m_fColor= 0.0f;
|
||||
btb->m_fSizeChange= 119.0f / 128.0f;
|
||||
btb->m_fRotOffset= 0.0f;
|
||||
btb->m_fTimeOffset= 0.0f;
|
||||
btb->m_iLevel= 0;
|
||||
btb->m_pParent= NULL;
|
||||
|
||||
t->m_fBaseTime= 12.0f;
|
||||
t->m_fLastChangeTime= t->m_fBaseTime + 5.0f;
|
||||
|
||||
ProcessTree(t);
|
||||
|
||||
g_iBlockElementsUsed+= t->m_iElementcount;
|
||||
}
|
||||
|
||||
g_Random.setSeed( 43 );
|
||||
fMinSize= 0.125f;
|
||||
for( int i= 1; i < m_iMaxBlockTrees; ++i )
|
||||
{
|
||||
BlockTree* t= g_BlockTrees + i;
|
||||
|
||||
t->m_iElementcount= 0;
|
||||
t->m_pElements= g_BlockElements + g_iBlockElementsUsed;
|
||||
t->m_fTimeStep= 0.125f;
|
||||
|
||||
g_iLastBuilderElement= 1;
|
||||
BlockTreeBuilder* btb= g_BuilderStack;
|
||||
btb->m_v3Pos=D3DXVECTOR3( g_Random.genFloat( -18.0f, 18.0f ),
|
||||
-1.5f,
|
||||
g_Random.genFloat( -18.0f, 18.0f ) );
|
||||
|
||||
btb->m_v3Rot=D3DXVECTOR3( g_Random.genFloat( 0.0f, c_PI ), 0, 0 );
|
||||
btb->m_iWalkAxis= 2;
|
||||
btb->m_fSize= g_Random.genFloat( 0.7f, 1.0f );
|
||||
btb->m_fColor= 0.0f;
|
||||
btb->m_fSizeChange= 59.0f / 64.0f;
|
||||
btb->m_fRotOffset= 0.0f;
|
||||
btb->m_fTimeOffset= 0.0f;
|
||||
btb->m_iLevel= 0;
|
||||
btb->m_pParent= NULL;
|
||||
|
||||
t->m_fBaseTime= 34.0f - btb->m_v3Pos.z / 6.0f;
|
||||
t->m_fLastChangeTime= t->m_fBaseTime + 5.0f;
|
||||
|
||||
ProcessTree(t);
|
||||
|
||||
g_iBlockElementsUsed+= t->m_iElementcount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MoveBTB( BlockTreeBuilder& btb, float fStep )
|
||||
{
|
||||
D3DXVECTOR3 Move( 0, 0, 0 );
|
||||
D3DXVECTOR3 Rot( 0, 0, 0 );
|
||||
|
||||
switch( btb.m_iWalkAxis )
|
||||
{
|
||||
case 1:
|
||||
Move.x+= fStep;
|
||||
Rot.z+= c_PI;
|
||||
break;
|
||||
case 2:
|
||||
Move.y+= fStep;
|
||||
Rot.z+= c_PI;
|
||||
break;
|
||||
case 3:
|
||||
Move.z+= fStep;
|
||||
Rot.y-= c_PI;
|
||||
break;
|
||||
case -1:
|
||||
Move.x-= fStep;
|
||||
Rot.z-= c_PI;
|
||||
break;
|
||||
case -2:
|
||||
Move.y-= fStep;
|
||||
Rot.z+= c_PI;
|
||||
break;
|
||||
case -3:
|
||||
Move.z-= fStep;
|
||||
Rot.y+= c_PI;
|
||||
break;
|
||||
}
|
||||
{
|
||||
D3DXMATRIX m1;
|
||||
D3DXMatrixRotationYawPitchRoll( &m1, btb.m_v3Rot.x, btb.m_v3Rot.y, btb.m_v3Rot.z );
|
||||
D3DXVec3TransformCoord( &Move, &Move, &m1 );
|
||||
}
|
||||
|
||||
btb.m_v3Pos+= Move;
|
||||
btb.m_v3Rot+= Rot * btb.m_fRotOffset;
|
||||
}
|
||||
|
||||
void ProcessTree( BlockTree* t )
|
||||
{
|
||||
while( g_iLastBuilderElement > 0 )
|
||||
{
|
||||
g_iLastBuilderElement--;
|
||||
BlockTreeBuilder btb= g_BuilderStack[ g_iLastBuilderElement ];
|
||||
|
||||
int iLength= 0;
|
||||
int iLeafMode= g_Random.genInteger( 0, 15 );
|
||||
while( true )
|
||||
{
|
||||
float fStep= 2.0f * btb.m_fSize;
|
||||
btb.m_fSize*= btb.m_fSizeChange;
|
||||
btb.m_fColor+= 1.0f / 24.0f;
|
||||
if( btb.m_fSize < fMinSize )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
MoveBTB(btb, fStep);
|
||||
|
||||
btb.m_pParent= AddTreeBox(t, btb);
|
||||
btb.m_fTimeOffset+= t->m_fTimeStep;
|
||||
|
||||
if( btb.m_iLevel > 1 && g_Random.genInteger( 1, 6 ) == 1 )
|
||||
{
|
||||
btb.m_fRotOffset*= -1;
|
||||
}
|
||||
|
||||
if( btb.m_iLevel == 0 )
|
||||
{
|
||||
if( iLength > 2 && iLength % 3 == 1 )
|
||||
{
|
||||
AddBuilderStack(btb, iLeafMode);
|
||||
AddBuilderStack(btb, iLeafMode + 2);
|
||||
}
|
||||
iLeafMode++;
|
||||
}
|
||||
else if( g_Random.genInteger( 0, 8 ) < iLength - btb.m_iLevel )
|
||||
{
|
||||
if( btb.m_iLevel < 5 )
|
||||
{
|
||||
AddBuilderStack(btb, iLeafMode);
|
||||
}
|
||||
iLeafMode++;
|
||||
}
|
||||
|
||||
iLength++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BlockTreeElement* AddTreeBox( BlockTree* t, BlockTreeBuilder& btb )
|
||||
{
|
||||
// add box
|
||||
assert( t->m_iElementcount < g_iMaxBlocksPerTree );
|
||||
assert( g_iBlockElementsUsed + t->m_iElementcount < m_iMaxTreeElements );
|
||||
BlockTreeElement* elem= t->m_pElements + t->m_iElementcount;
|
||||
t->m_iElementcount++;
|
||||
|
||||
elem->m_fColor= btb.m_fColor;
|
||||
elem->m_fSize= btb.m_fSize;
|
||||
elem->m_fTimeOffset= btb.m_fTimeOffset;
|
||||
elem->m_ParentObject= btb.m_pParent;
|
||||
elem->m_v3Pos= btb.m_v3Pos;
|
||||
elem->m_v3Rot= btb.m_v3Rot;
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
void AddBuilderStack( BlockTreeBuilder& btb, int iLeafMode )
|
||||
{
|
||||
assert( g_iLastBuilderElement < m_iMaxTreeBuilderElements );
|
||||
BlockTreeBuilder& btbNew= g_BuilderStack[ g_iLastBuilderElement ];
|
||||
g_iLastBuilderElement++;
|
||||
|
||||
btbNew= btb;
|
||||
int iSign= 1;
|
||||
int iNewMode= 1 + iLeafMode % 4;
|
||||
if( iNewMode > 2 )
|
||||
{
|
||||
iSign= -1;
|
||||
iNewMode-= 2;
|
||||
}
|
||||
iNewMode+= abs( btb.m_iWalkAxis );
|
||||
if( iNewMode > 3 )
|
||||
{
|
||||
iNewMode-= 3;
|
||||
}
|
||||
btbNew.m_iWalkAxis= iNewMode * iSign;
|
||||
if( btbNew.m_fRotOffset >= 0.0f )
|
||||
{
|
||||
btbNew.m_fRotOffset+= 3.0f / 128.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
btbNew.m_fRotOffset-= 3.0f / 128.0f;
|
||||
}
|
||||
|
||||
btbNew.m_iLevel++;
|
||||
}
|
||||
Reference in New Issue
Block a user