В максе эта операция называется weld.
Не учитываю вариант, когда количество треугольников изменяется.
Никак не получается . Вместо склееного меша получается какая-то каша.
По-ходу это как-то связано с тем как юнити добавляет в меш дополнительные вершины (+ я накосячил, очевидно).
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class CharPartsContourWelder : MonoBehaviour
{
public GameObject[] parts;
MeshFilter mesh_filter;
public float delta = 0.5f;
void Start()
{
List<CombineInstance> combineInstances = new List<CombineInstance>();
for (int sub = 0; sub < parts.Length; sub++)
{
CombineInstance ci = new CombineInstance();
ci.mesh = parts[sub].GetComponent<MeshFilter>().mesh;
ci.transform = parts[sub].transform.localToWorldMatrix;
parts[sub].renderer.enabled = false;
combineInstances.Add(ci);
}
mesh_filter = gameObject.GetComponent<MeshFilter>();
mesh_filter.mesh = new Mesh();
mesh_filter.mesh.CombineMeshes(combineInstances.ToArray(), true, true);
int length = mesh_filter.mesh.vertexCount;
int tri_length = mesh_filter.mesh.triangles.Length;
Vector3[] vec = new Vector3[length];
int[] tris = new int[tri_length];
mesh_filter.mesh.vertices.CopyTo(vec, 0);
mesh_filter.mesh.triangles.CopyTo(tris, 0);
int c = 0;
List<int> vert_id_list = new List<int>();
List<Vector3> vec_list = new List<Vector3>(vec);
List<int> tri_list = new List<int>(tris);
int i = 0;
int j = 0;
int cc = 0;
while (i < length - 1)
{
j = i + 1;
while (j < length)
{
if (Vector3.Distance(vec_list[i], vec_list[j]) < delta)
{
Vector3 tmp = vec_list[i];
vec_list[i] = vec_list[j] = tmp;
vec_list.Remove(vec_list[j]);
length--;
for (int yy = 0; yy < tri_length; yy++)
{
if (tris[yy] == j)
tris[yy] = i;
if (tris[yy] > j)
{
tris[yy]--;
}
}
}
else
{
j++;
}
}
i++;
};
vec = new Vector3[vec_list.Count];
vec_list.CopyTo(vec);
mesh_filter.mesh.triangles = tris;
mesh_filter.mesh.vertices = vec;
}
}
using System.Collections;
using System.Collections.Generic;
public class CharPartsContourWelder : MonoBehaviour
{
public GameObject[] parts;
MeshFilter mesh_filter;
public float delta = 0.5f;
void Start()
{
List<CombineInstance> combineInstances = new List<CombineInstance>();
for (int sub = 0; sub < parts.Length; sub++)
{
CombineInstance ci = new CombineInstance();
ci.mesh = parts[sub].GetComponent<MeshFilter>().mesh;
ci.transform = parts[sub].transform.localToWorldMatrix;
parts[sub].renderer.enabled = false;
combineInstances.Add(ci);
}
mesh_filter = gameObject.GetComponent<MeshFilter>();
mesh_filter.mesh = new Mesh();
mesh_filter.mesh.CombineMeshes(combineInstances.ToArray(), true, true);
int length = mesh_filter.mesh.vertexCount;
int tri_length = mesh_filter.mesh.triangles.Length;
Vector3[] vec = new Vector3[length];
int[] tris = new int[tri_length];
mesh_filter.mesh.vertices.CopyTo(vec, 0);
mesh_filter.mesh.triangles.CopyTo(tris, 0);
int c = 0;
List<int> vert_id_list = new List<int>();
List<Vector3> vec_list = new List<Vector3>(vec);
List<int> tri_list = new List<int>(tris);
int i = 0;
int j = 0;
int cc = 0;
while (i < length - 1)
{
j = i + 1;
while (j < length)
{
if (Vector3.Distance(vec_list[i], vec_list[j]) < delta)
{
Vector3 tmp = vec_list[i];
vec_list[i] = vec_list[j] = tmp;
vec_list.Remove(vec_list[j]);
length--;
for (int yy = 0; yy < tri_length; yy++)
{
if (tris[yy] == j)
tris[yy] = i;
if (tris[yy] > j)
{
tris[yy]--;
}
}
}
else
{
j++;
}
}
i++;
};
vec = new Vector3[vec_list.Count];
vec_list.CopyTo(vec);
mesh_filter.mesh.triangles = tris;
mesh_filter.mesh.vertices = vec;
}
}