WebGLでBox2Dを使用しています。Box2D は、一定のフレーム レート (「ワールド」更新のタイム ステップ) を要求します。
function update(time) {//update of box2d world
world.Step(
1/60 // 1 / frame-rate
, 3 //velocity iterations
, 8 //position iterations
);
しかし、以下のように定義された requestAnimFrame が正しい方法であることを読みました。
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 では一定のフレーム レートが得られないため、Box2D の変数が非同期になります。
これに対する修正はありますか?
[編集]
John (Cutch) のソリューションを実装すると、次のようになります。
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);
}
next_attribue
私の物理更新関数はs が設定されていることに注意してください。また、update
この前に物理演算が呼び出され、物理演算の世界を 1 フレーム先に進めます。
結果
アニメーションは非常にスムーズですが、非常に悪いジャンプとランダムに現れる微動が見られる場合を除きます。
このソリューションでは、次の問題が解決されていないと思いました。
----> 1) dt
より大きくなる可能性がありtime_step
ます : これによりdt/time_step
1 より大きくなり、補間式が台無しになります。
一貫しdt
てより大きいままである場合、問題が増加します。time_step
タイムギャップが よりも大きくなるという問題を克服することは可能time_step
ですか?
つまり、世界をレンダリングの 1 フレーム先に維持したとしても、時間のギャップが一貫して より大きいままであれば、time_step
その「先の」フレームを通過するのに長い時間はかからないでしょう。
----> 2) 1 ミリ秒dt
未満であると 想像してください。time_step
すると、世界は一度も更新されません。これで補間が行われ、おおよその位置が見つかりました (あるべき場所から 1 ミリ秒遅れています)。
次回は と の間dt
に違いが見られないとしましょうtime_step
。
dt
現在、とtime_step
が等しいことを考慮して、補間は行われません。では、次に描画されるのは、世界の「前方」フレームですよね?(これらの方程式を使用して、 でt = 1
)
しかし、正確には、レンダリングされた世界は、以前よりも 1 ミリ秒遅れているはずです。つまり、ワールド フレームから 1ms 遅れていたということは、消えてはならないということです。しかし、t = 1
では、物理ワールド フレームを描画し、その 1ms を忘れます。
私はコードまたは上記の2点について間違っていますか?
これらの問題を明確にしていただきたい。
[編集]
このWeb ページの作成者に、多くの図形を効率的に描画する方法をコメントで尋ねました。
私はこの方法でそれを行うことを学びました: 私は bufferData
呼び出しをcreateBuffer
節約bindBuffer
していbufferData
ます。
画面を更新するたびに、すべての形状を反復処理する必要があり、必要な形状のバッファーをバインドした後に呼び出す必要があります (を使用enableVertexAttribArray
) 。vertexAttribPointer
bindBuffer
私の形は時間とともに変化しません。最初から最後までさまざまな形 (多角形、円、三角形など) があります。