¿Cuál es la forma correcta de actualizar una velocidad de cuadro de física?

He buscado en Internet y eventualmente leí un artículo sugerido, "¡Arregla tu Timestep!" . De acuerdo con el artículo, se me ocurrió un método de actualización, pero todavía tengo problemas. Cada vez que instanciar más objects, en mi escena, obtengo una interacción física mucho más lenta. He solucionado otros subsistemas, que estaban desperdiciando ciclos durante el process de actualización, y he rastreado la caída de mi performance físico hasta este punto. Creo que la forma en que estoy actualizando mi física es de alguna manera incorrecta, porque estoy usando un time fijo de 1.0 / 60.0 para mi motor Box2D.

¿Cuáles son los errores que estoy cometiendo en mi process de actualización? ¿Cuál es la forma correcta de actualizar una velocidad de cuadro de física? Aquí está mi código:

 void Core::Update() { // Input this->cInput->Update(); // Physics this->cPhysics->Update(); // Keep frame rate static const double desinetworkingTime = 1.0 / 60.0; static double currentTime = (double)(GetTickCount()); static double accumulator = 0.0; double newTime = (double)(GetTickCount()); double frameTime = newTime - currentTime; if(frameTime > 0.25){ frameTime = 0.25; } currentTime = newTime; accumulator += frameTime; while(accumulator >= desinetworkingTime) { // Input this->cInput->Update(); // Physics this->cPhysics->Update(desinetworkingTime); // Scripts this->cScripts->Update(); accumulator -= desinetworkingTime; } 

He leído que no debe vincular la velocidad de fotogtwigs de su física con la velocidad de fotogtwigs del renderizado, así que utilizo this->cPhysics->Update(); . He usado mi enfoque anterior, pero con un ligero cambio; No estoy seguro si lo que estoy haciendo es correcto, pero resolvió mi problema de performance. Primero, cambié currentTime para get el time en milisegundos, en lugar de segundos. Al final, he movido todo mi código de actualización a un ciclo de paso de time, a exception de la actualización de renderizadores. Todavía no sé si este es el path correcto a seguir.

El problema está aquí

  static double currentTime = (double)time(NULL); static double accumulator = 0.0; double newTime = (double)time(NULL); 

su actualTiempo y newTime son exactamente iguales de esa manera, esto no puede funcionar.

necesita medir el time que necesita para un cuadro (el último cuadro) y dormir el time restante hasta que scope la marca de 1.0 s / 60 s. No olvide que el sueño no duerme exactamente la cantidad de time que pasó, por lo que debe competir por eso.

Una forma opcional de get el time utilizado para los frameworks es usar un enfoque de window deslizante para todos los times de cuadro y sumr los times y dividir por el recuento.

Otro inconveniente importante es limitar el time delta que realmente midió (digamos a 0.2 segundos) para evitar inestabilidades.

Edite 1 código de ejemplo para ilustrarlo

 private double Time = 0.0; private double deltaTArray[10]; private unsigned int deltaTArrayI; // NOTE< this->currentTime must be set once before this is called > void Core::Update() { // Input this->cInput->Update(); double newTime = (double)time(NULL); double deltaT = newTime - this->currentTime; this->currentTime = newTime; deltaT = min(deltaT, 0.25); // because of stability this->deltaTArray[this->deltaTArrayI] = deltaT; (this->deltaTArrayI)++; this->deltaTArrayI = this->deltaTArrayI % 10; // calculate delta T as average of the sliding window double deltaTAverage = 0.0; for( unsigned int i = 0; i < 10; ++i ) { deltaTAverage += this->deltaTArray[i]; } deltaTAverage = deltaTAverage / (double)10; // Physics this->cPhysics->Update(deltaTAverage); // Keep frame rate sleep(max((1.0/60.0)-deltaTAverage, 0)); // Render this->cRender->Update(); }