0

3Dシーンが表示されるAndroidアプリケーションで作業しており、ユーザーは画面をクリック/タップすることで領域を選択できるはずです。シーンは、さまざまなオブジェクトが配置された平面(ゲーム)ボードです。
さて、問題は、実際の画面空間座標からボード上のクリックされた領域をどのように取得するかです。

gluUnProject()(ほぼ)必要なすべてのパラメーターにアクセスできるので、を使用することを計画していました。残念ながら、winZパラメータが欠落しており、タッチイベントがGLスレッドとは異なるスレッドで発生しているため、現在の深度を取得できません。
私の新しい計画は、引き続きgluUnProjectを使用することですが、winZ0を使用して、結果のポイントをボードに投影します(ボードはモデル空間でから0,0,0に伸び10,0,10ます)。しかし、これを行う方法がわからないようです。

誰かがこれを行うために必要な数学を手伝ってくれるか(行列は私の最強の側面ではありませんでした)、またはおそらくより良い解決策を見つけることができれば、私は非常に幸せです。

明確にするために; これが私がやりたいことの画像です 画像
。赤い長方形はデバイス画面を表し、緑のxはタッチイベントを表し、黒い正方形はボードを表します(灰色の細分は1ユニットの正方形を表します)。ボード上のどこでタッチが発生したかを把握する必要があります(この場合は正方形1,1にあります)。

4

2 に答える 2

1

基本的にすでに2Dで作業しているので(3Dボードは0,0,0から10,10,0(x、y、z)まで伸びていると思います)、2D/3Dを変換および補間/外挿することができますgluUnProject()を使用しない画面空間座標からの空間座標。画面の解像度が必要になり、変換する3Dスペースグリッドの解像度を選択する必要があります。画面と3D空間の原点の両方が位置合わせされ(0,0画面空間が0,0,0 3D空間にある)、既存の10x10 3Dグリッドを使用して画面サイズが320x240の場合、320/10 = 32、および240 / 10 = 24であるため、1つの1x1領域の画面スペースサイズは32x24です。したがって、ユーザーが162、40を押すと、ユーザーは3D空間で(5、1、0)(162/32> = 5、<6、40 / 24> = 1、<2)内を押しています。これよりも高い解像度が必要な場合は、より高い3D空間グリッド解像度を選択できます(つまり、10ではなく20を使用します)。この係数を使用するためにGLマトリックスを更新する必要はありません。いくつかの点で簡単になるかもしれませんが、モデリングの観点からは、追加の作業が必要になると確信しています。20、1、3のような係数は(.5、1.5、0)になることに注意してください。画面と3D空間の原点がまだ位置合わせされていない場合は、これより前に画面空間の座標を変換する必要があります。0,0の画面スペースが10,10,0の場合、画面の解像度を取得し、そこから現在のポイントを差し引く必要があります。この例では、0,0を320、240に、この例では162、40のポイントになります。 158(320-158 == 162)、200(240-200 == 40)になります。いくつかの点で簡単になるかもしれませんが、モデリングの観点からは、追加の作業が必要になると確信しています。20、1、3のような係数は(.5、1.5、0)になることに注意してください。画面と3D空間の原点がまだ位置合わせされていない場合は、これより前に画面空間の座標を変換する必要があります。0,0の画面スペースが10,10,0の場合、画面の解像度を取得し、そこから現在のポイントを差し引く必要があります。この例では、0,0を320、240に、この例では162、40のポイントになります。 158(320-158 == 162)、200(240-200 == 40)になります。いくつかの点で簡単になるかもしれませんが、モデリングの観点からは、追加の作業が必要になると確信しています。20、1、3のような係数は(.5、1.5、0)になることに注意してください。画面と3D空間の原点がまだ位置合わせされていない場合は、これより前に画面空間の座標を変換する必要があります。0,0の画面スペースが10,10,0の場合、画面の解像度を取得し、そこから現在のポイントを差し引く必要があります。この例では、0,0を320、240に、この例では162、40のポイントになります。 158(320-158 == 162)、200(240-200 == 40)になります。

投影マトリックスの概要とそのすべてがどのように機能するかを知りたい場合は、非投影マトリックスのどこに画面スペースの寸法を配置するかを理解するのに役立ちます。OpenGLレッドブックのこの章をお読みください。http://www.glprogramming.com/red/chapter03.html

これがお役に立てば幸いです。

于 2012-04-03T20:32:46.367 に答える
0

それで、私は次のことを行うことによってこれを解決することができました:

float[] clipPoint = new float[4];
int[] viewport = new int[]{0, 0, width, height};

//screenY/screenX are the screen-coordinates, y should be flipped:
screenY = viewport[3] - screenY;

//Calculate a z-value appropriate for the far clip:
float dist = 1.0f;
float z = (1.0f/clip[0] - 1.0f/dist)/(1.0f/clip[0]-1.0f/clip[1]);

//Use gluUnProject to create a 3d point in the far clip plane:
GLU.gluUnProject(screenX, screenY, z, vMatrix, 0, pMatrix, 0, viewport, 0, clipPoint, 0);

//Get a point representing the 'camera':
float eyeX = lookat[0] + eyeOffset[0]; 
float eyeY = lookat[1] + eyeOffset[1];
float eyeZ = lookat[2] + eyeOffset[2];

//Do some magic to calculate where the line between clipPoint and eye/camera would intersect the y-plane:
float dX = eyeX - clipPoint[0];
float dY = eyeY - clipPoint[1];
float dZ = eyeZ - clipPoint[2];

float resX = glu[0] - (dX/dY)*glu[1];
float resZ = glu[2] - (dZ/dY)*glu[1];
//resX and resZ is the wanted result.
于 2012-04-04T21:31:52.663 に答える