Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 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
0
Question by adnan0819 · Mar 05 at 02:49 AM · meshverticesviewportworldtoscreenpoint

Finding Viewport Coordinates of Vertices of Meshes that are in View

Hi, I have an array of Tree meshes called myTrees. I am trying to get each mesh's viewport coordinates and write to files so I can later post process in Python. There is only one camera in the project and the screenshot script takes exactly the correct thing on the viewport. But the files written come out to be totally different (example: say I have one tree mesh in view, the screenshot would capture it correctly but the file writes like 41 tree mesh's vertices' coordinates. I suspect I am not understanding some kind of Viewport/World/Scene point transformations. Any help would be amazing. Thanks. The relevant code snippet is below. Also, I am checking if x and y are between 0 and 1 to make sure they are inside the viewport. FYI. my viewport and target size is fixed at 832x832 and I have set up the scene like so. Any advice would be great. You can ignore everything after line 20.

 for (int i = 0; i < myTrees.Count; i++) {
                 Mesh meshT = myTrees[i].GetComponent<MeshFilter>().sharedMesh;
                 Vector3[] verticesT = meshT.vertices;
                 int[] triangles = meshT.triangles;
                 string treeId = myTrees[i].GetInstanceID().ToString();
                 int tid=0;
                 for (int j = 0; j < triangles.Length; j++) {
 
                     if (j % 3 == 0) {
                         int triangleId = tid++;
                         
                         //Converting to World Point
 
                           Vector3 world_t = transform.TransformPoint(meshT.vertices[j]);
 
                          //Converting World Point to ViewPort Point
 
                         Vector3 world_v = Camera.main.WorldToViewportPoint(world_t);
 
                         float x = (float) world_v.x ;
                         float y =  (float) world_v.y;    
                         float z = (float) world_v.z;
                         float r = meshT.colors32 [j].r;
                         float g = meshT.colors32 [j].g;
                         float b = meshT.colors32 [j].b;

                              //Check to see if inside viewport i.e., inside [0,1]

                         if (x >= 0f && y >= 0f && x<=1f && y<=1f ) {
                             string col = "" + r.ToString () + "," + g.ToString () + "," + b.ToString ();
             
                             string position =  x.ToString ("0.0000") + "," + y.ToString ("0.0000") + "," + z.ToString ("0.0000");
 
                             string fullId = treeId + "-" + triangleId.ToString ();
 
                             line = fullId + "," + treeId + "," + triangleId.ToString () + "," + col + "," + position;// + "," +cam.pixelWidth.ToString()+","+cam.pixelHeight.ToString()+","+cam.pixelRect.ToString();
 
                             writer.WriteLine (line);
                             
                         
                         }
                     }
 
                 }
 
             }


Comment
Add comment · Show 1
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 adnan0819 · Mar 05 at 05:07 AM 0
Share

Please feel free to ignore anything after line 20. I think the issue is between line 10 and 20 (the point transformation). Please advice with any suggestion. Thank you.

1 Reply

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

Answer by Eno-Khaon · Mar 05 at 07:06 AM

