예제 #1
0
bool KX_KetsjiEngine::NextFrame()
{
	double timestep = 1.0/m_ticrate;
	double framestep = timestep;
//	static hidden::Clock sClock;

m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(),true);

//float dt = sClock.getTimeMicroseconds() * 0.000001f;
//sClock.reset();

if (m_bFixedTime)
	m_clockTime += timestep;
else
{

//	m_clockTime += dt;
	m_clockTime = m_kxsystem->GetTimeInSeconds();
}
	
	double deltatime = m_clockTime - m_frameTime;
	if (deltatime<0.f)
	{
		printf("problem with clock\n");
		deltatime = 0.f;
		m_clockTime = 0.f;
		m_frameTime = 0.f;
	}


	// Compute the number of logic frames to do each update (fixed tic bricks)
	int frames =int(deltatime*m_ticrate+1e-6);
//	if (frames>1)
//		printf("****************************************");
//	printf("dt = %f, deltatime = %f, frames = %d\n",dt, deltatime,frames);
	
//	if (!frames)
//		PIL_sleep_ms(1);
	
	KX_SceneList::iterator sceneit;
	
	if (frames>m_maxPhysicsFrame)
	{
	
	//	printf("framedOut: %d\n",frames);
		m_frameTime+=(frames-m_maxPhysicsFrame)*timestep;
		frames = m_maxPhysicsFrame;
	}
	

	bool doRender = frames>0;

	if (frames > m_maxLogicFrame)
	{
		framestep = (frames*timestep)/m_maxLogicFrame;
		frames = m_maxLogicFrame;
	}
		
	while (frames)
	{
	

		m_frameTime += framestep;
		
		for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
		// for each scene, call the proceed functions
		{
			KX_Scene* scene = *sceneit;
	
			/* Suspension holds the physics and logic processing for an
			* entire scene. Objects can be suspended individually, and
			* the settings for that preceed the logic and physics
			* update. */
			m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);

			m_sceneconverter->resetNoneDynamicObjectToIpo();//this is for none dynamic objects with ipo

			scene->UpdateObjectActivity();
	
			if (!scene->IsSuspended())
			{
				// if the scene was suspended recalcutlate the delta tu "curtime"
				m_suspendedtime = scene->getSuspendedTime();
				if (scene->getSuspendedTime()!=0.0)
					scene->setSuspendedDelta(scene->getSuspendedDelta()+m_clockTime-scene->getSuspendedTime());
				m_suspendeddelta = scene->getSuspendedDelta();

				
				m_logger->StartLog(tc_network, m_kxsystem->GetTimeInSeconds(), true);
				SG_SetActiveStage(SG_STAGE_NETWORK);
				scene->GetNetworkScene()->proceed(m_frameTime);
	
				//m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
				//SG_SetActiveStage(SG_STAGE_NETWORK_UPDATE);
				//scene->UpdateParents(m_frameTime);
				
				m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
				SG_SetActiveStage(SG_STAGE_PHYSICS1);
				// set Python hooks for each scene
#ifndef DISABLE_PYTHON
				PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
#endif
				KX_SetActiveScene(scene);
	
				scene->GetPhysicsEnvironment()->endFrame();
				
				// Update scenegraph after physics step. This maps physics calculations
				// into node positions.		
				//m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
				//SG_SetActiveStage(SG_STAGE_PHYSICS1_UPDATE);
				//scene->UpdateParents(m_frameTime);
				
				// Process sensors, and controllers
				m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
				SG_SetActiveStage(SG_STAGE_CONTROLLER);
				scene->LogicBeginFrame(m_frameTime);
	
				// Scenegraph needs to be updated again, because Logic Controllers 
				// can affect the local matrices.
				m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
				SG_SetActiveStage(SG_STAGE_CONTROLLER_UPDATE);
				scene->UpdateParents(m_frameTime);
	
				// Process actuators
	
				// Do some cleanup work for this logic frame
				m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
				SG_SetActiveStage(SG_STAGE_ACTUATOR);
				scene->LogicUpdateFrame(m_frameTime, true);
				
				scene->LogicEndFrame();
	
				// Actuators can affect the scenegraph
				m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
				SG_SetActiveStage(SG_STAGE_ACTUATOR_UPDATE);
				scene->UpdateParents(m_frameTime);
				
				m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
				SG_SetActiveStage(SG_STAGE_PHYSICS2);
				scene->GetPhysicsEnvironment()->beginFrame();
		
				// Perform physics calculations on the scene. This can involve 
				// many iterations of the physics solver.
				scene->GetPhysicsEnvironment()->proceedDeltaTime(m_frameTime,timestep,framestep);//m_deltatimerealDeltaTime);

				m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
				SG_SetActiveStage(SG_STAGE_PHYSICS2_UPDATE);
				scene->UpdateParents(m_frameTime);
			
			
				if (m_game2ipo)
				{					
					m_sceneconverter->WritePhysicsObjectToAnimationIpo(++m_currentFrame);
				}

				scene->setSuspendedTime(0.0);
			} // suspended
			else
				if(scene->getSuspendedTime()==0.0)
					scene->setSuspendedTime(m_clockTime);
	
			DoSound(scene);
			
			m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
		}

		// update system devices
		m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
		if (m_keyboarddevice)
			m_keyboarddevice->NextFrame();
	
		if (m_mousedevice)
			m_mousedevice->NextFrame();
		
		if (m_networkdevice)
			m_networkdevice->NextFrame();

		// scene management
		ProcessScheduledScenes();
		
		frames--;
	}

	bool bUseAsyncLogicBricks= false;//true;

	if (bUseAsyncLogicBricks)
	{	
		// Logic update sub frame: this will let some logic bricks run at the
		// full frame rate.
		for (sceneit = m_scenes.begin();sceneit != m_scenes.end(); ++sceneit)
		// for each scene, call the proceed functions
		{
			KX_Scene* scene = *sceneit;

			if (!scene->IsSuspended())
			{
				// if the scene was suspended recalcutlate the delta tu "curtime"
				m_suspendedtime = scene->getSuspendedTime();
				if (scene->getSuspendedTime()!=0.0)
					scene->setSuspendedDelta(scene->getSuspendedDelta()+m_clockTime-scene->getSuspendedTime());
				m_suspendeddelta = scene->getSuspendedDelta();
				
				// set Python hooks for each scene
#ifndef DISABLE_PYTHON
				PHY_SetActiveEnvironment(scene->GetPhysicsEnvironment());
#endif
				KX_SetActiveScene(scene);
				
				m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
				SG_SetActiveStage(SG_STAGE_PHYSICS1);
				scene->UpdateParents(m_clockTime);

				// Perform physics calculations on the scene. This can involve 
				// many iterations of the physics solver.
				m_logger->StartLog(tc_physics, m_kxsystem->GetTimeInSeconds(), true);
				scene->GetPhysicsEnvironment()->proceedDeltaTime(m_clockTime,timestep,timestep);
				// Update scenegraph after physics step. This maps physics calculations
				// into node positions.		
				m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
				SG_SetActiveStage(SG_STAGE_PHYSICS2);
				scene->UpdateParents(m_clockTime);
				
				// Do some cleanup work for this logic frame
				m_logger->StartLog(tc_logic, m_kxsystem->GetTimeInSeconds(), true);
				scene->LogicUpdateFrame(m_clockTime, false);

				// Actuators can affect the scenegraph
				m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
				SG_SetActiveStage(SG_STAGE_ACTUATOR);
				scene->UpdateParents(m_clockTime);
				 
 				scene->setSuspendedTime(0.0);
			} // suspended
 			else
 				if(scene->getSuspendedTime()==0.0)
 					scene->setSuspendedTime(m_clockTime);

			DoSound(scene);

			m_logger->StartLog(tc_services, m_kxsystem->GetTimeInSeconds(), true);
		}
	}


	m_previousClockTime = m_clockTime;
	
	// Start logging time spend outside main loop
	m_logger->StartLog(tc_outside, m_kxsystem->GetTimeInSeconds(), true);
	
	return doRender;
}
예제 #2
0
파일: BL_Action.cpp 프로젝트: UPBGE/blender
bool BL_Action::Play(const std::string& name,
					float start,
					float end,
					short priority,
					float blendin,
					short play_mode,
					float layer_weight,
					short ipo_flags,
					float playback_speed,
					short blend_mode)
{

	// Only start playing a new action if we're done, or if
	// the new action has a higher priority
	if (!IsDone() && priority > m_priority)
		return false;
	m_priority = priority;
	bAction* prev_action = m_action;

	KX_Scene* kxscene = m_obj->GetScene();

	// First try to load the action
	m_action = (bAction*)kxscene->GetLogicManager()->GetActionByName(name);
	if (!m_action)
	{
		CM_Error("failed to load action: " << name);
		m_done = true;
		return false;
	}

	// If we have the same settings, don't play again
	// This is to resolve potential issues with pulses on sensors such as the ones
	// reported in bug #29412. The fix is here so it works for both logic bricks and Python.
	// However, this may eventually lead to issues where a user wants to override an already
	// playing action with the same action and settings. If this becomes an issue,
	// then this fix may have to be re-evaluated.
	if (!IsDone() && m_action == prev_action && m_startframe == start && m_endframe == end
			&& m_priority == priority && m_speed == playback_speed)
		return false;

	// Keep a copy of the action for threading purposes
	if (m_tmpaction) {
		BKE_libblock_free(G.main, m_tmpaction);
		m_tmpaction = NULL;
	}
	m_tmpaction = BKE_action_copy(G.main, m_action);

	// First get rid of any old controllers
	ClearControllerList();

	// Create an SG_Controller
	SG_Controller *sg_contr = BL_CreateIPO(m_action, m_obj, kxscene->GetSceneConverter());
	m_sg_contr_list.push_back(sg_contr);
	m_obj->GetSGNode()->AddSGController(sg_contr);
	sg_contr->SetObject(m_obj->GetSGNode());

	// World
	sg_contr = BL_CreateWorldIPO(m_action, kxscene->GetBlenderScene()->world, kxscene->GetSceneConverter());
	if (sg_contr) {
		m_sg_contr_list.push_back(sg_contr);
		m_obj->GetSGNode()->AddSGController(sg_contr);
		sg_contr->SetObject(m_obj->GetSGNode());
	}

	// Try obcolor
	sg_contr = BL_CreateObColorIPO(m_action, m_obj, kxscene->GetSceneConverter());
	if (sg_contr) {
		m_sg_contr_list.push_back(sg_contr);
		m_obj->GetSGNode()->AddSGController(sg_contr);
		sg_contr->SetObject(m_obj->GetSGNode());
	}

	// Now try materials
	for (int matidx = 1; matidx <= m_obj->GetBlenderObject()->totcol; ++matidx) {
		Material *mat = give_current_material(m_obj->GetBlenderObject(), matidx);
		if (!mat) {
			continue;
		}

		KX_BlenderSceneConverter *converter = kxscene->GetSceneConverter();
		RAS_IPolyMaterial *polymat = converter->FindCachedPolyMaterial(kxscene, mat);
		if (!polymat) {
			continue;
		}

		sg_contr = BL_CreateMaterialIpo(m_action, mat, polymat, m_obj, converter);
		if (sg_contr) {
			m_sg_contr_list.push_back(sg_contr);
			m_obj->GetSGNode()->AddSGController(sg_contr);
			sg_contr->SetObject(m_obj->GetSGNode());
		}
	}

	// Extra controllers
	if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_LIGHT)
	{
		sg_contr = BL_CreateLampIPO(m_action, m_obj, kxscene->GetSceneConverter());
		m_sg_contr_list.push_back(sg_contr);
		m_obj->GetSGNode()->AddSGController(sg_contr);
		sg_contr->SetObject(m_obj->GetSGNode());
	}
	else if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_CAMERA)
	{
		sg_contr = BL_CreateCameraIPO(m_action, m_obj, kxscene->GetSceneConverter());
		m_sg_contr_list.push_back(sg_contr);
		m_obj->GetSGNode()->AddSGController(sg_contr);
		sg_contr->SetObject(m_obj->GetSGNode());
	}
	
	m_ipo_flags = ipo_flags;
	InitIPO();

	// Setup blendin shapes/poses
	if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
	{
		BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
		obj->GetPose(&m_blendinpose);
	}
	else
	{
		BL_DeformableGameObject *obj = (BL_DeformableGameObject*)m_obj;
		BL_ShapeDeformer *shape_deformer = dynamic_cast<BL_ShapeDeformer*>(obj->GetDeformer());
		
		if (shape_deformer && shape_deformer->GetKey())
		{
			obj->GetShape(m_blendinshape);

			// Now that we have the previous blend shape saved, we can clear out the key to avoid any
			// further interference.
			KeyBlock *kb;
			for (kb=(KeyBlock *)shape_deformer->GetKey()->block.first; kb; kb=(KeyBlock *)kb->next)
				kb->curval = 0.f;
		}
	}

	// Now that we have an action, we have something we can play
	m_starttime = KX_GetActiveEngine()->GetFrameTime() - kxscene->getSuspendedDelta();
	m_startframe = m_localframe = start;
	m_endframe = end;
	m_blendin = blendin;
	m_playmode = play_mode;
	m_blendmode = blend_mode;
	m_blendframe = 0.f;
	m_blendstart = 0.f;
	m_speed = playback_speed;
	m_layer_weight = layer_weight;
	
	m_done = false;
	m_appliedToObject = false;

	m_prevUpdate = -1.0f;

	return true;
}