6

javascript/jquery (キャンバスではなく DOM ベース) である種のドラッグ アンド ドロップ アプリを構築しています。

アイデアは、3D シーン (3D で回転した div) で div をドラッグできるようにすることです。

2D プランで動作します。問題は、シーンを 3D で回転させると、オブジェクトの位置が実際のマウスの位置を反映せず、座標が 3D に変換されることです。

図示例: 例

JSFIDDLE の例

マウスの絶対位置を基準にしてオブジェクトを移動させたい。

私はこのようにマウスの位置を計算します:

document.addEventListener(gestureMove, function (event) {
  if (mouseDown == true) {
  event.preventDefault();
  moveX = (event.pageX - $('#scene').offset().left);
  moveY = (event.pageY - $('#scene').offset().top);
}

#scene { 
  width: 1000px;
  height: 1000px;
  -webkit-transform-style: preserve-3d;
  -webkit-transform: rotateX( 35deg ); 
}

初期の解決策は、初期位置に基づいてマウスの位置とオブジェクトの差を計算し、ドラッグ中にオブジェクトの位置に加算することでした。動作していましたが、アニメーションは途切れ途切れで、まったくスムーズではありませんでした。

3D プランに対するマウス座標を取得するもっと簡単な方法があると確信していますが、現時点では実際の解決策を見つけることができませんでした。

この件に関する検索結果のほとんどは、ゲーム指向の言語、または canvas/webgl に関する質問を示しています。

何か案は ?

ありがとう

4

1 に答える 1

2

マウスの位置が画面の絶対位置であり、マウスの位置に直接基づいて 3D 平面上でオブジェクトをつかんでスライドさせたいとします。

3D ターゲット プレーンは次のように表すことができます。

  • 3D 原点O
  • U 軸と V 軸の方向を表す2 つの 3D ベクトルUV

次に、平面座標に対応する特定の 3D ポイント[u,v]は次のようになります。

point3d P = O + u*U + v*V

次に、この特定の 3D ポイントを画面にマップする操作を組み合わせることができます。これは通常、3D 変換行列ModelMatrixViewMatrix、およびProjectionMatrix、および 2D 画面の原点origin_2dと 2D スケーリング ベクトルによって決定されるビューポート変換で記述されますscale_2d。簡単に可逆な方法で問題を解決するには、.wそれぞれに - 座標を追加して、すべてを同次座標に昇格させます。この余分な座標はスケーリング ファクターとして機能します。デカルト座標を戻すには、同次の値.x.y値を値で割る必要があり.wます。

P_hom = [u, v, 1] * [U.x, U.y, U.z, 0] = [u, v, 1] * TexMatrix
                    [V.x, V.y, V.z, 0]
                    [O.x, O.y, O.z, 1]

P_clip_hom = P_hom * ModelMatrix * ViewMatrix * ProjectionMatrix
           = P_hom * ModelViewProjectionMatrix

screenpos_hom = P_clip_hom * [scale_2d.x     0        0] = P_clip_hom * PortMatrix
                             [   0        scale_2d.y  0]
                             [   0           0        0]
                             [origin_2d.x origin_2d.y 1]

So, screenpos_hom = [u, v, 1] * TexMatrix * ModelViewProjectionMatrix * PortMatrix
                  = [u, v, 1] * TexToScreenMatrix

-> [screenpos.x, screenpos.y] = [screenpos_hom.x, screenpos_hom.y] / screenpos_hom.w

TexToScreenMatrixは 3x3 行列であることに注意してください。あなたはそれを反転できるはずです:

UV_2d_hom = [screenpos.x, screenpos.y, 1] * (TexToScreenMatrix)^-1

-> [u, v] = [UV_2d_hom.x, UV_2d_hom.y] / UV_2d_hom.w

最後に、[u,v]座標を直接使用することも、上記のように座標を使用して 3D ポイントを再作成することもできますP

于 2012-09-19T22:40:55.203 に答える