Comments and answers for "Lower-level way to find NEARBY TRIANGLES on the mesh? (Answered.)"
http://answers.unity.com/questions/193695/in-unity-is-there-a-fast-way-to-find-nearby-triang.html
The latest comments and answers for the question "Lower-level way to find NEARBY TRIANGLES on the mesh? (Answered.)"Comment by sgrein on sgrein's answer
http://answers.unity.com/comments/1621303/view.html
So we cannot assume *any* spatial structure of the triangles in the triangle array? By that I mean, two consecutive triangles {0,1,2, 3,4,5} for example could be far apart in my 3d space?Thu, 11 Apr 2019 20:05:52 GMTsgreinAnswer by Trionet
http://answers.unity.com/answers/1176185/view.html
I've done this in a project before. I have a parallell list of MeshLinks I call them. They know all of their 3 adjancent triangles. With that you can also do a gathering of all triangles sharing a vertex through the neighbours neighbour and so on.
By also having a is_found boolean in the MeshLink you can check where you were and find any n adjancent triangles in O(n) time. You must ofcourse buffer the MeshLinks before hand. But then it is good to go. By some complex linear algorithms in searching adjancents you may also extend the mesh by splitting one in to 3 or 2 in to 4 without ever having to go through the whole mesh again.
In other words. Have you considered buffering all the adjancency of a mesh? It shouldn't be a performance issue then.Sun, 24 Apr 2016 17:11:59 GMTTrionetComment by Fattie on Fattie's answer
http://answers.unity.com/comments/264774/view.html
The correct answer to the actual question is incredibly simple: **the 3D pipeline does not know about triangle location**.
But spatial culling generally is completely relevant and would be very useful to anyone new to the field so ticking this answer!
Down with un-answered questions!!Sat, 09 Jun 2012 09:24:03 GMTFattieComment by Fattie on Fattie's answer
http://answers.unity.com/comments/204703/view.html
For anyone reading this in the future, to be clear, this sentence: *"It is an absolutely true statement that Unity shares vertices where it can. There is no situation where this is not true."* is completely and totally wrong, as can be easily seen from the example images above.
Tasarran has disappeared for holidays, so we have not been able to get him to delete these incredibly confusing and totally incorrect statements.
So if you are reading this in the future, don't get confused!
Note that it does not even make sense to say "Unity shares vertices where it can ..." because Unity simply uses whatever vertices you give it, made in a program like $$anonymous$$aya. It would be much like typing "Unity uses blue colours where it can..." - it makes no sense at all, Unity simply uses the colors the user gives it. Similarly Unity simply uses the vertices the user gives it.
Again: it is an absolutely commonplace, basic piece of knowledge when working in 3D, that models have no special reason to share verts (where possible) and that every model you ever get, from any program ($$anonymous$$aya, Blender, etc), typically has a big mess of verts some where'd (where possible) and some not shared (where possible) - you can clearly and instantly see this in any model you ever deal with, and it can be seen in the images above.Thu, 12 Jan 2012 08:33:43 GMTFattieComment by ina on ina's answer
http://answers.unity.com/comments/196693/view.html
I had thought Unity does auto-cullingMon, 19 Dec 2011 04:55:24 GMTinaComment by Fattie on Fattie's answer
http://answers.unity.com/comments/196186/view.html
HI @Tasarran, are you there? As we were discussing, your sentence: **"In a sphere without hard edges, or UV boundaries, ALL vertices WILL be shared by at least one other triangle."** is quite wrong.
If you have a look at the edits to the question, I have made some demonstrations of the issue for you.
In fact the download also includes all three example models. "Never shared" (as is often used by people manipulating mesh), "all shared", and the original unity sphere (which as it happens has a few hundred each way).Sat, 17 Dec 2011 08:17:41 GMTFattieComment by Fattie on Fattie's answer
http://answers.unity.com/comments/195993/view.html
Dear @Tasarran, are you still there?
Notice the edits to the original question. I got the Unity sphere for you, and massaged the verts. Note the the three images.
There is also a Unity project you can download! CheersFri, 16 Dec 2011 17:12:28 GMTFattieComment by Tasarran on Tasarran's answer
http://answers.unity.com/comments/194508/view.html
Leaving it in as an answer...
I know it isn't a solution, but it is an answer; the answer is no, but I elaborate why...Mon, 12 Dec 2011 18:55:47 GMTTasarranComment by Tasarran on Tasarran's answer
http://answers.unity.com/comments/194505/view.html
It is an absolutely true statement that Unity shares vertices where it can. There is no situation where this is not true.
A vertex can be shared by a thousand different triangles if needed.
(Say the center of the end of a big cylinder)Mon, 12 Dec 2011 18:44:17 GMTTasarranAnswer by Tasarran
http://answers.unity.com/answers/194488/view.html
<p>There is no quick and easy way to do it, the only way is by comparing spatial coordinates, and this is why:</p>
<p>It might not be possible to explain w/o a picture, if I need to elaborate, I will.</p>
<p>In that cube example, there are two shared verts per square side, and that is ALL the shared points.
The corner points are not shared between faces (squares), only between triangles on the same square.
Any edge that is hard (such as the actual edges of the square faces) will not share vertices.
In a sphere without hard edges, or UV boundaries, ALL vertices WILL be shared by at least one other triangle. Same thing goes for a mesh with no hard edges or UV boundaries.</p>
<p>If you have a cube in Unity, you have 12 triangles. They are paired in two triangles per face, each sharing two verts.
Each side will have two triangles, not sharing verts with any of the other faces, except the two verts on the other triangle in the pair.
The vertices from the separate sides will not share vertices, even though they are adjacent.</p>
<p>The only way to find out that the triangle on the other side of the hard border is adjacent, is to compare the actual coordinates of the points...</p>
<p>As you can see from the stats that Aldo posted (which are correct), if you have a cube, you basically have six squares that are INDEPENDANT of each other and share NO vertexes between them, and each of those squares is made up of two triangles which share two vertices each.
So, Square One has Triangle One, made up of Vert 0,1,& 2. It also has Triangle Two, with Verts 1 (shared), 2(shared), & 3.
This would be repeated all around: Square Two has Triangle Three (4,5,6), and Triangle Four (5,6,7), etc.
Until you get to Square Six, with Triangle Eleven (20, 21, 22) and Triangle Twelve (21,22,23).</p>
<p>Twenty four vertices, twelve shared.</p>
<p>The point is, even though vertices lie on the same exact coordinate as another point, they are no necessarily shared.</p>
<p>If you move one of those corner vertices, you will rip the cube open, because the vertices on the other two squares are NOT shared, even though they share the same coordinates. You'd have to move all three corners of the involved squares to not rip the cube.</p>
<p>It's not like the real world where you can point to the corner of a cube and say "That point is common to all three sides."</p>
<p>It just doesn't work that way in Unity.</p>
<p>In the end, using search trees (one example of which is discussed above), or other sorts of data-manipulation techniques can help you speed up the process, but when you get down to it, the only way is brute-force looping and comparing.</p>Mon, 12 Dec 2011 18:09:48 GMTTasarranComment by Fattie on Fattie's answer
http://answers.unity.com/comments/194320/view.html
@aldo (in brief!) you have made a number of statements such as: "Some "well behaved" meshes ... are constructed to avoid vertex duplication". This is wrong. If you feel it is not wrong, just explain what you mean by "are constructed by" ... by who?Mon, 12 Dec 2011 07:23:03 GMTFattieComment by aldonaletto on aldonaletto's answer
http://answers.unity.com/comments/194224/view.html
@Fattie, if the cube had no shared vertices, the count would be 36, not 24, what proofs that some triangles share vertices - not all, what I never said, but those that *can* be shared, what's explicitly mentioned in my answer. And what's wrong with my code? Obviously, its just pseudo-code, but even so it's correct. I tested it and - as expected - it correctly found all neighbors *in each face*, which in a cube means only 1 neighbor to a given triangle. I also run the same script with an Unity cylinder, and again it correctly reported the neighbors: 19 for each triangle in the top/bottom faces, and 4 for each "lateral face" triangle - btw, a cylinder has 80 triangles and only 88 vertices, proofing once more that Unity primitives "save" vertices whenever possible.<br>
Regarding the interesting linked article, it shows a tetrahedron case with a single triangle per face, thus without any neighbor in the same face.Sun, 11 Dec 2011 23:08:03 GMTaldonalettoComment by aldonaletto on aldonaletto's answer
http://answers.unity.com/comments/194151/view.html
@Fattie, place a cube in scene, and add this simple script:
<pre>
function Start(){
var mesh : $$anonymous$$esh = GetComponent($$anonymous$$eshFilter).mesh;
var qVert = mesh.vertices.length;
var qTri = mesh.triangles.length;
print("Vertices: "+qVert+" Triangles: "+qTri/3);
}
</pre>
Unity will print:<br>
Vertices: 24 Triangles: 12
We have 12 triangles in a cube, but only 24 vertices - thus, there are vertices referenced by more than one triangle.Sun, 11 Dec 2011 18:10:25 GMTaldonalettoComment by aldonaletto on aldonaletto's answer
http://answers.unity.com/comments/193899/view.html
I don't think this can be solved at the shader level - unless you just want to do some shader stuff with the neighbor triangles (draw them in a different color, for instance). OpenGL doesn't seem to have any function to help doing this job either, thus I afraid you will have to loop all triangles anyway - even if only once to create an auxiliary structure to speed things at runtime, like @Statement suggested, and your question *now* specifies (btw, I do believe you know how to loop over the triangles - the comments in the code are meant to help those who don't know).<br>
SIDENOTE: Comparing vertices in a per-dimension basis seems faster, but may actually be slower due to the .NET interpretation overhead. I suppose the Vector3 == operator compiles to a single library function call, while any per dimension comparison will compile to lots of CIL instructions.Sat, 10 Dec 2011 16:49:23 GMTaldonalettoComment by Statement on Statement's answer
http://answers.unity.com/comments/193856/view.html
Yeah, I always try to add comments, but @Fattie had the comments covered. :)Sat, 10 Dec 2011 12:02:01 GMTStatementComment by Bunny83 on Bunny83's answer
http://answers.unity.com/comments/193854/view.html
No offence meant / taken ;), You can vote whatever you think is right or wrong but a comment would be nice ;)Sat, 10 Dec 2011 11:59:33 GMTBunny83Comment by Statement on Statement's answer
http://answers.unity.com/comments/193852/view.html
I downvoted, mostly because it doesn't change the time complexity of the algorithm and it doesn't account for the "nearby" triangles criteria. But I guess it's a better solution to distance checking every other point, so I'll leave it unvoted. Happy?Sat, 10 Dec 2011 11:51:44 GMTStatementComment by Bunny83 on Bunny83's answer
http://answers.unity.com/comments/193849/view.html
Who gives this answer a downvote? Comparing the indices are the first thing that came to my mind but like aldonaletto mentioned (maybe badly worded) if you have uv-seams or custom-normals for some faces / triangles the second method is the best way to do this **without any extra data**.
The OP didn't specify how his mesh looks like and writing NEARBY in caps doesn't make it any clearer what nearby means. Only true neighbors (only triangles that share an edge), only touching neighbors, or all triangles within a certain range (not necessary touching)? Distance based solutions are not very robust since you have to know at least the average size of your triangle. If the size vary too much at some spots you won't have any neighbors because the triangles in this area are quite big and somewhere else you might have too much because there are many, very small triangles.
Distance approaches also comes with heavy processing time due to the square-root unless you do a squared distance comparison.
I just want to know the reason for the downvote since it is a solution to the question (might not be the fastest) and it doesn't contain miss-information (except the "badly created" should be a "usual" ;) )Sat, 10 Dec 2011 11:32:22 GMTBunny83Comment by Statement on Statement's answer
http://answers.unity.com/comments/193848/view.html
Well if the triangles move around too much, then the cost of building the Octree might weigh out the benefits of fast lookup. But look at it this way. Say you have 1000 triangles and need to check them against each other in your current solution. That's 1000*999 tests. Almost a million tests. With an octree, you'd probably do 2-3 tests per triangle to build the tree. That's 1000*3, 3000 tests. Then during the lookup, you'd have to access nodes, so that's another 3000 tests, and maybe inside each node there are 15-20 triangles so that's another 20000 tests. From a rough guesstimate, you're down from 1000k to 26k tests. But it's also a lot of memory management since you have to move around elements...
And I don't understand how you'd mix in mysql in this. But for mysql related storage, look into **morton code** curves. They might offer some help there.Sat, 10 Dec 2011 11:24:38 GMTStatementAnswer by Statement
http://answers.unity.com/answers/193770/view.html
**Spatial culling** might help you out here. There are many ways of doing this, but one of the more popular ones is probably the [Octree][1]. The idea is to store information in the tree about which triangles belong to which nodes. This obviously has a setup phase, but once the Octree is populated, getting the actual nearby triangles is much easier. Say you have triangle #379, and you want to find triangles that are close to it; you'd check which nodes that #379 is overlapping and you'll find all *potential* matches. So you'll get a *subset* of the triangles to work with, probably a few orders of magnitude less, which should quicken up your neighbor tests considerably.
You [might be lucky][2] and find some existing Octree implementation, but making your own can be a fun experience.
[1]: http://en.wikipedia.org/wiki/Octree
[2]: https://www.google.com/search?q=Unity+OctreeSat, 10 Dec 2011 00:54:59 GMTStatementAnswer by aldonaletto
http://answers.unity.com/answers/193769/view.html
Since neighbor triangles in a mesh share one or more vertex *(the vertex coordinates, not necessarily the vertex indexes!)*, one can loop over all triangles comparing their vertex coordinates to the desired triangle vertices - any match means that the triangle is a neighbor (not necessarily in the same plane):
var i: int = myTriangle * 3; // find the vertices of myTriangle...
var v1: Vector3 = vertices[triangles[i++]]; // and store them in
var v2: Vector3 = vertices[triangles[i++]]; // v1, v2 and v3
var v3: Vector3 = vertices[triangles[i]];
for (i = 0; i < triangles.length; i++){
// compare each vertex to v1, v2 and v3:
var v: Vector3 = vertices[triangles[i]];
if (v == v1 || v == v2 || v == v3){ // if any match found...
var nTri: int = i / 3; // get this triangle's number...
if (nTri != triNum){ // and if it's not myTriangle...
// triangle #nTri is neighbour of #myTriangle
}
}
}
NOTE: Different from the float equality operator (==), which only returns true if both operands are exactly the same, [Vector3 equality operator][1] returns true if both operands are close enough to be considered equal.
SPECIAL CASE: Some "well behaved" meshes (simple shapes, like Unity's cubes or planes) are constructed to avoid vertex duplication: if two or more triangles lie in the same face and share the same vertex, the vertex is stored only once. In these "well behaved" cases there's a much faster method to find neighbor triangles: loop over all triangles and compare their vertex indexes to the three ones of the main triangle - any match means that the triangle is a neighbor, and is in the same face:
var i: int = myTriangle * 3; // each triangle occupies 3 entries in the triangles array
var v1: int = triangles[i++]; // get v1, v2 and v3,
var v2: int = triangles[i++]; // the 3 vertex indexes of
var v3: int = triangles[i]; // triangle #myTriangle
for (i = 0; i < triangles.length; i++){
// compare each vertex index to v1, v2 and v3:
var v: int = triangles[i];
if (v == v1 || v == v2 || v == v3){ // if any common vertex found...
var nTri: int = i / 3; // find the triangle number...
if (nTri != myTriangle){ // and if it's diff from #myTriangle...
// triangle #nTri is neighbour of triangle #myTriangle
}
}
}
Int comparisons are way faster than Vector3 equality (which requires some internal distance evaluation). Obviously, this method is restricted to the "well behaved" cases above mentioned - if applied to a "badly behaved" mesh, some neighbors will not be found. If you're not sure about your meshes, it's better to compare the actual vertex coordinates using the first method.
[1]: http://unity3d.com/support/documentation/ScriptReference/Vector3-operator_eq.htmlSat, 10 Dec 2011 00:39:03 GMTaldonaletto