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?
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.addInPlace(mesh.getAbsolutePosition().add(facetVertices[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.
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. 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.
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.
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?
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…
I figured if you ignored me too long and I was stuck I’d just open a new topic.
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?
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.