ورود

View Full Version : سوال: مشکل با gluLookAt در sellect



mrbm_2007
پنج شنبه 05 خرداد 1390, 15:58 عصر
سلام
کد
private int[] GetSelected(int x, int y)
{
const int max = 512;
var Hit_Buffer = new int[max];
var viewport = new int[4];

Gl.glSelectBuffer(max, Hit_Buffer);
Gl.glRenderMode(Gl.GL_SELECT);

Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glPushMatrix();
Gl.glLoadIdentity();

Glu.gluLookAt(Distance * Math.Cos(beta) * Math.Cos(alpha)
, Distance * Math.Cos(beta) * Math.Sin(alpha)
, Distance * Math.Sin(beta)
, 0, 0, 0
, -Math.Sin(beta) * Math.Cos(alpha)
, -Math.Sin(beta) * Math.Sin(alpha)
, Math.Cos(beta));

Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport);
Glu.gluPickMatrix(x, viewport[3] - y, 1, 1, viewport);

Glu.gluPerspective(fovY, ogl1.Width / (double)(ogl1.Height != 0 ? ogl1.Height : 1), 0.1, 100.0);
Gl.glMatrixMode(Gl.GL_MODELVIEW);

Gl.glInitNames();
// render scene: a TRIANGLE
Gl.glPushName(1);
Gl.glBegin(Gl.GL_TRIANGLES);
Gl.glVertex3d(0, 0, 0);
Gl.glVertex3d(0, 1, 0);
Gl.glVertex3d(1, 0, 0);
Gl.glEnd();
Gl.glPopName();
//

Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glPopMatrix();
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glFlush();

var hits = Gl.glRenderMode(Gl.GL_RENDER);
Array.Resize(ref Hit_Buffer, hits);

return Hit_Buffer;
}

این تابع مختصات موس رو میگیره و تعیین میکنه که چه آبجکت هایی انتخاب شدند (hit).
من اینجا فقط یک مثلث ساده توی صفحه ی xy رسم کردم (به عنوان آبجکت 1)
این تابع به درستی کار میکنه ولی فقط اگر beta تقریبا بین -15 تا 15 درجه باشه و در غیر اینصورت کار نمیکنه!
در ضمن alpha زاویه دوربین حول محور z و alpha زاویه دید دوربین با صفحه ی xy هستند.
کجای کد مشکل داره؟

mrbm_2007
جمعه 06 خرداد 1390, 12:07 عصر
سلام مجدد
بالاخره خودم مشکل رو حل کردم!
این هم کد


private int[] GetSelected(int x, int y, bool debug)
{
var hits = 0; // number of hits

// Define select buffer
const int max = 512;
var Hit_buffer = new int[max];
Gl.glSelectBuffer(max, Hit_buffer);

var viewport = new int[4];
Gl.glViewport(0, 0, Width, (Height != 0 ? Height : 1));
Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport);

if (debug)// show real scene in debug mode
GlDraw();

if(!debug)
Gl.glRenderMode(Gl.GL_SELECT);

int s = debug ? 60 : 3; // test region size

Gl.glLoadIdentity();
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glPushMatrix();
Gl.glLoadIdentity();

Glu.gluPickMatrix(x, viewport[3] - y, s, s, viewport);

Glu.gluPerspective(fovY, Width / (double)(Height != 0 ? Height : 1), 0.1, 1000.0);
Gl.glMatrixMode(Gl.GL_MODELVIEW);

if (debug) // test region will be shown in left-bottom corner
Gl.glViewport(0, 0, s, s);

#region camera
Gl.glTranslated(Dx, Dy, 0);
var Distance = this.Distance;// *ogl1.Height / 60.0;
var CenterView = this.CenterView.Duplicate();
Glu.gluLookAt(Distance * Math.Cos(beta) * Math.Cos(alpha) + CenterView.x
, Distance * Math.Cos(beta) * Math.Sin(alpha) + CenterView.y
, Distance * Math.Sin(beta) + CenterView.z
, CenterView.x
, CenterView.y
, CenterView.z
, -Math.Sin(beta) * Math.Cos(alpha)
, -Math.Sin(beta) * Math.Sin(alpha)
, Math.Cos(beta));
#endregion

if (debug) // draw a bacground in left-bottom corner
{
ChangeColor(Color.Blue);
Glu.gluSphere(Glu.gluNewQuadric(), 50, 50, 50);
Gl.glBegin(Gl.GL_QUADS);
Gl.glVertex3d(-10, -10, -10);
Gl.glVertex3d(-10, 10, -10);
Gl.glVertex3d(10, 10, -10);
Gl.glVertex3d(10, -10, -10);
Gl.glEnd();
}

Gl.glInitNames();

// render scene
foreach (var b in Bodies)
{
Gl.glPushName(b.id);
var bb = b.Duplicate();
bb.color = Color.Red;
bb.Draw();
Gl.glPopName();
}
//

Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glPopMatrix();
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glFlush();

if (!debug)
hits = Gl.glRenderMode(Gl.GL_RENDER);

// process hits
int[] Res = { };
int startRecord = 0;
for (int i = 0; i < hits; i++)
{
for (int j = 0; j < Hit_buffer[startRecord]; j++)
{
Array.Resize(ref Res, Res.Length + 1);
Res[Res.Length - 1] = Hit_buffer[startRecord + 3 + j];
}
startRecord += 3 + Hit_buffer[startRecord];
}

return Res;
}در تابع بالا اگر پارامتر debug رو مساوی true قرار بدید، ناحیه انتخاب در گوشه ی چپ-پایین نشان داده می شود تا بصورت چشمی ببینید که چه آبجکت هایی در ناحیه قرار می گیرند!
چون ممکنه کد بالا یکم خسته کننده باشه قسمت های اصلی رو در زیر نوشتم :


// Define select buffer
const int max = 512;
var Hit_buffer = new int[max];
Gl.glSelectBuffer(max, Hit_buffer);

var viewport = new int[4];
Gl.glGetIntegerv(Gl.GL_VIEWPORT, viewport);

Gl.glRenderMode(Gl.GL_SELECT);

Gl.glLoadIdentity();
Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glPushMatrix();
Gl.glLoadIdentity();

Glu.gluPickMatrix(x, viewport[3] - y, 3, 3, viewport);

Glu.gluPerspective(fovY, Width / (double)(Height != 0 ? Height : 1), 0.1, 1000.0);
Gl.glMatrixMode(Gl.GL_MODELVIEW);

Gl.glInitNames();

// set camera (gluLookAt, ...) & draw scene

Gl.glMatrixMode(Gl.GL_PROJECTION);
Gl.glPopMatrix();
Gl.glMatrixMode(Gl.GL_MODELVIEW);
Gl.glFlush();

var hits = Gl.glRenderMode(Gl.GL_RENDER);

// process hits