Note that there are some explanatory texts on larger screens.

plurals
  1. POOpenGL ES (iPhone) Touch Picking
    text
    copied!<p>Looking to do classic OpenGL mouse picking in ES. I'd prefer not to use third party libs, GLU ports and OpenGL name stacks, etc, are out. This pretty much leaves inverse view transformation and ray intersection, correct?</p> <p>I've gotten pretty far with the help of: <a href="http://trac.bookofhook.com/bookofhook/trac.cgi/wiki/MousePicking" rel="noreferrer">http://trac.bookofhook.com/bookofhook/trac.cgi/wiki/MousePicking</a> <a href="http://eigenclass.blogspot.com/2008/10/opengl-es-picking-using-ray-boundingbox.html" rel="noreferrer">http://eigenclass.blogspot.com/2008/10/opengl-es-picking-using-ray-boundingbox.html</a></p> <p>. . .but I'm not there yet. This also reeks of THERE MUST BE AN EASIER WAY!!</p> <p>Here is some code:</p> <pre><code> -(void)handleTouch:(CGPoint)point { GLfloat width = backingWidth; GLfloat height = backingHeight; GLfloat x = point.x; GLfloat y = point.y; GLfloat z = 0.0f; //viewport -&gt; normalized dev coord -&gt; clip GLfloat n[] = { 2 * x / width - 1, 2 * y / height, 2 * z - 1, 1 }; float fov = 45.0f * (M_PI / 180.0f); float near = 0.01, far = 10.0f; float aspect = (float)backingWidth / (float)backingHeight; float top = tan(fov) * near; //float bottom = -top; //float left = aspect * bottom; float right = aspect * top; //I'm a viewing volume symmetric projection matrix GLfloat P[] = { near / right, 0, 0, 0, 0, near / top, 0, 0, 0, 0, -(far + near) / (far - near), (-2 * far * near) / (far - near), 0, 0, -1, 0 }; GLfloat Pminus1[] = { 1/P[0], 0, 0, 0, 0, 1/P[5], 0, 0, 0, 0, 0, 1/P[14], 0, 0, 1/P[11], -(P[10]/ (P[11]*P[14])) }; //clip -&gt; view GLfloat v[] = { Pminus1[0] * n[0] + Pminus1[1] * n[1] + Pminus1[2] * n[2] + Pminus1[3] * n[3], Pminus1[4] * n[0] + Pminus1[5] * n[1] + Pminus1[6] * n[2] + Pminus1[7] * n[3], Pminus1[8] * n[0] + Pminus1[9] * n[1] + Pminus1[10] * n[2] + Pminus1[11] * n[3], Pminus1[12] * n[0] + Pminus1[13] * n[1] + Pminus1[14] * n[2] + Pminus1[15] * n[3] }; //view -&gt; world GLfloat Rt[] = { mv[0], mv[4], mv[8], mv[1], mv[5], mv[9], mv[2], mv[6], mv[10] }; GLfloat tPrime[] = { Rt[0] * mv[3] + Rt[1] * mv[7] + Rt[2] * mv[11], Rt[3] * mv[3] + Rt[4] * mv[7] + Rt[5] * mv[11], Rt[6] * mv[3] + Rt[7] * mv[7] + Rt[8] * mv[11] }; GLfloat Mminus1[] = { Rt[0], Rt[1], Rt[2], -(tPrime[0]), Rt[3], Rt[4], Rt[5], -(tPrime[1]), Rt[6], Rt[7], Rt[8], -(tPrime[2]), 0, 0, 0, 1 }; //point in world space GLfloat w[] = { Mminus1[0] * v[0] + Mminus1[1] * v[1] + Mminus1[2] * v[2] + Mminus1[3] * v[3], Mminus1[4] * v[0] + Mminus1[5] * v[1] + Mminus1[6] * v[2] + Mminus1[7] * v[3], Mminus1[8] * v[0] + Mminus1[9] * v[1] + Mminus1[10] * v[2] + Mminus1[11] * v[3], Mminus1[12] * v[0] + Mminus1[13] * v[1] + Mminus1[14] * v[2] + Mminus1[15] * v[3] }; //r = a + t(w - a) GLfloat a[] = {0.0f, -0.1f, 0.0f}; GLfloat wminusa[] = {w[0] - a[0], w[1] - a[1], w[2] - a[2]}; vector[0] = a[0]; vector[1] = a[1], vector[2] = a[2]; vector[3] = w[0]; vector[4] = w[1]; vector[5] = -10.0f; //3 non-colinear points on the plane GLfloat p1[] = {rect.origin.x, rect.origin.y, 0}; GLfloat p2[] = {rect.origin.x + rect.size.width, rect.origin.y, 0}; GLfloat p3[] = {rect.origin.x + rect.size.width, rect.origin.y + rect.size.height, 0}; //location plane normal vector, Ax + By + Cz + D = 0 GLfloat lp[] = { p1[1] * (p2[2] - p3[2]) + p2[1] * (p3[2] - p1[2]) + p3[1] * (p1[2] - p2[2]), p1[2] * (p2[0] - p3[0]) + p2[2] * (p3[0] - p1[0]) + p3[2] * (p1[0] - p2[0]), p1[0] * (p2[1] - p3[1]) + p2[0] * (p3[1] - p1[1]) + p3[0] * (p1[1] - p2[1]), -(p1[0] * (((p2[1] * p3[2]) - (p3[1] * p2[2]))) + p2[0] * (((p3[1] * p1[2]) - (p1[1] * p3[2]))) + p3[0] * (((p1[1] * p2[2]) - (p2[1] * p1[2])))) }; GLfloat PnRd = (lp[0] * wminusa[0]) + (lp[1] * wminusa[1]) + (lp[2] * wminusa[2]); if(PnRd != 0) { GLfloat PnR0D = -((lp[0] * a[0]) + (lp[1] * a[1]) + (lp[2] * a[2]) + lp[3]); if(PnR0D != 0) { GLfloat t = PnR0D / PnRd; if(t &gt;= 0) { GLfloat p[] = { a[0] + wminusa[0] * t, a[1] + wminusa[1] * t, a[2] + wminusa[2] * t }; if(p[0] &gt; rect.origin.x &amp;&amp; p[0] &lt; rect.origin.x + rect.size.width &amp;&amp; p[1] &gt; rect.origin.y &amp;&amp; p[1] &lt; rect.origin.y + rect.size.height) NSLog(@"BOOM!!!"); } } } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload