# solved Moving spheres from origin point to closest mesh/face/vertex

## Recommended Posts

Hello!

My scenario:
- An OBJ file containing several meshes (cube, cones, monkey head, etc) all touching each other
- A sphere (or more than one) created off to the side of the imported mesh.

My objectives are:
- Determine the closest point on the imported mesh from the sphere.
- Create another Sphere at that point.

The end result is a sphere on the surface of the imported mesh.

Before I started playing with Babylon JS, I had tried Three JS.  I found a small routine that would do this.  Now I'd like to do the same thing in Babylon.  Here's the Three JS.

``````        // This function is called first.  it accepts datapoint as a parameter.  datapoint is the sphere that is off to the side of the imported model.
function updateClosestPointPosition(datapoint) {
var p = datapoint.position;
var geom = partmodel.geometry; // cone.geometry

var closestDistance = 1e9;     // Don't understand 1e9 to be honest
var closestFace = geom.faces.forEach(function (face) {
var normal = face.normal;
var va = geom.vertices[face.a];
var vb = geom.vertices[face.b];
var vc = geom.vertices[face.c];
var pd = normal.dot(p.clone().sub(va));
// move p -(pd - td) units in the direction of the normal
var proj = p.clone().sub(normal.clone().multiplyScalar(pd));
// closest point of proj and the triangle
var cp = closestPointToTriangle(proj, va, vb, vc);
if (cp.distanceTo(p) < closestDistance) {
closestDistance = cp.distanceTo(p);
closestPoint.position.copy(cp);
closestPoint.position.y.toString() + ',' + closestPoint.position.z.toString() + ',';
}
})

function sameSide(p1, p2, a, b) {
var ab = b.clone().sub(a)
var ap1 = p1.clone().sub(a)
var ap2 = p2.clone().sub(a)
var cp1 = new THREE.Vector3().crossVectors(ab, ap1)
var cp2 = new THREE.Vector3().crossVectors(ab, ap2)
return cp1.dot(cp2) >= 0
}

function pointInTriangle(p, a, b, c) {
return sameSide(p, a, b, c) && sameSide(p, b, a, c) && sameSide(p, c, a, b)
}

function closestToSegment(p, a, b) {
var ab = b.clone().sub(a)
var nab = ab.clone().normalize()
var n = nab.dot(p.clone().sub(a))
if (n < 0) return a
if (n > ab.length()) return b
}

function closestToSides(p, sides) {
var minDist = 1e9
var ret
sides.forEach(function (side) {
var ct = closestToSegment(p, side, side)
var dist = ct.distanceTo(p)
if (dist < minDist) {
minDist = dist
ret = ct
}
})

return ret
}

function closestPointToTriangle(p, a, b, c) {
// if the point is inside the triangle then it's the closest point
if (pointInTriangle(p, a, b, c)) return p
// otherwise it's the closest point to one of the sides
return closestToSides(p, [[a, b], [b, c], [a, c]])
}
``````

Is there an easy way to do this in babylon js or do i need to work on some conversion?

Here's the playground I started:  https://www.babylonjs-playground.com/indexStable.html#NSSAV4
The playground uses two spheres.

Unfortunately I am not sure how to do this offhand.

Thank you for the assistance!

##### Share on other sites

Thanks John,

I'll take a looksee.  I found the original example I grabbed from three js.  this is basically what I want to do:

##### Share on other sites

Nothing is built in but it could be done in exactly the same way. using the facet partitioning as @JohnK metionned as first segmenting will actually greatly improve your perf as you ll be able to do the face search on a smaller area.

##### Share on other sites

I ran through the documentation on facet data and used it to construct a function that seems to work for me.

``````function GetNearestPoint(currentSphere) {
var nearestMesh, nearestFacet, facetPos;
var projected;
var distance = 0;
var shortestDistance = 9999999;
meshes.forEach(function (mesh) {     // meshes is an array containing the mesh and its "sub meshes"
var facets = mesh.getFacetLocalPositions()

if (facets.length > 0) {
facets.forEach(function (facet) {
distance = BABYLON.Vector3.Distance(currentSphere.position, facet);
if (distance < shortestDistance) {
nearestFacet = facet;
shortestDistance = distance;
nearestMesh = mesh;
}
});
}
});

projected = BABYLON.Vector3.Zero();
var index = nearestMesh.getClosestFacetAtCoordinates(nearestFacet.x, nearestFacet.y, nearestFacet.z, projected);

return projected;  // use this set of coordinates to construct the newer/closer sphere
}``````

Thanks for the help, everyone!

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible. ×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.