721 lines
20 KiB
C++
721 lines
20 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()
|
|
{
|
|
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
|