2009-05-06 14 views
3

私は単純なソリッドモデリングアプリケーションを構築しています。ユーザーは、直交ビューと透視ビューの両方でオブジェクトを操作できる必要があります。たとえば、画面にボックスがあり、ユーザーがそれを選択するためにクリックすると、コーナーとセンターで「ハンドル」を取得して、そのハンドルの上にマウスを移動してドラッグする必要がありますボックスを拡大または移動します。3Dビューで操作ハンドルを実装する方法

これを実行するにはどのような戦略があり、どちらが最適ですか?私は2つの明白なものを考えることができます:

1)ハンドルを3Dオブジェクトとして扱います。私。ボックスの場合、「メイン」ボックスのコーナーにある小さなボックスをシーンに追加します。問題:これはパースビューでは機能しません。現在のズームレベルに相対的なボックスのサイズを決定する必要があります(ユーザーがズームイン/ズームアウトしても、ハンドルのサイズは同じでなければなりません)

2)シーンがレンダリングされた後にハンドルを追加します。オフスクリーンバッファーにレンダリングし、何らかの形でコーナーの2dの位置を決定し、ハンドルを描くために通常の2D描画技法を使用します。問題:私はどのようにヒットテストをしますか?私も、2段階のヒットテストのアプローチを行う必要があります。 3Dレンダリングされた画像で2dをどのように描画するのですか? GDIに戻りますか?

おそらく、両方のアプローチでより多くの問題があります。この問題に取り組む業界標準の方法はありますか?

私はOpenGLを使用しています。

答えて

2

私はハンドルを3Dオブジェクトとして扱います。ヒットテストは簡単です。

ハンドルを一定のサイズにしたい場合でも、それらを3Dオブジェクトとして扱うことはできますが、スケーリングする必要がありますそれらのサイズは、カメラとの距離に基づいて適宜設定します。これはちょっと面倒ですが、通常はハンドルがほんのわずかなので、通常は小さなオブジェクトなので、パフォーマンスは上手くいくはずです。

しかし、私は実際には、シーンと一緒にハンドルの大きさを調整すると言います。それらを目立たせるハンドルのレンダリングスタイル(明るいオレンジ色のボックスなど)を選択する限り、パースペクティブエフェクト(バックグラウンドの小さなハンドル)は実際にエンドユーザーにとってさまざまな方法でより簡単に作業します。 3Dシーンから奥行き感を得るのは難しい - ハンドルの視点の効果は、ハンドルが画面内のどのように「深い」かをより視覚的に把握するのに役立ちます。

+0

視覚的な手掛かりを追加する観点についてのポイントを参照してください。私はまだこれがユーザーにとって自然に感じられるとは確信していません。例えば、他のオブジェクトによってクリップされるハンドルはどうでしょうか?私は他の3Dモデラーを調べて、どのようにそれを行い、両方のアプローチをテストアプリケーションで試してみます。答える時間をとってくれてありがとう。 – Roel

+0

1つの選択肢は、パースペクティブを維持することですが、深度テストをオフにしてパースペクティブをレンダリングします。それらは常に表示されます(他のオブジェクトの上でも)。私はそれをデフォルトの方法にしませんが、それは素晴らしいオプションです。したがって、ハンドルを常に表示するかどうかを切り替えることができます。 –

+0

深度バッファでどのように動作するかを調べる必要がありますが、それはうまくいくと思います。私は私の前に多くの試行錯誤があります:)ありがとう。 – Roel

1

まずオフ、ハンドル/角がカメラの平面上の位置座標プロジェクト(有効2Dに変換すると、画面上の座標;画面サイズに対して、これを正規化)

ここ/直交有効にするためにいくつかの簡単なコードです2D-オーバーレイ描画:

void enable2D() 
{ 

    glMatrixMode(GL_PROJECTION); 
    glPushMatrix(); 
    glLoadIdentity(); 
    int wind[4]; 
    glGetIntegerv(GL_VIEWPORT,wind); 
    glOrtho(0,wind[2],0,wind[3],-1,1); 
    glMatrixMode(GL_MODELVIEW); 
    glPushMatrix(); 
    glLoadIdentity(); 
} 


void disable2D() 
{ 
    glMatrixMode(GL_PROJECTION); 
    glPopMatrix(); 
    glMatrixMode(GL_MODELVIEW); 
    glPopMatrix(); 
} 

enable2D()は、現在のモデルビュー/投影行列をキャッシュし、画面に正規化されたものと射影行列を置き換える(すなわち、画面の横幅/高さ)とモデルビューのための単位行列を復元します。

この呼び出しを行った後、画面/ピクセル座標を使用してglVertex2f()呼び出しを作成し、2Dで描画することができます。 (マウスの現在のピクセル座標を簡単に取得できるので、ヒットテストも可能です。)

完了したら、古いモデルビュー/投影行列を復元するためにdisable2Dを呼び出す:)

最も難しい部分はhitboxesは、2次元平面上に落ちるところコンピューティングとに2つのプロジェクト場合(オーバーレイを扱っていますこれは:)

+0

これは、コード内の他の多くの場所で使用できる非常に便利なテクニックのようです。私はまだOpenGLを初めて使っているので、私はまだロープを学んでいます。このようなヒントやトリックは来るのがかなり難しいようです。ありがとうございました! – Roel

+0

喜んでXD – ParoXoN

1

を助けたクリックで選択し、同じ場所、?)

希望私は、3D編集パッケージのハンドルでマニピュレータをコード化し、これらの同じ問題の多くに走ってきました。

まず、オープンソースマニピュレータがあります。最近の検索では見つからなかったでしょう.3Dウィジェット、ギザモ、マニピュレータ、ジンバルなど、これらの名前の数が多すぎるからです。

どうも私はマニピュレータを追加するしかありませんでした描画されると、すべてのハンドルを描画するシーンにオブジェクトを配置します。バウンディングボックスの計算と選択についても同じことが行われます。

Reedのアイデアは、同じサイズにしておくことは、オブジェクトに存在するハンドルでは面白く、そこでは動作する可能性があります。マニピュレータの場合、3D UI要素のほうが多く、大きさが変わっていなければ、はるかに使い易いことがわかりました。私はサイズがアクティブなビューポートに基づいてのみ決定されたバグがありました。これは、他のビューポートには恐ろしい巨大な/小さなマニピュレータをもたらし、非常に役に立たないものでした。シーンに追加する場合は、ビューポートごとに追加するか、または実際に固定サイズにすることができます。

+0

あなたの「マニピュレータ」は何を説明できますか?それは私の質問で説明した 'ハンドル'とは異なるようですね。 – Roel

+0

確かに、マニピュレータは、ジオメトリを変換するためのハンドルを提供する小さなものです。これは、通常、オブジェクト、バーテッジ、エッジ、フェイス、またはその他のコンポーネントです。 次はMayaのマニピュレータのイメージです。http:// www。imanishi.com/mayablog/mayaPolygon/pC1.jpg – tfinniga

関連する問題