// emission
void Fluid2::fluidEmission()
{
	if( Scene::testcase >= Scene::SMOKE )
	{
        Bbox2 source( -0.18f, -1.9f, 0.18f, -1.7f );
        Vec2 ismin = grid.getCellIndex( source.minPosition );
        Vec2 ismax = grid.getCellIndex( source.maxPosition );
        Index2 cornermin( (int) floor( ismin.x ), (int) floor( ismin.y ) );
        Index2 cornermax( (int) ceil( ismax.x ), (int) ceil(ismax.y ) );

		for( unsigned int i = cornermin.x; i <= cornermax.x; ++i )
		for( unsigned int j = cornermin.y; j <= cornermax.y; ++j )
			ink[ Index2( i, j ) ] = 1.0f;
        
        for( unsigned int i = cornermin.x; i <= cornermax.x+1; ++i )
		for( unsigned int j = cornermin.y; j <= cornermax.y; ++j )
            velocityX[ Index2( i, j ) ] = 0.0f;

		for( unsigned int i = cornermin.x; i <= cornermax.x; ++i )
		for( unsigned int j = cornermin.y; j <= cornermax.y+1; ++j )
            velocityY[ Index2( i, j ) ] = 8.0f;
	}
}
Пример #2
0
	void Data2 (int period, double value)	{ Put_Field (Index2 (period), value); }
Пример #3
0
	double Data2 (int period)				{ Get_Field (Index2 (period), &dvalue); return (dvalue); }
