Advertisement

Opengl - How To Draw Transformation Gizmos ?

Started by August 04, 2016 03:51 PM
12 comments, last by Alian Vesuf 8 years, 3 months ago

Hi,

I'm developing 3D editor for my game using OpenGL.
The editor is developed using OpenTK and C# but the game is written in C++
This is what i have accomplished so far.


Capture2.png

My question is how to draw transformation gizmos to manipulate the objects in the scene.
Im referring to the Translate Scale and Rotate gizmos used in every 3d application.
I have implemented picking using Bullet Physics but i have no idea how to draw the handles.

Any tips, ideas, links would be appreciated.
Thank you !

A- Why in the heck you are using WinForms.

B- It's literally 3 lines that you can do with different colors. Set up a VBO with a line in it and redraw the VBO with different model matrix and colors according to each segment (Usually z-blue, y-green, x-red).

You can even use the basic glBegin and glEnd draw functions.

Advertisement

A - I'm very comfortable with C# and Winforms but I'm thinking of switching to Qt
B - Can you please add more details. I don't want to use immediate mode.

Its harder than you describe it

1. You click on a 3d scene. This involves casting rays checking for collisions and identifying the object by a pointer.
2. Highlight the object by enabling some uniforms.
3. Prepare gizmo VBO.
4. Draw the gizmo in the center of the object and in front of everything ( z buffer )
5. Cast rays for collisions with X, Y, Z handles of the gizmo and transform the object accordingly when dragging mouse.

And this is only for the translate gizmo.

Your items look like you've already got it figured out.

Your steps 1, 2, and 5 aren't necessary for rendering.

3. Prepare gismo VBO.

4. Draw the gismo at the object's origin with depth testing disabled, using the same orientation as the object or the world.

That's it.

The problems of hit tests and manipulating the scene objects are not concerns of OpenGL nor a concern of rendering.

The above is true - but maybe you are confused with how to do the mouse movement to 3d transformations for rotational and scaling movement?

Or were you strictly asking about drawing the gizmo?

Sometimes editors have gizmos scale with objects (and also perspective scale with objects) and sometimes the gizmos are always the same size. Judging by your progress it seems that this would not be a problem for you either way though.

3. Prepare gismo VBO. 4. Draw the gismo at the object's origin with depth testing disabled, using the same orientation as the object or the world.


This is what i have. Surprisingly the gizmo is centered at the last drawn objects origin if i don't update it's model matrix. The gizmo is an imported 3d model.

Capture3.png

@[member='EarthBanana'],

The above is true - but maybe you are confused with how to do the mouse movement to 3d transformations for rotational and scaling movement? Or were you strictly asking about drawing the gizmo?


For now i'm confused on how to draw the gizmos. Especially the rotation gizmo It has rings and indicators which visualize angles of the rotation.
The other problem is how to detect which circle is dragged and rotate the object accordingly.

dasdaa.png
Advertisement

Interacting with that thing (particularly the rotation one) is far from simple. I would have each part be a separate piece. You mentioned you have done picking so that's great, for your translation one all you have to do it when a user clicks down find out what they are clicking on. If it is the green arrow then remember the current mouse position and remember it's the green arrow. At this point you may want to transform that mouse position into world space (project it onto a plane that is parallel to the axis you selected, for green you might want to use green/red as vectors on that plane). Next when the user moves their mouse, project the new mouse position back onto the same plane. Work out the difference in whatever axis it was and move your object by that much. I foresee some weird behaviour possibly occurring depending on the plane you use, for the red/blue arrows I think it's safe to use red/blue plane but for the green if you used the green/blue plane (in that image) and dragged right horizontally then the thing would probably move down which isn't what you want. For that reason it might be an idea to use a plane that has a normal facing the user. I think you'd need to try it out or get some input off others for that.

If you want to move in a given plane (for example x/z) then you could put a little square in the corner between your arrows to click on. Use the same principle again by projecting onto the plane that the square lies on.

The rotation one is very similar, if the user clicks on the yellow circle you project their mouse onto that plane, you know the origin of the circle so given those you can work out the angle that the mouse is around it (you could use atan2). When the user drags you do the same, project the new position, work out the new angle and the difference between the two is how much to rotate your object.

Make collision meshes of sorts, the rotation one is then just a bunch of rings. I'd make them rings so they can only be interacted with first on the edges. You could ray cast to select things but since you have picking already I'd be tempted to use that.

I quite like this problem, wouldn't mind having a go at coding this one up myself :).

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

@[member='Nanoha'], Thank you for the tips.

I'm interested to know how the gizmos are drawn. Look at the rings of the rotation gizmo. It's like dotted lines.

I quite like this problem, wouldn't mind having a go at coding this one up myself

If you like the problem then code something, a library or a class and write an article about it since there is not much about this topic on the internet.
Everything i found was coded in deprecated OpenGL. I highly encourage you to write an article about it.

@[member='Nanoha'], Thank you for the tips.

I'm interested to know how the gizmos are drawn. Look at the rings of the rotation gizmo. It's like dotted lines.

I quite like this problem, wouldn't mind having a go at coding this one up myself

If you like the problem then code something, a library or a class and write an article about it since there is not much about this topic on the internet.
Everything i found was coded in deprecated OpenGL. I highly encourage you to write an article about it.

I haven't actually had to mess much with lines in OpenGL but you should be able to achieve dotted lines using a shader. You could make parts visible/invisible using the alpha when you draw it. I found this and a link to the tutorial here

If I had a personal reason to code up some gizmos I would. I think that would make for a good tutorial but I don't have any projects that would need this.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

If you want to make the entire ring of the rotational gizmo clickable/draggable then it might be tricky - but the screenshot seems to have small screen facing quads which would be used as handles - if thats the case then its just a matter of drawing the ring itself.

I use a simple geometry shader which takes a radius and draws the colored rings using line_strip as output and points as input - this in practice takes more than a single vert as input (draw the gizmo in pieces) to make look good because there is a max limit output for vertices a geometry shader will hit for a single input - this suffers from kind of looking weird sometimes cause of using gl line width to draw

You could theoretically use a triangle_strip output from a geometry shader to draw each ring - would take some fussing with to get right.

Edit: it looks like the screen shot you showed uses something like the method i mention with a geom shader except it uses points as the output instead of line_strip

This topic is closed to new replies.

Advertisement