void BulletSpheresApp::update()
{
	// update time
	// update bullet context
	updateTime(); 
	
	mContext->setGravity( vec3( 0 ) );
	mContext->update();

	// add attractive force
	mat4 * matrices = (mat4*)mMatrices->map( GL_WRITE_ONLY );
	for( auto &body : mRigidBodies ){
		body.update( mTimeElapsed );
		int index = body.getId();
		if( index >=2 ){		// small orbs
			for( int i=0; i<2; i++ ){
				vec3 pos		= mRigidBodies[i].getPos();
				float size		= mRigidBodies[i].getSize();
				float strength	= mRigidBodies[i].getStrength();
				body.attract( pos, size, strength );
			}
			matrices[index-2] = body.getMatrix();
		} else {				// big orbs
			float size			= mRigidBodies[index].getSize();
			body.attract( vec3( 0 ), size, 1.0f );
		}
	}
	mMatrices->unmap();
}
void BulletSpheresApp::keyDown( KeyEvent event )
{
	switch( event.getChar() ){
		case 'f': setFullScreen( ! isFullScreen() );	break;
		case 'd': mContext->toggleDebugDraw();			break;
		default : break;
	}
}
void HeightfieldTerrainApp::addBox()
{
	// This is just a simple function to add some box shapes to our world. We're not
	// creating a corresponding visual object so you'll only be able to see them if
	// you have debug draw working.
	auto box = bt::createBoxShape( vec3( 1.0f ) );
	mRigidBodies.push_back( bt::RigidBody::create( bt::RigidBody::Format()
												  .collisionShape( box )
												  .initialPosition( vec3( randFloat(-5, 5), 10, randFloat(-5, 5) ) )
												  .mass( 1.0f ) ) );
	mContext->addRigidBody( mRigidBodies.back() );
}
void BulletSpheresApp::draw()
{
	drawToDepthFbo();
	gl::clear( Color( 0.1f, 0.1f, 0.1f ) );
	gl::setMatrices( mCam );
	gl::viewport( vec2( 0 ), getWindowSize() );
	
	// Draw small spheres
	{
		gl::ScopedTextureBind scopeTex0( mLight->getFbo()->getDepthTexture(), 0 );
		gl::ScopedTextureBind scopeTex1( mStripeTex, 1 );
		
		mRenderGlsl->uniform( "uShadowMap",	0 );
		mRenderGlsl->uniform( "uStripeTex",	1 );
		mRenderGlsl->uniform( "uLightPos",		mLight->getPos() );
		mRenderGlsl->uniform( "uDepthBias",	mLight->getDepthBias() );
		mRenderGlsl->uniform( "uLightPos1",	mRigidBodies[0].getPos() );
		mRenderGlsl->uniform( "uLightPos2",	mRigidBodies[1].getPos() );
		mRenderGlsl->uniform( "uRadius1",		mRigidBodies[0].getSize() );
		mRenderGlsl->uniform( "uRadius2",		mRigidBodies[1].getSize() );
		mRenderGlsl->uniform( "uShadowMvp",	mLight->getViewProjection() );
		
		mRenderSphere->drawInstanced( NUM_PARTICLES - 2 );
	}
	
	// Draw big spheres
	mGlowGlsl->bind();
	mGlowGlsl->uniform( "uLightPos", mLight->getPos() );
	for( auto &body : mRigidBodies ){
		auto index = body.getId();
		if( index < NUM_GLOWS ){
			mGlowGlsl->uniform( "uColor", mGlowColors[index] );
			body.draw();
		}
	}
	
	// Draw light source (if point light)
	if( mLight->getPos().w > 0.5f )
		mLight->draw();
	
	mContext->debugDraw();
}
void HeightfieldTerrainApp::setupHeightfield()
{
//	mHeightfieldMap = Channel32f( loadImage( loadAsset( "heightfield.jpg" ) ) );
	Perlin perlin( 4, 12 );
	mHeightfieldMap = Channel32f( Width, Depth );
	
	auto minHeight = 0.0f;
	auto maxHeight = 0.0f;
	
	// Now we'll give our Map some Height values.
	for( int y = 0; y < Depth; ++y ) {
		for( int x = 0; x < Width; ++x ) {
			// Now create our heightfield, which is just a two-dimensional array that has
			// a value, height. Instead of this you could easily use Perline to get smoother
			// values or create a black and white image.
			auto val = 25.0f * perlin.fBm( x/float(Depth), y/float(Width) );
			if( val > maxHeight ) maxHeight = val;
			else if ( val < minHeight ) minHeight = val;
			mHeightfieldMap.setValue( ivec2( x, y ), val );
		}
	}
	
	// Create our heightfieldShape with our heightfieldMap and maxHeight and minHeight
	auto heightField = bt::createHeightfieldShape( &mHeightfieldMap, maxHeight, minHeight, vec3( 10 ) );
	heightField->setLocalScaling( bt::toBullet( vec3( 100 ) ) );
	
	// Make our rigidbody out of this collision shape.
	mHeightfieldTerrain = bt::RigidBody::create( bt::RigidBody::Format().collisionShape( heightField ) );
	ci::AxisAlignedBox3f box;
	mHeightfieldTerrain->getAabb( box );
	
	cout << box.getCenter() << endl;
	
	// Collect it in my vector
	mRigidBodies.push_back( mHeightfieldTerrain );
	// And add that rigidbody to the world.
	mContext->addRigidBody( mHeightfieldTerrain );
	
	// Now we can create a batch using the draw helper from bullet which passes back a vboMesh based on our map.
	mBatch = gl::Batch::create( bt::drawableHelpers::getDrawableHeightfield( &mHeightfieldMap ), mPhongShader );
}
void HeightfieldTerrainApp::draw()
{
	static float rotation = 0.0f;
	// clear out the window with black
	gl::clear( Color( 0, 0, 0 ) );
	// set our camera
	gl::setMatrices( mCam );
	// rotate the camera position
	gl::multViewMatrix( rotate( toRadians( rotation += 0.1 ), vec3( 0.0f, 1.0f, 0.0f ) ) );
	{
		gl::ScopedModelMatrix scope;
		// Transform it with the physics heightfield
		gl::multModelMatrix( translate( bt::fromBullet( mHeightfieldTerrain->getRigidBody()->getWorldTransform().getOrigin() ) ) );
		mBatch->draw();
	}
	// If we want to draw the debug we can set this and just toggle on and off using...
	//
	// mContext->toggleDebugDraw()
	//
	mContext->debugDraw();
}
void HeightfieldTerrainApp::update()
{
	// must update the world.
	mContext->update();
	mCam.setEyePoint( vec3(mCam.getEyePoint().x, mCamHeight, mCam.getEyePoint().z ) );
}