iphone - Translate 3d object center coordinates to 2d visible viewport coordinates -
i have loaded wavefront object in iphone opengl.

it can rotated around x/y axis, panned around, zoomed in/out.
my task - when object tapped, highlight it's 2d center coordinates on screen example this: (imagine + in center of visible object.) 
when loading opengl object store it's:
- object center position in world,
- x,y,z position offset,
- x,y,z rotation,
- zoom scale.
when user taps on screen, can distinguish object tapped. - user can tap anywhere on object - tapped point not center.
when user touches object, want able find out corresponding object visible approximate center coordinates.
how can that?
most code in google find meant - translate 3d coordinates 2d without rotation.
some variables in code:
vertex3d centerposition; vertex3d currentposition; rotation3d currentrotation; //centerposition.x, centerposition.y, centerposition.z //currentposition.x, currentposition.y, currentposition.z //currentrotation.x, currentrotation.y, currentrotation.z thank in advance.
(to find out object tapped - re-color each object in different color, know color user tapped.)
object drawself function:
// save current transformation pushing on stack glpushmatrix(); // load identity matrix restore origin glloadidentity(); // translate current position gltranslatef(currentposition.x, currentposition.y, currentposition.z); // rotate current rotation glrotatef(currentrotation.x, 1.0, 0.0, 0.0); glrotatef(currentrotation.y, 0.0, 1.0, 0.0); glrotatef(currentrotation.z, 0.0, 0.0, 1.0); // enable , load vertex array glenableclientstate(gl_vertex_array); glenableclientstate(gl_normal_array); glvertexpointer(3, gl_float, 0, vertices); glnormalpointer(gl_float, 0, vertexnormals); // loop through each group if (texturecoords != null) { glenableclientstate(gl_texture_coord_array); gltexcoordpointer(valuespercoord, gl_float, 0, texturecoords); } (openglwavefrontgroup *group in groups) { if (texturecoords != null && group.material.texture != nil) [group.material.texture bind]; // set color , materials based on group's material color3d ambient = group.material.ambient; glmaterialfv(gl_front_and_back, gl_ambient, (const glfloat *)&ambient); color3d diffuse = group.material.diffuse; glcolor4f(diffuse.red, diffuse.green, diffuse.blue, diffuse.alpha); glmaterialfv(gl_front_and_back, gl_diffuse, (const glfloat *)&diffuse); color3d specular = group.material.specular; glmaterialfv(gl_front_and_back, gl_specular, (const glfloat *)&specular); glmaterialf(gl_front_and_back, gl_shininess, group.material.shininess); gldrawelements(gl_triangles, 3*group.numberoffaces, gl_unsigned_short, &(group.faces[0])); } if (texturecoords != null) gldisableclientstate(gl_texture_coord_array); gldisableclientstate(gl_vertex_array); gldisableclientstate(gl_normal_array); // restore current transformation popping off glpopmatrix();
ok, said, you'll need apply same transformations object center applied object's vertices graphics pipeline; time, graphics pipeline won't - you'll have yourself. , involves matrix calculations, i'd suggest getting maths library the opengl maths library, has advatage function names etc. extremly similar opengl.
step 1: transform center form object coordinates modelview coordinates
in code, set 4x4 modelview matrix this:
// load identity matrix restore origin glloadidentity(); // translate current position gltranslatef(currentposition.x, currentposition.y, currentposition.z); // rotate current rotation glrotatef(currentrotation.x, 1.0, 0.0, 0.0); glrotatef(currentrotation.y, 0.0, 1.0, 0.0); glrotatef(currentrotation.z, 0.0, 0.0, 1.0); you need multiply matrix object center, , opengl not that, since it's not maths library itself. if use glm, there functions rotate(), translate() etc function similiar glrotatef() & gltranslatef(), , can use them build modelview matrix. also, since matrix 4x4, you'll have append 1.f 4th component object center ( called 'w-component' ), otherwise can't multiply 4x4 matrix.
alternatively, query current value of th modelview matrix directly opengl:
glfloat matrix[16]; glgetfloatv (gl_modelview_matrix, matrix); but you'll have write own code multiplication...
step 2: go modelview coordinates clip coordinates
from posted, can't tell whether ever change projection matrix ( there glmatrixmode( gl_projection ) somewhere? ) - if never touch projection matrix, can omit step; otherwise you'll need multiply transformed object center projection matrix well.
step 3: perspective division
divide 4 components of object center 4th - throw away 4th component, keeping xyz. if omitted step 2, can omit division.
step 4: map object center coordinates window coordinates
the object center defined in normalized device coordinates, x&y components in range [-1.f, 1.f]. last step mapping them viewport, i.e. pixel positions. z-component not matter anyway, let's ignore z , call x & y component obj_x , obj_y, respectively.
the viewport dimensions should set somewhere in code glviewport( viewport_x, viewport_y, width, height ). function arguments, can calculate pixel position center this:
pixel_x = width/2 * obj_x + viewport_x + width/2; pixel_y = height/2 * obj_y + viewport_y + height/2; and that's it.
Comments
Post a Comment