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; } }
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(); }
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); }
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 }
/// 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; }
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; } }
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; } }
void CollisionHandler::Update( double i_fFrameTime ) { DetectCollisions( i_fFrameTime ); }