Uso Box2D con WebGL. Box2D richiede una frequenza fotogrammi costante (i passaggi temporali per i suoi aggiornamenti "mondiali").requestAnimFrame non può fornire una frequenza fotogrammi costante, ma il mio motore fisico ne ha bisogno
function update(time) {//update of box2d world
world.Step(
1/60 // 1/frame-rate
, 3 //velocity iterations
, 8 //position iterations
);
Ma ho letto che requestAnimFrame definito come sotto è la strada giusta da percorrere.
requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {
window.setTimeout(callback, 1000/60);
};
})();
requestAnimFrame non mi dà un frame rate costante e quindi le variabili di mio Box2D stanno andando non sincronizzato.
C'è una soluzione a questo?
Giovanni (Cotch) soluzione [EDIT] quando sembra implementate come questo:
function interpolate(dt) {
var t = dt/time_step;
body_coordinates = (1-t) * body_coordinates + t * next_body_coordinates;
}
var physicsDt = 0;
function tick() {
var time_now = new Date().getTime();
var dt = time_now - last_time; //Note that last_time is initialized priorly
last_time = time_now;
physicsDt += dt;
clear_the_screen();
requestAnimFrame(tick);
drawEverything();
if(physicsDt >= time_step) {
update();
physicsDt -= time_step;
}
interpolate(dt);
}
Nota che la mia funzione di aggiornamento di fisica si prende cura che siano impostati i next_attribue
s. E inoltre, una fisica update
è chiamato prima di questo, per mantenere il mondo della fisica avanti di 1 fotogramma.
Il risultato
l'animazione è abbastanza liscia, tranne che per quei tempi, quando riesco a vedere alcuni salti davvero male e casuale apparire micro-movimenti.
ho pensato che i seguenti problemi non sono stati affrontati nella soluzione:
----> 1)dt
può diventare più grande di time_step
: Questo renderebbe dt/time_step
maggiore di 1, che rovinerebbe le equazioni di interpolazione.
Quando dt
rimane più grande di time_step
in modo coerente, i problemi aumenterebbero. E 'possibile superare il problema del divario temporale che diventa più grande di time_step
?
Voglio dire, anche se teniamo il mondo un fotogramma prima del rendering, se intervalli di tempo sempre maggiore di rimanere time_step
, non ci sarebbe voluto molto passare che "avanti" frame.
----> 2) Imagine dt
essendo minore time_step
da 1 ms. Quindi, il mondo non viene aggiornato una volta. Ora l'interpolazione viene eseguita e viene trovata la posizione approssimativa (1 ms dietro dove avrebbe dovuto essere).
Diciamo che la prossima volta non si vedrà alcuna differenza tra dt
e time_step
.
Ora, nessuna interpolazione viene eseguita considerando che dt
e time_step
sono uguali. Quindi, la prossima che viene disegnata è la "prima" frame nel mondo, giusto? (Utilizzando quelle equazioni, con t = 1
)
Ma con precisione, il mondo reso dovrebbe essere che 1ms dietro la quale era prima. Voglio dire, che 1ms con cui era dietro la cornice del mondo non dovrebbe svanire. Ma con t = 1
, disegna la cornice del mondo fisico e dimentica quel millesimo.
Mi sbaglio sul codice o sui 2 punti precedenti?
Vi chiedo di chiarire questi problemi.
[EDIT]
ho chiesto l'autore di this pagina web, di un modo di disegnare in modo efficiente molte forme, nei commenti there.
ho imparato a fare in questo modo: sto risparmiando bufferData
chiamate mantenendo buffer separati per ogni forma e chiamando createBuffer
, bindBuffer
, bufferData
solo una volta durante init.
Ogni rinfresco la schermata, devo iterare su tutte le forme e devo chiamare enableVertexAttribArray
e vertexAttribPointer
dopo tampone di legame della forma desiderata (usando bindBuffer
).
Le mie forme non cambiano nel tempo. Ce ne sono solo una varietà (come poligoni, cerchi, triangoli) che rimangono dall'inizio alla fine.
Non sono sicuro di come quel codice disaccoppia la simulazione fisica. Quindi, 'frameCallBack' è la funzione di" aggiornamento "? Ci vuole differenza nel tempo dell'ultima chiamata e la chiamata corrente come argomento, e solo dopo che il frame della fisica corrente è durato per 32 millisecondi, aggiorna il mondo. Ho ragione? – batman
Ma cosa succede se l'aggiornamento del mondo e l'aggiornamento dello schermo devono avvenire dopo intervalli di tempo comparabili? Diciamo che il mio mondo della fisica aspetta 60 ms prima di un aggiornamento. L'aggiornamento della prima schermata avviene a 59 ms. Il mondo della fisica non si aggiornerà poiché non sono passati 60 ms dall'ultimo aggiornamento. La schermata successiva si aggiorna? dopo altri 59 ms. Ora aggiornamenti sul mondo della fisica. Ma quando dovrebbe essere aggiornato dopo 60 ms, ora avviene dopo 118 ms. Non è molto impreciso? – batman
Oh e non capisco quel secondo frammento che hai inserito.Puoi spiegare per favore? – batman