Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Help me with raycasting against a mesh collider.

Discussion in 'Scripting' started by Nanako, Dec 4, 2014.

  1. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Okay, my objective is to determine if an object (with a mesh collider of low polycount, but a potentially arbitrary convex shape) is visible, by raycasting against it from a camera.

    My problem is picking exactly where to raycast, to ensure i hit it. I need some way of picking a random point in, or on a mesh, that will ensure a reasonable degree of accuracy, but most importantly be fast. Or alternatively, a set of non random points like the top, topleft/right corners, and right/left sides. However i'm not sure how to translate those into points on the mesh surface, rather than points on the bounding box


    My criteria are, in order of descending importance:

    1. A raycast to the target point has to actually hit the collider. A cast against empty space is an inefficient waste
    2. Performance/speed/efficiency
    3. reasonable distrubution, with a modest margin for error. (maybe allowing false negatives 15-20% of the time)

    My original plan was to cast against 5 or so points on the outer bounds of the collider, but then i ran into a wall, in that a mesh collider will almost always not-uniformly fill its bounds, and so that would result in casting against empty spaces where there is no collider to hit.

    I could just cast against the centre of the object, and indeed i will do exactly that for especially small things (anything below a certain volume) but that still leaves quite a lot of objects where a single central cast would produce a false negative far too often.

    I'm also planning to scale up the number of raycasts based on the volume of the object, so i'll only be using the full 5-6 casts against especially large things, which need it for accuracy. and a smaller number against smaller things.

    The specific context here, is lots of small objects (often a few hundred in the scene at once), which will quite likely be piled up on and around each other. I need to determine which ones are visible, in order to determine which ones i can safely delete without the player noticing.

    As mentioned, performance is the most important thing. Far more important than ensuring an even distribution of points.
     
    Last edited: Dec 4, 2014
  2. jgodfrey

    jgodfrey

    Joined:
    Nov 14, 2009
    Posts:
    564
    Maybe I'm off base here, but... Don't you have access to the underlying mesh itself via MeshFilter.mesh.vertices?
     
  3. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    i do indeed. and i've just realised that i also have access to an easy array of points on the mesh surface, via its vertex list >.<

    are there likely to be any problems casting against vertices? since they all sit on the surface of the mesh, it's possible that a raycast against one might just "skim" the surface of the mesh and not touch any faces, would that still register a hit ?
     
  4. sootie8

    sootie8

    Joined:
    Mar 25, 2014
    Posts:
    233
  5. ZO5KmUG6R

    ZO5KmUG6R

    Joined:
    Jul 15, 2010
    Posts:
    489
    you can raycast in the direction of the center of the mesh

    theObject.transform.position + theMesh.bounds.center; would be the worldspace position of the mesh center. There are ways to convert to direction however I don't know of them
     
  6. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
  7. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    duh :p of course i knew that. but a single raycast to the centre is only useful for small objects

    for anything reasonably sized, the chance of false negatives gets way too high, especially in a cluttered environment
     
    Last edited: Dec 5, 2014
    ZO5KmUG6R likes this.
  8. Nanako

    Nanako

    Joined:
    Sep 24, 2014
    Posts:
    1,047
    Resurrecting this thread, i need more ideas.

    Casting against random vertices doesn't seem to be working for me, at least in my use cases. The vertices are too unevenly distributed and my rate of false negatives is far too high for this method to be efficient or worth pursuing farther imo.I could increase the number of samples (currently using 3 for small objects) but the cost to gain the necessary accuracy is too high for my liking. looking for alternatives

    Does anyone have ideas on casting to specific directional points on a mesh surface? Even, something like scanning the highest point on a mesh, i can't quite figure out how to do, at least not without processing through the list of vertices, and then that information would become irrelevant whenever the object rotated

    How can i figure out where the surface of a mesh is, in any given direction from the centre? (such as straight up)
     
  9. Stoven

    Stoven

    Joined:
    Jul 28, 2014
    Posts:
    171
    First of all, why are you trying to cast onto the Vertices as opposed to the Triangles that the Mesh consists of?

    Secondly, I'm assuming you're transforming these Vertices to their true world positions instead of their local positions of the Mesh?

    Thirdly, why not simply use a generalized Box-shape and find the Ray intersection for each mesh-object instead of a Mesh? If performance is that critical, I wouldn't want to cast against triangles of each Mesh. The Box-method would lead to false-positives sure, but for something like visibility of an object I think its worth doing as an alternative.

    Yes you would need to transform the local coordinates of a Box-shape for a particular Mesh object. I'm assuming these Meshes are using Vertices that do not change (the Transform of their GameObject changes, but not the Vertices themselves)?
     
    Last edited: Dec 9, 2014