Draw an arrow between the surface of two meshes?

I’m trying to draw a arrow between the surface of two meshes.

Eventually the meshes will be moving and will be of arbitrary shape, so it’s necessary to dynamically calculate the starting and ending points of the line.

I’ve setup a simple demo using a Ray to calculate the points between the meshes:

Unfortunately, the Ray seems to pick an intercept point that is on the opposite face of the mesh from where I want it to start. (You can see the red line runs through the mesh rather than starting on the surface). I don’t understand why, since the Ray doesn’t even intercept that face of the mesh – the white line for the Ray starts in the middle of the mesh.

Any ideas of how to calculate the start and end of the line so that it’s on the surface of the meshes nearest to each other?

1 Like

May be something like that ?

1 Like

This unfortunately not universal. If you swap the positions of the meshes:

This makes the whole thing damn time consuming to calculate.

If we just focus on faces you can use Babylon.js docs FaceData to get the faces with additional information. (we call them facets)

You need to calculate distance between the faces of mesh1 to mesh2. First you can filter the list of faces only to those pointing from mesh1 to mesh2 and vice versa to speed up finding the two closest faces. Use the Babylon.js docs face normal to filter.

Then you can easily find the center of the faces (triangle):

const facetVertices = [];
mesh.getFacetVertices(facetIndex, facetVertices); 
const center = BABYLON.Vector3.Zero();
for (let i = 0; i < facetVertices.length; i++) {
center.scaleInPlace(1 / facetVertices.length);

Loop through the filtered facets to find the two with the lowest distance.

Quite interesting question, I’ll try to write a PG later.


Highly unoptimized version!! This is not what I was writing about in my previous post.

Finds the closest two vertices and draws a line between them. Rotate the camera for a better view :see_no_evil:


Thanks for all the quick replies!

Not that beggars can be choosers, but using Facets or Vertices may lead to some strange results. Here’s your last example when using boxes instead of sphere-ish things:

I suspect that using Facts will lead to some strange endpoint alignment too, since a plane may be divided up into two large triangles and you’d end up pointing to the center of one of those two triangles.

Maybe there’s a solution if we flip the problem around the other way? Is it possible to translate a vector pointing from the center of a mesh to a point on the texture of the mesh?

You asked for arbitrary meshes and it’s difficult to get the closest two points on the surfaces of I emphasize here, arbitrary meshes. You can use the Ray approach only when you have a starting Vector3 for the Ray and a direction Vector3. If it’s good enough for you to cast the ray from the center of one mesh towards the center of the second mesh it’s fairly easy to get the intersection points.

You can use increaseVertices:

There are multiple solutions here but I need to know how precise results you need. I’ll gladly help you to find the best one. :slight_smile: Could provide some more inputs on your requirements?

Yea, sorry my original post wasn’t very articulate. This is what I had in mind – draw a line between the center points of the two meshes and where that line intersects the surface of the two meshes would be the start and end points of the line. That way the movement of the line would be smooth as the objects move around. Lame attempt at a diagram below – I want to find the red points on the surface of the mesh along the dotted line between the blue centers of the meshes so that I can draw the green line. :slight_smile:

I like the Ray idea, but I can’t figure out how to get it to pick a point on the mesh that is along the line between the two centers. e.g. - the original PG I posted picks the wrong face of the box and your first PG demonstrates that swapping direction causes problems.

Hopefully that’s a better description?

It’s cool! I like it :slight_smile:

Absolutely! Let me create a PG. (2:44 AM here, maybe I will fall asleep before finishing it. If so, I’ll get back to you tomorrow)

Here you go! Hopefuly you’ll manage to add the arrow cap yourself :wink: I’m going to sleep…

1 Like

You’re amazing, thanks so much! :vulcan_salute:

1 Like

You are very welcome!

Please mark as a solution. Thanks!

1 Like

I don’t get how this works. When I comment out the render events and just draw the Ray once it doesn’t connect to the surface of the mesh. Is there something magical that happens with Rays during rendering?

After you modify the position and/or direction of the Ray just call scene.render() to update everything on the scene and get the proper intersections.

Or check for the intersections after the scene is ready.

1 Like

Hopefuly you’ll manage to add the arrow cap yourself

Man, I tried. I can’t figure out how to subtract the arrow cap length from the length of the line. Also, re-creating it on every render seems wrong. There must be a better way…

Kinda got arrow caps working. Not sure why I need the fudgeFactor variable to adjust the end of the line offset.

1 Like

Oh sorry I totally forgot about your question.

By adding the arrow cap you make the line longer by the length of the cap so you have to draw the line shorter.

I’m glad you made it yourself. Maybe you could write a drawArrow helper function and share with the community :wink:

I figured if you ignored me too long and I was stuck I’d just open a new topic. :wink:

I still don’t understand why I need the fudgeFactor in this PG. When the arrow cap is 0.1 units long, I have to make the line 0.3 units shorter so that everything lines up okay… any insights?

Happy to write a drawArrow helper. Were you imagining that as a separate project or a pull request?

Ignored is a too strong word :smiley:

Let me see. Hang on…

Maybe we could create helper functions for drawing various elemenrts. Circles, rectangles, lines with various configurable caps, arrows, stripes, SVG support (I have this one already partialy implemented, but is uses an external library to parrse the SVG), etc. The community could build a quite extensive library for various stuff. :muscle:

@sebavan @Deltakosh @Evgeni_Popov @RaananW
What package would be the best place to put these helpers in? Or should it be a separate 3rd party npm package?

Thank you!