// advection
void Fluid2::fluidAdvection( const float dt )
{
    // ink
    {
	    Array2<float> inkcopy( ink );
	    CellSampler inksampler( grid, inkcopy );

        const Index2& size = ink.getSize();
	    for( unsigned int i = 0; i < size.x; ++i )
	    for( unsigned int j = 0; j < size.y; ++j )
	    {
		    const Index2 id( i, j );

		    const Vec2 pos( grid.getCellPos( id ) );
		    const Vec2 vel( ( velocityX[ id ] + velocityX[ Index2( i+1, j ) ] ) * 0.5f,
                            ( velocityY[ id ] + velocityY[ Index2( i, j+1 ) ] ) * 0.5f );
		    const Vec2 endpos( pos - dt * vel );

		    ink[ id ] = inksampler.getValue( endpos );;
	    }
    }

    // velocity
    {
	    Array2< float > ucopy( velocityX );
        Array2< float > vcopy( velocityY );
	    FaceSampler usampler( grid, ucopy, 0 );
	    FaceSampler vsampler( grid, vcopy, 1 );
        const Index2& sizeu = velocityX.getSize();
        const Index2& sizev = velocityY.getSize();

	    for( unsigned int i = 0; i < sizeu.x; ++i )
	    for( unsigned int j = 0; j < sizeu.y; ++j )
	    {
		    const Index2 id( i, j );
            const Index2 idv1( clamp( i-1, 0, sizev.x-1 ), clamp( j  , 0, sizev.y-1 ) );
            const Index2 idv2( clamp( i  , 0, sizev.x-1 ), clamp( j  , 0, sizev.y-1 ) );
            const Index2 idv3( clamp( i-1, 0, sizev.x-1 ), clamp( j+1, 0, sizev.y-1 ) );
            const Index2 idv4( clamp( i  , 0, sizev.x-1 ), clamp( j+1, 0, sizev.y-1 ) );

		    const Vec2 pos( grid.getFaceXPos( id ) );
		    const Vec2 vel( ucopy[ id ], ( vcopy[ idv1 ] + vcopy[ idv2 ] + vcopy[ idv3 ] + vcopy[ idv4 ] ) * 0.25f );
		    const Vec2 endpos( pos - dt * vel );

		    velocityX[ id ] = usampler.getValue( endpos );
	    }

	    for( unsigned int i = 0; i < sizev.x; ++i )
	    for( unsigned int j = 0; j < sizev.y; ++j )
	    {
		    const Index2 id( i, j );
            const Index2 idu1( clamp( i  , 0, sizeu.x-1 ), clamp( j-1, 0, sizeu.y-1 ) );
            const Index2 idu2( clamp( i  , 0, sizeu.x-1 ), clamp( j  , 0, sizeu.y-1 ) );
            const Index2 idu3( clamp( i+1, 0, sizeu.x-1 ), clamp( j-1, 0, sizeu.y-1 ) );
            const Index2 idu4( clamp( i+1, 0, sizeu.x-1 ), clamp( j  , 0, sizeu.y-1 ) );

		    const Vec2 pos( grid.getFaceYPos( id ) );
		    const Vec2 vel( ( ucopy[ idu1 ] + ucopy[ idu2 ] + ucopy[ idu3 ] + ucopy[ idu4 ] ) * 0.25f, vcopy[ id ] );
		    const Vec2 endpos( pos - dt * vel );

		    velocityY[ id ] = vsampler.getValue( endpos );
	    }
    }
}
// pressure
void Fluid2::fluidPressureProjection( const float dt )
{
	if( Scene::testcase >= Scene::SMOKE )
	{
        const Vec2 dx = grid.getCellDx();
        const Vec2 invDx( 1.0f / dx.x, 1.0f / dx.y );
        const Vec2 invDxSq( 1.0f / ( dx.x * dx.x ), 1.0f / ( dx.y * dx.y ) );
        
        const Index2& size = pressure.getSize();
        const Index2& sizeu = velocityX.getSize();
        const Index2& sizev = velocityY.getSize();

        // wall boundary conditions
        for( unsigned int j = 0; j < sizeu.y; ++j )
        {
            velocityX[ Index2( 0, j ) ] = 0.0f;
            velocityX[ Index2( sizeu.x-1, j ) ] = 0.0f;
        }
        for( unsigned int i = 0; i < sizev.x; ++i )
        {
            velocityY[ Index2( i, 0 ) ] = 0.0f;
            // TOP as solid
            //velocityY[ Index2( i, sizev.y-1 ) ] = 0.0f;
        }
        
        // rhs
        const float rhoOverDt = Scene::kDensity / dt;
        std::vector< double > rhs( size.x * size.y );
		for( unsigned int i = 0; i < size.x; ++i )
		for( unsigned int j = 0; j < size.y; ++j )
        {
            const Index2 id( i, j );
            rhs[ pressure.getLinearIndex( i, j ) ] = - rhoOverDt * 
                ( ( velocityX[ Index2( i+1, j ) ] - velocityX[ id ] ) * invDx.x + 
                  ( velocityY[ Index2( i, j+1 ) ] - velocityY[ id ] ) * invDx.y );
        }
        
        // A
        SparseMatrix< double > A( size.x * size.y, 5 );
        for( unsigned int i = 0; i < size.x; ++i )
		for( unsigned int j = 0; j < size.y; ++j )
        {
            const unsigned int id = pressure.getLinearIndex( i, j );
            if( i > 0 ) {
                const unsigned int id1 = pressure.getLinearIndex( i-1, j );
                A.add_to_element( id, id, 1. * invDxSq.x );
                A.add_to_element( id, id1, -1. * invDxSq.x ); }
            if( i < size.x-1 ) {
                const unsigned int id1 = pressure.getLinearIndex( i+1, j );
                A.add_to_element( id, id, 1. * invDxSq.x );
                A.add_to_element( id, id1, -1. * invDxSq.x ); }
            if( j > 0 ) {
                const unsigned int id1 = pressure.getLinearIndex( i, j-1 );
                A.add_to_element( id, id, 1. * invDxSq.y );
                A.add_to_element( id, id1, -1. * invDxSq.y ); }
            // TOP as air
            A.add_to_element( id, id, 1. * invDxSq.y );
            if( j < size.y-1 ) {
                const unsigned int id1 = pressure.getLinearIndex( i, j+1 );
                A.add_to_element( id, id1, -1. * invDxSq.y ); }
            //// TOP as wall
            //if( j < size.y-1 ) {
            //    const unsigned int id1 = pressure.getLinearIndex( i, j+1 );
            //    A.add_to_element( id, id, 1. * invDxSq.y );
            //    A.add_to_element( id, id1, -1. * invDxSq.y ); }
        }
        
        // pcg solver
        PCGSolver< double > solver;
        solver.set_solver_parameters( 1e-6, 10000 );
        
        double residual_out;
        int iterations_out;
        std::vector< double > p( size.x * size.y );
        solver.solve( A, rhs, p, residual_out, iterations_out );
        std::cout << "Pressure system result: res=" << residual_out << ", iter=" << iterations_out << std::endl;

        // set pressure
        for( unsigned int i = 0, n = size.x * size.y; i < n; ++i )
            pressure[ i ] = (float) p[ i ];

        // apply pressure gradient
        const float dtOverRho = dt / Scene::kDensity;
		for( unsigned int i = 1; i < sizeu.x - 1; ++i )
		for( unsigned int j = 0; j < sizeu.y; ++j )
        {
            const Index2 id( i, j );
            const float gradp = ( pressure[ id ] - pressure[ Index2( i-1, j ) ] ) * invDx.x;
            velocityX[ id ] -= dtOverRho * gradp;
        }
		for( unsigned int i = 0; i < sizev.x; ++i )
		for( unsigned int j = 1; j < sizev.y - 1; ++j )
        {
            const Index2 id( i, j );
            const float gradp = ( pressure[ id ] - pressure[ Index2( i, j-1 ) ] ) * invDx.y;
            velocityY[ id ] -= dtOverRho * gradp;
        }
        // apply pressure gradient: TOP as air
        for( unsigned int i = 0; i < sizev.x; ++i )
        {
            const Index2 id( i, sizev.y-1 );
            const float gradp = ( 0.0f - pressure[ Index2( i, size.y-1 ) ] ) * invDx.y;
            velocityY[ id ] -= dtOverRho * gradp;
        }
	}
}
Пример #6
0
bool GameMap::initWithLevel( int mainLevel, int viceLevel )
{
	Return_False_If(!Node::init());

	this->makeMap(mainLevel, viceLevel);

	const int order = m_objects.size()*m_objects[0].size();
	const Size size = this->getContentSize();
	float x = 0;
	float up_height = 0;
	while (x<size.width)
	{
		Sprite* sp = Sprite::create("bound_up.png");
		sp->setPosition(x, size.height);
		sp->setAnchorPoint(Point(0,0));
		addChild(sp, order);

		x += sp->getContentSize().width;

		up_height = sp->getContentSize().height;
	}
	x = 0;
	float bottom_height = 0;
	while (x<size.width)
	{
		Sprite* sp = Sprite::create("bound_bottom.png");
		sp->setPosition(x, 0);
		sp->setAnchorPoint(Point(0,1));
		addChild(sp, order+1);

		x += sp->getContentSize().width;

		bottom_height = sp->getContentSize().height;
	}

	float y = -bottom_height;
	float left_width = 0;
	while (y<size.height)
	{
		Sprite* sp = Sprite::create("bound_left.png");
		sp->setPosition(0, y);
		sp->setAnchorPoint(Point(1,0));
		addChild(sp, order);

		left_width = sp->getContentSize().width;

		sp = Sprite::create("bound_left.png");
		sp->setAnchorPoint(Point(0,0));
		sp->setRotation(180);
		sp->setPosition(size.width+left_width, y+sp->getContentSize().height);
		addChild(sp, order);

		y += sp->getContentSize().height;
	}

	//init display number
	for (int r=0; r<m_objects.size(); ++r)
	{
		for (int c=0; c<m_objects[r].size(); ++c)
		{
			int mine_count = 0;
			for (auto&x : getSurrounding(Index2(r,c)))
			{
				if (m_objects[x.first][x.second]->isMine())
				{
					++mine_count;
				}
			}
			m_objects[ r ][ c ]->setSurroundMineCount(mine_count);
		}
	}

	CCAssert(NULL!=m_pPlayer, "");
	dig(pointToIndex2(m_pPlayer->getPosition()));

// 	Size size = this->getContentSize(); 
// 	-m_border.width, -m_border.height, size.width+m_border.width*2, size.height+m_border.height*2
	const float tool = toolbar->getContentSize().height*4/5;
	this->runAction( Follow::create(m_pPlayer, Rect(-left_width, -bottom_height-tool, size.width+left_width*2, size.height+up_height+bottom_height+tool)));
	return true;
}