Reputation:
I have a code with which I generate a pawn in OpenGL. However, I want to make its parts draggable. My question is more of a general one, but here's the code for my pawn so that you get an idea of what I'm doing:
int main()
{
/* open gl initialization */
while(running())
{
glClear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glColor3ub(0, 0, 0);
/* the basis of the pawn */
glPushMatrix();
glScalef(1.6, 1.6, 0.8);
glTranslatef(0.0, 0.0, -2.7 - offset);
drawSmoothUnityEllipsoidPatch(0, 2*M_PI, 0, M_PI /2 );
glPopMatrix();
/* upped ellipsoid */
glPushMatrix();
glScalef(0.8, 0.8, 0.15);
glTranslatef(0.0 - offset, 0.0, 6.0);
drawSmoothUnitySphere();
glPopMatrix();
/* lower ellipsoid */
glPushMatrix();
glScalef(1.2, 1.2, 0.15);
glTranslatef(0.0 - offset, 0.0, -10.0);
drawSmoothUnitySphere();
glPopMatrix();
/* the cone */
glPushMatrix();
glScalef(1.0, 1.0, 3.5);
glTranslatef(0.0 + offset, 0.0, -0.5);
drawSmoothUnityCone();
glPopMatrix();
/* the sphere on top of the pawn */
glPushMatrix();
glScalef(0.7, 0.7, 0.7);
glTranslatef(0.0, 0.0, 2.3 + offset);
drawSmoothUnitySphere();
glPopMatrix();
glfwTerminate();
return 0;
}
where offset is irrelevant. The functions drawSmoothUnity(shape) just draw a unity shape in the centre of the coordinate system. I want to te able to drag and drop any of these shapes in the visible area (800x600, my window-size).
Upvotes: 0
Views: 3653
Reputation: 789
You can use gluUnproject to map your cursor position from screen space into world space. By tracking the delta of the 3D world coordinates when the mouse button was first clicked to the current position (after dragging) this gives you the x,y&z values you should use to translate your object.
Also, it should be 'glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);'
This is kind of off the top of my head and is psuedocodish. This doesn't take into account any selection or any of that. So, clicking down and moving the mouse would move the object even if the object wasn't under the mouse cursor when you clicked. You'll obviously need to add mouse handlers.
glm::dvec3 original_position;//position of object when we start moving
glm::dvec3 world_anchor;//world space coordinates of where we left clicked
glm::ivec2 screen_anchor;//screen space coordinates of where we left clicked
Object object;
OnLButtonDown(int x, int y)//x,y = where we clicked
{
original_position = object.GetPosition();
screen_anchor = ivec2(x,y);//screen coords where we clicked
gluUnproject(x,y,0,modelview_matrix,projection_matrix,viewport,&world_anchor.x,
&world_anchor.y,&world_anchor.z);
}
OnMouseMove(int x, int y) //x,y = current mouse cursor position
{
if(left_button_down)
MoveObject(screen_anchor.x-x,screen_anchor.y-y);
}
}
MoveObject(int dx, int dy)//dx,dy = distance from current mouse position to screen_anchor
{
glm::dvec3 world_position;//current mouse position in world coordinates
gluUnProject(dx,dy,0,modelview_matrix,projection_matrix,viewport,&world_position.x,
&world_position.y,&world_position.z);
glm::dev3 world_delta = world_anchor-world_position;
object.SetPosition(original_position+world_delta);
}
Upvotes: 2