Bladetrick Posted October 9, 2018 Share Posted October 9, 2018 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 return a.clone().add(nab.multiplyScalar(n)) } function closestToSides(p, sides) { var minDist = 1e9 var ret sides.forEach(function (side) { var ct = closestToSegment(p, side[0], side[1]) 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! Quote Link to comment Share on other sites More sharing options...
JohnK Posted October 9, 2018 Share Posted October 9, 2018 https://doc.babylonjs.com/how_to/how_to_use_facetdata#mesh-partitioning Have a read through this section it may give you ideas Bladetrick, ssaket and trevordev 3 Quote Link to comment Share on other sites More sharing options...
Bladetrick Posted October 10, 2018 Author Share Posted October 10, 2018 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: https://codepen.io/maurizzzio/pen/pERqxV?editors=0010 Quote Link to comment Share on other sites More sharing options...
Sebavan Posted October 10, 2018 Share Posted October 10, 2018 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. Bladetrick 1 Quote Link to comment Share on other sites More sharing options...
Bladetrick Posted October 11, 2018 Author Share Posted October 11, 2018 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! GameMonetize and JohnK 2 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.