- Home /
Convex collider sometimes works, sometimes doesn't.
Hi guys, i've asked this question before, but there was no helpfull answer. After spending some time to solve this problem i found some topics an ideas whats wrong. I've created bug repport, and waiting for answer. Ok.
I'm trying to make a convex hull in game and assign to it a convex collider. Genereted convex hull named as "buggy". When i try to set it's collider as convex, an error ocurred. It says:
Adjacencies::CreateDatabase: can't work on non-manifold meshes. UnityEditor.DockArea:OnGUI()
But if i scale this mesh and repeat operation, sometimes convex is created.
To understand why it happens, i created custom meshes which have to be non'manifolds and errorous, but convex collider works fine on them.
I readed some PhysX docs and they says that convex collider can be created from cloud of points and cooked from other mesh... I desided if empty box and inverted normal generates convex normally, then u're using point's cloud. But... if u use point's cloud why my mesh is errorous?
Ok.. The only one thing what i got in mind, that production convex hull from my points in mesh generates non-manifold hull (TJoints or empty space or wtf?), and this process connot be controlled... But guys, this feature is very important to my project, so.. am i right and what sould i do to make this mesh works correctly?
Ok.. here screanshot of buggi mesh:
if we add some scale:
Other meshes:
Answer by XienDev · Dec 03, 2012 at 03:23 PM
I found new thing in PhysX SDK:
NOTE: The hull generation may fail for input point sets which contain certain degenerate configurations. If you feel this to be an issue, please try not to provide input that contains two or more points close to each other, or in other ways would generate very thin triangles. NOTE: As of 2.5 the legacy cooker has been deprecated since its output is not compatible with the hardware collision code.
Ок.. My vertices distanses for working mesh are:
0.1639287 0.140883 0.1536848
0.04036737 0.02971855 0.04332503
0.08544358 0.1271901 0.1483075
0.1271901 0.09134685 0.04332503
0.1432375 0.1269664 0.1188899
0.1269664 0.02627614 0.1135911
0.1153614 0.1432159 0.1639287
And for not working mesh are:
0.1624586 0.1407853 0.1527793
0.04009848 0.02970564 0.0431602
0.0854082 0.1262902 0.1472641
0.1262902 0.09064174 0.0431602
0.1431873 0.126594 0.1187421
0.126594 0.02618538 0.1133408
0.1152456 0.1422343 0.1624586
I think here may be a problem... hm... do some experiments;
each line is triangle vertices distances.. some of triangles are realy very small:
i.e:
0.05025257 6.743496E-07 0.05025324
or
0.9859269 0.9859269 4.768372E-07
Answer by XienDev · Dec 09, 2012 at 10:44 AM
Ok, i've finnaly made a tool to patch mesh and remove small triangles... but i should remove all triangles that are smaller than Vector3.kEpsilon * 1000.0f, but with this params it's also do not work's correctly... ammm.. look at my steps.... this post would be to long.
Before we got started, i post some simple snippets of scripts:
1) Script to check distances from each to each point:
void CheckDistances() { Mesh m = gameObject.GetComponent().mesh; Vector3[] points = m.vertices; for (int i = 0; i < points.Length; i++) { for (int j = i + 1; j < points.Length; j++) { float d = Vector3.Distance(points[i], points[j]); if (d < Vector3.kEpsilon) { Debug.Log("I: "+i+" J: "+ j); } } } }
2) Method i used to check if my triangles are smaller than requared size:
bool checkTriangleForPatch(int index, ref Vector3[] vertices, ref int[] triangles) { bool result = false;
Vector3 p1 = vertices[triangles[index*3]]; Vector3 p2 = vertices[triangles[index*3+1]]; Vector3 p3 = vertices[triangles[index*3+2]];
float a = Vector3.Distance(p1, p2); float b = Vector3.Distance(p2, p3); float c = Vector3.Distance(p3, p1); float p = (a+b+c) / 2.0f; float r = Mathf.Sqrt(((p-a)(p-b)(p-c)) / p); //радиус вписанной окружности if (r*2 < Vector3.kEpsilon) { result = true; } return result; }
3) Main function to patch mesh:
int next = FindNextToPatch(0, ref vertices, ref triangles); if (next == -1) { result = PatchMeshState.NotPatched; return result; } while (next != -1) { List sharedTriangles = GetSharedTriangles(next, ref vertices, ref triangles); if (sharedTriangles.Count > 0) { Edge longestEdge = GetLongestEdge(next, ref vertices, ref triangles); if (longestEdge.Length > Vector3.kEpsilon) { ClipToLongestEdge(next, longestEdge, sharedTriangles, ref vertices, ref triangles); } else { DeleteTriangleAndFillEmptySpace(next, ref sharedTriangles, ref vertices, ref triangles); } } next = FindNextToPatch(0, ref vertices, ref triangles); }
Ok let's took for example a capsule to look how this tool is working(i've edited this tool to remove triangle at id):
Now we patch this triangle via ClipToLongestEdge:
And here we patch same triangle via DeleteTriangleAndFillEmptySpace:
Ok... next step is checking which points are very close to each other in mesh we are interested in:
I: 37 J: 70 I: 41 J: 71
i -> first point; j -> second point; distance between them is less than vector3.kEpsilon (it's like doubles)
And now lets look to these points to be sure that they are close enought(i post one picture, becouse groups at the same positions):
37: x: -3.504073; y: 0.7674599; z: -3.379824;
70: x: -3.504073; y: 0.7674594; z: -3.379824;
41: x: 0.4926167; y: 0.6595895; z: -0.7416723;
71: x: 0.4926167; y: 0.65959; z: -0.7416723'
Getting control mesh stats:
144 -> triangles 74 -> vertices
And checking for bad triangles (if inradius < Vector3.kEpsilon):
Bad triangle id: 12 Bad triangle id: 13 Bad triangle id: 14 Bad triangle id: 15 Bad triangle id: 38 Bad triangle id: 82 Bad triangle id: 83 Bad triangle id: 134 Bad triangle id: 135 Num of bad triangles: 9
Patch it with vector3.kEpsilon:
Patched. Patched triangles count: 12
(why numbers are different is becouse in ClipToLongestEdge, we remove triangle with shared edge equals to shortest edge of bad triangle, if longest is bigger than vector3.kEpsilon, and in secont method, if all edges are less than vector3.kEpsilon, we remove all sharedEdge triangles, and badTriangle (also we remove their bad vertices, in first 1, in second 2 vertices.) )
Ok.. now let's check for distances:
non of vertices is placed near other one at distance is less then Vector3.kEpsilon;
ok, let's check for inradiuses:
Num of bad triangles: 0
and check for stats:
132 <- triangles; 68 <- vertices;
... ok... adding mesh collider and make it convex:
WTF ? I guess, this distance is too short, let's do... vector3.kEpsilon*10, for patch;
NotPatched. 132 <- triangles; 68 <- vertices;
Ok, let's try vector3.kEpsilon*100:
Patched Patched triangles count: 4
stats:
128 <- triangles; 66 <- vertices;
And check for distances and inradius to kEpsilon*100.0f:
Num of bad triangles: 0
triing mesh collider:
f*ck... not working... okey... making min distance to kEpsilon*1000.0f ( 0.01f):
Bad triangle id: 19 Bad triangle id: 25 Bad triangle id: 27 Bad triangle id: 40 Bad triangle id: 48 Bad triangle id: 52 Bad triangle id: 60 Bad triangle id: 61 Bad triangle id: 62 Bad triangle id: 63 Bad triangle id: 65 Bad triangle id: 69 Bad triangle id: 76 Bad triangle id: 80 Bad triangle id: 82 Bad triangle id: 85 Bad triangle id: 88 Bad triangle id: 92 Bad triangle id: 97 Bad triangle id: 98 Bad triangle id: 99 Bad triangle id: 100 Bad triangle id: 102 Bad triangle id: 106 Bad triangle id: 114 Bad triangle id: 120 Bad triangle id: 121 Bad triangle id: 125 Bad triangle id: 126 Num of bad triangles: 29
this tiangles indiametr is less then 0.01 and greater then 0.001 (becouse other we patched in previous steps);
patching it:
Patched. Patched triangles count: 48
80 <- triangles; 42 <- vertices;
trying convex collider:
Yeah.. it's finally works... but wait... Not all points inside a hull... What's NOW ?
and if we slightly change scale, then it works fine:
btw, on every step i removed and added mesh collider to make it's sharedMesh update
and resulting distances:
0.1624586 0.1407853 0.1527793 0.0854082 0.1262902 0.1472641 0.1262902 0.09064174 0.0431602 0.1387644 0.126594 0.12164 0.126594 0.01682952 0.1342831 0.1152456 0.1422343 0.1624586 0.1422343 0.05491636 0.0964755
see more at: http://pastebin.com/DVnBRb82
What's wrong now ?
http://forum.unity3d.com/attachment.php?attachmentid=41644&d=1355047169 <- package with all this meshes