#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() { return 0; } /*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 ) { // initial fill the particle system #ifndef DISABLEFLUIDS #ifndef DISABLEFLOCKFLUIDS InstanceData* instanceData; g_FluidParticleSystem.InstanceDataBuffer->Lock(0, sizeof(InstanceData) * g_FluidParticleSystem.InstanceCount, (void**)&instanceData, 0);//D3DLOCK_DISCARD); g_FluidParticleSystem.InstanceCount = 0; #endif #endif 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; #ifndef DISABLEFLUIDS #ifndef DISABLEFLOCKFLUIDS // particle stuff { instanceData[g_FluidParticleSystem.InstanceCount].pos[0] = vecFinalData[ iPos * 2 ].x; instanceData[g_FluidParticleSystem.InstanceCount].pos[1] = vecFinalData[ iPos * 2 ].y; instanceData[g_FluidParticleSystem.InstanceCount].pos[2] = vecFinalData[ iPos * 2 ].z; instanceData[g_FluidParticleSystem.InstanceCount].size = 2.0f; instanceData[g_FluidParticleSystem.InstanceCount].intensity = 0.04; g_FluidParticleSystem.InstanceCount ++; } #endif #endif iPos++; iSplinePos= iEnd + iSteps * m_iTesselation; iSteps--; } 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(); #ifndef DISABLEFLUIDS #ifndef DISABLEFLOCKFLUIDS g_FluidParticleSystem.InstanceDataBuffer->Unlock(); #endif #endif } 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 ), }; void PrepareFlockObjects() { for( int i= OI_FlockFirst; i < OI_FlockLast; ++i ) { g_Objects[ i ].Create( 40000, 60000, true ); g_Objects[ i ].m_iUsedShader[ 0 ]= Text; g_Objects[ i ].m_iUsedPreShader= PreDepth; } for( int i= 0; i < g_iFlockCount; ++i ) { g_Flocks[ i ].Init(); } for( int i= 0; i < 8; ++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= iRow * 5.0f; 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= iRow * 5.0f; 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 < 5; ++iStreet ) { float fCurDist= fabs( fabs( Test[ iLast - 1 ].x - iStreet * 5.0f) - fDist ); if( fabs( iStreet * 5.0f ) > fabs( Test[ iLast - 1 ].x ) ) { fCurDist*= 0.55f; } if( fCurDist < fMinDist ) { fMinDist= fCurDist; iRow= iStreet; } } Test[ iLast ].x= iRow * 5.0f; Test[ iLast ].y= fHeight; Test[ iLast ].z= Test[ iLast - 1 ].z; iLast++; } else { for( int iStreet= 0; iStreet < 5; ++iStreet ) { float fCurDist= fabs( fabs( Test[ iLast - 1 ].z - iStreet * 5.0f) - fDist ); if( fabs( iStreet * 5.0f ) > 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= iRow * 5.0f; 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= iRow * 5.0f + Test[ iLast - 1 ].z * 0.25f; Test[ iLast - 1].x= iRow * 5.0f + 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= iRow * 5.0f + Test[ iLast - 1 ].x * 0.25f; Test[ iLast - 1].z= iRow * 5.0f + 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++; } } for( int i= OI_FlockFirst; i < OI_FlockLast; ++i ) { g_Objects[ i ].HideVertexData(); } } //-8, 39