コード例 #1
0
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 );
}
コード例 #2
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 );
		}
	}

}