Well, there's a bit going on here that looks either confusing or potentially incorrect, so let's break down the process:

 -- // For each tree...
 for (int i = 0; i < myTrees.Count; i++)
 {
 --    // Get its mesh, vertices, and triangles...
     Mesh meshT = myTrees[i].GetComponent<MeshFilter>().sharedMesh;
     Vector3[] verticesT = meshT.vertices;
     int[] triangles = meshT.triangles;
     
 --    // Get two unique identifiers for the tree
     string treeId = myTrees[i].GetInstanceID().ToString();
     int tid=0;
     
 --    // for every triangle in the mesh (which come in groups of 3)
     for (int j = 0; j < triangles.Length; j++)
     {
 --        // So, only check the first vertex per triangle?
 --        // The for loop could be changed to better facilitate that process:
 --        // for(int j = 0; j < triangles.Length; j+=3)
         if (j % 3 == 0)
         {
 --            // Assign, then increment for output string(s)
             int triangleId = tid++;
             
             //Converting to World Point
 --            // How are you not going out of bounds of the array?
 --            // Also, you already made a copy of that array, yet you
 --            // make a new copy with every pass.
 --            // -> verticesT[triangles[j]] <-
 --            // ----------------------------------------
 --            // ALSO, you're not using the correct Transform data.
 --            // You're positioning the vertices based on the current
 --            // Transform's position/rotation/scale rather than the
 --            // tree itself. You should use:
 --            // myTrees[i].transform.TransformPoint(verticesT[triangles[j]]);
             Vector3 world_t = transform.TransformPoint(meshT.vertices[j]);

             //Converting World Point to ViewPort Point
 --            // Then you take the world-space position of the tree
 --            // (or whatever it currently is) and get the main camera's
 --            // viewport position of that.
             Vector3 world_v = Camera.main.WorldToViewportPoint(world_t);

 --            // Redundant casts to "float"?
             float x = (float) world_v.x ;
             float y =  (float) world_v.y;    
             float z = (float) world_v.z;
 --            // Like up above, if you're going to access these
 --            // arrays, and especially multiple times per pass,
 --            // you should probably cache the array data.
             float r = meshT.colors32 [j].r;
             float g = meshT.colors32 [j].g;
             float b = meshT.colors32 [j].b;


So, essentially, it's mainly just unclear what the intent is with respect to using only the first vertex of each triangle, and your logic for transforming local to world positions simply isn't viable at all.


To reiterate a few notes I inserted into the script, elements that could be cleaned up a bit for more efficient usage could include:

Reading Mesh data was given improvements over time, so using...
 List<Vector3> treeVerts = new List<Vector3>();
 Mesh.GetVertices(treeVerts);
 List<int> treeTris = new List<int>();
 Mesh.GetTriangles(treeTris);
 List<Color32> treeColors = new List<Color32>();
 Mesh.GetColors(treeColors);

... should be a viable replacement. Note that this isn't *universally* true, especially since you're not currently reusing them later, but it's generally just a good point of reference anyway.


With the idea of using List<>(s) in mind, this would also change the syntax for adapting the for loop (as necessary), as well as skipping the modulo operation altogether:

 for(int j = 0; j < triangles.Count; j+=3)


The purpose of using TransformPoint() is to test which trees are within view of the camera, so the vertices of each tree need to be translated to the positions of, well, the trees. Doing this means making use of each tree's Transform data as the vertices of its Mesh are being tested. I'm not sure which GameObject this script is currently attached to, but it is almost definitely NOT the one you're intending to use in this situation:

 // Assuming "myTrees" IS NOT an array of Transforms...
 // If it is, then the ".transform" step is obviously unnecessary.
 myTrees[i].transform.TransformPoint(verticesT[triangles[j]]);


Fundamentally, the rest looks like it's probably in reasonable shape at this point. Apart from some redundancy (it's not necessary to read each of the X/Y/Z-axis values out of "world_v" to their own floats, as well as re-casting those floats as floats), there probably aren't any other crippling problems in this situation.

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 adnan0819 · Mar 20 at 10:20 PM 0
Share

Thank you so much. You are a lifesaver. Really appreciate how you annotated the code and additionally provided workflow directions. The "transform" part got my thing working.

Really grateful for the suggestions. Now I need to figure out how to make it more efficient, meaning, every time I do this (bound to a keypress), the whole myTrees array needs to be searched which has hundreds of trees - each with thousands of triangles. Having lists like you suggested would still have the same asymptotic complexity (loops' iterations) as far as I understand; if you have any suggestions about this, I'll be extremely grateful.

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

151 People are following this question.

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

Related Questions

Alternative Ways of Finding Vertices 2 Answers

Determine neighbor boundary vertices order 0 Answers

How to find the closest 4 verts/corners ( along with their orientation ) of a rectangular object in relationship with another object? 1 Answer

mask one gameObject mesh by another mesh vertex transparency 1 Answer

Mesh SetVertices() vs vertices 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