Example #1
0
HRESULT ParticleSystem::CreateRndTex(int size)
{
	HRESULT hr = S_OK;

	D3DXVECTOR4* randomValues = new D3DXVECTOR4[size];
	for(int i = 0; i < size; i++)
	{
		randomValues[i].x = RndFloat(-1.0f, 1.0f);
		randomValues[i].y = RndFloat(-1.0f, 1.0f);
		randomValues[i].z = RndFloat(-1.0f, 1.0f);
		randomValues[i].w = RndFloat(-1.0f, 1.0f);
	}
	
    D3D11_SUBRESOURCE_DATA subresData;
    subresData.pSysMem = randomValues; 
	subresData.SysMemPitch = sizeof(D3DXVECTOR4) * size;
    subresData.SysMemSlicePitch = sizeof(D3DXVECTOR4) * size;
	
    D3D11_TEXTURE1D_DESC texDesc;
    texDesc.Width = size;
    texDesc.MipLevels = 1;
    texDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
    texDesc.Usage = D3D11_USAGE_IMMUTABLE;
    texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
    texDesc.CPUAccessFlags = 0;
    texDesc.MiscFlags = 0;
    texDesc.ArraySize = 1;

	ID3D11Texture1D* rndTex = NULL;
	hr = this->gDevice->CreateTexture1D(&texDesc, &subresData, &rndTex);
	if(FAILED(hr))
	{
		MessageBox(0, "Failed to create random texture", "CreateTexture1D", MB_ICONERROR);
	}
	
    D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
	viewDesc.Format = texDesc.Format;
    viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
    viewDesc.Texture1D.MipLevels = texDesc.MipLevels;
	viewDesc.Texture1D.MostDetailedMip = 0;
	
	hr = this->gDevice->CreateShaderResourceView(rndTex, &viewDesc, &this->mRndTexSRV);
	if(FAILED(hr))
	{
		MessageBox(0, "Failed to create shader resource view", "CreateShaderResourceView", MB_ICONERROR);
	}

	rndTex->Release();
	delete [] randomValues;

	return hr;
}
void LevelDirector::Update( float dt, IGameContext & context )
{
// Debug code to see current spawn parameters
{
//GetRender().DrawText( 0, 50, Color(255,255,255), 25, "%i% (%i/%i ~ %f)", m_sinkPercent, m_currentSinkPixels, m_initialSinkPixels, m_currentSinkPixels/(float)m_initialSinkPixels );

/*int totalObjects = 0;

for ( SpawnedVector::iterator iter = m_spawns.begin(); iter != m_spawns.end(); ++iter )
{
	const GameObject *pObj = context.GetOjectsStorage().GetGameObject( iter->m_id );
	if ( pObj )
		++totalObjects;
}
IRender & render = GetRender();
render.DrawText( 0, 50, Color(255,255,255), 10, "Spawn timeout: %f", m_spawnTimeout );
render.DrawText( 0, 60, Color(255,255,255), 10, "Objects: %i/%i", totalObjects, m_maxObjects );
float totalProb = 0;
for ( AIProtoVector::iterator iter = m_protos.begin(); iter != m_protos.end(); ++iter )
{
	totalProb += iter->m_spawnProb;
}

for ( AIProtoVector::iterator iter = m_protos.begin(); iter != m_protos.end(); ++iter )
{
	SAIProto & p = *iter;
	render.DrawText( 0, 70 + (iter-m_protos.begin())*10, Color(255,255,255), 10, "%10.10s: %3.3f %3.3f", p.m_objectProto.c_str(), iter->m_spawnProb, iter->m_spawnProb / totalProb );
}*/
}
      // Creating target objects
	if ( !m_targetObjectID.IsValid() )
	{
		if ( !m_createTargetRequestID.IsValid() )
		{
			SCreateObjectRequest::SData data;
			data.x = m_targetObjectX;
			data.y = m_targetObjectY;
			m_createTargetRequestID = context.CreateGameObject( m_targetObjectProto, data );
		}
		else
		{
			m_targetObjectID = context.GetCreateRequestResult( m_createTargetRequestID );
			assert( m_targetObjectID.IsValid() );
			m_createTargetRequestID.Invalidate();
			m_initialSinkPixels = 0;
			const PhysicComponent *pPhys = context.GetOjectsStorage().GetPhysicComponent( context.GetOjectsStorage().GetGameObject( m_targetObjectID )->GetPhysicComponent() );
			if ( pPhys )
			{
				for ( int x = 0; x < pPhys->m_collisionMask.GetWidth(); ++x )
				{
					if ( pPhys->m_collisionMask.Get( x, m_sinkLineY ) )
						++m_initialSinkPixels;
				}
			}
			m_currentSinkPixels = m_initialSinkPixels;
		}
	}

	SpawnRequestRemover remover( this, context );
	SpawnRequests::iterator newEnd = std::remove_if( m_requests.begin(), m_requests.end(), remover );

	m_requests.erase( newEnd, m_requests.end() );

	  // Process spawn cooldowns
	for ( AIProtoVector::iterator iter = m_protos.begin(); iter != m_protos.end(); ++iter )
	{
		if ( iter->m_spawnProb < 1.0f )
			iter->m_spawnProb += iter->m_cooldownPerSecond * dt;
		if ( iter->m_spawnProb > 1.0f )
			iter->m_spawnProb = 1.0f;
	}

	  // Process global spawn timeout
	m_spawnTimeout -= dt;
	if ( m_spawnTimeout > 0 )
		return;

	  // Count objects by type
	for ( CountMap::iterator iter = m_objectsCounts.begin(); iter != m_objectsCounts.end(); ++iter )
		iter->second = 0;

	const ObjectsStorage & storage = context.GetOjectsStorage();

	int totalObjects = 0;
	
	for ( int i = 0; i < (int)m_spawns.size(); ++i )
	{
		const SSpawnedObject & spawn = m_spawns[ i ];
		const GameObject *pObj = storage.GetGameObject( spawn.m_id );
		if ( pObj )
		{
			++m_objectsCounts[ spawn.m_proto ];
			++totalObjects;
		}
		else
		{
			m_spawns.erase( m_spawns.begin() + i );
			--i;
		}
	}

	if ( totalObjects >= m_maxObjects )
		return;

	  // Calculate total spawn probability for all objects
	float totalProb = 0.0f;

	for ( AIProtoVector::iterator iter = m_protos.begin(); iter != m_protos.end(); ++iter )
	{
		totalProb += iter->m_spawnProb;
	}

	if ( totalProb <= 0.0001f )
		return;

	  // Choose an object to spawn based on relative weight
	float prob1 = 0;
	float rnd1 = RndFloat( 0, 1.0f );

	for ( AIProtoVector::iterator iter = m_protos.begin(); iter != m_protos.end(); ++iter )
	{
		prob1 += iter->m_spawnProb / totalProb;
		if ( rnd1 < prob1 )
		{
			SAIProto & p = *iter;
			const int intervalIndex = RndInt( 0, (int)p.m_intervals.size() - 1 );
			const SAIInterval & in = p.m_intervals[ intervalIndex ];

			if ( in.m_schemesWeight <= 0 )
				continue;

			SCreateObjectRequest::SData data;

			int dx = ( in.x2 <= in.x1 ) ? 0 : ( RndInt( 0, in.x2 - in.x1 ) );
			int dy = ( in.y2 <= in.y1 ) ? 0 : ( RndInt( 0, in.y2 - in.y1 ) );
			data.x = in.x1 + dx;
			data.y = in.y1 + dy;
			data.dir = in.dir;

			int prob = 0;
			int rnd = RndInt( 0, in.m_schemesWeight - 1 );
			for ( SAIInterval::SchemeVector::const_iterator sIter = in.m_schemes.begin(); sIter != in.m_schemes.end(); ++sIter )
			{
				prob += sIter->m_weight;
				if ( rnd < prob )
				{
					data.ai = sIter->m_aiName;
					break;
				}
			}

			m_requests.push_back( SSpawnRequest( context.CreateGameObject( p.m_objectProto, data ), iter - m_protos.begin() ) );

			p.m_spawnProb = 0;
			
			const float fillPercent = totalObjects / (float)m_maxObjects;
			const int minSpawnTimeout = 100 + fillPercent * 500;
			const int maxSpawnTimeout = 200 + fillPercent * 1000;
			m_spawnTimeout = RndInt( minSpawnTimeout, maxSpawnTimeout ) / 1000.0f;
			break;
		}
	}
}