Пример #1
0
bool CIterativeSheetSimulator::Think( )
{
	assert( m_SimulationSteps >= 0 );

	// Need to iteratively perform collision detection
	if (m_CurrentCollisionPt >= 0)
	{
		DetectCollisions();
		return false;
	}
	else
	{
		// Simulate it a bunch of times
		Simulate(m_TimeStep, static_cast<int>(m_SubSteps));

		// Reset the collision point for collision detect
		m_CurrentCollisionPt = 0;
		--m_SimulationSteps;

		if ( m_SimulationSteps == 0 )
		{
			ClampPointsToCollisionPlanes();
		}

		return true;
	}
}
Пример #2
0
void renderLoop(int value)
{
    
    
    render();
    glutTimerFunc(1000/30,renderLoop,1);
    KeyboardOperations();
    DetectCollisions();
}
void PhysicsSystem::Update(float deltaTime)
{
    Integrate(deltaTime);
    DetectCollisions();
    ResolveContacts(deltaTime);
    SendCollisionMessages();

    contacts.clear();
    UpdateDebugDraw();
}
Пример #4
0
void ODESimulator::Step(Real dt)
{
  Assert(timestep == 0);
  //Timer timer;
  //double collisionTime,stepTime,updateTime;

  gContacts.clear();

  timestep=dt;
  DetectCollisions();

  //printf("  %d contacts detected\n",gContacts.size());

  //collisionTime = timer.ElapsedTime();
  //timer.Reset();

  StepDynamics(dt);

  //stepTime = timer.ElapsedTime();
  //timer.Reset();

  for(map<pair<ODEObjectID,ODEObjectID>,ODEContactList>::iterator i=contactList.begin();i!=contactList.end();i++) {  
    ODEContactList& cl=i->second;
    cl.forces.clear();
    for(size_t j=0;j<cl.feedbackIndices.size();j++) {
      int k=cl.feedbackIndices[j];
      Assert(k >= 0 && k < (int)gContacts.size());
      list<ODEContactResult>::iterator cres=gContacts.begin();
      advance(cres,k);
      Vector3 temp;
      for(size_t i=0;i<cres->feedback.size();i++) {
	CopyVector(temp,cres->feedback[i].f1);
	cl.forces.push_back(temp);
	/*
	if(!cl.points.back().isValidForce(-temp)) {
	  printf("ODESimulator: Warning, solved contact force %d %d is invalid\n",k,i);
	  cout<<"  Force: "<<-temp<<", normal "<<cl.points.back().n<<" kFriction "<<cl.points.back().kFriction<<endl;
	}
	*/
      }
    }
    if(!cl.feedbackIndices.empty())
      Assert(cl.points.size() == cl.forces.size());
  }

  timestep = 0;
  //KH: commented this out so GetContacts() would work for ContactSensor simulation.  Be careful about loading state
  //gContacts.clear();

  //updateTime = timer.ElapsedTime();

  //printf("ODE simulation step: %g collision, %g step, %g update\n",collisionTime,stepTime,updateTime);
}
Пример #5
0
void SgObjectManager::Update( SgMap *map , SgViewPort *viewport , SgInputManager* pInput )
{
	//if the game is paused we just draw the objects (and don't animate them)
	if(m_pTimer->IsPaused())
	{
		return;
	}
	//Create a new random seed for randomness.
	RandomSeed(timeGetTime());
	//animate each object individually (if user object we pass the input along)
	for(int i=0; i<m_dwMaxObjects; i++){
		//if object exists
		if(m_ppObject[i]!=NULL){
			if(i!=(m_dwUserObject-1)){
				m_ppObject[i]->Animate(m_pTimer, map, NULL, this);
			}else{
				m_ppObject[i]->Animate(m_pTimer, map, pInput, this);
			}
		}
	}

	//set the viewport to the user objects
	viewport->update(m_pTimer->Time());

	if((m_dwUserObject>0) && (m_ppObject[m_dwUserObject-1]!=NULL) )
	{
		viewport->force_position(m_ppObject[m_dwUserObject-1]->GetX(), m_ppObject[m_dwUserObject-1]->GetY());
		
	}
	else
	{
		viewport->stop_scroll();
	}

	//detect collisions (which will do all necessary steps if there is a collision)
	DetectCollisions();
	
	Cull(); //cull old objects
}
Пример #6
0
/// Processes physics for all registered objects
void PhysicsManager::ProcessPhysics()
{
	if (physicsState->simulationPaused)
		return;
	/// Returns straight away if paused.
	if (paused)
		return;
	if (physicalEntities.Size() == 0)
		return;

	activeTriangles.Clear();

	time_t currentTime = Timer::GetCurrentTimeMs();
	time_t millisecondsSinceLastUpdate = currentTime - lastUpdate;
	lastUpdate = currentTime;
  //  std::cout<<"\nCurrent time: "<<currentTime<<" last update: "<<lastUpdate;

	/// Throw away time if we've got more than 1 second, since this assumes we're debugging
	if (millisecondsSinceLastUpdate > 100){
		if (millisecondsSinceLastUpdate > 1000)
			std::cout<<"\nPhysicsManager::Throwing away "<<millisecondsSinceLastUpdate / 1000<<" debugging seconds";
		millisecondsSinceLastUpdate = 100;
	}

	float totalTimeSinceLastUpdate = millisecondsSinceLastUpdate * 0.001f;
	/// Multiply the total time since last update with the simulation speed multiplier before actual calculations are begun.
	totalTimeSinceLastUpdate = totalTimeSinceLastUpdate * simulationSpeed;

	/// Just return if simulation speed decreases beyond 0.1%!
	if (simulationSpeed <= 0.0001f){
		return;
	}

	/// Debugging time statistics
	float messageProcessingTime = 0;
	float recalculatingPropertiesDuration = 0;
	float collissionProcessingFrameTime = 0;

	// Reset previous frame-times
	recalculatingPropertiesDuration = 0;
	float integration = 0;
	collissionProcessingFrameTime = 0;
	physicsMeshCollisionChecks = 0;

	// To be sent for Collision callback.
	List<Message*> messages;


	/// Do one process for each 10 ms we've gotten stored up
	/// Get sub-time to calculate.
	float dt = 0.010f * simulationSpeed;
	float timeDiff = dt;
	float timeInSecondsSinceLastUpdate = dt;

	static float timeRemainingFromLastIteration = 0.f;
	/// Add time from last iteration that wasn't spent (since only evaluating one physics step at a time, 10 ms default).
	float timeToIterate = totalTimeSinceLastUpdate + timeRemainingFromLastIteration;
	float stepSize = 0.010f;
	int steps = timeToIterate / stepSize + 0.5f;

	/// Use a new step size based on the amount of steps. This will hopefully vary between 5.0 and 15.0 then.
	float newStepSize = timeToIterate / steps;
	int newStepSizeMs = newStepSize * 1000;
	newStepSize = newStepSizeMs * 0.001f;
	if (newStepSize < 0.005f || newStepSize > 0.015f)
	{
		LogPhysics("Step size out of good range: "+String(newStepSize), WARNING);
		if (newStepSize < 0.f)
			return;
//		assert(False)
	}
//	assert(newStepSize > 0.005f && newStepSize < 0.015f);
	

//	if (steps < 1) // At least 1 physics simulation per frame, yo. Otherwise you get a 'stuttering' effect when some frames have movement and some don't.
//		steps = 1;
	float timeLeft = timeToIterate - steps * newStepSizeMs * 0.001f;
	/// Store time we won't simulate now.
	timeRemainingFromLastIteration = timeLeft;
//	std::cout<<"\nSteps: "<<steps;

	for(int i = 0; i < steps; ++i)
	{
		/// Set current time in physics for this frame. This time is not the same as real time.
		physicsNowMs += newStepSizeMs;
			
		/// Process estimators (if any) within all registered entities?
		int milliseconds = newStepSizeMs;
		for (int i = 0 ; i < physicalEntities.Size(); ++i)
		{
			Entity * entity = physicalEntities[i];
			List<Estimator*> & estimators = entity->physics->estimators;
			for (int j = 0; j < estimators.Size(); ++j)
			{
				Estimator * estimator = estimators[j];
				estimator->Process(milliseconds);
				if (entity->name == "ExplosionEntity")
					int lp = 5;
				// Recalculate other stuff too.
				entity->physics->UpdateProperties(entity);
				// Re-calculate transform matrix, as it was probably affected..?
				entity->RecalculateMatrix(Entity::ALL_PARTS);
				if (estimator->finished)
				{
					estimators.RemoveIndex(j, ListOption::RETAIN_ORDER);
					--j;
					delete estimator;
				}
			}
		}

		/// Awesome.
		Integrate(newStepSize);
		
		/// Apply external constraints
	//	ApplyContraints();		

		/// Apply pathfinding for all relevant entities - should be done in separate property-files. Or in more dedicated classes for specific games.
//		ApplyPathfinding();
        
		Timer collisionTimer;
		collisionTimer.Start();

		Timer timer;
		timer.Start();
		/// Detect collisions.
		List<Collision> collisions;
		Timer sweepTimer;
		sweepTimer.Start();
		// Generate pair of possible collissions via some optimized way (AABB-sorting or Octree).
		List<EntityPair> pairs = this->aabbSweeper->Sweep();
		sweepTimer.Stop();
		int sweepDur = sweepTimer.GetMs();
		FrameStats.physicsCollisionDetectionAABBSweep += sweepDur;
//		std::cout<<"\nAABB sweep pairs: "<<pairs.Size()<<" with "<<physicalEntities.Size()<<" entities";
		Timer detectorTimer;
		detectorTimer.Start();

		if (collisionDetector)
		{
			collisionDetector->DetectCollisions(pairs, collisions);
		}
		
		// Old approach which combined collision-detection and resolution in a big mess...
		else 
			DetectCollisions();
		detectorTimer.Stop();
		int detectorMs = detectorTimer.GetMs();
		FrameStats.physicsCollisionDetectionChosenDetector += detectorMs;
		timer.Stop();
		int thisFrame = timer.GetMs();
		FrameStats.physicsCollisionDetection += thisFrame;

		timer.Start();
		/// And resolve them.
		if (collisionResolver)
			collisionResolver->ResolveCollisions(collisions);
		timer.Stop();
		FrameStats.physicsCollisionResolution += timer.GetMs();

		timer.Start();
		messages.Clear();
		for (int i = 0; i < collisions.Size(); ++i)
		{
			Collision & c = collisions[i];
			if (c.one->physics->onCollision)
				c.one->OnCollision(c);
			if (c.two->physics->onCollision)
				c.two->OnCollision(c);
			if (c.one->physics->collisionCallback || c.two->physics->collisionCallback)
			{
				/// Check max callbacks.
				int & maxCallbacks1 = c.one->physics->maxCallbacks;
				int & maxCallbacks2 = c.two->physics->maxCallbacks;
				if (maxCallbacks1 == 0 || maxCallbacks2 == 0)
					continue;
				CollisionCallback * cc = new CollisionCallback(c.one, c.two);
				cc->impactNormal = c.collisionNormal;
				messages.Add(cc);
				if (maxCallbacks1 > 0)
					--maxCallbacks1;
				if (maxCallbacks2 > 0)
					--maxCallbacks2;
			}
		}
		if (messages.Size())
			MesMan.QueueMessages(messages);
		timer.Stop();
		FrameStats.physicsCollisionCallback += timer.GetMs();

		collisionTimer.Stop();
		FrameStats.physicsCollisions += collisionTimer.GetMs();
		int64 colMs = collisionTimer.GetMs();
		if (colMs > 50)
		{
			std::cout<<"\nCollision detection and resolution taking "<<colMs<<" milliseconds per frame.";
			break; // Break the loop. Simulate more next time if it's already being slow.
		}
	}
	// Recalc matrices for the semi-dynamic ones.
	if (physicsIntegrator)
		physicsIntegrator->RecalculateMatrices(semiDynamicEntities);
	else 
		LogPhysics("No integrator assigned", ERROR);

	// Reset previous frame-times
//	FrameStats.physicsIntegration = integration;
	collissionProcessingFrameTime = 0;
	physicsMeshCollisionChecks = 0;
}
Пример #7
0
void CCameraFlight::UpdateFlight(SViewParams &viewParams)
{
	if(m_eMovementMode != eCFM_FREE_FLIGHT &&
		(m_fFlightProgress >= 1.0f || m_eMovementMode == eCFM_NONE || m_cameraCourse.size() < 3))
	{
		//update free fly point while not in free fly
		m_freeFlyPoint.m_vCamPos = viewParams.position;
		m_freeFlyPoint.m_vCamLookAt = viewParams.position + Vec3Constants<float>::fVec3_OneY;
		m_eState = eCFS_NONE;
		//nothing else to do
		return;
	}

	m_eState = eCFS_RUNNING;

	//update ref pos
	if(m_pRefEnt)
		m_vRefPos = m_pRefEnt->GetWorldPos();
	//if refPos2 is set, find middle
	if(m_vRefPos2.len2() > 0.0f)
		m_vRefPos = (m_vRefPos + m_vRefPos2) * 0.5f;

	//find target
	SCameraFlightPoint targetPoint = SCameraFlightPoint();

	switch(m_eMovementMode)
	{
	case eCFM_FREE_FLIGHT:
		targetPoint = m_freeFlyPoint;
		break;
	case eCFM_SPLINE:
		targetPoint = GetSplinePoint(m_fFlightProgress);
		break;
	case eCFM_LINE:
		targetPoint = GetTrackPoint(m_fFlightProgress);
		break;
	default:
		break;
	}

	//compute new dir/pos
	m_vLookingDirection = targetPoint.m_vCamLookAt - targetPoint.m_vCamPos;
	if(m_bUseRefDir)
	{
		m_vLookingDirection = m_vRefDir;
		m_qFadeOrientation = Quat::CreateRotationVDir(m_vLookingDirection, 0.0f);
	}
	m_vLookingDirection.NormalizeSafe();
	Quat qTempDirection = Quat::CreateRotationVDir(m_vLookingDirection, 0.0f);
	Vec3 vTempPos = targetPoint.m_vCamPos;

	bool bFading = false;

	//compute fading
	if(m_eMovementMode != eCFM_FREE_FLIGHT)
	{
		if(m_fFlightProgress > m_fFadeOutTime && (m_eFadeMode == eCFFM_OUT || m_eFadeMode == eCFFM_INOUT))
		{
			//fade position
			m_fFadeProgress = InterpolateTo(m_fFadeProgress, 1.0f, m_fFadeTime);
			m_vTargetFadePos = vTempPos * (1.0f - m_fFadeProgress) + viewParams.position * m_fFadeProgress;
			//fade orientation
			qTempDirection = Quat_tpl<float>::CreateNlerp(m_qFadeOrientation, viewParams.rotation, m_fFadeProgress);
			if(m_fFadeProgress < 0.998f)
			{
				bFading = true;
				m_eState = eCFS_FADE_OUT;
			}
		}
		else if(m_fFlightProgress < m_fFadeInTime && (m_eFadeMode == eCFFM_IN || m_eFadeMode == eCFFM_INOUT))
		{
			//fade position
			m_fFadeProgress = InterpolateTo(m_fFadeProgress, 1.0f, m_fFadeTime);
			m_vTargetFadePos = viewParams.position * (1.0f - m_fFadeProgress) + vTempPos * m_fFadeProgress;
			//fade orientation
			qTempDirection = Quat_tpl<float>::CreateNlerp(viewParams.rotation, qTempDirection, m_fFadeProgress);
			if(m_fFadeProgress < 0.998f)
			{
				bFading = true;
				m_eState = eCFS_FADE_IN;
			}
		}
		else
		{
			m_vTargetFadePos = vTempPos;
			//m_vTargetFadeLookAt = targetPoint.m_vCamLookAt;
			m_qFadeOrientation = qTempDirection;
			m_fFadeProgress = 0.0f;
			m_eState = eCFS_RUNNING;
		}
	}
	else
	{
		m_vTargetFadePos = vTempPos;
	}

	//update dir
	m_vLookingDirection = qTempDirection.GetColumn1();

	//raycast to prevent clipping during flight
	if(m_eMovementMode != eCFM_FREE_FLIGHT)
		DetectCollisions();

	//set position and rotation to viewparams
	viewParams.rotation = qTempDirection;
	viewParams.position = m_vTargetFadePos;//InterpolateTo(m_vTargetFadePos, viewParams.position, 1.0f);

	//progress flight
	if(m_eMovementMode != eCFM_FREE_FLIGHT && !bFading)
	{
		if(m_bPaused && m_fFlightProgress < 0.2f)
		{
			m_fFlightProgress += gEnv->pTimer->GetFrameTime() * m_fFlightSpeed;
			m_fFlightProgress = min(0.2f, m_fFlightProgress);
		}
		else if (!m_bPaused)
			m_fFlightProgress += gEnv->pTimer->GetFrameTime() * m_fFlightSpeed;
	}
}
Пример #8
0
void Application::Process(sf::RenderWindow* window) {
	switch(currentState) {
		case e_START:
			// RETURN - Start game
			if(hInput.isKeyPressed(e_KEYBOARD, sf::Keyboard::Return)) {
				currentState = e_INGAME;
				StartTimer.restart();
			}
			// ESCAPE - Close game
			if(hInput.isKeyPressed(e_KEYBOARD, sf::Keyboard::Escape)) {
				window->close();
			}
			break;
		case e_INGAME:
			// Check win state
			if(winState != e_ONGOING) {
				if (Players[0].dead){
					Players[0].DEAD();
					Players[1].animatedSprite.stop();
				}
				else if (Players[1].dead) {
					Players[1].DEAD();
				}
				if (DeathTimer.getElapsedTime() >= sf::seconds(1.5)){
					currentState = e_END;
				}
				
			} else {
				if(gameStarted == false) {		// If game not started yet
					if(StartTimer.getElapsedTime() >= sf::seconds(START_COUNTDOWN)) {		// If countdown has finished
						gameStarted = true;
						ControlChangeTimer.restart();
					}
				} else {
					// Update player classes
					for(int i = 0; i < PLAYER_COUNT; ++i) {
						Players[i].Update(&hInput);
					}
					
					LocationComparison();
					for(int i = 0; i < PLAYER_COUNT; ++i) {
						Players[i].Update(&hInput);
					}

					// Collision detection
					DetectCollisions();

					if(ControlChangeTimer.getElapsedTime() >= sf::seconds(CONTROL_CHANGE_DELAY)) {
						for(int i = 0; i < PLAYER_COUNT; ++i) {
							Players[i].ChangeControls(&hInput);
							ControlChangeTimer.restart();
						}
					}

					// Check win condition
					if(Players[0].dead) {
						winState = e_PLAYER_1_WIN;
						DeathTimer.restart();
					} else if(Players[1].dead) {
						winState = e_PLAYER_0_WIN;
						DeathTimer.restart();
					}
					break;
				}
			}
		case e_END:
			// ESCAPE - Close game
			if(hInput.isKeyPressed(e_KEYBOARD, sf::Keyboard::Escape)) {
				window->close();
			}

			// RETURN - Start game again
			if(hInput.isKeyPressed(e_KEYBOARD, sf::Keyboard::Return)) {
				Initialise();
			}
			break;
	}
}
Пример #9
0
void CollisionHandler::Update( double i_fFrameTime )
{
	DetectCollisions( i_fFrameTime );
}