Пример #1
0
bool PitMorph::DoSequence( TimeClock* timeClock )
{
	const float SPEED = 4.0f  * ( TERRAIN_HEIGHT / 10.0f );
	// m term in y = mx+b
	const float SLOPE = 1.0f;
	
	bool last = false;
	Lilith3D* lilith = Lilith3D::Instance();
	TerrainMesh* tmesh = lilith->GetTerrainMesh();
	float height = tmesh->Height( terrainX, terrainY ) - timeClock->CalcVelocity( SPEED );
	height = Clamp( height, TERRAIN_MIN, TERRAIN_MAX );

	// essentially the x-intecept:
	// y = mx + b, b=height
	// x = -height / m
	float radius = ( TERRAIN_MAX - height ) / SLOPE;
	int   irad = int( radius ) + 1;

	Rectangle2I bounds;
	bounds.Set( terrainX - irad, terrainY - irad, terrainX + irad, terrainY + irad );
	Rectangle2I constrain;
	constrain.Set( 0, 0, lilith3d::VERTEXSIZE-1, lilith3d::VERTEXSIZE-1 );
	bounds.DoIntersection( constrain );

	// Do the center first.
	if ( height <= altitude )
		last = true;

	if ( tmesh->Height( terrainX, terrainY ) > altitude )
	{
		tmesh->StartHeightChange();
		tmesh->SetHeight( terrainX, terrainY, height );

		for( int j=bounds.min.y; j<=bounds.max.y; ++j )
		{
			for( int i=bounds.min.x; i<=bounds.max.x; ++i )
			{
				if ( i != terrainX || j != terrainY )
				{
					float len = Length( float( terrainX-i ), float( terrainY-j ), 0.0f );
					float setHeight = len*SLOPE + height;
					if ( setHeight < tmesh->Height( i, j ) )
						tmesh->SetHeight( i, j, setHeight );
				}
			}
		}
		tmesh->EndHeightChange();
	}

	for(	Publisher< PitMorphListener >::const_iterator it = publish.begin();
			it != publish.end();
			++it )
	{
		if ( last )
			(*it)->PitDone( this, terrainX, terrainY, height );
		else
			(*it)->PitSink( this, terrainX, terrainY, height );
	}

	return last;
}
Пример #2
0
bool VolcanoMorph::DoSequence( TimeClock* timeClock )
{
	const float SPEED = 4.0f  * ( TERRAIN_HEIGHT / 10.0f );
	// m term in y = mx+b
	const float SLOPE = -1.3f;
	const float SMOOTH_RADIUS = 3.0f;
	bool last = false;

	Lilith3D* lilith = Lilith3D::Instance();
	TerrainMesh* tmesh = lilith->GetTerrainMesh();

	float height = tmesh->Height( terrainX, terrainY ) + timeClock->CalcVelocity( SPEED );
	height = Clamp( height, TERRAIN_MIN, TERRAIN_MAX );

	// essentially the x-intecept:
	// y = mx + b, b=height
	// x = -height / m
	float radius = -( height - TERRAIN_MIN ) / SLOPE;
	int   irad = int( radius ) + 1;

	Rectangle2I bounds;
	bounds.Set( terrainX - irad, terrainY - irad, terrainX + irad, terrainY + irad );
	Rectangle2I constrain;
	constrain.Set( 0, 0, lilith3d::VERTEXSIZE-1, lilith3d::VERTEXSIZE-1 );

	bounds.DoIntersection( constrain );

	// Do the center first.
	if ( height >= altitude )
		last = true;

	if ( tmesh->Height( terrainX, terrainY ) < altitude )
	{
		tmesh->StartHeightChange();
		tmesh->SetHeight( terrainX, terrainY, height );

		for( int j=bounds.min.y; j<=bounds.max.y; ++j )
		{
			for( int i=bounds.min.x; i<=bounds.max.x; ++i )
			{
				if ( i != terrainX || j != terrainY )
				{
					float len = Length( float( terrainX-i ), float( terrainY-j ) );
					float setHeight = len*SLOPE + height;
					
					if ( len < SMOOTH_RADIUS )
						setHeight += fuzzHeight[ (j*lilith3d::VERTEXSIZE+i) % FUZZ_SIZE ];

					if ( setHeight > tmesh->Height( i, j ) )
						tmesh->SetHeight( i, j, setHeight );
				}
			}
		}
		tmesh->EndHeightChange();
	}

	// Inform listeners of changes.
	for( Publisher< VolcanoMorphListener >::const_iterator it = publish.begin();
		 it != publish.end();
		 ++it )
	{
		if ( !last )
			(*it)->VolcanoGrow( this, terrainX, terrainY, height );
		else
			(*it)->VolcanoDone( this, terrainX, terrainY, height );
	}
	
	// And now the particles and lights!
	const float FUZZ = 4.0f;
	const float FUZZMORE = 8.0f;
	float alt = tmesh->Height( terrainX, terrainY );

	GravParticles* grav = lilith->GetGravParticles();
	TimeClock* tc = Lilith3D::GetTimeClock();

	while ( tc->Msec() > lastParticleTime )
	{
		lastParticleTime += 50;
		Vector3F loc = { (float)terrainX, (float)terrainY, alt };
		Vector3F vel = {	-FUZZ / 2 + rand.FRand( FUZZ ),	// velocity
							-FUZZ / 2 + rand.FRand( FUZZ ),
							SPEED * 1.3f };
		Color3F col = {	0.8f + rand.FRand(0.2f), 			// coloring
							0.6f + rand.FRand(0.2f), 
							0.0f };

		grav->Create( loc, vel, col,
					  GravParticles::GRAVITY,
					  1.0f,
					  GravParticles::FLAME0 );

		for( int i=0; i<3; ++i )
		{
			Vector3F vel2 = {	-FUZZMORE / 2 + rand.FRand( FUZZMORE ),
								-FUZZMORE / 2 + rand.FRand( FUZZMORE ),
								SPEED * 0.8f };
			Color3F col2 = { 1.0f, 0.0f, 0.0f };
			grav->Create( loc, vel2, col2, 
						  GravParticles::GRAVITY,
						  GravParticles::MEDIUM );
		}
	}				  
//	glowLight->SetPos( (float)terrainX, (float)terrainY, alt );
	if ( decal ) {
		decal->SetAlpha( 1.0f );
		const float FADEOUT = 0.8f * altitude;
		if ( alt > FADEOUT ) {
			decal->SetAlpha( Interpolate( FADEOUT, 1.0f, altitude, 0.0f, alt ));
		}
	}
	return last;
}