コード例 #1
0
void Object_Player::createCapsuleObject(hkpWorld* world)
{
	// Create a temp body info
	hkpCharacterRigidBodyCinfo	bodyInfo;

	// Capsule Parameters
	hkVector4	vertexA(0.0f, 1.0f, 0.0f, 0);	// Top
	hkVector4	vertexB(0.0f, -1.0f, 0.0f, 0);	// Bottom
	hkReal		radius	=	1.0f;				// Radius

	// Create Capsule Based on Parameters
	hkpCapsuleShape* capsuleShape = new hkpCapsuleShape(vertexA, vertexB, radius);

	// Set The Object's Properties
	bodyInfo.m_shape = capsuleShape;
	bodyInfo.m_position.set(position.x, position.y, position.z, 0.0f);
	bodyInfo.m_maxSlope = HK_REAL_PI / 3.0f;

	// Calculate Mass Properties
	hkMassProperties massProperties;

	hkpInertiaTensorComputer::computeShapeVolumeMassProperties(capsuleShape, mass, massProperties);
	
	// Create Rigid Body
	objectBody = new hkpCharacterRigidBody(bodyInfo);

	// No longer need the reference on the shape, as the rigidbody owns it now
	capsuleShape->removeReference();

	// Add Rigid Body to the World
	world->addEntity(objectBody->getRigidBody());
}
コード例 #2
0
void Gdc2005Demo::optionUpdate()
{
	const hkVector4 UP(0,1,0);

	// Handle load save

	//Set capsule size.
	{
		const hkReal totalHeight = m_options.m_Proxy.m_height;
		const hkReal radius = m_options.m_Proxy.m_radius;
		const hkReal capsulePoint = totalHeight*0.5f - radius;

		updateProxyDisplay(m_options.m_Proxy.m_radius, m_options.m_Proxy.m_height);

		hkVector4 vertexA(0, capsulePoint * 2 + radius, 0);
		hkVector4 vertexB(0, radius, 0);
		hkpCapsuleShape* capsule = static_cast<hkpCapsuleShape*>( const_cast<hkpShape*>(m_characterProxy->getShapePhantom()->getCollidable()->getShape() ));
		capsule->setRadius( radius );
		capsule->setVertex(0, vertexA);
		capsule->setVertex(1, vertexB);
	}

	// Set gravity
	hkVector4 gravity;
	gravity.setMul4( -m_options.m_Physics.m_gravity, UP);
	m_world->setGravity( gravity );

	// Ragdoll bodies (green)
	if (m_options.m_Display.m_ragdoll != m_ragdollDisplayBodiesVisible )
	{
		toggleRagdollVisibility();
	}

	if (m_options.m_Display.m_proxy != m_proxyVisible)
	{
		toggleProxyVisibility();
	}

	// Graphics
	hkDefaultDemo::forceShadowState( m_options.m_Display.m_shadows );

	if (m_lightmapDisplay)
	{
		if (m_options.m_Display.m_lightmaps)
		{
			int vertsIn = m_env->m_displayWorld->findDisplayObject( m_vertexColorDisplay );
			if (vertsIn >= 0 )
			{
				m_env->m_displayWorld->removeDisplayObject( vertsIn );
				m_vertexColorDisplay->release(); // already have a ref anyway
				m_env->m_displayWorld->addDisplayObject( m_lightmapDisplay );
			}
		}
		else
		{
			int lmIn = m_env->m_displayWorld->findDisplayObject( m_lightmapDisplay );
			if (lmIn >= 0 )
			{
				m_env->m_displayWorld->removeDisplayObject( lmIn );
				m_lightmapDisplay->release(); // already have a ref anyway
				m_env->m_displayWorld->addDisplayObject( m_vertexColorDisplay );
			}
		}
	}

	hkReal w = hkMath::max2(
		  m_animatedSkeleton->getAnimationControl(GDC_DEATH_CONTROL)->getWeight(),
		  m_animatedSkeleton->getAnimationControl(GDC_DYING_CONTROL)->getWeight());

	setMotors(m_ragdollInstance,
		m_options.m_Matching.m_force * w,
		m_options.m_Matching.m_tau,
		m_options.m_Matching.m_proportinalRecovery,
		m_options.m_Matching.m_constantRecovery);

	// Do rebuild walls, save and load from XML, etc., when we have finished tweaking
	if (m_tweaking == false)
	{

		switch (m_options.m_Misc.m_settings)
		{
			case hkGdcMiscOptions::SAVE:
				{
					hkBinaryPackfileWriter pw;
					pw.setContents(&m_options, Gdc2005DemoOptionsClass);

					hkOfstream settingsFile("GdcDemoSettings.bin");
					if (settingsFile.isOk())
					{
						hkPackfileWriter::Options o;
						pw.save( settingsFile.getStreamWriter(), o );
					}
				}
				break;
			case hkGdcMiscOptions::LOAD:
				{
					hkBinaryPackfileReader pw;

					hkIfstream settingsFile("GdcDemoSettings.bin");
					if (settingsFile.isOk())
					{
						pw.loadEntireFile( settingsFile.getStreamReader() );
						Gdc2005DemoOptions* options = (Gdc2005DemoOptions*)pw.getContents(Gdc2005DemoOptionsClass.getName());
						m_options = *options;
					}
				}
				break;
			case hkGdcMiscOptions::DEFAULT:
				{
					// Copy from defaults
					m_options = Gdc2005DemoOptions();
					m_selected = "/";
				}
				break;
			case hkGdcMiscOptions::NONE:
				break;
		}
		m_options.m_Misc.m_settings = hkGdcMiscOptions::NONE;

		if (m_options.m_Physics.m_rebuildWall)
		{
			rebuildBrickWall();
			m_options.m_Physics.m_rebuildWall = false; // reset
		}
	}
}
コード例 #3
0
AsymetricCharacterRbDemo::AsymetricCharacterRbDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env)
{
		
	// Create the world
	{
		hkpWorldCinfo info;
		info.setBroadPhaseWorldSize( 350.0f );  
		info.m_gravity.set(0, -9.8f, 0);
		info.m_collisionTolerance = 0.01f;		
		info.m_contactPointGeneration = hkpWorldCinfo::CONTACT_POINT_ACCEPT_ALWAYS;
		m_world = new hkpWorld( info );
		m_world->lock();

		hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());

		setupGraphics();
	}
	
	//	Create a terrain (more bumpy as in the classical character proxy demo)
	TerrainHeightFieldShape* heightFieldShape;
	{
		hkpSampledHeightFieldBaseCinfo ci;
		ci.m_xRes = 64;
		ci.m_zRes = 64;
		ci.m_scale.set(1.6f, 0.2f, 1.6f);

		// Fill in a data array
		m_data = hkAllocate<hkReal>((ci.m_xRes * ci.m_zRes), HK_MEMORY_CLASS_DEMO);
		
		for (int x = 0; x < ci.m_xRes; x++)
		{
			for (int z = 0; z < ci.m_zRes; z++)
			{
				hkReal dx,dz,height = 0;
				int octave = 1;
				
				// Add together a few sine and cose waves
				for (int i=0; i< 3; i++)
				{
					dx = hkReal(x * octave) / ci.m_xRes;
					dz = hkReal(z * octave) / ci.m_zRes;
					height +=  4 * i * hkMath::cos(dx * HK_REAL_PI) * hkMath::sin(dz * HK_REAL_PI);
					height -= 2.5f;
					octave *= 2;				
				}

				m_data[x*ci.m_zRes + z] = height;
			}
		}

		heightFieldShape = new TerrainHeightFieldShape( ci , m_data );
		
		//	Create terrain as a fixed rigid body
		{
			hkpRigidBodyCinfo rci;
			rci.m_motionType = hkpMotion::MOTION_FIXED;
			rci.m_position.setMul4( -0.5f, heightFieldShape->m_extents ); // center the heighfield
			rci.m_shape = heightFieldShape;
			rci.m_friction = 0.5f;
			
			hkpRigidBody* terrain = new hkpRigidBody( rci );

			m_world->addEntity(terrain);

			terrain->removeReference();
		}

		heightFieldShape->removeReference();
	}
	
	// Create some random static pilars (green) and smaller dynamic boxes (blue)
	{
		hkPseudoRandomGenerator randgen(12345);

		for (int i=0; i < 80; i++)
		{
			
			if (i%2)
			{
				// Dynamic boxes of random size
				hkVector4 size;
				randgen.getRandomVector11(size);
				size.setAbs4( size );
				size.mul4(0.5f);
				hkVector4 minSize; minSize.setAll3(0.25f);
				size.add4(minSize);
				
				// Random position
				hkVector4 position;
				randgen.getRandomVector11( position );
				position(0) *= 25; position(2) *= 25; position(1) = 4;

				{ 
					// To illustrate using the shape, create a rigid body by first defining a template.
					hkpRigidBodyCinfo rci;
					rci.m_shape = new hkpBoxShape( size );
					rci.m_position = position;
					rci.m_friction = 0.5f;
					rci.m_restitution = 0.0f;
					// Density of concrete
					const hkReal density = 2000.0f;
					rci.m_mass = size(0)*size(1)*size(2)*density;
					
					hkVector4 halfExtents(size(0) * 0.5f, size(1) * 0.5f, size(2) * 0.5f);
					hkpMassProperties massProperties;
					hkpInertiaTensorComputer::computeBoxVolumeMassProperties(halfExtents, rci.m_mass, massProperties);
					rci.m_inertiaTensor = massProperties.m_inertiaTensor;
					rci.m_motionType = hkpMotion::MOTION_BOX_INERTIA;
										
					// Create a rigid body (using the template above).
					hkpRigidBody* box = new hkpRigidBody(rci);

					// Remove reference since the body now "owns" the Shape.
					rci.m_shape->removeReference();

					box->addProperty(HK_PROPERTY_DEBUG_DISPLAY_COLOR, int(hkColor::DARKBLUE)); 

					// Finally add body so we can see it, and remove reference since the world now "owns" it.
					m_world->addEntity(box)->removeReference();
				} 

			}
			else
			{
				// Fixed pilars of random size
				hkVector4 size;
				randgen.getRandomVector11(size);
				size.setAbs4( size );
				hkVector4 minSize; minSize.setAll3(0.5f);
				size.add4(minSize);
				size(1) = 2.5f;

				// Random position
				hkVector4 position;
				randgen.getRandomVector11( position );
				position(0) *= 25; position(2) *= 25; position(1) = 0;

				{ 
					// To illustrate using the shape, create a rigid body by first defining a template.
					hkpRigidBodyCinfo rci;
					
					rci.m_shape = new hkpBoxShape( size );
					rci.m_position = position;
					rci.m_friction = 0.1f;
					rci.m_motionType = hkpMotion::MOTION_FIXED;
					

					// Create a rigid body (using the template above).
					hkpRigidBody* pilar = new hkpRigidBody(rci);

					// Remove reference since the body now "owns" the shape.
					rci.m_shape->removeReference();

					pilar->addProperty(HK_PROPERTY_DEBUG_DISPLAY_COLOR, int(hkColor::DARKGREEN)); 

					// Finally add body so we can see it, and remove reference since the world now "owns" it.
					m_world->addEntity(pilar);

					pilar->removeReference();
				} 
			}
		}
	}

	//	Create a character rigid body
	{
	
		// Construct a shape
		hkVector4 vertexA(0.4f,0,0);
		hkVector4 vertexB(-0.4f,0,0);		

		// Create a capsule to represent the character standing
		hkpShape* capsule = new hkpCapsuleShape(vertexA, vertexB, 0.6f);
		

		// Construct a character rigid body
		hkpCharacterRigidBodyCinfo info;
		info.m_mass = 100.0f;
		info.m_shape = capsule;
		info.m_maxForce = 1000.0f;
		info.m_up = UP;
		info.m_position.set(32.0f, 3.0f, 10.0f);
		info.m_maxSlope = HK_REAL_PI/2.0f;	// Only vertical plane is too steep


		m_characterRigidBody = new hkpCharacterRigidBody( info );
		m_world->addEntity( m_characterRigidBody->getRigidBody() );

		capsule->removeReference();

	}
	
	// Create the character state machine and context
	{
		hkpCharacterState* state;
		hkpCharacterStateManager* manager = new hkpCharacterStateManager();

		state = new hkpCharacterStateOnGround();
		manager->registerState( state,	HK_CHARACTER_ON_GROUND);
		state->removeReference();

		state = new hkpCharacterStateInAir();
		manager->registerState( state,	HK_CHARACTER_IN_AIR);
		state->removeReference();

		state = new hkpCharacterStateJumping();
		manager->registerState( state,	HK_CHARACTER_JUMPING);
		state->removeReference();

		state = new hkpCharacterStateClimbing();
		manager->registerState( state,	HK_CHARACTER_CLIMBING);
		state->removeReference();

		m_characterContext = new hkpCharacterContext(manager, HK_CHARACTER_IN_AIR);	
		manager->removeReference();			

		// Set new filter parameters for final output velocity filtering
		// Smoother interactions with small dynamic boxes
		m_characterContext->setCharacterType(hkpCharacterContext::HK_CHARACTER_RIGIDBODY);
		m_characterContext->setFilterParameters(0.9f,12.0f,200.0f);
	}

	// Initialize hkpSurfaceInfo of ground from previous frame
	// Specific case (character is in the air, UP is Y)
	m_previousGround = new hkpSurfaceInfo(UP,hkVector4::getZero(),hkpSurfaceInfo::UNSUPPORTED);
	m_framesInAir = 0;
	
	// Current camera angle about up
	m_currentAngle = 0.0f;

	// Init actual time
	m_time = 0.0f;

	// Init rigid body normal
	m_rigidBodyNormal = UP;

	m_world->unlock();
}
コード例 #4
0
hkpWorld* PlanetGravityDemo::loadWorld( const char* path, hkpPhysicsData** physicsData, hkPackfileReader::AllocatedData** memData )
{
	hkIstream infile( path );
	HK_ASSERT( 0x215d080c, infile.isOk() );

	*physicsData = hkpHavokSnapshot::load( infile.getStreamReader(), memData );

	HK_ASSERT( 0, *physicsData != HK_NULL );

	// Ensure non-multithreaded simulation for non-multithreaded platforms

	hkpWorld* world = (*physicsData)->createWorld();
	world->setGravity( hkVector4::getZero() );

	//	Create a character rigid body object
	{
		// Construct a shape
		hkVector4 vertexA( 0.0f,  0.4f, 0.0f );
		hkVector4 vertexB( 0.0f, -0.4f, 0.0f );

		// Create a capsule to represent the character standing
		m_standShape = new hkpCapsuleShape( vertexA, vertexB, 0.6f );

		// Create a capsule to represent the character crouching
		// Note that we create the smaller capsule with the base at the same position as the larger capsule.		
		m_crouchShape = new hkpCapsuleShape( hkVector4::getZero(), vertexB, 0.6f );

		// Construct a character rigid body
		hkpCharacterRigidBodyCinfo info;
		info.m_mass = 80.0f;
		info.m_shape = m_standShape;

		info.m_maxForce = 8000.0f;
		info.m_position.set( 30.f, 0.f, 30.f );
		info.m_maxSlope = 45.0f * HK_REAL_DEG_TO_RAD;
		info.m_friction = 0.25f;
		m_characterRigidBody = new hkpCharacterRigidBody( info );
		world->addEntity( m_characterRigidBody->getRigidBody() );
		m_characterRigidBody->getRigidBody()->setRestitution( 0.0f );
	}

	// Create the Character state machine and context
	{
		hkpCharacterState* state;
		hkpCharacterStateManager* manager = new hkpCharacterStateManager();

		state = new hkpCharacterStateOnGround();
		manager->registerState( state,	HK_CHARACTER_ON_GROUND );

		static_cast<hkpCharacterStateOnGround*>( manager->getState( HK_CHARACTER_ON_GROUND ) )->setDisableHorizontalProjection( true );
		state->removeReference();

		state = new hkpCharacterStateInAir();
		manager->registerState( state,	HK_CHARACTER_IN_AIR );
		state->removeReference();

		state = new hkpCharacterStateJumping();
		manager->registerState( state,	HK_CHARACTER_JUMPING );
		state->removeReference();

		m_characterContext = new hkpCharacterContext( manager, HK_CHARACTER_IN_AIR );
		manager->removeReference();

		// Set character type
		m_characterContext->setCharacterType( hkpCharacterContext::HK_CHARACTER_RIGIDBODY );
	}

	return world;
}
コード例 #5
0
PlatformsCharacterRbDemo::PlatformsCharacterRbDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env)
{

	// Setup the graphics
	{
		// Disable back face culling
		setGraphicsState(HKG_ENABLED_CULLFACE, false);

		// don't really want shadows as makes it too dark
		forceShadowState(false);

		setupLights(m_env); // so that the extra lights are added

		// allow color change on precreated objects
		m_env->m_displayHandler->setAllowColorChangeOnPrecreated(true);
	}

	// Create the world
	{
		hkpWorldCinfo info;
		info.setBroadPhaseWorldSize( 350.0f );
		info.m_gravity.set(0,0,-9.8f);
		info.m_collisionTolerance = 0.01f;
		m_world = new hkpWorld( info );
		m_world->lock();

		hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());

		setupGraphics();
	}

	// Load the level
	{
		m_loader = new hkLoader();

		hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Physics/levels/test_platform.hkx");
		hkRootLevelContainer* container = m_loader->load( assetFile.cString() );
		HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset");
		hkxScene* scene = reinterpret_cast<hkxScene*>( container->findObjectByType( hkxSceneClass.getName() ));

		HK_ASSERT2(0x27343635, scene, "No scene loaded");
		env->m_sceneConverter->convert( scene, hkgAssetConverter::CONVERT_ALL );

		hkpPhysicsData* physics = reinterpret_cast<hkpPhysicsData*>( container->findObjectByType( hkpPhysicsDataClass.getName() ));
		HK_ASSERT2(0x27343635, physics, "No physics loaded");

		// Physics
		if (physics)
		{
			const hkArray<hkpPhysicsSystem*>& psys = physics->getPhysicsSystems();

			// Tie the two together
			for (int i=0; i<psys.getSize(); i++)
			{
				hkpPhysicsSystem* system = psys[i];

				// Change the layer of the rigid bodies
				for (int rb=0; rb < system->getRigidBodies().getSize(); rb++)
				{
					const hkUlong id = hkUlong(system->getRigidBodies()[rb]->getCollidable());
					HK_SET_OBJECT_COLOR(id,NORMAL_GRAY);
					m_objectIds.pushBack(id);
				}

				// Associate the display and physics (by name)
				if (scene)
				{
					addPrecreatedDisplayObjectsByName( psys[i]->getRigidBodies(), scene );
				}

				// add the lot to the world
				m_world->addPhysicsSystem(system);
			}
		}
	}

	// Add horizontal keyframed platform
	{

		hkpShape* platform = new hkpBoxShape(hkVector4(1.5,2.5,0.25));

		hkpRigidBodyCinfo rbci;
		rbci.m_shape = platform;
		rbci.m_motionType = hkpMotion::MOTION_KEYFRAMED;
		rbci.m_position.set(2.5f, 0.0f, 0.25f);
		rbci.m_friction = 1.0f;
		rbci.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(hkpGroupFilter::calcFilterInfo(1));

		m_horPlatform = new hkpRigidBody(rbci);

		platform->removeReference();
		m_world->addEntity(m_horPlatform);
		m_horPlatform->removeReference();

	}

	// Add vertical keyframed platform
	{
		hkpShape* platform = new hkpBoxShape(hkVector4(1.5,2.5,0.25));

		hkpRigidBodyCinfo rbci;
		rbci.m_shape = platform;
		rbci.m_motionType = hkpMotion::MOTION_KEYFRAMED;
		rbci.m_position.set(-3.5f, 0.0f, 3.25f);
		rbci.m_friction = 1.0f;
		rbci.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(hkpGroupFilter::calcFilterInfo(1));

		m_verPlatform = new hkpRigidBody(rbci);

		platform->removeReference();
		m_world->addEntity(m_verPlatform);
		m_verPlatform->removeReference();
	}

	//	Create a character rigid body
	{
		// Create a capsule to represent the character standing
		hkVector4 vertexA(0,0, 0.4f);
		hkVector4 vertexB(0,0,-0.4f);
	
		m_standShape = new hkpCapsuleShape(vertexA, vertexB, .6f);

		// Construct a character rigid body
		hkpCharacterRigidBodyCinfo info;
		info.m_mass = 100.0f;
		info.m_shape = m_standShape;

		info.m_maxForce = 1000.0f;
		info.m_up = UP;
		info.m_position.set(0.0f, 5.0f, 1.5f);
		info.m_maxSlope = HK_REAL_PI/2.0f;

		m_characterRigidBody = new hkpCharacterRigidBody( info );
		m_world->addEntity( m_characterRigidBody->getRigidBody() );

	}
	
	// Create the character state machine
	{
		hkpCharacterState* state;
		hkpCharacterStateManager* manager = new hkpCharacterStateManager();

		state = new hkpCharacterStateOnGround();
		manager->registerState( state,	HK_CHARACTER_ON_GROUND);
		state->removeReference();

		state = new hkpCharacterStateInAir();
		manager->registerState( state,	HK_CHARACTER_IN_AIR);
		state->removeReference();

		state = new hkpCharacterStateJumping();
		manager->registerState( state,	HK_CHARACTER_JUMPING);
		state->removeReference();

		state = new hkpCharacterStateClimbing();
		manager->registerState( state,	HK_CHARACTER_CLIMBING);
		state->removeReference();

		m_characterContext = new hkpCharacterContext(manager, HK_CHARACTER_ON_GROUND);
		m_characterContext->setCharacterType(hkpCharacterContext::HK_CHARACTER_RIGIDBODY);
		manager->removeReference();
	}

	// Set colors of platforms
	HK_SET_OBJECT_COLOR(hkUlong(m_verPlatform->getCollidable()),hkColor::BLUE);
	HK_SET_OBJECT_COLOR(hkUlong(m_horPlatform->getCollidable()),hkColor::GREEN);

	// Set global time
	m_time = 0.0f;

	// Initialize hkpSurfaceInfo for previous ground 
	m_previousGround = new hkpSurfaceInfo();
	m_framesInAir = 0;

	// Current camera angle about up
	m_currentAngle = HK_REAL_PI * 0.5f;

	m_world->unlock();
}
コード例 #6
0
int main( void )
{

	// init random seed equal to current time
	std::srand(std::time(0));

	const unsigned MAX_NR_RECTANGLES = 100;

	// windows size
	int windowWidth = 600;
	int windowHeight = 600;

	// Initialise GLFW
	if(!glfwInit()) {
		std::cerr << "Failed to initialize GLFW" << std::endl;
		return -1;
	}

	glfwWindowHint(GLFW_SAMPLES, 4);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	// Open a window and create its OpenGL context
	// window = glfwCreateWindow( 1024, 768, "Tutorial 03 - Matrices", NULL, NULL);
	window = glfwCreateWindow(windowWidth, windowHeight, "Mondrian", NULL, NULL);
	if(window == NULL) {
		std::cerr << "Failed to open GLFW window.";
		std::cerr << " If you have an Intel GPU, they are not 3.3 compatible.";
		std::cerr << " Try the 2.1 version of the tutorials." << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	// Initialize GLEW
	glewExperimental = true; // Needed for core profile
	if (glewInit() != GLEW_OK) {
		std::cerr << "Failed to initialize GLEW" << std::endl;
		return -1;
	}

	// enable z-buffer
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	// Ensure we can capture the escape key being pressed below
	glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
	glfwSetMouseButtonCallback(window, mouseButtonCallback);

	// white background
	glm::vec4 whiteColor (1.0f, 1.0f, 1.0f, 0.0f);
	glClearColor(whiteColor.r, whiteColor.g, whiteColor.b, whiteColor.a);

	// nr rectangles * 2 triangles each * 3 vertices * 4 floats
	float cpuBufferDataPoints[MAX_NR_RECTANGLES * 2 * 3 * 4];
	float cpuBufferColors[MAX_NR_RECTANGLES * 2 * 3 * 4];
	// nr rectangles * 2 triangles each * 3 vertices * 4x4 floats
	float cpuBufferMVProw1[MAX_NR_RECTANGLES * 2 * 3 * 4];
	float cpuBufferMVProw2[MAX_NR_RECTANGLES * 2 * 3 * 4];
	float cpuBufferMVProw3[MAX_NR_RECTANGLES * 2 * 3 * 4];
	float cpuBufferMVProw4[MAX_NR_RECTANGLES * 2 * 3 * 4];
	float *cpuBufferLines;

	// Create and compile our GLSL program from the shaders
	GLuint rectangleProgram = LoadShaders( "rectangleVertexShader.glsl", "rectangleFragmentShader.glsl" );
	GLuint lineProgram = LoadShaders( "lineVertexShader.glsl", "lineFragmentShader.glsl" );

	// Use our shader (it's not required to be using a program to bind VAOs)
	glUseProgram(rectangleProgram);

	// VAOs
	GLuint rectangleVAO;
	GLuint lineVAO;
	glGenVertexArrays(1, &rectangleVAO);
	glGenVertexArrays(1, &lineVAO);
	glBindVertexArray(rectangleVAO);

	// left, right, bottom, top, angle1, angle2
	// glm::mat4 Projection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f,0.0001f,10.0f); // In world coordinates
	glm::mat4 Projection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f); // In world coordinates
	for (unsigned row = 0; row < 4; row++) {
		for (unsigned col = 0; col < 4; col++) {
			std::cout << std::setw(10) << Projection[col][row] << " ";
		}
		std::cout << std::endl;
	}

	glm::vec4 testvertex;
	for (int i = -10; i <= 10; i++) {
		testvertex = glm::vec4(1.0);
		testvertex.z = i;
		testvertex = Projection * testvertex;
		std::cout << "z = " << std::setw(3) << i << " " << testvertex.z << std::endl;
	}
	std::cout << std::endl;

	// glm::mat4 Projection = glm::ortho(-20.0f, 20.0f, -20.0f, 20.0f,1.0f,100.0f); // In world coordinates
	/*
	glm::mat4 Projection = glm::perspective(
		45.0f,         // The horizontal Field of View, in degrees : the amount of "zoom". Think "camera lens". Usually between 90° (extra wide) and 30° (quite zoomed in)
		4.0f / 4.0f, // Aspect Ratio. Depends on the size of your window. Notice that 4/3 == 800/600 == 1280/960, sounds familiar ?
		0.1f,        // Near clipping plane. Keep as big as possible, or you'll get precision issues.
		100.0f       // Far clipping plane. Keep as little as possible.
	);		
	*/
	// Camera matrix
	/*
	 * view es una matriz cuadrada almacenada por columnas (no por filas)
	 * al poner la camara mirando al origen en una posicion z=2 (positivo),
	 * lo que hace, es generar una matriz de transformación que moverá el objeto
	 * en el eje z dos unidades de "w" */
	glm::mat4 View = glm::lookAt(
		glm::vec3(0,0,2), // Camera is at (4,3,3), in World Space
		glm::vec3(0,0,0), // and looks at the origin
		glm::vec3(0,1,0)  // Head is up (set to 0,-1,0 to look upside-down)
	);
	// glm::mat4 View = glm::mat4(1.0f);
	/*
	for (unsigned row = 0; row < 4; row++) {
		for (unsigned col = 0; col < 4; col++) {
			std::cout << std::setw(3) << View[col][row] << " ";
		}
		std::cout << std::endl;
	}
	*/

	GLuint rectangleVertexBuffer;
	glGenBuffers(1, &rectangleVertexBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleVertexBuffer);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(
		0,					// attribute. No particular reason for 0, but must match the layout in the shader.
		4,					// size
		GL_FLOAT,			// type
		GL_FALSE,			// normalized?
		0,					// stride
		(void*)0			// array buffer offset
	);

	GLuint rectangleColorBuffer;
	glGenBuffers(1, &rectangleColorBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleColorBuffer);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(
		1,					// attribute. No particular reason for 0, but must match the layout in the shader.
		4,					// size
		GL_FLOAT,			// type
		GL_FALSE,			// normalized?
		0,					// stride
		(void*)0			// array buffer offset
	);

	// GLuint rectangleMVPBuffer;
	GLuint rectangleMVProw1Buffer;
	GLuint rectangleMVProw2Buffer;
	GLuint rectangleMVProw3Buffer;
	GLuint rectangleMVProw4Buffer;
	glGenBuffers(1, &rectangleMVProw1Buffer);
	glGenBuffers(1, &rectangleMVProw2Buffer);
	glGenBuffers(1, &rectangleMVProw3Buffer);
	glGenBuffers(1, &rectangleMVProw4Buffer);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw1Buffer);
	glEnableVertexAttribArray(2);
	glVertexAttribPointer(
		2,										// attribute. No particular reason for 0, but must match the layout in the shader.
		4,												// size
		GL_FLOAT,								// type
		GL_FALSE,								// normalized?
		0,		// stride
		(void*)(0)								// array buffer offset
	);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw2Buffer);
	glEnableVertexAttribArray(3);
	glVertexAttribPointer(
		3,										// attribute. No particular reason for 0, but must match the layout in the shader.
		4,												// size
		GL_FLOAT,								// type
		GL_FALSE,								// normalized?
		0,		// stride
		(void*)(0)								// array buffer offset
	);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw3Buffer);
	glEnableVertexAttribArray(4);
	glVertexAttribPointer(
		4,										// attribute. No particular reason for 0, but must match the layout in the shader.
		4,												// size
		GL_FLOAT,								// type
		GL_FALSE,								// normalized?
		0,		// stride
		(void*)(0)								// array buffer offset
	);
	glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw4Buffer);
	glEnableVertexAttribArray(5);
	glVertexAttribPointer(
		5,										// attribute. No particular reason for 0, but must match the layout in the shader.
		4,												// size
		GL_FLOAT,								// type
		GL_FALSE,								// normalized?
		0,		// stride
		(void*)(0)								// array buffer offset
	);

	glBindVertexArray(lineVAO);
	GLuint lineVertexBuffer;
	glGenBuffers(1, &lineVertexBuffer);
	glBindBuffer(GL_ARRAY_BUFFER, lineVertexBuffer);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(
		0,					// attribute. No particular reason for 0, but must match the layout in the shader.
		2,					// size
		GL_FLOAT,			// type
		GL_FALSE,			// normalized?
		0,					// stride
		(void*)0			// array buffer offset
	);

	// get a handle for MVP uniform matrix in line program (it's not required
	// to be using the line program right now
	// GLuint lineMVPID = glGetUniformLocation(lineProgram, "MVP");

	glBindVertexArray(rectangleVAO);


	std::set<float> verticalLines;
	std::set<float> horizontalLines;
	unsigned nrLines = 0;

	unsigned simulationTime = 0;
	bool justEnded = true;

	double lineThickness = 0.1;
		
	do {

		// update window's title to show fps
		updateFPSCounter(window);

		// Clear the screen
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// update viewport 
		glfwGetWindowSize(window, &windowWidth, &windowHeight);
		glViewport(0, 0, windowWidth, windowHeight);	// (x,y) offset from lower left; (width, height)

		// std::cout << "nr rectangles: " << rectangles.size() << std::endl;

		// every 75 steps, create a new rectangle
		if (simulationTime % 500 == 0 && !endSimulation && rectangles.size() < MAX_NR_RECTANGLES) {
				// create rectangle
				Rectangle rectangle;
				// insert rectangle into array
				rectangles.push_back(rectangle);
		}

		// update cpu buffers

		// fill up new cpu position buffers
		float rectangleCoords[2 * 3 * 4];
		unsigned coordCounter = 0;
		for (unsigned i = 0; i < rectangles.size(); i++) {
				rectangles[i].getCoords(rectangleCoords);
				for (unsigned j = 0; j < 2*3*4; j++) {
						cpuBufferDataPoints[coordCounter] = rectangleCoords[j];
						coordCounter++;
				}
				// std::cout << "rectangle ID: " << rectangles[i].getID() << std::endl;
				// std::cout << "horizontal: [" << rectangles[i].getLeft() << " : " << rectangles[i].getRight() << "]" << std::endl;
				// std::cout << "vertical: [" << rectangles[i].getBottom() << " : " << rectangles[i].getTop() << "]" << std::endl;
		}

		// fill up new cpu colors buffers
		float rectangleColorComponents[2 * 3 * 4];
		coordCounter = 0;
		for (unsigned i = 0; i < rectangles.size(); i++) {
				rectangles[i].getColorComponents(rectangleColorComponents);
				for (unsigned j = 0; j < 2*3*4; j++) {
						cpuBufferColors[coordCounter] = rectangleColorComponents[j];
						coordCounter++;
				}
		}

		// fill up new cpu mvp buffers
		unsigned counter = 0;
		for (unsigned i = 0; i < rectangles.size(); i++) {
			glm::mat4 Model = rectangles[i].getModel();
			// glm::mat4 MVP = Projection * View * Model;
			glm::mat4 MVP = Projection * Model * View;
			// TODO: try to transfer glm::mat MVP to buffer directly with glBufferData
			// glm::vec4 vertexa = Model * rectangles[i].getVertexA();
			// glm::vec4 vertexb = Model * rectangles[i].getVertexB();
			// glm::vec4 vertexc = Model * rectangles[i].getVertexC();
			// glm::vec4 vertexd = Model * rectangles[i].getVertexD();

			// std::cout << "final positions: " << std::endl;
			// std::cout << vertexa.x << " " << vertexa.y << " " << vertexa.z << std::endl;
			// std::cout << vertexb.x << " " << vertexb.y << " " << vertexb.z << std::endl;
			// std::cout << vertexc.x << " " << vertexc.y << " " << vertexc.z << std::endl;
			// std::cout << vertexd.x << " " << vertexd.y << " " << vertexd.z << std::endl;

			for (unsigned vertex = 0; vertex < 6; vertex++) {
				for (unsigned element = 0; element < 4; element++) {
					// cpuBufferMVProw1[counter] = static_cast<int>(MVP[0][element]);
					// cpuBufferMVProw2[counter] = static_cast<int>(MVP[1][element]);
					// cpuBufferMVProw3[counter] = static_cast<int>(MVP[2][element]);
					// cpuBufferMVProw4[counter] = static_cast<int>(MVP[3][element]);

					// TODO swap these lines
					cpuBufferMVProw1[counter] = MVP[0][element];
					cpuBufferMVProw2[counter] = MVP[1][element];
					cpuBufferMVProw3[counter] = MVP[2][element];
					cpuBufferMVProw4[counter] = MVP[3][element];

					// for these ones
					// cpuBufferMVProw1[counter] = MVP[element][0];
					// cpuBufferMVProw2[counter] = MVP[element][1];
					// cpuBufferMVProw3[counter] = MVP[element][2];
					// cpuBufferMVProw4[counter] = MVP[element][3];

					// std::cout << "double: " << std::endl;
					// std::cout << MVP[0][element] << " ";
					// std::cout << MVP[1][element] << " ";
					// std::cout << MVP[2][element] << " ";
					// std::cout << MVP[3][element] << std::endl;
					// std::cout << "int: " << std::endl;
					// std::cout << cpuBufferMVProw1[counter] << " ";
					// std::cout << cpuBufferMVProw2[counter] << " ";
					// std::cout << cpuBufferMVProw3[counter] << " ";
					// std::cout << cpuBufferMVProw4[counter] << std::endl;
					counter++;
				}
			}
		}

		glUseProgram(rectangleProgram);
		glBindVertexArray(rectangleVAO);

		// transfer data to position and color buffers
		glBindBuffer(GL_ARRAY_BUFFER, rectangleVertexBuffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferDataPoints, GL_STREAM_DRAW);

		glBindBuffer(GL_ARRAY_BUFFER, rectangleColorBuffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferColors, GL_STREAM_DRAW);

		glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw1Buffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferMVProw1, GL_STREAM_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw2Buffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferMVProw2, GL_STREAM_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw3Buffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferMVProw3, GL_STREAM_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, rectangleMVProw4Buffer);
		glBufferData(GL_ARRAY_BUFFER, sizeof(float) * rectangles.size() * 2 * 3 * 4, cpuBufferMVProw4, GL_STREAM_DRAW);

		// draw rectangles
		glDrawArrays(GL_TRIANGLES, 0, rectangles.size()*2*3); // 3 indices starting at 0 -> 1 triangle

		for (unsigned i = 0; i < rectangles.size(); i++) {
			// std::cout << "updating rectangle id: " << i << std::endl;
			rectangles[i].updateModel();
			rectangles[i].shouldBeAlive();
		}

		for (std::vector<Rectangle>::iterator it = rectangles.begin(); it != rectangles.end();) {
			if (it->isAlive()) {
				it++;
			} else {
				it = rectangles.erase(it);
			}
		}

		if (endSimulation && !justEnded) {
			glUseProgram(lineProgram);
			glBindVertexArray(lineVAO);
			// std::cout << "drawing lines..." << std::endl;
			glDrawArrays(GL_TRIANGLES, 0, nrLines * 2 * 3); // 3 indices starting at 0 -> 1 triangle
		}

		if (endSimulation && justEnded) {

			std::cout << "creating lines..." << std::endl;
			justEnded = false;

			// load data in cpuBufferLines just the very first time

			// get vertical and horizontal coords of every line that should be drawn
			for (unsigned i = 0; i < rectangles.size(); i++) {
				if (rectangles[i].getIsPinned()) {
					// values in {-10:10}
					int left = static_cast<int>(round(rectangles[i].getLeft()));
					int right = static_cast<int>(round(rectangles[i].getRight()));
					int bottom = static_cast<int>(round(rectangles[i].getBottom()));
					int top = static_cast<int>(round(rectangles[i].getTop()));
					std::cout << "left: " << left << " right: " << right << " top: " << top << " bottom: " << bottom << std::endl;
					verticalLines.insert(left);
					verticalLines.insert(right);
					horizontalLines.insert(bottom);
					horizontalLines.insert(top);
				}
			}

			unsigned nrVerticalLines = verticalLines.size();
			unsigned nrHorizontalLines = horizontalLines.size();
			nrLines = nrVerticalLines + nrHorizontalLines;
			std::cout << "nr lines to draw: " << nrLines << std::endl;
			// 1 line = 2 triangles; 1 triangle = 3 points each; 1 point = 2 coord each;
			cpuBufferLines = new float[nrLines * 2 * 3 * 2];
			unsigned counter = 0;
			glm::mat4 PV = Projection * View;
			for (std::set<float>::iterator it = verticalLines.begin(); it != verticalLines.end(); it++) {
				glm::vec4 vertexA (*it - lineThickness, 10, 0, 1);
				glm::vec4 vertexB (*it + lineThickness, 10, 0, 1);
				glm::vec4 vertexC (*it - lineThickness, -10, 0, 1);
				glm::vec4 vertexD (*it + lineThickness, -10, 0, 1);
				vertexA = PV * vertexA;
				vertexB = PV * vertexB;
				vertexC = PV * vertexC;
				vertexD = PV * vertexD;
				// glm::vec4 firstPointMVP = Projection * View * firstPoint;
				// glm::vec4 secondPointMVP = Projection * View * secondPoint;
				// sent the points in {-10:10} domain
				// first triangle ABC
				cpuBufferLines[counter] = vertexA.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexA.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexB.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexB.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexC.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexC.y;		// y
				counter++;
				// second triangle BCD
				cpuBufferLines[counter] = vertexB.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexB.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexC.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexC.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexD.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexD.y;		// y
				counter++;
				// std::cout << "vertical line: " << std::endl;
				// std::cout << "(" << firstPointMVP.x << "," << firstPointMVP.y << ")" << std::endl;
				// std::cout << "(" << secondPointMVP.x << "," << secondPointMVP.y << ")" << std::endl;
			}

			for (std::set<float>::iterator it = horizontalLines.begin(); it != horizontalLines.end(); it++) {
				glm::vec4 vertexA (-10, *it + lineThickness, 0, 1);
				glm::vec4 vertexB (10, *it + lineThickness, 0, 1);
				glm::vec4 vertexC (-10, *it - lineThickness, 0, 1);
				glm::vec4 vertexD (10, *it - lineThickness, 0, 1);
				vertexA = PV * vertexA;
				vertexB = PV * vertexB;
				vertexC = PV * vertexC;
				vertexD = PV * vertexD;
				// glm::vec4 firstPointMVP = Projection * View * firstPoint;
				// glm::vec4 secondPointMVP = Projection * View * secondPoint;
				// first triangle ABC
				cpuBufferLines[counter] = vertexA.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexA.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexB.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexB.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexC.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexC.y;		// y
				counter++;
				// second triangle BCD
				cpuBufferLines[counter] = vertexB.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexB.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexC.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexC.y;		// y
				counter++;
				cpuBufferLines[counter] = vertexD.x;		// x
				counter++;
				cpuBufferLines[counter] = vertexD.y;		// y
				counter++;
				// std::cout << "horizontal line: " << std::endl;
				// std::cout << "(" << firstPointMVP.x << "," << firstPointMVP.y << ")" << std::endl;
				// std::cout << "(" << secondPointMVP.x << "," << secondPointMVP.y << ")" << std::endl;
			}

			glBindBuffer(GL_ARRAY_BUFFER, lineVertexBuffer);
			glBufferData(GL_ARRAY_BUFFER, sizeof(float) * nrLines * 2 * 3 * 2, cpuBufferLines, GL_STATIC_DRAW);


			// send MVP matrix to line program
			// TODO: check if i need to be using line program and to have bound line VAO
			// glUniformMatrix4fv(lineMVPID, 1, GL_FALSE, &PV[0][0]);
		}

		// Swap buffers
		glfwSwapBuffers(window);
		glfwPollEvents();
		// usleep(500000);
		// usleep(100000);

		simulationTime++;

		// int dummy;
		// std::cin >> dummy;

	} while ( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 );


	glBindVertexArray(rectangleVAO);
	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);

	glBindVertexArray(lineVAO);
	glDisableVertexAttribArray(0);

	// Cleanup VBO and shader
	glDeleteBuffers(1, &rectangleVertexBuffer);
	glDeleteBuffers(1, &rectangleColorBuffer);
	glDeleteBuffers(1, &rectangleMVProw1Buffer);
	glDeleteBuffers(1, &rectangleMVProw2Buffer);
	glDeleteBuffers(1, &rectangleMVProw3Buffer);
	glDeleteBuffers(1, &rectangleMVProw4Buffer);
	glDeleteBuffers(1, &lineVertexBuffer);
	glDeleteProgram(rectangleProgram);
	glDeleteProgram(lineProgram);
	glDeleteVertexArrays(1, &rectangleVAO);
	glDeleteVertexArrays(1, &lineVAO);

	// Close OpenGL window and terminate GLFW
	glfwTerminate();

	delete [] cpuBufferLines;				// make sure new was executed, i.e: right click event

	return 0;
}
コード例 #7
0
void PrevailingWindDemo::createPalmTree ( hkpWorld* world, const hkpWind* wind, const hkVector4& pos )
{
	const hkReal trunkHeight = 4.0f;
	const hkReal trunkBottomRadius = 0.5f;
	const hkReal trunkTopRadius = 0.2f;
	const hkReal trunkStiffness = 0.1f;
	const hkReal segmentMass = 0.6f;
	const int numberOfSegments = 4;
	const hkReal segmentGap = 0.2f;
	const int numberOfFronds = 6;
	const hkReal frondWidth = 2.0f;
	const hkReal frondLength = 3.0f;
	const hkReal frondMass = 0.4f;
	
	// The trunk
	hkArray<hkpRigidBody*> trunk;

	const hkReal segmentHeight = (trunkHeight - ((numberOfSegments - 1) * segmentGap)) / numberOfSegments;
	const hkReal radiusIncrement = (trunkBottomRadius - trunkTopRadius) / numberOfSegments;

	for ( int i = 0; i < numberOfSegments; i++ )
	{
		hkpShape* segmentShape;
		hkpRigidBodyCinfo info;
		{
			hkVector4 bottom( 0.0f, (segmentHeight + segmentGap) * i, 0.0f );
			hkVector4 top( 0.0f, (segmentHeight + segmentGap) * i + segmentHeight, 0.0f );
			hkReal radius = trunkBottomRadius - (radiusIncrement * i);
			segmentShape = new hkpCylinderShape( bottom, top, radius, 0.03f );
				
			info.m_shape = segmentShape;
			info.m_position = pos;
			
			if (i == 0)
			{
				info.m_motionType = hkpMotion::MOTION_FIXED;
			}
			else
			{
				hkpMassProperties massProperties;
				{			
					hkpInertiaTensorComputer::computeCylinderVolumeMassProperties( bottom, top, radius, segmentMass, massProperties );
				}
				info.m_motionType = hkpMotion::MOTION_DYNAMIC;
				info.m_mass = massProperties.m_mass;
				info.m_inertiaTensor = massProperties.m_inertiaTensor;
				info.m_centerOfMass = massProperties.m_centerOfMass;
			}
		}
		
		hkpRigidBody* segment = new hkpRigidBody( info );
		segmentShape->removeReference();
		
		trunk.pushBack( segment );
		world->addEntity( segment );
		segment->removeReference();

		if (i > 0)
		{
			hkpWindAction* action = new hkpWindAction( segment, wind, 0.1f );
			world->addAction(action);
			action->removeReference();
		}
	}

	
	for ( int i = 1; i < numberOfSegments; i++ )
	{
		// We model the connection between the segments with a ragdoll constraint.
		hkpRagdollConstraintData* rdc;
		{
			hkReal planeMin = HK_REAL_PI * -0.025f;
			hkReal planeMax = HK_REAL_PI *  0.025f;
			hkReal twistMin = HK_REAL_PI * -0.025f;
			hkReal twistMax = HK_REAL_PI *  0.025f;
			hkReal coneMin  = HK_REAL_PI * -0.05f;
			hkReal coneMax  = HK_REAL_PI *  0.05f;

			rdc = new hkpRagdollConstraintData();

			rdc->setPlaneMinAngularLimit( planeMin );
			rdc->setPlaneMaxAngularLimit( planeMax );
			rdc->setTwistMinAngularLimit( twistMin );
			rdc->setTwistMaxAngularLimit( twistMax );

			hkVector4 twistAxis( 0.0f, 1.0f, 0.0f );
			hkVector4 planeAxis( 0.0f, 0.0f, 1.0f );
			hkVector4 pivot( 0.0f, (segmentHeight + segmentGap) * i, 0.0f );

			rdc->setInBodySpace( pivot, pivot, planeAxis, planeAxis, twistAxis, twistAxis );
			rdc->setAsymmetricConeAngle( coneMin, coneMax );

			//world->createAndAddConstraintInstance( trunk[i - 1], trunk[i], rdc )->removeReference();

			hkpConstraintInstance* constraint = new hkpConstraintInstance( trunk[i - 1], trunk[i], rdc );
			world->addConstraint(constraint);

			hkpPositionConstraintMotor* motor = new hkpPositionConstraintMotor( 0 );
			motor->m_tau = trunkStiffness;
			motor->m_maxForce = 1000.0f;
			motor->m_constantRecoveryVelocity = 0.1f;

			rdc->setTwistMotor( motor ); 
			rdc->setConeMotor( motor ); 
			rdc->setPlaneMotor( motor ); 
			rdc->setMotorsActive(constraint, true);

			motor->removeReference();

			constraint->removeReference();
			rdc->removeReference();
		}
	}

	// The angle that the leaves make with the ground in their half lifted position.
	hkQuaternion tilt;
	{
		hkVector4 axis( 0.0f, 0.0f, 1.0f );
		tilt.setAxisAngle( axis, HK_REAL_PI * 0.1f );
	}
	hkQuaternion tiltRot;

	// The fronds
	for ( int i = 0; i < numberOfFronds; i++ )
	{
		hkQuaternion rotation;
		{
			hkVector4 axis( 0.0f, 1.0f, 0.0f );
			rotation.setAxisAngle( axis, HK_REAL_PI * 2.0f * ( i / (hkReal) numberOfFronds ) );
			rotation.normalize();
		}

		hkpShape* frondShape;
		hkpRigidBodyCinfo info;
		{
			hkVector4 vertexA( 0.0f, 0.0f, 0.0f );
			hkVector4 vertexB( frondLength, 0.0f, frondWidth / 2.0f );
			hkVector4 vertexC( frondLength, 0.0f, - frondWidth / 2.0f );
				
			frondShape = new hkpTriangleShape( vertexA, vertexB, vertexC, 0.01f );
			info.m_shape = frondShape;
			
			hkVector4 relPos;
			relPos.setRotatedDir( rotation, hkVector4( trunkTopRadius + 0.3f, trunkHeight, 0.0f ) );

			info.m_position.setAdd4( pos, relPos );
			
			hkpMassProperties massProperties;
			{
				hkReal mass = frondMass;
				hkpInertiaTensorComputer::computeTriangleSurfaceMassProperties( vertexA, vertexB, vertexC, mass, 0.01f, massProperties );
			}

			info.m_motionType = hkpMotion::MOTION_DYNAMIC;
			info.m_mass = massProperties.m_mass;
			info.m_inertiaTensor = massProperties.m_inertiaTensor;
			info.m_centerOfMass = massProperties.m_centerOfMass;

			tiltRot.setMul( rotation, tilt );
			info.m_rotation = tiltRot;
		}
		
		hkpRigidBody* frond = new hkpRigidBody( info );
		frondShape->removeReference();
		
		world->addEntity( frond );

		hkpWindAction* action = new hkpWindAction( frond, wind, 0.1f );
		world->addAction(action);
		action->removeReference();

		
		// We model the connection between the fronds and the trunk with a ragdoll constraint.
		hkpRagdollConstraintData* rdc;
		{
			hkReal planeMin = HK_REAL_PI * -0.005f;
			hkReal planeMax = HK_REAL_PI *  0.005f;
			hkReal twistMin = HK_REAL_PI * -0.05f;
			hkReal twistMax = HK_REAL_PI *  0.05f;
			hkReal coneMin  = HK_REAL_PI * -0.2f;
			hkReal coneMax  = HK_REAL_PI *  0.2f;

			rdc = new hkpRagdollConstraintData();

			rdc->setPlaneMinAngularLimit( planeMin );
			rdc->setPlaneMaxAngularLimit( planeMax );
			rdc->setTwistMinAngularLimit( twistMin );
			rdc->setTwistMaxAngularLimit( twistMax );

			hkVector4 twistAxisFrond( 1.0f, 0.0f, 0.0f );
			hkVector4 twistAxisTrunk;
			twistAxisTrunk.setRotatedDir( tiltRot, twistAxisFrond );
			
			hkVector4 planeAxisFrond( 0.0f, 0.0f, 1.0f );
			hkVector4 planeAxisTrunk;
			planeAxisTrunk.setRotatedDir( tiltRot, planeAxisFrond );
			
			hkVector4 pivotFrond( 0.0f, 0.0f, 0.0f );
			hkVector4 pivotTrunk;
			pivotTrunk.setRotatedDir( rotation, hkVector4( trunkTopRadius + 0.3f, trunkHeight, 0.0f ) );

			rdc->setInBodySpace( pivotTrunk, pivotFrond, planeAxisTrunk, planeAxisFrond, twistAxisTrunk, twistAxisFrond );
			rdc->setAsymmetricConeAngle( coneMin, coneMax );

			world->createAndAddConstraintInstance( trunk[ numberOfSegments - 1 ], frond, rdc )->removeReference();
			rdc->removeReference();
			frond->removeReference();
		}
	}
}
コード例 #8
0
ファイル: Silhouette.cpp プロジェクト: benardp/contours
bool FEdge::intersectParametric(FEdge & fe2, Vec3r viewpoint, real t3D, real u3D)
{
  Vec3r A1 = vertexA()->getPoint3D();
  Vec3r B1 = vertexB()->getPoint3D();
  Vec3r A2 = fe2.vertexA()->getPoint3D();
  Vec3r B2 = fe2.vertexB()->getPoint3D();

  if (sameSide(A1,B1,viewpoint, A2, B2) || sameSide(A2, B2, viewpoint, A1, B1))
    return false;

  // now, there *must* be an intersection.

  // for each edge, the normal of the plane containing the edge and the viewpoint
  Vec3r N1 = (A1-viewpoint) ^ (B1-viewpoint);
  Vec3r N2 = (A2-viewpoint) ^ (B2-viewpoint);

  // direction vector of the intersection of the two planes.
  Vec3r V = N1 ^ N2;

  // check if the planes coincide (i.e., source edges are colinear)
  assert(V.norm() > 0);
  
  // ----- compute t parameter ------

  // form a plane for line 1, normal to the plane containing the viewpoint

  Vec3r BA1 = B1 - A1;
  Vec3r hsNormal1 = N1 ^ BA1;
  
  // intersect ray in direction of V through the plane
  real w1;
  GeomUtils::intersection_test res1 = GeomUtils::intersectLinePlanePN(viewpoint, V, hsNormal1, A1, w1);

  if (res1 != GeomUtils::DO_INTERSECT)
    {
      printf("res1 = %d\n", res1);
      printf("viewpoint = [%f %f %f]\n", viewpoint[0], viewpoint[1], viewpoint[2]);
      printf("A1 = [%f %f %f]\n", A1[0], A1[1], A1[2]);
      printf("B1 = [%f %f %f]\n", B1[0], B1[1], B1[2]);
      printf("A2 = [%f %f %f]\n", A2[0], A2[1], A2[2]);
      printf("B2 = [%f %f %f]\n", B2[0], B2[1], B2[2]);
      printf("N1 = [%f %f %f]\n", N1[0], N1[1], N1[2]);
      printf("N2 = [%f %f %f]\n", N2[0], N2[1], N2[2]);
      printf("V = [%f %f %f]\n", V[0], V[1], V[2]);
      printf("hsNormal1 = [%f %f %f]\n", hsNormal1[0], hsNormal1[1], hsNormal1[2]);
    }

  assert(res1 == GeomUtils::DO_INTERSECT);

  Vec3r pt1 = viewpoint + w1 * V;

  t3D = ((pt1 - A1) * BA1) / (BA1*BA1);

  assert(t3D >=0 && t3D <= 1);

  // if (t3D < 0 || t3D > 1)
    //    return false;


  // ----- compute u parameter ------

  // form a half-space plane for line 2

  Vec3r BA2 = B2 - A2;
  Vec3r hsNormal2 = N2 ^ BA2;
  
  real w2;
  GeomUtils::intersection_test res2 = GeomUtils::intersectLinePlanePN(viewpoint, V, hsNormal2, A2, w2);

  if (res2 != GeomUtils::DO_INTERSECT)
    {
      printf("res1 = %d\n", res1);
      printf("viewpoint = [%f %f %f]\n", viewpoint[0], viewpoint[1], viewpoint[2]);
      printf("A1 = [%f %f %f]\n", A1[0], A1[1], A1[2]);
      printf("B1 = [%f %f %f]\n", B1[0], B1[1], B1[2]);
      printf("A2 = [%f %f %f]\n", A2[0], A2[1], A2[2]);
      printf("B2 = [%f %f %f]\n", B2[0], B2[1], B2[2]);
      printf("N1 = [%f %f %f]\n", N1[0], N1[1], N1[2]);
      printf("N2 = [%f %f %f]\n", N2[0], N2[1], N2[2]);
      printf("V = [%f %f %f]\n", V[0], V[1], V[2]);
      printf("hsNormal2 = [%f %f %f]\n", hsNormal2[0], hsNormal2[1], hsNormal2[2]);
    }

  assert(res2 == GeomUtils::DO_INTERSECT);

  Vec3r pt2 = viewpoint + w2 * V;

  u3D = ((pt2 - A2) * BA2) / (BA2*BA2);

  assert( u3D >=0 && u3D <=1);

  //  if (u3D < 0 || u3D > 1)
  //    return false;


  
  return true;
}
コード例 #9
0
CharacterDemo::CharacterDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env)
{

	//
	// Setup the camera
	//
	{
		hkVector4 from(  0.0f, 20.0f, -80.0f);
		hkVector4 to  (  0.0f,  0.0f,   0.0f);
		hkVector4 up  (  0.0f,  1.0f,   0.0f);
		setupDefaultCameras( env, from, to, up );

		// disable back face culling
		setGraphicsState(HKG_ENABLED_CULLFACE, false);

		// don't really want shadows as makes it too dark
		forceShadowState(false);

		setupLights(m_env); // so that the extra lights are added
		// float lightDir[] = { 0, -0.5f, -1 };
		// setSoleDirectionLight(m_env, lightDir, 0xffffffff );
	}

	//
	// Create the world
	//
	{
		hkpWorldCinfo info;
		info.setBroadPhaseWorldSize( 350.0f );  
		info.m_gravity.set(0,0,-9.8f);
		info.m_collisionTolerance = 0.1f;		
		m_world = new hkpWorld( info );
		m_world->lock();

		hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());

		setupGraphics();
	}

	// Load the level
	{
		hkVector4 tkScaleFactor(.32f,.32f,.32f);
		hkString fullname("Resources/Physics/Tk/CharacterController/");

		// We load our test case level.
		//fullname += "testcases.tk";
		fullname += "level.tk";

		hkpShape* moppShape = GameUtils::loadTK2MOPP(fullname.cString(),tkScaleFactor, -1.0f);
		HK_ASSERT2(0x64232cc0, moppShape,"TK file failed to load to MOPP in GameUtils::loadTK2MOPP.");

		hkpRigidBodyCinfo ci;
		ci.m_shape = moppShape;
		ci.m_motionType = hkpMotion::MOTION_FIXED;
		ci.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo( 0, 1 );

		hkpRigidBody* entity = new hkpRigidBody(ci);
		moppShape->removeReference();
		m_world->addEntity(entity);
		entity->removeReference();
	}
	
	// Add a ladder
	hkVector4 baseSize( 1.0f, 0.5f, 3.6f);
	{ 
		hkpRigidBodyCinfo rci;
		rci.m_shape = new hkpBoxShape( baseSize );
		rci.m_position.set(3.4f, 8.f, 2);
		rci.m_motionType = hkpMotion::MOTION_FIXED;
		hkpRigidBody* ladder = new hkpRigidBody(rci);
		rci.m_shape->removeReference();
		m_world->addEntity(ladder)->removeReference();

		// Add a property so we can identify this as a ladder
		hkpPropertyValue val(1);
		ladder->addProperty(HK_OBJECT_IS_LADDER, val);

		// Color the ladder so we can see it clearly
		HK_SET_OBJECT_COLOR((hkUlong)ladder->getCollidable(), 0x7f1f3f1f);
	} 	
	//
	//	Create a character proxy object
	//
	{
		// Construct a shape

		hkVector4 vertexA(0,0, 0.4f);
		hkVector4 vertexB(0,0,-0.4f);		

		// Create a capsule to represent the character standing
		m_standShape = new hkpCapsuleShape(vertexA, vertexB, .6f);

		// Create a capsule to represent the character crouching
		// Note that we create the smaller capsule with the base at the same position as the larger capsule.
		// This means we can simply swap the shapes without having to reposition the character proxy,
		// and if the character is standing on the ground, it will still be on the ground.
		vertexA.setZero4();
		m_crouchShape = new hkpCapsuleShape(vertexA, vertexB, .6f);


		// Construct a Shape Phantom
		m_phantom = new hkpSimpleShapePhantom( m_standShape, hkTransform::getIdentity(), hkpGroupFilter::calcFilterInfo(0,2) );
		
		// Add the phantom to the world
		m_world->addPhantom(m_phantom);
		m_phantom->removeReference();

		// Construct a character proxy
		hkpCharacterProxyCinfo cpci;
		cpci.m_position.set(-9.1f, 35, .4f);
		cpci.m_staticFriction = 0.0f;
		cpci.m_dynamicFriction = 1.0f;
		cpci.m_up.setNeg4( m_world->getGravity() );
		cpci.m_up.normalize3();	
		cpci.m_userPlanes = 4;
		cpci.m_maxSlope = HK_REAL_PI / 3.f;

		cpci.m_shapePhantom = m_phantom;
		m_characterProxy = new hkpCharacterProxy( cpci );
	}
	
	//
	// Add in a custom friction model
	//
	{
		hkVector4 up( 0.f, 0.f, 1.f );
		m_listener = new MyCharacterListener();
		m_characterProxy->addCharacterProxyListener(m_listener);
	}

	//
	// Create the Character state machine and context
	//
	{
		hkpCharacterState* state;
		hkpCharacterStateManager* manager = new hkpCharacterStateManager();

		state = new hkpCharacterStateOnGround();
		manager->registerState( state,	HK_CHARACTER_ON_GROUND);
		state->removeReference();

		state = new hkpCharacterStateInAir();
		manager->registerState( state,	HK_CHARACTER_IN_AIR);
		state->removeReference();

		state = new hkpCharacterStateJumping();
		manager->registerState( state,	HK_CHARACTER_JUMPING);
		state->removeReference();

		state = new hkpCharacterStateClimbing();
		manager->registerState( state,	HK_CHARACTER_CLIMBING);
		state->removeReference();

		m_characterContext = new hkpCharacterContext(manager, HK_CHARACTER_ON_GROUND);
		manager->removeReference();
	}
	
	// Current camera angle about up
	m_currentAngle = HK_REAL_PI * 0.5f;
	
	m_world->unlock();
}
コード例 #10
0
ファイル: AI.cpp プロジェクト: Hasan-Jawaheri/RPG
UnitAI::UnitAI ( float fHeight, float fRadius, bool bReference ) : AI ( ) {
	fH = fHeight;
	fR = fRadius;
	ZeroMemory ( &movement, sizeof MOVEMENT_STRUCT );
	movement.bEnabled = true;
	movement.fSpeed = 1.0f;

	if ( !bReference ) {
		APPHANDLE->core->PhysicsDevice->GetWorld()->lock ( );

		// Create a capsule to the character standing
		hkVector4 vertexA ( 0, fHeight, 0 );
		hkVector4 vertexB ( 0, fRadius, 0 );
		hkpShape* standShape = new hkpCapsuleShape ( vertexA, vertexB, fRadius );

		// Construct a character rigid body
		hkpCharacterRigidBodyCinfo info;
		info.m_mass = 250.0f;
		info.m_friction = 0.0f;
		info.m_shape = standShape;

		info.m_maxForce = 50.0f;
		info.m_up = hkVector4 ( 0, 1, 0 );
		info.m_position.set ( 0, 0, 0 );
		info.m_maxSlope = 35.0f * HK_REAL_DEG_TO_RAD;
	
		characterRigidBody = new hkpCharacterRigidBody ( info );
		standShape->removeReference ( );
		hkpCharacterRigidBodyListener* listener = new hkpCharacterRigidBodyListener ( );
		characterRigidBody->setListener ( listener );
		listener->removeReference ( );
		APPHANDLE->core->PhysicsDevice->GetWorld()->addEntity( characterRigidBody->getRigidBody ( ) );

		hkpCharacterState* state;
		hkpCharacterStateManager* manager = new hkpCharacterStateManager ( );

		state = new hkpCharacterStateOnGround ( );
		manager->registerState ( state,	HK_CHARACTER_ON_GROUND );
		state->removeReference ( );

		state = new hkpCharacterStateInAir ( );
		manager->registerState ( state,	HK_CHARACTER_IN_AIR );
		state->removeReference ( );

		state = new hkpCharacterStateJumping ( );
		manager->registerState ( state,	HK_CHARACTER_JUMPING );
		state->removeReference ( );

		state = new hkpCharacterStateClimbing ( );
		manager->registerState ( state,	HK_CHARACTER_CLIMBING );
		state->removeReference ( );

		characterContext = new hkpCharacterContext ( manager, HK_CHARACTER_ON_GROUND );
		manager->removeReference ( );

		// Set character type
		characterContext->setCharacterType ( hkpCharacterContext::HK_CHARACTER_RIGIDBODY );
	
		APPHANDLE->core->PhysicsDevice->GetWorld()->unlock ( );
	} else
		characterContext = nullptr;
}