Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
8
Question by pgbrandao · Nov 16, 2009 at 02:19 PM · physics

Closest point on mesh / collider

Hi everyone!

I'm stumbling across a small problem, here's hoping someone can help. Basically what I need is the nearest point to an object.

For now, I've been trying to use Collider.ClosestPointOnBounds. It looks perfect! Right? Unfortunately, the results I'm getting from this method are axis-aligned. Whenever the object is rotated (which is just about always), the method returns an invalid point which isn't actually on the surface. So I'll have to use another approach...

Also, it doesn't matter to me whether the nearest point is on the collider or the mesh. I just need a way to know which point on the surface of an object is nearest to another point.

Any help is really appreciated!

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
13
Best Answer

Answer by duck · Nov 16, 2009 at 09:42 PM

Here's a method which will give you the nearest vertex of the gameObject's mesh. I've written this code to be suitable for putting into a MonoBehaviour script, because it uses references to the gameObject's "transform" and "MeshFilter" components.

An alternative would be to make a static "helper tool" version of this function which could accept both a point and a GameObject parameter.

public Vector3 NearestVertexTo(Vector3 point) { // convert point to local space point = transform.InverseTransformPoint(point);

 Mesh mesh = GetComponent<MeshFilter>().mesh;
 float minDistanceSqr = Mathf.Infinity;
 Vector3 nearestVertex = Vector3.zero;

 // scan all vertices to find nearest
 foreach (Vector3 vertex in mesh.vertices)
 {
     Vector3 diff = point-vertex;
     float distSqr = diff.sqrMagnitude;

     if (distSqr < minDistanceSqr)
     {
         minDistanceSqr = distSqr;
         nearestVertex = vertex;
     }
 }

 // convert nearest vertex back to world space
 return transform.TransformPoint(nearestVertex);

}

If you really need to find the nearest point within the surface of the nearest triangle of your mesh, this code could serve as a good starting point.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image pgbrandao · Nov 17, 2009 at 01:50 PM 0
Share

That's an interesting idea, Duck. The problem is that my meshes are rather large, thus this would be rather inefficient. I've already used a different approach, but hopefully your snippet will come in useful to someone else going through the same problem. :-)

avatar image JPhilipp pgbrandao · Jun 26, 2018 at 06:55 PM 1
Share

So Pgbrandao, what is your solution? Please share, thanks.

avatar image duck ♦♦ · Nov 17, 2009 at 03:54 PM 1
Share

Don't underestimate how fast unity's code executes (unless you're targeting the iPhone!). There are ways this could be optimised too. You could spread the process out over a number of frames, only processing a handful of vertices per frame. Alternatively, if the point being tested is likely to move along a path at a reasonable speed, you could make use of the fact that result each frame will most likely either be the same vertex as found last frame, or a neighbour of the vertex found last frame, by using a lookup table of each vertex's neigbours.

avatar image Kilometers · Dec 08, 2011 at 12:55 AM 1
Share

I'm really curious about what your solution was. Right now, Duck's solution is my only option, and like you I have a large mesh, so the efficiency thing does concern me. NOTE: I do have one way that I have slimmed down the searching process. What I do is, based on the world coordinate of the point that I am comparing with the mesh, I can slim down the vertex search to a specific series of indices in the vertex array. That cuts down the search from an average of 20k verts to 2k.

avatar image cregox · Oct 24, 2013 at 12:47 PM 0
Share

I believe the fastest way to do this would be through shaders... But I haven't done it yet. In any case, I'd love to read more about @pgbrandao's solution. And, @$$anonymous$$ilometers you talk about "slim$$anonymous$$g down the vertex search to a specific series of indices, based on the world coordinate" but that doesn't say much about the solution as well, dude - the irony here is that you did ask the other dude for an explanation but you didn't really gave yours.

avatar image whydoidoit · Feb 19, 2014 at 10:29 AM 1
Share

Just out of interest - the nearest point on the mesh rather than the nearest vertex can be found using this method: http://answers.unity3d.com/questions/424974/nearest-point-on-mesh.html

avatar image
2

Answer by andeeee · Nov 18, 2009 at 04:19 PM

Don't know if you're still interested in this, but I've posted some code for this on the forum:-

http://forum.unity3d.com/viewtopic.php?t=36772

It's a bit like the code Duck suggested, but it also implements the nearest point on triangle part and uses a spatial data structure to store the vertices so as to reduce the overhead of the search.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image JPhilipp · Jun 26, 2018 at 06:56 PM 0
Share

This link doesn't work anymore. Thanks

avatar image
0

Answer by VoxelBoy · Nov 16, 2009 at 07:25 PM

As a quick workaround, you could try the following in whatever script you're calculating the point from: -Un-rotate the object with the collider so it's rotation = Quaternion.identity. Keep the previous rotation in a temp. variable. -Use the Collider.ClosestPointOnBounds method to calculate the Point -Rotate the object back to it's original rotation. -Rotate the point along the object's position with the same rotation you applied to the object.

This should, in theory, result in a point that's on the object/collider's surface even when it's rotated.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image robert · Nov 17, 2009 at 08:52 AM 0
Share

False. Apart from the fact, that the operations are listed in a wrong order, this would only work if the object/collider was a right cuboid (a rectangular box), because only then the bounds would align with object's/collider's faces.

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

The name 'Joystick' does not denote a valid type ('not found') 2 Answers

Raycast length must be equal to the target distance 2 Answers

unique physics scripting? 2 Answers

hit.rigidbody.useGravity problem? 1 Answer

Destroy parts of a Wall 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges