Answers for "Dynamically combine verticies that share the same space"
http://answers.unity.com/questions/228841/dynamically-combine-verticies-that-share-the-same.html
The latest answers for the question "Dynamically combine verticies that share the same space"Answer by kilik128
http://answers.unity.com/answers/667535/view.html
is Uv destroy for my try
but vertex workingWed, 19 Mar 2014 01:39:45 GMTkilik128Answer by boxiness
http://answers.unity.com/answers/666626/view.html
Numberkruncher I modified your code to use uniform spatial partitioning. Now it should be like 100 times faster on large meshes. Hope this can help someone.
public static void AutoWeld (Mesh mesh, float threshold, float bucketStep) {
Vector3[] oldVertices = mesh.vertices;
Vector3[] newVertices = new Vector3[oldVertices.Length];
int[] old2new = new int[oldVertices.Length];
int newSize = 0;
// Find AABB
Vector3 min = new Vector3 (float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 max = new Vector3 (float.MinValue, float.MinValue, float.MinValue);
for (int i = 0; i < oldVertices.Length; i++) {
if (oldVertices[i].x < min.x) min.x = oldVertices[i].x;
if (oldVertices[i].y < min.y) min.y = oldVertices[i].y;
if (oldVertices[i].z < min.z) min.z = oldVertices[i].z;
if (oldVertices[i].x > max.x) max.x = oldVertices[i].x;
if (oldVertices[i].y > max.y) max.y = oldVertices[i].y;
if (oldVertices[i].z > max.z) max.z = oldVertices[i].z;
}
// Make cubic buckets, each with dimensions "bucketStep"
int bucketSizeX = Mathf.FloorToInt ((max.x - min.x) / bucketStep) + 1;
int bucketSizeY = Mathf.FloorToInt ((max.y - min.y) / bucketStep) + 1;
int bucketSizeZ = Mathf.FloorToInt ((max.z - min.z) / bucketStep) + 1;
List<int>[,,] buckets = new List<int>[bucketSizeX, bucketSizeY, bucketSizeZ];
// Make new vertices
for (int i = 0; i < oldVertices.Length; i++) {
// Determine which bucket it belongs to
int x = Mathf.FloorToInt ((oldVertices[i].x - min.x) / bucketStep);
int y = Mathf.FloorToInt ((oldVertices[i].y - min.y) / bucketStep);
int z = Mathf.FloorToInt ((oldVertices[i].z - min.z) / bucketStep);
// Check to see if it's already been added
if (buckets[x, y, z] == null)
buckets[x, y, z] = new List<int> (); // Make buckets lazily
for (int j = 0; j < buckets[x, y, z].Count; j++) {
Vector3 to = newVertices[buckets[x, y, z][j]] - oldVertices[i];
if (Vector3.SqrMagnitude (to) < threshold) {
old2new[i] = buckets[x, y, z][j];
goto skip; // Skip to next old vertex if this one is already there
}
}
// Add new vertex
newVertices[newSize] = oldVertices[i];
buckets[x, y, z].Add (newSize);
old2new[i] = newSize;
newSize++;
skip:;
}
// Make new triangles
int[] oldTris = mesh.triangles;
int[] newTris = new int[oldTris.Length];
for (int i = 0; i < oldTris.Length; i++) {
newTris[i] = old2new[oldTris[i]];
}
Vector3[] finalVertices = new Vector3[newSize];
for (int i = 0; i < newSize; i++)
finalVertices[i] = newVertices[i];
mesh.Clear();
mesh.vertices = finalVertices;
mesh.triangles = newTris;
mesh.RecalculateNormals ();
mesh.Optimize ();
}Tue, 18 Mar 2014 02:25:52 GMTboxinessAnswer by aldonaletto
http://answers.unity.com/answers/230762/view.html
You must not share equal vertices when their uv or normals are different, what usually happens at the edges of different faces, or to "close" a curved surface. Consider the Unity cube: it has 24 vertices (4 per face) instead of just 8, because the normals (and uv, I guess) are different at the edges.<br>
In order to do a safer vertex reduction, you should also compare uv and normals of equal vertices. To further complicate matters, there may exist other less popular properties associated to each vertex, like uv2, tangents and colors, which should be compared too for a 100% safe vertex reduction (take a look at the [Mesh doc][1] for a complete list).<br>
NOTE: I would also replace the first *foreach* by a regular *for (int k=0;...;...)* - I have not found any .NET doc ensuring that the *foreach* sequence also starts at 0.
[1]: http://unity3d.com/support/documentation/ScriptReference/Mesh.htmlFri, 23 Mar 2012 00:37:35 GMTaldonalettoAnswer by numberkruncher
http://answers.unity.com/answers/230713/view.html
I think the answer is that this is not feasible. I have worked out how to write this logic and have points 1/3/4 working great. Here is the code that I wrote for step 2.
Whilst this does in fact weld the verticies together, it screws up the UV coordinates because it seems that there can only be one UV coordinate pair for each vertex. This has had the effect of (properly mapped->mirrored->stretched->mirrored->properly mapped->...)
If anybody knows how to solve this problem then that would be fantastic. Still, here is the welding code that I wrote should it be of any use to anybody:
private void AutoWeld(Mesh mesh, float threshold) {
Vector3[] verts = mesh.vertices;
// Build new vertex buffer and remove "duplicate" verticies
// that are within the given threshold.
List<Vector3> newVerts = new List<Vector3>();
List<Vector2> newUVs = new List<Vector2>();
int k = 0;
foreach (Vector3 vert in verts) {
// Has vertex already been added to newVerts list?
foreach (Vector3 newVert in newVerts)
if (Vector3.Distance(newVert, vert) <= threshold)
goto skipToNext;
// Accept new vertex!
newVerts.Add(vert);
newUVs.Add(mesh.uv[k]);
skipToNext:;
++k;
}
// Rebuild triangles using new verticies
int[] tris = mesh.triangles;
for (int i = 0; i < tris.Length; ++i) {
// Find new vertex point from buffer
for (int j = 0; j < newVerts.Count; ++j) {
if (Vector3.Distance(newVerts[j], verts[ tris[i] ]) <= threshold) {
tris[i] = j;
break;
}
}
}
// Update mesh!
mesh.Clear();
mesh.vertices = newVerts.ToArray();
mesh.triangles = tris;
mesh.uv = newUVs.ToArray();
mesh.RecalculateBounds();
}Thu, 22 Mar 2012 21:44:51 GMTnumberkruncher