コード例 #1
0
void DetailedTimersDemo::timeDemo( hkDemo* demo, int iterations, const char* fileName )
{

	//
	//	Time the demo
	//
	hkMonitorStreamFrameInfo frameInfo;
#	ifdef HK_PS2
		frameInfo.m_indexOfTimer0 = 1;
		frameInfo.m_indexOfTimer1 = 0;
			// Assume that each instruction cache miss cost around 35 cycles.
			// So we can see how much of our overall time is spent waiting for the
			// memory system
		frameInfo.m_timerFactor0 = 35.0f / 300.f;
		frameInfo.m_timerFactor1 = 1.0f / 300.f;
		frameInfo.m_heading = "usec: IcachePenalty (assuming 35 cycle penalty)";
#	else
		frameInfo.m_indexOfTimer0 = 0;
		frameInfo.m_indexOfTimer1 = -1;
		frameInfo.m_heading = "usecs";
		frameInfo.m_timerFactor0 = 1e6f / hkReal(hkStopwatch::getTicksPerSecond());
#	endif

	int demoIdx = hkDemoDatabase::getInstance().findDemo( TEST_DEMO_FULLPATH );
	HK_ASSERT2(0x654e432e, demoIdx != -1, "Demo does not exist" );

	const bool isPhysicsDemo = (HK_DEMO_TYPE_PHYSICS == hkDemoDatabase::getInstance().getDemos()[ demoIdx ].m_demoTypeFlags);


	//
	//	Setup some memory to store all the timer information 
	//  for all frames
	//
	int numThreads = 1;

	if( isPhysicsDemo )
	{
		hkCpuJobThreadPool* mtUtil = (hkCpuJobThreadPool*)static_cast<hkDefaultPhysicsDemo*>(demo)->m_jobThreadPool;
		if (mtUtil)
		{
			numThreads += mtUtil->getNumThreads();
		}
	}

	hkMonitorStreamAnalyzer streamAnalyzer( 10000000, numThreads );

	for (int i = 0; i < iterations; i++ )
	{

		//
		//	Setup the timerinfo and memory on a per frame bases
		//
		hkMonitorStream& stream = hkMonitorStream::getInstance();
		stream.resize( 2 * 1024 * 1024  );	// 2 meg for timer info per frame
		stream.reset();

		//
		//	Start timers
		//
#		ifdef HK_PS2
			scePcStart( SCE_PC_CTE | SCE_PC_U0 | SCE_PC_U1 | SCE_PC0_ICACHE_MISS | SCE_PC1_CPU_CYCLE, 0 ,0 );
#		endif

		//
		//	Step the demo
		//
		demo->stepDemo();

		//
		//	Stop timers. This is necessary as a timer overflow on PlayStation(R)2 causes an exception
		//
#		ifdef HK_PS2
		scePcStop() ;
#		endif

		//
		//	Analyze the per frame info and copy the data over to the multi frame buffer
		//

		if( numThreads > 1 )
		{
			hkCpuJobThreadPool* mtUtil = (hkCpuJobThreadPool*)static_cast<hkDefaultPhysicsDemo*>(demo)->m_jobThreadPool;

			// Loop through each thread. Capture the frame details from the local
			// stream analyzer in each thread.
			for (int t = 0; t < mtUtil->getNumThreads(); ++t)
			{
				hkCpuJobThreadPool::WorkerThreadData& data = mtUtil->m_workerThreads[t];

				if (data.m_monitorStreamBegin != data.m_monitorStreamEnd )
				{
					frameInfo.m_threadId = t + 1;
					streamAnalyzer.captureFrameDetails( data.m_monitorStreamBegin,data.m_monitorStreamEnd, frameInfo );
				}
			}
		}
		frameInfo.m_threadId = 0;
		streamAnalyzer.captureFrameDetails(stream.getStart(), stream.getEnd(), frameInfo );
	}

	//
	// Write the results to a file
	//
	{
		// Disable double conversion check - we know this will fail
		pushDoubleConversionCheck(false);
		hkReferencedObject::lockAll();
		
		hkOstream ostr (fileName);
		ostr << TEST_DEMO_NAME "   Timers: \n";

		streamAnalyzer.writeStatistics( ostr );
		hkReferencedObject::unlockAll();
		
		popDoubleConversionCheck();
	}

}
コード例 #2
0
hkDemo::Result BasicMovementDemo::stepDemo()
{
	// for PlayStation(R)2 metrowerks
	pushDoubleConversionCheck( false );

	// Display current settings
	{
		char buf[255];
		for (int i=0; i< NUM_ANIMS; i++)
		{
			hkString::sprintf(buf, "anim%d: %0.3f", i, m_control[i]->getWeight());
			const int h = m_env->m_window->getHeight();
			m_env->m_textDisplay->outputText( buf, 20, h-70+16*i, curveCols[i], 1);
		}
	}

	popDoubleConversionCheck();

	// Handle the keys
	{
		bool jumping = (m_control[1]->getWeight() > 0.001f);

		if (!jumping)
		{
			hkVector4 upVec(0,0,1);
			hkReal up, turn;
			up = m_env->m_gamePad->getStickPosY( 1 ); // 1 is the only one on PSP

			const hkBool upPressed = (up > 0.0f);
			const hkBool easeIn = (m_control[0]->getEaseStatus() == hkaDefaultAnimationControl::EASING_IN ) || ( m_control[0]->getEaseStatus() == hkaDefaultAnimationControl::EASED_IN );
			if ( easeIn  && ( !upPressed ))
			{
				// Ease in stand
				m_control[0]->easeOut( 0.9f );
			}
			else if (( !easeIn )  && upPressed )
			{
				// Ease in walk cycle
				m_control[0]->easeIn( 0.9f );
			}

			turn = m_env->m_gamePad->getStickPosX(1);

			turn *= -5.0f * HK_REAL_PI / 180.0f * m_control[0]->getWeight();

			hkQuaternion q;
			q.setAxisAngle(upVec, turn);
			m_currentMotion.m_rotation.mul(q);
		}
		else
		{
			hkReal remaining = m_control[1]->getAnimationBinding()->m_animation->m_duration - m_control[1]->getLocalTime();

			// If we've played through then fade out
			const hkBool easeIn = (m_control[1]->getEaseStatus() == hkaDefaultAnimationControl::EASING_IN ) || ( m_control[1]->getEaseStatus() == hkaDefaultAnimationControl::EASED_IN );
			if ( easeIn && (remaining < 0.2f))
			{
				m_control[1]->easeOut( remaining );
				m_control[0]->setLocalTime( m_control[0]->getAnimationBinding()->m_animation->m_duration - remaining );
				m_control[0]->easeIn( remaining );
			}


		}

		if (m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_2) && !jumping)
		{
			// Reset jump animation and play
			m_control[1]->setLocalTime(0.0f);

			m_control[1]->easeIn( 0.1f );
			m_control[0]->easeOut( 0.1f );
		}

		if (m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_1))
		{
			m_currentMotion.setIdentity();
		}

	}

	// Grab accumulated motion
	{
		hkQsTransform deltaMotion;
		deltaMotion.setIdentity();
		m_skeletonInstance->getDeltaReferenceFrame( m_timestep, deltaMotion);

		hkQsTransform temp;
		temp.setMul(m_currentMotion, deltaMotion);
		m_currentMotion = temp;
	}

	const int boneCount = m_skeleton->m_numBones;

	// Advance the active animations
	m_skeletonInstance->stepDeltaTime( 1.0f / 60.0f );

	// Sample the active animations and combine into a single pose
	hkaPose pose (m_skeleton);
	m_skeletonInstance->sampleAndCombineAnimations( pose.accessUnsyncedPoseLocalSpace().begin(), pose.getFloatSlotValues().begin()  );
	AnimationUtils::drawPose( pose, hkQsTransform::getIdentity() );

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

	// Convert accumlated info to graphics matrix
	hkTransform graphicsTransform;
	m_currentMotion.copyToTransform(graphicsTransform);

	// Skin the meshes
	{
		const hkArray<hkQsTransform>& poseInWorld = pose.getSyncedPoseModelSpace();

		for (int i=0; i < m_numSkinBindings; i++)
		{
			// assumes either a straight map (null map) or a single one (1 palette)
			hkInt16* usedBones = m_skinBindings[i]->m_mappings? m_skinBindings[i]->m_mappings[0].m_mapping : HK_NULL;
			int numUsedBones = usedBones? m_skinBindings[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;
				compositeWorldInverse[p].setMul( poseInWorld[ boneIndex ], m_skinBindings[i]->m_boneFromSkinMeshTransforms[ boneIndex ] );
			}


			AnimationUtils::skinMesh( *m_skinBindings[i]->m_mesh, graphicsTransform, compositeWorldInverse.begin(), *m_env->m_sceneConverter );
		}
	}

	return hkDemo::DEMO_OK;
}