Example #1
0
void ArtkpApp::update()
{
	static int lastCapture = -1;

	mFps = getAverageFps();

	// switch between capture devices
	if ( lastCapture != mCurrentCapture )
	{
		if ( ( lastCapture >= 0 ) && ( mCaptures[ lastCapture ] ) )
			mCaptures[ lastCapture ].stop();

		if ( mCaptures[ mCurrentCapture ] )
			mCaptures[ mCurrentCapture ].start();

		mCapture = mCaptures[ mCurrentCapture ];
		lastCapture = mCurrentCapture;
	}

	// detect the markers
	if ( mCapture && mCapture.checkNewFrame() )
	{
		Surface8u captSurf( mCapture.getSurface() );
		mCaptTexture = gl::Texture( captSurf );
		mArTracker.update( captSurf );
	}
}
Example #2
0
void BulletTestApp::shutdown()
{
	if ( mCapture && mCapture.isCapturing() ) {
		mCapture.stop();
	}
	if ( mLight ) {
		delete mLight;
	}
	if ( mTerrain != 0 ) {
		//delete mTerrain;
	}
}
Example #3
0
void ArtkpApp::shutdown()
{
	if ( mCapture )
	{
		mCapture.stop();
	}
}
Example #4
0
void Fluid2DCamAppApp::setup()
{
	glEnable( GL_TEXTURE_2D );
	
	mVelThreshold = 0.75f;
	mNumActiveFlowVectors = 0;
#if defined( CINDER_MSW )
	mVelScale = 0.5f;
	mDenScale = 0.0025f;
#elif defined( CINDER_MAC )
	mVelScale = 2.0f;
	mDenScale = 0.007f;
#endif

	mFluid2D.set( mFluid2DResX, mFluid2DResY );
	mFluid2D.enableDensity();
	mFluid2D.enableVorticityConfinement();
	mFluid2D.setNumPressureIters( 24 );
	mFluid2D.initSimData();
	
	// Create these so we can create the textures ahead of time
	mSurfVel0		= Surface32f( mFluid2DResX, mFluid2DResY, false, SurfaceChannelOrder::RGB );
	mSurfVel1		= Surface32f( mFluid2DResX, mFluid2DResY, false, SurfaceChannelOrder::RGB );
	mChanDen0		= Channel32f( mFluid2DResX, mFluid2DResY );
	mChanDen1		= Channel32f( mFluid2DResX, mFluid2DResY );
	mChanDiv		= Channel32f( mFluid2DResX, mFluid2DResY );
	mChanPrs		= Channel32f( mFluid2DResX, mFluid2DResY );
	mChanCurl		= Channel32f( mFluid2DResX, mFluid2DResY );
	mChanCurlLen	= Channel32f( mFluid2DResX, mFluid2DResY );
	mTexVel0		= gl::Texture( mSurfVel0 );
	mTexVel1		= gl::Texture( mSurfVel1 );
	mTexDen0		= gl::Texture( mChanDen0 );
	mTexDen1		= gl::Texture( mChanDen1 );
	mTexDiv			= gl::Texture( mChanDiv );
	mTexPrs			= gl::Texture( mChanPrs );
	mTexCurl		= gl::Texture( mChanCurl );
	mTexCurlLen		= gl::Texture( mChanCurlLen );
	
	mParams = params::InterfaceGl( "Params", Vec2i( 300, 400 ) );
	mParams.addParam( "Stam Step", mFluid2D.stamStepAddr() );
	mParams.addSeparator();
	mParams.addParam( "Velocity Threshold", &mVelThreshold, "min=0 max=2 step=0.001" );
	mParams.addSeparator();
	mParams.addParam( "Velocity Input Scale", &mVelScale, "min=0 max=10 step=0.001" );
	mParams.addParam( "Density Input Scale", &mDenScale, "min=0 max=1 step=0.0001" );
	mParams.addSeparator();
	mParams.addParam( "Velocity Dissipation", mFluid2D.velocityDissipationAddr(), "min=0 max=1 step=0.0001" );
	mParams.addParam( "Density Dissipation", mFluid2D.densityDissipationAddr(), "min=0 max=1 step=0.0001" );
	mParams.addSeparator();
	mParams.addParam( "Velocity Viscosity", mFluid2D.velocityViscosityAddr(), "min=0 max=10 step=0.000001" );
	mParams.addParam( "Density Viscosity", mFluid2D.densityViscosityAddr(), "min=0 max=10 step=0.000001" );
	mParams.addSeparator();
	mParams.addParam( "Vorticity Confinement", mFluid2D.enableVorticityConfinementAddr() );
	mParams.addSeparator();
	std::vector<std::string> boundaries;
	boundaries.push_back( "None" ); boundaries.push_back( "Wall" ); boundaries.push_back( "Wrap" );
	mParams.addParam( "Boundary Type", boundaries, mFluid2D.boundaryTypeAddr() );
	mParams.addSeparator();
	mParams.addParam( "Enable Buoyancy", mFluid2D.enableBuoyancyAddr() );
	mParams.addParam( "Buoyancy Scale", mFluid2D.buoyancyScaleAddr(), "min=0 max=100 step=0.001" );
	mParams.addParam( "Vorticity Scale", mFluid2D.vorticityScaleAddr(), "min=0 max=1 step=0.001" );
	
	// Camera
	try {
		mCapture = Capture( 640, 480 );
		mCapture.start();
	}
	catch( ... ) {
		console() << "Failed to initialize capture" << std::endl;
	}
}
Example #5
0
void Fluid2DCamAppApp::update()
{
	
	if( mCapture && mCapture.checkNewFrame() ) {
		if( ! mTexCam ) {
			mTexCam = gl::Texture( mCapture.getSurface() );
		}

		// Flip the image
		if( ! mFlipped ) {
			Surface8u srcImg = mCapture.getSurface();
			mFlipped = Surface8u( srcImg.getWidth(), srcImg.getHeight(), srcImg.hasAlpha(), srcImg.getChannelOrder() );
		}
		Surface8u srcImg = mCapture.getSurface();
		mFlipped = Surface8u( srcImg.getWidth(), srcImg.getHeight(), srcImg.hasAlpha(), srcImg.getChannelOrder() );
		for( int y = 0; y < mCapture.getHeight(); ++y ) {
			const Color8u* src = (const Color8u*)(srcImg.getData() + (y + 1)*srcImg.getRowBytes() - srcImg.getPixelInc());
			Color8u* dst = (Color8u*)(mFlipped.getData() + y*mFlipped.getRowBytes());
			for( int x = 0; x < mCapture.getWidth(); ++x ) {
				*dst = *src;
				++dst;
				--src;
			} 
		}
		
		// Create scaled image
		if( ! mCurScaled  ) {
			mCurScaled = Surface8u( mFlipped.getWidth()/kFlowScale, mFlipped.getHeight()/kFlowScale, mFlipped.hasAlpha(), mFlipped.getChannelOrder() );
		}		
		ip::resize( mFlipped, &mCurScaled );

		// Optical flow 
		if( mCurScaled && mPrvScaled ) {
			mPrvCvData = mCurCvData;
			mCurCvData = cv::Mat( toOcv( Channel( mCurScaled ) ) );

			if( mPrvCvData.data && mCurCvData.data ) {
				int pyrLvels		= 3;
				int winSize			= 3;
				int iters			= 5;
				int poly_n			= 7;
				double poly_sigma	= 1.5;
				cv::calcOpticalFlowFarneback( mPrvCvData, mCurCvData, mFlow, 0.5, pyrLvels, 2*winSize + 1, iters, poly_n, poly_sigma, cv::OPTFLOW_FARNEBACK_GAUSSIAN );

				if( mFlow.data ) {
					if( mFlowVectors.empty() ) {
						mFlowVectors.resize( mCurScaled.getWidth()*mCurScaled.getHeight() );
					}
					
					//memset( &mFlowVectors[0], 0, mCurScaled.getWidth()*mCurScaled.getHeight()*sizeof( Vec2f ) );
					mNumActiveFlowVectors = 0;
					for( int j = 0; j < mCurScaled.getHeight(); ++j ) {
						for( int i = 0; i < mCurScaled.getWidth(); ++i ) {
							const float* fptr = reinterpret_cast<float*>(mFlow.data + j*mFlow.step + i*sizeof(float)*2);
							//
							Vec2f v = Vec2f( fptr[0], fptr[1] ); 
							if( v.lengthSquared() >= mVelThreshold ) {
								if( mNumActiveFlowVectors >= (int)mFlowVectors.size() ) {
									mFlowVectors.push_back( std::make_pair( Vec2i( i, j ), v ) );
								}
								else {
									mFlowVectors[mNumActiveFlowVectors] = std::make_pair( Vec2i( i, j ), v );
								}
								++mNumActiveFlowVectors;
							}
						}
					}
				}
			}
		}

		// Update texture
		mTexCam.update( mFlipped );

		// Save previous frame
		if( ! mPrvScaled ) {
			mPrvScaled = Surface8u( mCurScaled.getWidth(), mCurScaled.getHeight(), mCurScaled.hasAlpha(), mCurScaled.getChannelOrder() );
		}
		memcpy( mPrvScaled.getData(), mCurScaled.getData(), mCurScaled.getHeight()*mCurScaled.getRowBytes() );
	}

	// Update fluid
	float dx = (mFluid2DResX - 2)/(float)(640/kFlowScale);
	float dy = (mFluid2DResY - 2)/(float)(480/kFlowScale);
	for( int i = 0; i < mNumActiveFlowVectors; ++i ) {
		Vec2f P = mFlowVectors[i].first;
		const Vec2f& v = mFlowVectors[i].second;
		mFluid2D.splatDensity( P.x*dx + 1, P.y*dy + 1, mDenScale*v.lengthSquared() );
		mFluid2D.splatVelocity( P.x*dx + 1, P.y*dy + 1, v*mVelScale );
	}
	mFluid2D.step();

	// Update velocity
	const Vec2f* srcVel0 = mFluid2D.dbgVel0().data();
	const Vec2f* srcVel1 = mFluid2D.dbgVel1().data();
	Colorf* dstVel0 = (Colorf*)mSurfVel0.getData();
	Colorf* dstVel1 = (Colorf*)mSurfVel1.getData();
	for( int j = 0; j < mFluid2DResY; ++j ) {
		for( int i = 0; i < mFluid2DResX; ++i ) {
			*dstVel0 = Colorf( srcVel0->x, srcVel0->y, 0.0f );
			*dstVel1 = Colorf( srcVel1->x, srcVel1->y, 0.0f );
			++srcVel0;
			++srcVel1;
			++dstVel0;
			++dstVel1;
		}
	}
	
	// Update Density
	mChanDen0 = Channel32f( mFluid2DResX, mFluid2DResY, mFluid2DResX*sizeof(float), 1, mFluid2D.dbgDen0().data() );
	mChanDen1 = Channel32f( mFluid2DResX, mFluid2DResY, mFluid2DResX*sizeof(float), 1, mFluid2D.dbgDen1().data() );
	
	mTexDen0.update( mChanDen0 );
	mTexDen1.update( mChanDen1 );
	
	// Update velocity textures
	mTexVel0.update( mSurfVel0 );
	mTexVel1.update( mSurfVel1 );
	
	// Update Divergence
	mChanDiv = Channel32f( mFluid2DResX, mFluid2DResY, mFluid2DResX*sizeof(float), 1, mFluid2D.dbgDivergence().data() );
	mTexDiv.update( mChanDiv );

	// Update Divergence
	mChanPrs = Channel32f( mFluid2DResX, mFluid2DResY, mFluid2DResX*sizeof(float), 1, mFluid2D.dbgPressure().data() );
	mTexPrs.update( mChanPrs );

	// Update Curl, Curl Length
	mChanCurl = Channel32f( mFluid2DResX, mFluid2DResY, mFluid2DResX*sizeof(float), 1, mFluid2D.dbgCurl().data() );
	mTexCurl.update( mChanCurl );
	mChanCurlLen = Channel32f( mFluid2DResX, mFluid2DResY, mFluid2DResX*sizeof(float), 1, mFluid2D.dbgCurlLength().data() );
	mTexCurlLen.update( mChanCurlLen );
}
Example #6
0
void BulletTestApp::update()
{

	// Run next test
	if ( mTest != mTestPrev ) {
		mTestPrev = mTest;
		initTest();
	}

	mFrameRate = getAverageFps();

	// Update light
	mLight->update( mCamera );

	if ( mTest < 3 ) {

		// Set box rotation
		float rotation = math<float>::sin( ( float )getElapsedSeconds() * 0.3333f ) * 0.35f	;
		mGroundTransform.setRotation( btQuaternion( 0.25f, 0.0f, 1.0f + rotation * 0.1f, rotation ) );
		mGroundTransform.setOrigin( btVector3( 0.0f, -60.0f, 0.0f ) );

		// Apply rotation to box
		btRigidBody* body = bullet::toBulletRigidBody( mGround );
		body->getMotionState()->setWorldTransform( mGroundTransform );
		body->setWorldTransform( mGroundTransform );

	} else if ( mTest == 6 ) {

		// Read data
		Channel32f& input = mTerrain->getData();

		// Get image dimensions
		int32_t height = input.getHeight();
		int32_t width = input.getWidth();
		
		// Create output channel
		Channel32f output = Channel32f( width, height );
		
		// Move pixel value over by one
		for ( int32_t y = 0; y < height; y++ ) {
			for ( int32_t x = 0; x < width; x++ ) {
				float value = input.getValue( Vec2i( x, y ) );
				Vec2i position( ( x + 1 ) % width, ( y + 1 ) % height );
				output.setValue( position, value );
			}

		}

		// Copy new data back to original
		input.copyFrom( output, output.getBounds() );

		// Shift texture coordinates to match positions
		vector<Vec2f>& texCoords = mTerrain->getTexCoords();
		Vec2f delta( 1.0f / (float)width, 1.0f / (float)height );
		for ( vector<Vec2f>::iterator uv = texCoords.begin(); uv != texCoords.end(); ++uv ) {
			*uv -= delta;
		}

		// Update terrain VBO
		mTerrain->updateVbo();

	} else if ( mTest == 7 ) {

		bool init = !mSurface;
		
		if ( mCapture.isCapturing() && mCapture.checkNewFrame() ) {
		
			mSurface = mCapture.getSurface();
			ip::flipVertical( &mSurface );

			if ( init ) {
				mTerrain = new DynamicTerrain( Channel32f( 160, 160 ), -1.0f, 1.0f, Vec3f( 2.0f, 70.0f, 2.0f ), 0.0f );
				mWorld->pushBack( mTerrain );
				btRigidBody* terrain = ( btRigidBody* )mTerrain->getBulletBody();
				terrain->setAngularFactor( 0.6f );
				terrain->setFriction( 0.6f );
			} else {
				mTerrain->getData().copyFrom( Channel32f( mSurface ), Area( 0, 0, 160, 160 ) );
				mTerrain->updateVbo();
			}

		}

	}
	
	// Update dynamics world
	mWorld->update( mFrameRate );

	/*if ( mGround ) { 
		Iter iter = mWorld->find( mGround );
		OutputDebugStringA( toString( iter->getPosition().x ).c_str() );
		OutputDebugStringA( "\n" );
	}*/

	// Remove out of bounbds objects
	for ( bullet::Iter object = mWorld->begin(); object != mWorld->end(); ) {
		if ( object != mWorld->begin() && object->getPosition().y < -800.0f ) {
			object = mWorld->erase( object );
		} else {
			++object;
		}
	}

	// Remove objects when count is too high
	uint32_t max = mTest >= 4 ? MAX_OBJECTS_TERRAIN : MAX_OBJECTS;
	if ( mWorld->getNumObjects() > max + 1 ) {
		for ( uint32_t i = 1; i < mWorld->getNumObjects() - MAX_OBJECTS_TERRAIN; i++ ) {
			mWorld->erase( mWorld->begin() + 1 );
		}
	}

}
Example #7
0
void BulletTestApp::initTest()
{

	// Clean up last test
	if ( mWorld ) {
		mWorld->clear();
	}
	
	// Used when generating terrain
	Channel32f heightField;

	// Create and add the wobbly box
	mGroundTransform.setIdentity();
	switch ( mTest ) {
	case 0:
		mGround = bullet::createRigidBox( mWorld, Vec3f( 200.0f, 35.0f, 200.0f ), 0.0f );
		bullet::createRigidSphere( mWorld, 50.0f, 64, 0.0f, Vec3f( 0.0f, -50.0f, 0.0f ) );
		break;
	case 1:
		mGround = bullet::createRigidHull( mWorld, mConvex, Vec3f::one() * 50.0f, 0.0f );
		break;
	case 2:
		mGround = bullet::createRigidMesh( mWorld, mConcave, Vec3f( 10.0f, 1.0f, 10.0f ), 0.0f, 0.0f );
		break;
	case 3:
		mGround = bullet::createRigidBox( mWorld, Vec3f( 200.0f, 35.0f, 200.0f ), 0.0f );
		break;
	case 4:
		mGround = bullet::createRigidBox( mWorld, Vec3f( 200.0f, 35.0f, 200.0f ), 0.0f );
		break;
	case 5:
		heightField = Channel32f( loadImage( loadResource( RES_IMAGE_HEIGHTFIELD_SM ) ) );
		mGround = bullet::createRigidTerrain( mWorld, heightField, -1.0f, 1.0f, Vec3f( 6.0f, 80.0f, 6.0f ), 0.0f );
		break;
	case 6:

		// ADVANCED: To add a custom class, create a standard pointer to it and 
		// pushBack it into your world. Be sure to delete this pointer when you no loinger need it
		heightField = Channel32f( loadImage( loadResource( RES_IMAGE_HEIGHTFIELD ) ) );
		mTerrain = new DynamicTerrain( heightField, -1.0f, 1.0f, Vec3f( 2.0f, 50.0f, 2.0f ), 0.0f );
		mWorld->pushBack( mTerrain );
		break;

	case 7:

		// Start capture
		if ( !mCapture ) {
			mCapture = Capture( 320, 240 );
			mCapture.start();
		}

		break;

	}

	// Set friction for box
	if ( mTest < 5 ) {
		btRigidBody* boxBody = bullet::toBulletRigidBody( mGround );
		boxBody->setFriction( 0.95f );
	}

}
Example #8
0
void BulletTestApp::initTest()
{

	// Clean up last test
	if ( mWorld ) {
		mWorld->clear();
		mWorld->getInfo().m_sparsesdf.Reset();
	}
	
	// Used when generating terrain
	Channel32f heightField;

	// Create and add the wobbly box
	btSoftBody* body				= 0;
	btSoftBody::Material* material	= 0;
	mGroundTransform.setIdentity();
	switch ( mTest ) {
	case 0:
		mGround = bullet::createRigidBox( mWorld, Vec3f( 200.0f, 35.0f, 200.0f ), 0.0f );
		bullet::createRigidSphere( mWorld, 50.0f, 0.0f, Vec3f( 0.0f, -50.0f, 0.0f ) );
		break;
	case 1:
		mGround = bullet::createRigidHull( mWorld, mConvex, Vec3f::one() * 50.0f, 0.0f );
		break;
	case 2:
		mGround = bullet::createRigidMesh( mWorld, mConcave, Vec3f( 10.0f, 1.0f, 10.0f ), 0.0f, 0.0f );
		break;
	case 5:
		heightField = Channel32f( loadImage( loadResource( RES_IMAGE_HEIGHTFIELD_SM ) ) );
		mGround = bullet::createRigidTerrain( mWorld, heightField, -1.0f, 1.0f, Vec3f( 6.0f, 80.0f, 6.0f ), 0.0f );
		break;
	case 6:
		// ADVANCED: To add a custom class, create a standard pointer to it and 
		// pushBack it into your world. Be sure to delete this pointer when you no longer need it.
		heightField = Channel32f( loadImage( loadResource( RES_IMAGE_HEIGHTFIELD ) ) );
		mTerrain = new DynamicTerrain( heightField, -1.0f, 1.0f, Vec3f( 2.0f, 50.0f, 2.0f ), 0.0f );
		mWorld->pushBack( mTerrain );
		break;
	case 7:

		// Start capture
		if ( !mCapture ) {
			mCapture = Capture( 320, 240 );
			mCapture.start();
		}

		break;
	case 8:
		mWorld->getInfo().m_gravity = toBulletVector3( Vec3f( 0.0f, -0.5f, 0.0f ) );

		mGround = bullet::createSoftCloth( mWorld, Vec2f::one() * 180.0f, Vec2i( 18, 20 ), SoftCloth::CLOTH_ATTACH_CORNER_ALL, Vec3f( 0.0f, 0.0f, 40.0f ), Quatf( 0.0f, 0.0f, 0.0f, 0.1f ) );
		
		body = toBulletSoftBody( mGround );
		
		body->m_materials[ 0 ]->m_kAST	= 0.2f;
		body->m_materials[ 0 ]->m_kLST	= 0.2f;
		body->m_materials[ 0 ]->m_kVST	= 0.2f;
		
		body->m_cfg.kDF					= 0.9f; 
		body->m_cfg.kSRHR_CL			= 1.0f;
		body->m_cfg.kSR_SPLT_CL			= 0.0f;
		body->m_cfg.collisions			= btSoftBody::fCollision::CL_SS + btSoftBody::fCollision::CL_RS;
		
		body->getCollisionShape()->setMargin( 0.0001f );
		body->setTotalMass( 500.0f );
		body->generateClusters( 0 );

		material						= body->appendMaterial();
		material->m_kAST				= 0.5f;
		material->m_kLST				= 0.5f;
		material->m_kVST				= 1.0f;
		body->generateBendingConstraints( 1, material );

		break;
	case 9:
		heightField = Channel32f( loadImage( loadResource( RES_IMAGE_HEIGHTFIELD_SM ) ) );
		mGround = bullet::createRigidTerrain( mWorld, heightField, -1.0f, 1.0f, Vec3f( 6.0f, 80.0f, 6.0f ), 0.0f );
		break;
	default:
		mGround = bullet::createRigidBox( mWorld, Vec3f( 200.0f, 35.0f, 200.0f ), 0.0f );
		break;
	}

	// Set friction for box
	if ( mTest < 5 ) {
		btRigidBody* boxBody = bullet::toBulletRigidBody( mGround );
		boxBody->setFriction( 0.95f );
	}

}