Closest point on mesh

I am interested in annotating an object by creating a 2d plane with text on it. I would like for the annotation to be connected to the mesh via a line.

I can get the center of the bounding box of the object - I am interested in finding out the closest point on the mesh from the bounding box center.

Blender (module bpy) has a function closest_point_on_mesh - is there an equivalent to this in Babylon?

Hiya S, welcome to the BJS forum!

Just off the top of my head, a picking ray can likely get your wishes done. Raycasts - Babylon.js Documentation

Just in case you are flexible… I know of another way to label/annotate mesh… and we use it heavily around here… called GUI 2d. Here’s a quickie demo. Here are Full GUI 2d docs.

The “label” can be any size, has word-wrapping power, font-styling, colors, round/square borders, does auto-billboarding (always faces camera), never occluded (blocked), clickable or not, rotate-on-z, mix’n’match widgets… it all works great. In some ways, it’s WAY MORE POWERFUL than html. But it takes some time, like all powerful things, and it can use some serious code-space, like any great gui, including html.

I think… you will be happier using BabylonJS GUI2d… than doing what you might be thinking-about.

But even cooler, all the gooey GUI goodness… can STILL be used on a plane. That sparkly demo above is on a plane… but then ya need to do that ray-cast that you talked about (to link plane with front-side of mesh), and set the plane’s billboardMode = true. And it can be blocked… so you need to worry about alien spaceship mesh… accidentally landing in front of your camera… blocking the view to your annotations. :wink:

All in all, BJS GUI has both full-screen mode, and paste-it-onto-a-mesh-as-a-texture mode. All GUI controls (widgets) can be set “linkWithMesh” (with or without extender lines)… and the labels can be screen-positioned “offset” X and/or Y… to keep them from sitting directly atop the mesh they are linked-with.

I think you should take a little tour of the docs and demos. I think you’ll fall in love with it.

Write back, as wanted. Good to have you with us. Feel free to tell us about your hopes/projects… we’re all one big family of 3d lunatics 'round here… good times.

1 Like

Hi Wingnut,

Thank you very much for your answer - I really appreciate it.

I took an extensive look through the Babylon demos and documentation. The reason I am opting for controlling everything in the annotation creation (extender lines, 2d plane, text) is because I am generating quite a lot of annotations. Part of my project deals with finding a good layout where the annotations are not overlaying each other. I am under the impression that GUI 2D may not give me the control that I am looking for in terms of manipulating the “extender lines”, but I may be wrong.

So far, I have come up with the function below. Using raycasting also sounds doable - I am assuming I would be shooting raycasts from the center of the bounding box towards discretized positions on the bounding sphere.

function closestPointOnMesh(mesh) {
    var center = mesh.getBoundingInfo().boundingBox.centerWorld;
    var positions = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
	var minSquaredDistance = 100000;
    var closestVertex = BABYLON.Vector3.Zero;
	var numberOfVertices = positions.length/3;	

	for(var i = 0; i<numberOfVertices; i++) {
        var vertPosition = new BABYLON.Vector3(positions[i*3], positions[i*3+1], positions[i*3+2]);
        var dsq = BABYLON.Vector3.DistanceSquared(center, vertPosition);

        if (minSquaredDistance > dsq)  {
            minSquaredDistance = dsq;
            closestVertex = vertPosition;
        }
	}

    return closestVertex;
}
1 Like

Hi again. Actually, I think you would be shooting the ray from camera to mesh. A “picking ray”… and that returns a “pickingInfo” or “pickInfo” object… which can contain some yummy info… such as faceID and distance to mesh surface, and maybe a face-normal. These things could be used to position and billboard the annotations.

Also, that mesh.getBoundingInfo().boundngBox is full of good boundingBox measurement values… both local and world space. I haven’t done much with boundingSpheres… though… totally dumb in that department… but a worthwhile pursuit. I’m glad you have some experience in these things… you seem to have good knowledge and have done this kind of thing before. (Forum helpers never know the experience levels of visitors, so people like me sort of “over-explain” a bit.) I did some of that to you… and you don’t need it… sorry about that. :slight_smile:

Yeah, you’re on the right track and your code is looking good and interesting. (I’m pretty sure you’re a much better coder than I am.) :slight_smile:

Yeah, investigate that darned pickingInfo object. You probably saw it mentioned in the raycast docs. It’s getNormal() method is useful. perhaps.

Have you tested billboardMode for mesh, yet? It will try to keep a plane orthogonal to line-of-view, but it gets a little unwieldy when the camera nears the poles (way up high, looking down at mesh, or vise-versa). Keep your camera near flat/equatorial (set upper/lower .beta limits on arcRotate cam, perhaps), and billboarding works pretty good.

You might also be interested in mesh.lookAt(something)… and similar. lookAt() needs to be inside the renderLoop… constantly refreshed… but it’s very tiny/fast code, under the hood. Having 20 mesh constantly looking-at camera.position or maybe looking-at camera.childedInvisibleMesh (that you created)… is easy, perf-wise. No problems. Vrooooom.

Be sure to forum-search, playground-search, docs-search, and old-forum-search… for some of these terms. These subjects have been talked-about often, especially billboarding’s slight z-spinning of the annotation plane… when the camera gets near polar positions.

dynamicTexture is a hot search term for you, too. It is/was the primary way to write text on a plane… before GUI 2D (and before the short-lived Canvas2D system) came along. An in-code playground search for dynamicTexture brings-back quite a good haul.

DynamicTextures are based-upon “Context 2d”… a system somewhat similar to SVG, if you know what that is. A draw-on-a-texture system.

AdvancedDynamicTextures (the GUI 2D system I love)… is also based-upon Context2d, of course. It’s a much fancier “layer” atop Context2d… than dynamcTextures. Both are fun and interesting. GUI 2d is much easier, especially in the “measuring” department, so I took more interest in that… than in dynamicTextures. DynamicTextures CAN be irritating… sometimes seemingly unpredictable… but not really. Ya just gotta know the Context 2D spec… well. Previous experience with SVG might help.

Ok, cool… ya got some leads, ya got some programming experience… I think you’ll be fartin’ thru silk in no-time. Welcome aboard. I think you should de-solution my post… and wait a bit longer… for better answers. By Monday/Tuesday… you may see some MUCH wiser comments. I’m more the BJS “forum clown” than I am wise-tech. I get the MOST fun from BabylonJS… when I do something weird and it crashes my browser. I love that. It means I’m properly demented. :smiley:

“discretized” :slight_smile: Cool word!