Files
bluflame/evoke-64k/bp10/flockspline.cpp
2026-04-18 22:31:51 +02:00

688 lines
19 KiB
C++

#include "flockspline.h"
#include "globals.h"
#include "intrin.h"
static const int m_iMaxSplineLength= 128 * Flock::m_iTimeResolution * 30;
static D3DXVECTOR3 g_vecSplineData[ m_iMaxSplineLength ];
static D3DXVECTOR3 g_vecSplineDataUp[ m_iMaxSplineLength ];
static D3DXVECTOR3 g_vecSplineDataRight[ m_iMaxSplineLength ];
int g_iSplineDataUsed= 0;
Flock g_Flocks[ g_iFlockCount ];
static const int m_iMaxPreSplineLength= 2048;
static D3DXVECTOR3 g_vecSplinePreData[ m_iMaxPreSplineLength ];
static D3DXVECTOR3 g_vecSplinePreUpData[ m_iMaxPreSplineLength ];
static int g_iPreSplineCount;
void Flock::Init()
{
m_iSplineLength= -1;
m_iBoidCount= -1;
m_fTimeOffset= 0.0f;
m_fMaxTimeAdd= -666666.0f;
m_fColorIncrement= 1.0f / 128.0f;
m_iTesselation= 4;
}
void Flock::GeneratePreSpline( D3DXVECTOR3* pBase,
int iCountpoints,
float fDistStep,
float fMaxOffset)
{
g_iPreSplineCount= 0;
for( int i= 1; i < iCountpoints; ++i )
{
D3DXVECTOR3 vDir= pBase[ i ] - pBase[ i - 1 ];
D3DXVECTOR3 vUp;
D3DXVECTOR3 vRight;
CreateBaseUpVector( vDir, vUp );
D3DXVec3Cross( &vRight, &vUp, &vDir );
D3DXVec3Cross( &vUp, &vRight, &vDir );
D3DXVec3Normalize( &vUp, &vUp );
D3DXVec3Normalize( &vRight, &vRight );
float fDist= D3DXVec3Length( &vDir );
int iSteps= max( 1, (int)(fDist / fDistStep) );
for( int j= 0; j < iSteps; ++j )
{
float fAntiFac= (float)j / (float)iSteps;
float fFac= 1.0f - fAntiFac;
D3DXVECTOR3 vec3Pos= pBase[ i - 1 ] * fFac + pBase[ i ] * fAntiFac;
if( j > 0 )
{
float fRad= g_Random.genFloat( 0.0f, fMaxOffset );
float fDir= g_Random.genFloat( 0.0f, c_2PI );
vec3Pos+= vUp * fRad * sin( fDir );
vec3Pos+= vRight * fRad * cos( fDir );
}
g_vecSplinePreData[ g_iPreSplineCount ]= vec3Pos;
g_iPreSplineCount++;
}
}
}
int Flock::GenerateSplineBands()
{
const int iBaseFlock= 48;
int iFlockCount= 0;
D3DXVECTOR3 vMidStart;
vMidStart.x= 2.5f;
vMidStart.z= 36.0f;
D3DXVECTOR3 vX;
vX.x= -0.9f / 128.0f;
vX.y= 0.0f;
vX.z= 0.15f / 128.0f;
D3DXVECTOR3 vY;
vY.x= 0.0f;
vY.y= 1.0f / 128.0f;
vY.z= 0.0f;
//static D3DXVECTOR3 g_vecSplinePreData[ m_iMaxPreSplineLength ];
//static D3DXVECTOR3 g_vecSplinePreUpData[ m_iMaxPreSplineLength ];
int StartOffset= 0;
float fTimeOffset= 256.0f;
for( int i= 0; i < 17; ++i )
{
D3DXVECTOR3 vMid;
vMid.x= vMidStart.x + sinf( (float)i * -2.0f ) * 1.0f;
vMid.z= vMidStart.z + cosf( (float)i * -2.0f ) * 1.0f;
vMid.y= 64.0f;// + g_fYSpecialBandOffset[ i - 10 ];
if( i == 14 )
{
vMid.x= -5.0f;
}
const signed char* g_pData= g_PointData + StartOffset;
while( true )
{
g_iPreSplineCount= 1;
Flock* pF= g_Flocks + iBaseFlock + iFlockCount;
int startx= *((short int*)g_pData);
g_pData+= 2;
if( startx == 0x7fff )
{
break;
}
int starty= *((short int*)g_pData);
g_pData+= 2;
D3DXVECTOR2 g_vecActPoint;
g_vecActPoint.x= (float)startx;
g_vecActPoint.y= (float)starty;
{
D3DXVECTOR3 vAct;
vAct= vMid;
vAct+= g_vecActPoint.x * vX;
vAct+= g_vecActPoint.y * vY;
g_vecSplinePreData[ g_iPreSplineCount ]= vAct;
g_iPreSplineCount++;
}
while( true )
{
int x= *g_pData;
g_pData++;
int y= *g_pData;
g_pData++;
if( x == 0 && y == 0 )
{
break;
}
g_vecActPoint.x+= x;
g_vecActPoint.y+= y;
{
D3DXVECTOR3 vAct;
vAct= vMid;
vAct+= g_vecActPoint.x * vX;
vAct+= g_vecActPoint.y * vY;
g_vecSplinePreData[ g_iPreSplineCount ]= vAct;
g_iPreSplineCount++;
}
}
assert( g_iPreSplineCount > 3 );
g_vecSplinePreData[ 0 ]= 2 * g_vecSplinePreData[ 1 ] - g_vecSplinePreData[ 2 ];
g_vecSplinePreData[ g_iPreSplineCount ]= 2 * g_vecSplinePreData[ g_iPreSplineCount - 1 ] - g_vecSplinePreData[ g_iPreSplineCount - 2 ];
g_iPreSplineCount++;
pF->GenerateUpVectors();
pF->GenerateSplinePoints( 1 );
pF->GenerateBoidsText( 24 );
pF->m_iTesselation= 1;
pF->m_fTimeOffset= fTimeOffset;
fTimeOffset+= 0.06f * (float)pF->m_iSplineLength / (float)m_iTimeResolution;
iFlockCount++;
}
fTimeOffset+= 0.6f;
StartOffset= g_pData -g_PointData;
StartOffset+= 4;
}
return iFlockCount;
}
void Flock::CreateBaseUpVector( D3DXVECTOR3& vec3In, D3DXVECTOR3& vec3Out )
{
vec3Out= D3DXVECTOR3( 0.0f, 1.0f, 1.0f );
if( fabs( D3DXVec3Dot( &vec3In, &vec3Out ) ) > 0.9f )
{
vec3Out= D3DXVECTOR3( 1.0f, 0.0f, 1.0f );
}
}
void Flock::GenerateUpVectors()
{
D3DXVECTOR3 vec3PrevUp;
CreateBaseUpVector( g_vecSplinePreData[ 1 ] - g_vecSplinePreData[ 0 ], vec3PrevUp );
for( int i= 0; i < g_iPreSplineCount - 1; ++i )
{
D3DXVECTOR3 vec3Along= g_vecSplinePreData[ i + 1 ] - g_vecSplinePreData[ max( 0, i - 1 ) ];
D3DXVECTOR3 vec3NextRight;
D3DXVec3Cross( &vec3NextRight, &vec3PrevUp, &vec3Along );
D3DXVec3Cross( &(g_vecSplinePreUpData[ i ]), &vec3Along, &vec3NextRight );
D3DXVec3Normalize( &(g_vecSplinePreUpData[ i ]), &(g_vecSplinePreUpData[ i ]) );
vec3PrevUp= g_vecSplinePreUpData[ i ];
}
g_vecSplinePreUpData[ g_iPreSplineCount - 1 ]= g_vecSplinePreUpData[ g_iPreSplineCount - 2 ];
}
void Flock::GenerateSplinePoints( int iTicksPerPrePoint )
{
m_iSplineLength= iTicksPerPrePoint * ( g_iPreSplineCount - 3 );
m_vecSplineData= g_vecSplineData + g_iSplineDataUsed;
m_vecSplineDataUp= g_vecSplineDataUp + g_iSplineDataUsed;
m_vecSplineDataRight= g_vecSplineDataRight + g_iSplineDataUsed;
g_iSplineDataUsed+= m_iSplineLength;
for( int i= 0; i < g_iPreSplineCount - 3; ++i )
{
for( int j= 0; j < iTicksPerPrePoint; ++j )
{
D3DXVECTOR3& vecPos= m_vecSplineData[ i * iTicksPerPrePoint + j ];
D3DXVECTOR3& vecUp= m_vecSplineDataUp[ i * iTicksPerPrePoint + j ];
float fWeight= (float)j / (float)iTicksPerPrePoint;
D3DXVec3CatmullRom(
&vecPos,
g_vecSplinePreData + i,
g_vecSplinePreData + i + 1,
g_vecSplinePreData + i + 2,
g_vecSplinePreData + i + 3,
fWeight );
D3DXVec3Lerp(
&vecUp,
g_vecSplinePreUpData + i + 1,
g_vecSplinePreUpData + i + 2,
fWeight );
}
}
D3DXVECTOR3 vecLast= m_vecSplineData[ 0 ] + m_vecSplineData[ 0 ] - m_vecSplineData[ 1 ];
for( int i= 0; i < m_iSplineLength; ++i )
{
D3DXVECTOR3 vecFront= vecLast - m_vecSplineData[ i ];
D3DXVec3Cross( m_vecSplineDataRight + i, m_vecSplineDataUp + i, &vecFront );
D3DXVec3Normalize( m_vecSplineDataRight + i, m_vecSplineDataRight + i );
D3DXVec3Cross( m_vecSplineDataUp + i, &vecFront, m_vecSplineDataRight + i );
D3DXVec3Normalize( m_vecSplineDataUp + i, m_vecSplineDataUp + i );
vecLast= m_vecSplineData[ i ];
}
}
void Flock::GenerateBoids01( int iCount )
{
m_iBoidCount= min( iCount, m_iMaxBoidCount );
int iTimeStep= 2 * m_iTimeResolution / m_iBoidCount;
for( int i= 0; i < m_iBoidCount; ++i )
{
Boid& b= m_BoidData[ i ];
b.m_iTimeOffset= i * iTimeStep;
b.m_iLength= g_Random.genInteger( 24, 36 );
m_fMaxTimeAdd= max( m_fMaxTimeAdd, 0.1f + (float)(b.m_iLength + b.m_iTimeOffset) / (float)m_iTimeResolution );
b.m_fRotOffset= g_Random.genFloat( -0.5f, 0.5f );
b.m_RotFunc.x= g_Random.genFloat( 0.0f, c_2PI );
b.m_RotFunc.y= g_Random.genFloat( 0.5f * c_PI, c_PI );
b.m_RotFunc.z= g_Random.genFloat( 0.25f, 1.0f );
b.m_DistFunc.x= sqrtf( g_Random.genFloat( 1.0f / 4.0f, 4.0f ) );
b.m_DistFunc.y= g_Random.genFloat( 0.5f * b.m_DistFunc.x, b.m_DistFunc.x * 1.5f );
b.m_DistFunc.z= g_Random.genFloat( 0.5f, 2.0f );
b.m_fWidth= g_Random.genFloat( 1.0f / 6.0f, 1.0f / 4.0f );
b.m_fColor= 0.7f * (float)i / (float)m_iBoidCount + g_Random.genFloat( 0.05f, 0.25f );
}
}
void Flock::GenerateBoids02( int iCount )
{
m_iBoidCount= min( iCount, m_iMaxBoidCount );
int iTimeStep= 3 * m_iTimeResolution / m_iBoidCount;
for( int i= 0; i < m_iBoidCount; ++i )
{
Boid& b= m_BoidData[ i ];
b.m_iTimeOffset= i * iTimeStep;
b.m_iLength= g_Random.genInteger( 48, 80 );
m_fMaxTimeAdd= max( m_fMaxTimeAdd, 0.1f + (float)(b.m_iLength + b.m_iTimeOffset) / (float)m_iTimeResolution );
b.m_fRotOffset= g_Random.genFloat( -0.5f, 0.5f );
b.m_RotFunc.x= g_Random.genFloat( 0.0f, c_2PI );
b.m_RotFunc.y= g_Random.genFloat( 0.5f * c_PI, c_PI );
b.m_RotFunc.z= g_Random.genFloat( 0.25f, 1.0f );
b.m_DistFunc.x= sqrtf( g_Random.genFloat( 1.0f / 4.0f, 16.0f ) );
b.m_DistFunc.y= g_Random.genFloat( 0.5f * b.m_DistFunc.x, b.m_DistFunc.x * 1.5f );
b.m_DistFunc.z= g_Random.genFloat( 0.5f, 2.0f );
b.m_fWidth= g_Random.genFloat( 1.0f / 6.0f, 1.0f / 4.0f );
b.m_fColor= 0.7f * (float)i / (float)m_iBoidCount + g_Random.genFloat( 0.05f, 0.25f );
}
}
void Flock::GenerateBoids03( int iCount )
{
m_iBoidCount= min( iCount, m_iMaxBoidCount );
int iTimeStep= 2 * m_iTimeResolution / m_iBoidCount;
for( int i= 0; i < m_iBoidCount; ++i )
{
Boid& b= m_BoidData[ i ];
b.m_iTimeOffset= i * iTimeStep;
b.m_iLength= g_Random.genInteger( 16, 32 );
m_fMaxTimeAdd= max( m_fMaxTimeAdd, 0.1f + (float)(b.m_iLength + b.m_iTimeOffset) / (float)m_iTimeResolution );
b.m_fRotOffset= g_Random.genFloat( -0.5f, 0.5f );
b.m_RotFunc.x= g_Random.genFloat( 0.0f, c_2PI );
b.m_RotFunc.y= g_Random.genFloat( 0.5f * c_PI, c_PI );
b.m_RotFunc.z= g_Random.genFloat( 0.75f, 1.5f );
b.m_DistFunc.x= sqrtf( g_Random.genFloat( 1.0f / 4.0f, 2.0f ) );
b.m_DistFunc.y= g_Random.genFloat( 0.5f * b.m_DistFunc.x, b.m_DistFunc.x * 1.5f );
b.m_DistFunc.z= g_Random.genFloat( 0.5f, 2.0f );
b.m_fWidth= g_Random.genFloat( 1.0f / 6.0f, 1.0f / 4.0f );
b.m_fColor= 0.7f * (float)i / (float)m_iBoidCount + g_Random.genFloat( 0.05f, 0.25f );
}
}
void Flock::GenerateBoidsText( int iCount )
{
m_iBoidCount= min( iCount, m_iMaxBoidCount );
int iTimeStep= 13 * m_iTimeResolution / m_iBoidCount / 15;
for( int i= 0; i < m_iBoidCount; ++i )
{
Boid& b= m_BoidData[ i ];
b.m_iTimeOffset= i * iTimeStep;
b.m_iLength= g_Random.genInteger( 8, 12 );
m_fMaxTimeAdd= max( m_fMaxTimeAdd, 0.1f + (float)(b.m_iLength + b.m_iTimeOffset) / (float)m_iTimeResolution );
b.m_fRotOffset= g_Random.genFloat( -0.5f, 0.5f );
b.m_RotFunc.x= g_Random.genFloat( 0.0f, c_2PI );
b.m_RotFunc.y= g_Random.genFloat( 0.5f * c_PI, c_PI );
b.m_RotFunc.z= g_Random.genFloat( 2.0f, 6.0f );
b.m_DistFunc.x= sqrtf( g_Random.genFloat( 1.0f / 64.0f, 1 / 24.0f ) );
b.m_DistFunc.y= g_Random.genFloat( 0.25f * b.m_DistFunc.x, b.m_DistFunc.x * 0.5f );
b.m_DistFunc.z= g_Random.genFloat( 0.5f, 0.75f );
b.m_fWidth= g_Random.genFloat( 1.0f / 6.0f, 1.0f / 8.0f );
b.m_fColor= 0.7f * (float)i / (float)m_iBoidCount + g_Random.genFloat( 0.05f, 0.25f );
}
}
bool Flock::IsActive( float fTime )
{
if( m_iSplineLength < 0 )
{
return false;
}
fTime-= m_fTimeOffset;
if( fTime > 0 && fTime < (float)m_iSplineLength / (float)m_iTimeResolution + m_fMaxTimeAdd )
{
return true;
}
return false;
}
static D3DXVECTOR3 vecFinalData[ 2048 ];
static D3DXVECTOR3 vecFinalNorm[ 1024 ];
void Flock::AddToScene( float fTime, int iObject )
{
assert( iObject < OI_FlockLast );
fTime-= m_fTimeOffset;
g_Objects[ iObject ].Lock();
for( int i= 0; i < m_iBoidCount; ++i )
{
int iPos= 0;
Boid& b= m_BoidData[ i ];
int iStart= (int)(fTime * (float)m_iTimeResolution) - b.m_iTimeOffset;
int iEnd= iStart - b.m_iLength;
iStart= min( iStart, m_iSplineLength - 1 );
iEnd= max( iEnd, 0 );
if( iStart <= iEnd )
{
continue;
}
int iSplinePos= iStart;
int iSteps= ( iStart - iEnd ) / m_iTesselation;
assert( iSteps < 1000 );
while( iSteps >= 0 )
{
D3DXVECTOR3& SplinePos= m_vecSplineData[ iSplinePos ];
D3DXVECTOR3& vecUp= m_vecSplineDataUp[ iSplinePos ];
D3DXVECTOR3& vecRight= m_vecSplineDataRight[ iSplinePos ];
float fVal= (float)iSplinePos / (float)m_iTimeResolution + 128.0f;
float fDir= b.m_RotFunc.x + b.m_RotFunc.y * sin( fVal * b.m_RotFunc.z );
float fNorm= fDir + b.m_fRotOffset;
D3DXVECTOR3 vBase= vecUp * sin( fDir ) + vecRight * cos( fDir );
D3DXVECTOR3 vNorm= vecUp * sin( fDir ) + vecRight * cos( fDir );
D3DXVECTOR3 vRight= vecUp * cos( fDir ) - vecRight * sin( fDir );
float fDist= b.m_DistFunc.x + b.m_DistFunc.y * sin( fVal * b.m_DistFunc.z );
vecFinalData[ iPos * 2 ]= SplinePos + vBase * fDist - vRight * b.m_fWidth;
vecFinalData[ iPos * 2 + 1 ]= SplinePos + vBase * fDist + vRight * b.m_fWidth;
vecFinalNorm[ iPos ]= vNorm;
iPos++;
iSplinePos= iEnd + iSteps * m_iTesselation;
iSteps--;
}
for( int i= 0; i < iPos; ++i )
{
}
float fColor= b.m_fColor - m_fColorIncrement * iPos / 2;
Renderjob::SVertex* pV= g_Objects[ iObject ].m_pLockVertex + g_Objects[ iObject ].m_iVertCount;
for( int i= 0; i < iPos; ++i )
{
pV->x= vecFinalData[ i * 2 ].x;
pV->y= vecFinalData[ i * 2 ].y;
pV->z= vecFinalData[ i * 2 ].z;
pV->nx= vecFinalNorm[ i ].x;
pV->ny= vecFinalNorm[ i ].y;
pV->nz= vecFinalNorm[ i ].z;
pV->dwColor= 0x00ffffff;
pV->tu= fColor;
pV->tv= 0.0f;
pV++;
pV->x= vecFinalData[ i * 2 + 1 ].x;
pV->y= vecFinalData[ i * 2 + 1 ].y;
pV->z= vecFinalData[ i * 2 + 1 ].z;
pV->nx= vecFinalNorm[ i ].x;
pV->ny= vecFinalNorm[ i ].y;
pV->nz= vecFinalNorm[ i ].z;
pV->dwColor= 0x00ffffff;
pV->tu= fColor;
pV->tv= 1.0f;
pV++;
pV->x= vecFinalData[ i * 2 + 1 ].x;
pV->y= vecFinalData[ i * 2 + 1 ].y;
pV->z= vecFinalData[ i * 2 + 1 ].z;
pV->nx= -vecFinalNorm[ i ].x;
pV->ny= -vecFinalNorm[ i ].y;
pV->nz= -vecFinalNorm[ i ].z;
pV->dwColor= 0x00ffffff;
pV->tu= fColor;
pV->tv= 1.0f;
pV++;
pV->x= vecFinalData[ i * 2 ].x;
pV->y= vecFinalData[ i * 2 ].y;
pV->z= vecFinalData[ i * 2 ].z;
pV->nx= -vecFinalNorm[ i ].x;
pV->ny= -vecFinalNorm[ i ].y;
pV->nz= -vecFinalNorm[ i ].z;
pV->dwColor= 0x00ffffff;
pV->tu= fColor;
pV->tv= 0.0f;
pV++;
fColor+= m_fColorIncrement;
}
WORD* pW= g_Objects[ iObject ].m_pLockIndex + g_Objects[ iObject ].m_iIndexCount;
int iBase= g_Objects[ iObject ].m_iVertCount;
for( int i= 0; i < 2 * iPos - 1; ++i )
{
*pW++= iBase;
*pW++= iBase + 1;
*pW++= iBase + 4;
*pW++= iBase + 4;
*pW++= iBase + 1;
*pW++= iBase + 5;
iBase+= 2;
}
g_Objects[ iObject ].m_iVertCount+= 4 * iPos;
g_Objects[ iObject ].m_iIndexCount+= 12 * ( iPos - 1 );
}
g_Objects[ iObject ].Unlock();
}
static D3DXVECTOR3 Test[128];
static D3DXVECTOR3 FinalFly[4]=
{
D3DXVECTOR3( -8.0f, 50.0f, 39.0f ),
D3DXVECTOR3( -8.0f, 58.0f, 39.0f ),
D3DXVECTOR3( 16.0f, 192.0f, 0.0f ),
D3DXVECTOR3( 16.0f, 198.0f, 0.0f ),
};
extern int g_iStreetCountX;
extern float g_fStreetX[ 24 ];
extern int g_iStreetCountY;
extern float g_fStreetY[ 24 ];
void PrepareFlockObjects()
{
for( int i= OI_FlockFirst; i < OI_FlockLast; ++i )
{
g_Objects[ i ].Create( 40000, 60000, true );
g_Objects[ i ].m_iUsedShader[ 0 ]= Rainbow;
g_Objects[ i ].m_iUsedPreShader= PreDepth;
}
for( int i= 0; i < g_iFlockCount; ++i )
{
g_Flocks[ i ].Init();
}
for( int i= 0; i < 24; ++i )
{
int iLast= 0;
Test[ iLast ].x= -8.0f;
Test[ iLast ].y= 4.0f;
Test[ iLast ].z= 39.0f;
iLast++;
float fHeight= g_Random.genFloat( 4.0f, 16.0f );
int iModeXZ= g_Random.genInteger( 0, 1 );
int iRow= g_Random.genInteger( 0, 1 );
float fPos;
if( iModeXZ == 0 )
{
fPos= g_Random.genFloat( -32.0f, 52.0f );
Test[ iLast ].x= g_fStreetX[ iRow ];
Test[ iLast ].y= fHeight;
Test[ iLast ].z= fPos;
iLast++;
}
else
{
fPos= g_Random.genFloat( -24.0f, 24.0f );
Test[ iLast ].x= fPos;
Test[ iLast ].y= fHeight;
Test[ iLast ].z= g_fStreetY[ iRow ];
iLast++;
}
int iLength= g_Random.genInteger( 3, 6 );
for( int iTurn= 0; iTurn < iLength; ++iTurn )
{
float fDist= g_Random.genFloat( 24.0f, 64.0f );
float fMinDist= 10000.0f;
iModeXZ= 1 - iModeXZ;
if( iModeXZ == 0 )
{
for( int iStreet= 0; iStreet < g_iStreetCountX; ++iStreet )
{
float fCurDist= fabs( fabs( Test[ iLast - 1 ].x - g_fStreetX[ iStreet ]) - fDist );
if( fabs( g_fStreetX[ iStreet ] ) > fabs( Test[ iLast - 1 ].x ) )
{
fCurDist*= 0.55f;
}
if( fCurDist < fMinDist )
{
fMinDist= fCurDist;
iRow= iStreet;
}
}
Test[ iLast ].x= g_fStreetX[ iRow ];
Test[ iLast ].y= fHeight;
Test[ iLast ].z= Test[ iLast - 1 ].z;
iLast++;
}
else
{
for( int iStreet= 0; iStreet < g_iStreetCountY; ++iStreet )
{
float fCurDist= fabs( fabs( Test[ iLast - 1 ].z - g_fStreetY[ iStreet ]) - fDist );
if( fabs( g_fStreetY[ iStreet ] ) > fabs( Test[ iLast - 1 ].z ) )
{
fCurDist*= 0.55f;
}
if( fCurDist < fMinDist )
{
fMinDist= fCurDist;
iRow= iStreet;
}
}
Test[ iLast ].x=Test[ iLast - 1 ].x;
Test[ iLast ].y= fHeight;
Test[ iLast ].z= g_fStreetY[ iRow ];
iLast++;
}
if( g_Random.genInteger( 0, 1 ) == 1 )
{
Test[ iLast ]=Test[ iLast - 1 ];
iLast++;
Test[ iLast ]=Test[ iLast - 1 ];
iLast++;
float fChange= g_Random.genFloat( 3.5f, 7.0f );
float fNewHeight= fHeight;
if( g_Random.genInteger( 0, 1 ) )
{
fNewHeight+= fChange;
}
else
{
fNewHeight-= fChange;
}
fNewHeight= minimum( fNewHeight, 16.0f );
fNewHeight= maximum( fNewHeight, 4.0f );
fHeight= fNewHeight;
float fPercent= g_Random.genFloat( 0.35f, 0.65f );
float fPercentMod= g_Random.genFloat( 0.05f, 0.15f );
D3DXVec3Lerp( Test + iLast - 3, Test + iLast - 4, Test + iLast - 1, fPercent - fPercentMod );
D3DXVec3Lerp( Test + iLast - 2, Test + iLast - 4, Test + iLast - 1, fPercent + fPercentMod );
Test[ iLast - 2 ].y= fHeight;
Test[ iLast - 1 ].y= fHeight;
}
}
if( iModeXZ == 0 )
{
Test[ iLast ].x= g_fStreetX[ iRow ] + Test[ iLast - 1 ].z * 0.25f;
Test[ iLast - 1].x= g_fStreetX[ iRow ] + Test[ iLast - 1 ].z * 0.125f;
Test[ iLast ].y= -16.0f;
Test[ iLast ].z= Test[ iLast - 1 ].z;
iLast++;
}
else
{
Test[ iLast ].x=Test[ iLast - 1 ].x;
Test[ iLast ].y= -16.0f;
Test[ iLast ].z= g_fStreetY[ iRow ] + Test[ iLast - 1 ].x * 0.25f;
Test[ iLast - 1].z= g_fStreetY[ iRow ] + Test[ iLast - 1 ].x * 0.125f;
iLast++;
}
g_Flocks[ i ].GeneratePreSpline(
Test,
iLast,
4.0f,
4.0f );
g_Flocks[ i ].GenerateUpVectors();
g_Flocks[ i ].GenerateSplinePoints( 24 );
g_Flocks[ i ].GenerateBoids01( 96 );
g_Flocks[ i ].m_iTesselation= 2;
g_Flocks[ i ].m_fTimeOffset= 0.0f;
}
for( int i= 0; i < 3; ++i )
{
g_Flocks[ 24 + i ].GeneratePreSpline(
FinalFly,
4,
8.0f,
12.0f );
g_Flocks[ 24 + i ].GenerateUpVectors();
g_Flocks[ 24 + i ].GenerateSplinePoints( 64 );
g_Flocks[ 24 + i ].GenerateBoids02( 64 );
g_Flocks[ 24 + i ].m_iTesselation= 1;
g_Flocks[ 24 + i ].m_fTimeOffset= 320.0f;
}
Flock::GenerateSplineBands();
}
void AddFlockObjectsToScene( float fTime )
{
for( int i= OI_FlockFirst; i < OI_FlockLast; ++i )
{
g_Objects[ i ].HideVertexData();
}
int iObjectID= OI_FlockFirst;
for( int i= 0; i < g_iFlockCount; ++i )
{
assert( iObjectID < OI_FlockLast );
if( g_Flocks[ i ].IsActive( fTime ) )
{
g_Flocks[ i ].AddToScene( fTime, iObjectID );
iObjectID++;
}
}
}
//-8, 39