1

ユーザーが地球上のどこをクリックしたかを判断できます。

ユーザーが最初にマウスボタンを押したとき、クリックした場所を保存できます。それをと呼びましょうpin

次に、マウスをドラッグしながらpin、マウスカーソルの下に置きます。

ここに画像の説明を入力してください

これは、マウスポインターの下を大まかに維持しているように見えるがpin、地球儀を正しく維持していないコードです。ちらつき、ランダムに回転します。時々それは軸を完全にひっくり返すので、地球は瞬間的に後ろから前になります。

function evtPos(evt) {
    if(!scene.ortho) return null;
    var x = lerp(scene.ortho[0],scene.ortho[1],evt.clientX/canvas.width),
        y = lerp(scene.ortho[3],scene.ortho[2],evt.clientY/canvas.height), // flipped
        sqrd = x*x+y*y;
    return (sqrd > 1)?
        null:
        mat4_vec3_multiply(mat4_inverse(scene.mvMatrix),[x,y,Math.sqrt(1-sqrd)]);
}

function onMouseDown(evt) {
    pin = evtPos(evt);
}

function onMouseMove(evt,keys,isMouseDown) {
    if(!isMouseDown) return;
    var pt = evtPos(evt);
    if(pin == null) pin = pt;
    if(pt == null) return;
    var d = vec3_sub(pt,pin),
        rotx = Math.atan2(d[1],d[2]),
        roty = (d[2] >= 0)?
            -Math.atan2(d[0] * Math.cos(rotx),d[2]):
            Math.atan2(d[0] * Math.cos(rotx),-d[2]),
        rotz = Math.atan2(Math.cos(rotx),Math.sin(rotx)*Math.sin(roty));
    scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(rotx,[1,0,0]));
    scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(roty,[0,1,0]));
    scene.mvMatrix = mat4_multiply(scene.mvMatrix,mat4_rotation(rotz,[0,0,1]));
}

function onMouseUp(evt) {
    pin = null;
}

pinまた、時間の経過とともに、エラーが発生し、マウスポインタからさらに離れていくように見えます。mvMatrixイベントごとにたくさんのsamll増分ではなく、どういうわけか完全に計算する必要があると思いますか?

ユーザーが地球儀をドラッグして自然にナビゲートできるようにしたいと思います。私が見つけた地球儀を回転させるすべてのコードは、マウスポインターの下で地球儀を「固定」するのではなく、矢印キーなどの固定速度を使用します。UnityにはQuaternion.FromToRotation(fromPos,toPos)非常に有望な機能がありますが、ソースは利用できません。

4

1 に答える 1

1

これを行うためのアプローチの1つは、arcBallアルゴリズムです。JavaScriptの実装も利用できるので、自分で実装する必要はありません。

于 2013-02-20T15:56:27.040 に答える