Пример #1
0
WorldRaycastDemo::WorldRaycastDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env)
{
	//
	// Setup the camera.
	//
	{
		hkVector4 from(30.0f, 8.0f, 25.0f);
		hkVector4 to  ( 4.0f, 0.0f, -3.0f);
		hkVector4 up  ( 0.0f, 1.0f,  0.0f);
		setupDefaultCameras(env, from, to, up);
	}

	//
	// Create the world.
	//
	{
		hkpWorldCinfo info;
		info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); 
		
		// Set gravity to zero so body floats.
		info.m_gravity.set(0.0f, 0.0f, 0.0f);	
		info.setBroadPhaseWorldSize( 100.0f );
		m_world = new hkpWorld(info);
		m_world->lock();

		// Disable backface culling, since we have mopp's etc.
		setGraphicsState(HKG_ENABLED_CULLFACE, false);

		setupGraphics();
	}

	// register all agents(however, we put all objects into the some group,
	// so no collision will be detected
	hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() );

	// Add a collision filter to the world to allow the bodies interpenetrate
	{
		hkpGroupFilter* filter = new hkpGroupFilter();
		filter->disableCollisionsBetween( hkpGroupFilterSetup::LAYER_DEBRIS, hkpGroupFilterSetup::LAYER_DEBRIS );
		m_world->setCollisionFilter( filter );
		filter->removeReference();
	}

	//
	// Set the simulation time to 0
	//
	m_time = 0;


	//
	// Create some bodies (reuse the ShapeRaycastApi demo)
	//
	createBodies();

	m_world->unlock();
}
WorldSnapshotWithContactPointsDemo::WorldSnapshotWithContactPointsDemo( hkDemoEnvironment* env) 
	: hkDefaultPhysicsDemo(env) 
{
	hkpWorld::IgnoreForceMultithreadedSimulation ignoreForceMultithreaded;

	// Setup the camera
	{
		hkVector4 from(10, -10, 6);
		hkVector4 to(0, 0, -4);
		hkVector4 up(0, 0, 1);
		setupDefaultCameras( env, from, to, up );
	}

	// Load the startup scene
	{
		// Load the world.
		m_world = loadWorld(ORIGINAL_FILE, &m_physicsData, &m_loadedData);
		m_world->lock();

		m_debugViewerNames.pushBack( hkpActiveContactPointViewer::getName() );
		m_debugViewerNames.pushBack( hkpInactiveContactPointViewer::getName() );

		// Disable culling
		setGraphicsState(HKG_ENABLED_CULLFACE, false);

		// Enable wire frame display mode
		setGraphicsState(HKG_ENABLED_WIREFRAME, true);

		// Setup graphics
		setupGraphics();
		m_world->unlock();
	}

	// Disable warning: 'm_contactRestingVelocity not set, setting it to REAL_MAX, so that the new collision restitution code will be disabled'
	hkError::getInstance().setEnabled(0xf03243ed, false);
}
WorldRayCastMultithreadedDemo::WorldRayCastMultithreadedDemo(hkDemoEnvironment* env)
	: hkDefaultPhysicsDemo(env),
	m_semaphore(0,1000)
{
	const WorldRayCastMultithreadedDemoVariant& variant = g_WorldRayCastMultithreadedDemoVariants[m_variantId];

	//
	// Setup the camera.
	//
	{
		hkVector4 from(30.0f, 8.0f, 25.0f);
		hkVector4 to  ( 4.0f, 0.0f, -3.0f);
		hkVector4 up  ( 0.0f, 1.0f,  0.0f);
		setupDefaultCameras(env, from, to, up);
	}

	//
	// Create the world.
	//
	{
		hkpWorldCinfo info;
		info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); 
		
		// Set gravity to zero so body floats.
		info.m_gravity.set(0.0f, 0.0f, 0.0f);	
		info.setBroadPhaseWorldSize( 100.0f );
		m_world = new hkpWorld(info);
		m_world->lock();

		// Disable backface culling, since we have mopp's etc.
		setGraphicsState(HKG_ENABLED_CULLFACE, false);

		setupGraphics();
	}

	// register all agents(however, we put all objects into the some group,
	// so no collision will be detected
	hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() );

	// Add a collision filter to the world to allow the bodies interpenetrate
	{
		hkpGroupFilter* filter = new hkpGroupFilter();
		filter->disableCollisionsBetween( hkpGroupFilterSetup::LAYER_DEBRIS, hkpGroupFilterSetup::LAYER_DEBRIS );
		m_world->setCollisionFilter( filter );
		filter->removeReference();
	}

	//
	// Set the simulation time to 0
	//
	m_time = 0;

	//
	// Create some bodies (reuse the ShapeRayCastApi demo)
	//
	createBodies();

	m_world->unlock();


	hkpCollisionQueryJobQueueUtils::registerWithJobQueue(m_jobQueue);


	// Special case for this demo variant: we do not allow the # of active SPUs to drop to zero as this can cause a deadlock.
	if ( variant.m_demoType == WorldRayCastMultithreadedDemoVariant::MULTITHREADED_ON_SPU )
	{
		m_allowZeroActiveSpus = false;
	}

}
Пример #4
0
MoppInstancingDemo::MoppInstancingDemo(hkDemoEnvironment* env)
	:	hkDefaultPhysicsDemo(env)
{
	// Disable face culling
	setGraphicsState(HKG_ENABLED_CULLFACE, false);

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

	//
	// Create the world
	//
	{
		hkpWorldCinfo info;
		info.m_gravity.set(0.0f, -9.5f, 0.0f);
		info.setBroadPhaseWorldSize(150.0f);
		info.setupSolverInfo( hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM );
		m_world = new hkpWorld( info );
		m_world->lock();

		// Register ALL agents (though some may not be necessary)
		hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());

		setupGraphics();
	}

	//
	//  create the ground mopps
	//  See the comments on createMoppShape() below.
	//

	m_originalMopp = createMoppShape();
	m_smallMopp = createScaledMopp(m_originalMopp, .75f);
	m_bigMopp = createScaledMopp(m_originalMopp, 1.5f);

	hkpShape* shapes[3] = { m_originalMopp, m_smallMopp, m_bigMopp};
	hkReal offsets[3] = {0.0f, -20.0f, 30.0f};
	
	//
	//	Create the fixed rigid bodies and add them to the world
	//
	for (int i=0; i<3; i++)
	{
		hkpRigidBodyCinfo groundInfo;
		groundInfo.m_motionType = hkpMotion::MOTION_FIXED;

		groundInfo.m_shape = shapes[i];
		groundInfo.m_position.set(offsets[i],-2.6f,0.0f);
		
		m_fixedBodies[i] = new hkpRigidBody(groundInfo);
		m_world->addEntity( m_fixedBodies[i] );

		// Drop some boxes on the mesh
		hkVector4 center(offsets[i] - 1.0f, 0, 2.5f);
		addBoxPile(10, center);
	}

	m_world->unlock();
}
Пример #5
0
MeshWeldingDemo::MeshWeldingDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env)
{
	const WeldingVariant& variant =  g_variants[m_variantId];

	//
	// Create the world.
	//
	{

		hkpWorldCinfo info;
		info.m_toiCollisionResponseRotateNormal = 0;
		info.m_gravity.setZero4();

		if ( variant.m_weldingType == TWO_SIDED )
		{
			info.m_enableToiWeldRejection = true;
		}

		m_world = new hkpWorld( info );
		m_world->lock();

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

	//
	// Setup graphics
	//

	{
		// Disable culling
		setGraphicsState(HKG_ENABLED_CULLFACE, false);

		// Enable wire frame display mode
		setGraphicsState(HKG_ENABLED_WIREFRAME, true);

		//
		// Setup default camera
		//
		{

			hkVector4 from(0.0f, 30.0f, 10.0f);
			hkVector4 to(0,0,0);
			hkVector4 up(0.0f, 1.0f, 0.0f);

			setupDefaultCameras( env, from, to, up, 0.1f, 500.0f);
		}
		
		setupGraphics();
	}

	//
	// Create self-propelled, moving block.
	//
	{
		hkVector4 posBlock(-7.8f, 1.0f, 0.0f);
		float mass = 1;
		float friction = 0.f;
		float restitution = 0;
		m_movingBody = createDynamicBox(posBlock, mass, friction, restitution, m_world);

		hkpCollidableQualityType qt = (variant.m_simulationType == CONTINUOUS) ? HK_COLLIDABLE_QUALITY_CRITICAL : HK_COLLIDABLE_QUALITY_DEBRIS;
		m_movingBody->setQualityType( qt );

		m_world->addEntity( m_movingBody );
		{
			PushAction* pushAction = new PushAction( m_movingBody );
			m_world->addAction(pushAction);
			pushAction->removeReference();
		}
	}

	//
	// Load simple mesh from xml file, create welding information, add welding utility and
	// insert it into world.
	//
	{
		hkVector4 posSimpleMesh(0, -1, 0);
		loadAndInitSimpleMesh(posSimpleMesh, m_world, m_ringData);
	}



	m_world->unlock();

	m_bodySpeed = 0;
}
TriSampledHeightFieldDemo::TriSampledHeightFieldDemo(hkDemoEnvironment* env)
	:	hkDefaultPhysicsDemo(env, DEMO_FLAGS_NO_SERIALIZE)
{
	// Disable face culling
	setGraphicsState(HKG_ENABLED_CULLFACE, false);

	// Setup a camera in the right place to see our demo.
	{
		hkVector4 from( -3.7f, 5, 17.6f );
		hkVector4 to  (-1.5f, 1, 1.1f );
		hkVector4 up  (  0.0f, 1.0f, 0.0f);
		setupDefaultCameras(env, from, to, up);
	}

	{
		hkpWorldCinfo info;
		info.setBroadPhaseWorldSize( 100.0f );
		info.m_collisionTolerance = 0.03f;
		m_world = new hkpWorld(info);
		m_world->lock();

		setupGraphics();
	}

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

	//
	// Create two movable rigid bodies to fall on the two heightfields.
	//
	{
		hkVector4 halfExtents(1.f, .25f, 1.f );
		hkpShape* shape = new hkpBoxShape( halfExtents , 0 );

		for (int i = 0; i < 2; i++ )
		{
			hkpRigidBodyCinfo ci;
			ci.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA;
			ci.m_shape = shape;
			ci.m_mass = 4.f;
			hkpMassProperties m;
			hkpInertiaTensorComputer::computeShapeVolumeMassProperties(shape,4, m);
			ci.m_inertiaTensor = m.m_inertiaTensor;
			ci.m_position.set( hkReal(i * 7) - 5 , 4, 3 );

			hkpRigidBody* body = new hkpRigidBody( ci );
			m_world->addEntity(body);
			body->removeReference();
		}
		shape->removeReference();
	}


	{
		// Create our heightfield

		hkpSampledHeightFieldBaseCinfo ci;
		ci.m_xRes = 7;
		ci.m_zRes = 7;
		SimpleSampledHeightFieldShape* heightFieldShape = new SimpleSampledHeightFieldShape( ci );

		{
			//
			// Create the first fixed rigid body, using the standard heightfield as the shape
			//

			hkpRigidBodyCinfo rci;
			rci.m_motionType = hkpMotion::MOTION_FIXED;
			rci.m_position.set(-8, 0, 0);
			rci.m_shape = heightFieldShape;
			rci.m_friction = 0.2f;

			hkpRigidBody* bodyA = new hkpRigidBody( rci );
			m_world->addEntity(bodyA);
			bodyA->removeReference();


			//
			// Create the second fixed rigid body, using the triSampledHeightfield
			//

			// Wrap the heightfield in a hkpTriSampledHeightFieldCollection:
			hkpTriSampledHeightFieldCollection* collection = new hkpTriSampledHeightFieldCollection( heightFieldShape );

			// Now wrap the hkpTriSampledHeightFieldCollection in a hkpTriSampledHeightFieldBvTreeShape
			hkpTriSampledHeightFieldBvTreeShape* bvTree = new hkpTriSampledHeightFieldBvTreeShape( collection );

			// Finally, assign the new hkpTriSampledHeightFieldBvTreeShape to be the rigid body's shape
			rci.m_shape = bvTree;

			rci.m_position.set(-1,0,0);
			hkpRigidBody* bodyB = new hkpRigidBody( rci );
			m_world->addEntity(bodyB);
			bodyB->removeReference();

			heightFieldShape->removeReference();
			collection->removeReference();
			bvTree->removeReference();

		}

		hkString left("Standard heightfield.");
		m_env->m_textDisplay->outputText3D(left, -7, -.2f, 7, 0xffffffff, 2000);

		hkString right("Triangle heightfield.");
		m_env->m_textDisplay->outputText3D(right, -1, -.2f, 7, 0xffffffff, 2000);
	}

	m_world->unlock();
}
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();
}
MirroredMotionDemo::MirroredMotionDemo( hkDemoEnvironment* env )
:	hkDefaultAnimationDemo(env)
{
	// Character parameters
//	const char *sceneFileName = "Resources/Animation/Scene/hkScene.hkx";
	const char *rigFileName = "Resources/Animation/HavokGirl/hkRig.hkx";
			const char *skinFileName = "Resources/Animation/HavokGirl/hkLowResSkin.hkx";

	// Mirroring Parameters
	const char * leftPrefix[2] = { " L ", "EyeL" };
	const char *rightPrefix[2] = { " R ", "EyeR" };
	const int numPrefix = 2;
	const hkQuaternion mirrorAxis( 1.0f, 0.0f, 0.0f, 0.0f );

	// Show backfaces so that you can see inside of things
	setGraphicsState( HKG_ENABLED_CULLFACE, false );

	env->m_sceneConverter->setAllowTextureSharing( true );
	env->m_sceneConverter->setAllowMaterialSharing( true );

	//
	// Setup the camera
	//
	{
		hkVector4 from( 0,-6,1 );
		hkVector4 to  ( 0,0,0 );
		hkVector4 up  ( 0.0f, 0.0f, 1.0f );
		setupDefaultCameras( env, from, to, up, 0.01f, 100 );
	}

	m_loader = new hkLoader();

	// Get the rig
	{
		hkString assetFile = hkAssetManagementUtil::getFilePath( rigFileName );
		hkRootLevelContainer* container = m_loader->load( assetFile.cString() );
		HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset");
		hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() ));

		HK_ASSERT2(0x27343435, ac && (ac->m_numSkeletons > 0), "No skeleton loaded");
		m_skeleton = ac->m_skeletons[0];
	}

	// Get the animation and the binding
	{
		hkString assetFile = hkAssetManagementUtil::getFilePath(
			g_variants[ env->m_variantId ].m_animationFileName );
		hkRootLevelContainer* container = m_loader->load( assetFile.cString() );
		HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset");
		hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() ));

		HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded");
		m_animation[0] =  ac->m_animations[0];

		HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded");
		m_binding[0] = ac->m_bindings[0];
	}

	// Create the mirrored animation and binding
	{
		hkObjectArray< hkString > ltag;
		hkObjectArray< hkString > rtag;

		for ( int j = 0; j < ( numPrefix ); j++ )
		{
			ltag.pushBack( ( leftPrefix  )[ j ] );
			rtag.pushBack( ( rightPrefix )[ j ] );
		}

		hkaMirroredSkeleton *mirroredSkeleton = new hkaMirroredSkeleton( m_skeleton );

		mirroredSkeleton->computeBonePairingFromNames( ltag, rtag );

		hkaMirroredAnimation *mirroredAnimation = new hkaMirroredAnimation( m_animation[0], m_binding[0], mirroredSkeleton );
		mirroredSkeleton->removeReference();

		mirroredSkeleton->setAllBoneInvariantsFromReferencePose( mirrorAxis, 0.0f );

		m_binding[1] = mirroredAnimation->createMirroredBinding();
		m_animation[1] = mirroredAnimation;
	}

	// Create the skeletons
	for ( int i = 0; i < 2; i++ )
	{
		m_skeletonInstance[i] = new hkaAnimatedSkeleton( m_skeleton );
		m_skeletonInstance[i]->setReferencePoseWeightThreshold( 0.1f );
	}

	// Convert the skin (once for each character standard and mirrored)
	for ( int i = 0; i < 2; i++ )
	{
		hkString assetFile = hkAssetManagementUtil::getFilePath( skinFileName );
		hkRootLevelContainer* container = m_loader->load( assetFile.cString() );
		if ( container != HK_NULL )
		{
			HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset");

			hkxScene* scene = reinterpret_cast<hkxScene*>( container->findObjectByType( hkxSceneClass.getName() ));
			HK_ASSERT2(0x27343435, scene , "No scene loaded");

			hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() ));
			HK_ASSERT2(0x27343435, ac && (ac->m_numSkins > 0), "No skins loaded");

			m_numSkinBindings[i] = ac->m_numSkins;
			m_skinBindings[i] = ac->m_skins;

			m_numAttachments[i] = ac->m_numAttachments;
			m_attachments[i] = ac->m_attachments;

			// Make graphics output buffers for the skins
			env->m_sceneConverter->convert( scene );

			// Handle the attachements
			for (int a=0; a < m_numAttachments[i]; ++a)
			{
				hkaBoneAttachment* ba = m_attachments[i][a];
				hkgDisplayObject* hkgObject = HK_NULL;

				//Check the attachment is a mesh
				if ( hkString::strCmp(ba->m_attachment.m_class->getName(), hkxMeshClass.getName()) == 0)
				{
					hkgObject = env->m_sceneConverter->findFirstDisplayObjectUsingMesh((hkxMesh*)ba->m_attachment.m_object);
					if (hkgObject)
					{
						hkgObject->setStatusFlags( hkgObject->getStatusFlags() | HKG_DISPLAY_OBJECT_DYNAMIC);
					}
				}

				m_attachmentObjects[i].pushBack(hkgObject);
			}
		}
		else
		{
			m_numSkinBindings[i] = 0;
			m_skinBindings[i] = 0;
			m_numAttachments[i] = 0;
		}
	}

	// Grab the animations
	for ( int i = 0; i < 2; i++ )
	{
		m_control[i] = new hkaDefaultAnimationControl( m_binding[i] );
		m_control[i]->setMasterWeight( 1.0f );
		m_control[i]->setPlaybackSpeed( 1.0f );

		// Ease all controls out initially
		m_control[i]->easeIn(1.0f);

		m_skeletonInstance[i]->addAnimationControl( m_control[i] );
		m_control[i]->removeReference();

		// Set ease curves explicitly
		m_control[i]->setEaseInCurve(0, 0, 1, 1);	// Smooth
		m_control[i]->setEaseOutCurve(1, 1, 0, 0);	// Smooth

		m_accumulatedMotion[i].setIdentity();
	}

	// make a world so that we can auto create a display world to hold the skin
	setupGraphics( );

	m_axisCounter = 0;
	m_env = env;

	m_drawSkin = true;
	m_wireframe = false;
	m_timestep = 1.0f / 60.0f;
	m_useExtractedMotion = true;
	m_paused = false;
	m_separation = 1.0f;
}
hkDemo::Result MirroredMotionDemo::stepDemo()
{
	// Check user input
	{
		if (m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_1 ))
		{
			for ( int i = 0; i < 2; i++ )
			{
				if (( m_control[i]->getEaseStatus() == hkaDefaultAnimationControl::EASING_IN ) ||
					( m_control[i]->getEaseStatus() == hkaDefaultAnimationControl::EASED_IN ))
				{
					m_control[i]->easeOut( .5f );
				}
				else
				{
					m_control[i]->easeIn( .5f );
				}
			}
		}

		if (m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_2 ))
		{
			m_wireframe = !m_wireframe;
			setGraphicsState( HKG_ENABLED_WIREFRAME, m_wireframe );
		}

		if (m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_3 ))
		{
			m_drawSkin = !m_drawSkin;
		}

		if ( m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_0 ) )
		{
			m_useExtractedMotion = !m_useExtractedMotion;
		}

		if ( m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_L1 ) )
		{
			m_accumulatedMotion[0].setIdentity();
			m_accumulatedMotion[1].setIdentity();
		}

		if ( m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_R1 ) )
		{
			m_paused = !m_paused;

			if ( m_paused )
			{
				m_timestep = 0;
			}
			else
			{
				m_timestep = 1.0f / 60.0f;
			}
		}


	}

	const int boneCount = m_skeleton->m_numBones;

	for ( int j = 0; j < 2; j++ )
	{
		// Grab accumulated motion
		{
			hkQsTransform deltaMotion;
			deltaMotion.setIdentity();
			m_skeletonInstance[j]->getDeltaReferenceFrame( m_timestep, deltaMotion );
			m_accumulatedMotion[j].setMulEq( deltaMotion );
		}

		// Advance the active animations
		m_skeletonInstance[j]->stepDeltaTime( m_timestep );

		// Sample the active animations and combine into a single pose
		hkaPose pose (m_skeleton);
		m_skeletonInstance[j]->sampleAndCombineAnimations( pose.accessUnsyncedPoseLocalSpace().begin(), pose.getFloatSlotValues().begin() );

		hkReal separation = m_separation * hkReal( 2*j-1 );

		hkQsTransform Q( hkQsTransform::IDENTITY );
		Q.m_translation.set( separation, 0, 0 );

		if ( m_useExtractedMotion )
		{
			Q.setMulEq( m_accumulatedMotion[j] );
		}

		pose.syncModelSpace();

		AnimationUtils::drawPose( pose, Q );
		// Test if the skin is to be drawn
		if ( !m_drawSkin )
		{
			Q.m_translation( 2 ) -= 2.0f * m_separation;
		}

		// Construct the composite world transform
		hkLocalArray<hkTransform> compositeWorldInverse( boneCount );
		compositeWorldInverse.setSize( boneCount );

		const hkArray<hkQsTransform>& poseModelSpace = pose.getSyncedPoseModelSpace();

		// Skin the meshes
		for (int i=0; i < m_numSkinBindings[j]; i++)
		{
			// assumes either a straight map (null map) or a single one (1 palette)
			hkInt16* usedBones = m_skinBindings[j][i]->m_mappings? m_skinBindings[j][i]->m_mappings[0].m_mapping : HK_NULL;
			int numUsedBones = usedBones? m_skinBindings[j][i]->m_mappings[0].m_numMapping : boneCount;

			// Multiply through by the bind pose inverse world inverse matrices
			for (int p=0; p < numUsedBones; p++)
			{
				int boneIndex = usedBones? usedBones[p] : p;
				hkTransform tWorld; poseModelSpace[ boneIndex ].copyToTransform(tWorld);
				compositeWorldInverse[p].setMul( tWorld, m_skinBindings[j][i]->m_boneFromSkinMeshTransforms[ boneIndex ] );
			}

			AnimationUtils::skinMesh( *m_skinBindings[j][i]->m_mesh, hkTransform( Q.m_rotation, hkVector4( Q.m_translation(0), Q.m_translation(1), Q.m_translation(2), 1 ) ), compositeWorldInverse.begin(), *m_env->m_sceneConverter );
		}

		// Move the attachments
		{
			HK_ALIGN(float f[16], 16);
			for (int a=0; a < m_numAttachments[j]; a++)
			{
				if (m_attachmentObjects[j][a])
				{
					hkaBoneAttachment* ba = m_attachments[j][a];
					hkQsTransform modelFromBone = pose.getBoneModelSpace( ba->m_boneIndex );
					hkQsTransform worldFromBoneQs;
					worldFromBoneQs.setMul( Q, modelFromBone );
					worldFromBoneQs.get4x4ColumnMajor(f);
					hkMatrix4 worldFromBone; worldFromBone.set4x4ColumnMajor(f);
					hkMatrix4 worldFromAttachment; worldFromAttachment.setMul(worldFromBone, ba->m_boneFromAttachment);
					m_env->m_sceneConverter->updateAttachment(m_attachmentObjects[j][a], worldFromAttachment);
				}
			}
		}


	}

	return hkDemo::DEMO_OK;
}
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();
}
Пример #11
0
SimpleShapesDemo::SimpleShapesDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env)
{
	const ShapeVariant& variant =  g_variants[m_variantId];

	// Setup the camera.
	{
		hkVector4 from(0.0f, 5.0f, 10.0f);
		hkVector4 to  (0.0f, 0.0f,  0.0f);
		hkVector4 up  (0.0f, 1.0f,  0.0f);
		setupDefaultCameras(env, from, to, up);
	}

	// Create the world, setting gravity to zero so body floats.
	hkpWorldCinfo info;
	info.m_gravity.set(0.0f, 0.0f, 0.0f);	
	info.setBroadPhaseWorldSize( 100.0f );
	m_world = new hkpWorld(info);
	m_world->lock();

	setupGraphics();

	// Create the shape variant
	hkpShape* shape = 0;
	switch (variant.m_shapeType)
	{
		// Box
	case HK_SHAPE_BOX:
		{
			// Data specific to this shape.
			hkVector4 halfExtents(1.0f, 1.0f, 1.0f);

			/////////////////// SHAPE CONSTRUCTION ////////////////
			shape = new hkpBoxShape(halfExtents, 0 );

			break;
		}


		// Sphere
	case HK_SHAPE_SPHERE:
		{
			// The box is of side 2, so we must bound it by a sphere of radius >= sqrt(3)
			hkReal radius = 1.75f;

			/////////////////// SHAPE CONSTRUCTION ////////////////
			shape = new hkpSphereShape(radius);

			break;
		}


		// Triangle
	case HK_SHAPE_TRIANGLE:
		{
			// Disable face culling
			setGraphicsState(HKG_ENABLED_CULLFACE, false);

			float vertices[] = {
				-0.5f, -0.5f,  0.0f, 0.0f, // v0
				0.5f, -0.5f,  0.0f, 0.0f, // v1
				0.0f,  0.5f,  0.0f, 0.0f, // v2
			};

			/////////////////// SHAPE CONSTRUCTION ////////////////
			shape = new hkpTriangleShape();

			int index = 0;
			for (int i = 0; i < 3; i++)
			{
				static_cast<hkpTriangleShape*>(shape)->setVertex(i, hkVector4(vertices[index], vertices[index + 1], vertices[index + 2]));
				index = index + 4;
			}

			break;
		}


		// Capsule
	case HK_SHAPE_CAPSULE:
		{
			hkReal radius = 1.5f;
			hkVector4 top(0.0f, 1.5f, 0.0f);
			hkVector4 bottom(0.0f, -1.0f, 0.0f);

			/////////////////// SHAPE CONSTRUCTION ////////////////
			shape = new hkpCapsuleShape(top, bottom, radius);

			break;
		}


		// Cylinder
	case HK_SHAPE_CYLINDER:
		{
			hkReal radius = 1.5f;
			hkVector4 top(0.0f, 1.5f, 0.0f);
			hkVector4 bottom(0.0f, -1.0f, 0.0f);

			/////////////////// SHAPE CONSTRUCTION ////////////////
			shape = new hkpCylinderShape(top, bottom, radius);

			break;
		}


		// Convex vertices
	case HK_SHAPE_CONVEX_VERTICES:
		{
			// Data specific to this shape.
			int numVertices = 4;

			// 16 = 4 (size of "each float group", 3 for x,y,z, 1 for padding) * 4 (size of float)
			int stride = sizeof(float) * 4;

			float vertices[] = { // 4 vertices plus padding
				-2.0f, 2.0f, 1.0f, 0.0f, // v0
				1.0f, 3.0f, 0.0f, 0.0f, // v1
				0.0f, 1.0f, 3.0f, 0.0f, // v2
				1.0f, 0.0f, 0.0f, 0.0f  // v3
			};

			/////////////////// SHAPE CONSTRUCTION ////////////////
			hkStridedVertices stridedVerts;
			{
				stridedVerts.m_numVertices = numVertices;
				stridedVerts.m_striding = stride;
				stridedVerts.m_vertices = vertices;
			}
			
			shape = new hkpConvexVerticesShape(stridedVerts);

			break;
		}

	default:
		break;
	}

	// Make sure that a shape was created
	HK_ASSERT(0, shape);

	// To illustrate using the shape, first define a rigid body template.
	hkpRigidBodyCinfo rigidBodyInfo;
	rigidBodyInfo.m_position.set(0.0f, 0.0f, 0.0f);
	rigidBodyInfo.m_angularDamping = 0.0f;
	rigidBodyInfo.m_linearDamping = 0.0f;

	rigidBodyInfo.m_shape = shape;

	// Compute the rigid body inertia.
	rigidBodyInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;
	hkpInertiaTensorComputer::setShapeVolumeMassProperties( rigidBodyInfo.m_shape, 100.0f, rigidBodyInfo );

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

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

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

	m_world->unlock();
}