How to draw a 3D mesh in screen-space?

Hi all,

I want to draw a 3D gizmo in screen-space, in front of everything else.

The View::draw2d method seems like a good candidate to achieve just that but the documentation states that “the Z value is not used”. So from what I understand (and also, its name), it’s for drawing 2D shapes only.

Another possibility would be to draw our mesh in world-space with View::draw() while always keeping it in the same relative position with respect to the viewport’s camera, but we would surely encounter issues related to clipping planes/intersection with the actual model.

Yet another possibility would be to “manually” transform our mesh geometry to camera-space and then use the draw2d method but I guess that we’ll encounter ordering/depth issues between the mesh faces since the Z coordinates is ignored, right?

So is there a proper way to draw 3D primitives in screen-space with the Ruby API?

Thanks :slight_smile:

“Screen space” is two dimensional. Locations are described with x, y screen coordinates.

Several methods that deal with 2D coordinates in the API use Geom::Point3d arguments, even though they could have just taken 2 element arrays of integer values.
I agree it is weird, especially because this method came after the implementation of the Geom::Point2d class.

Yes with the View#draw method … you are still drawing in the view space and not the model space (ie, the objects are not model geometry.)

However, currently we can only draw to the view from inside an active tool instance.
See the abstract Sketchup::Tool class for more information.

As said, you can only do this (currently) from within a custom Ruby tool.

ThomThom has an open source extension that implements a gizmo.

BTW, we’ve discussed here (in this category) recently about getting the camera’s image plane.
Any “gizmo” would need to be in front of the image plane.

If you use the Tool#draw method be sure to also implement Tool#GetExtents else you are at risk of having your drawn geometry clipped. GetExtents tells the graphics pipeline how to expand the model’s bounding box to include what you drew.

1 Like

Indeed, I’m being inaccurate. I guess what I’m trying to achieve is really to render a 3D mesh in camera-space and most importantly, in front of everything else.

Yes, that’s the approach I’m using right now.

Thanks for the link. I looked at the code and it seems that drawing is done with a mixture of View::draw2d and View::screen_coords. However, it works fine in this specific case because it only draws lines and semi-transparent triangles.

In my case, I would like to be able to draw any opaque mesh, which does not seem doable with the Ruby API, because then depth-ordering becomes an issue, right?

Thanks for the discussion though. We can maybe fallback to a similar style with transparent primitives, similarly to the extension you linked.

I don’t know for sure what he does as I’ve not examined the code of TT’s extension.

The Sketchup::View#drawing_color= method assigns the drawing color (from within a tool’s #draw method.)

A Sketchup::Color object has an alpha parameter to it’s constructor, as well as a dedicated #aplha= setter method.

Also, SketchUp 2020.0 added an options hash (to the #draw and #draw2d methods) that allows painting the OpenGL objects with textures. It the texture is fully opaque …

See also:

@merwan, This is the topic in which we discussed the image plane, and there are some snippets posted by various participants: