Added Submesh to ModelLoader

This commit is contained in:
FlorianSpeicher
2025-06-06 19:09:40 +02:00
parent a449079b46
commit 5702cbb451

View File

@@ -7,19 +7,167 @@ using UnityEngine;
/// </summary> /// </summary>
public class ModelLoader public class ModelLoader
{ {
public static void LoadChildModelsFromPackedModel(List<ChildModel> appendList, string[] port, string[] nameHuman, public static void LoadChildModelsFromPackedModel(
string[] nameId, Mesh[] meshes, Material[] mats, Vector3[] offset, Quaternion[] rotation, Vector3[] scale, List<Port>[] ports, List<Color>[] colors = null, int fromMesh = 0, int toMesh = -1) List<ChildModel> appendList,
string[] port,
string[] nameHuman,
string[] nameId,
Mesh[] meshes,
Material[] mats,
Vector3[] offset,
Quaternion[] rotation,
Vector3[] scale,
List<Port>[] ports,
List<Color>[] colors = null,
int fromMesh = 0,
int toMesh = -1,
bool useSubmeshes = true
)
{ {
Debug.Log("LoadChildModels " + fromMesh + " to " + toMesh + " from " + mats.Length + " meshes"); Debug.Log("LoadChildModels " + fromMesh + " to " + toMesh + " from " + mats.Length + " meshes");
int sum = 0;
foreach (Mesh mesh in meshes)
{
sum += mesh.subMeshCount;
Debug.Log($"Model has {mesh.subMeshCount} subMeshes");
}
Debug.Log($"LoadChildModels needs at least {sum} Array size and has {port.Length}");
Debug.Log($"port.Length: {port.Length}, nameHuman.Length: {nameHuman.Length}, nameId.Length: {nameId.Length}, meshes.Length: {meshes.Length}, mats.Length: {mats.Length}");
int maxLength = Mathf.Min(port.Length, nameHuman.Length, nameId.Length, meshes.Length, mats.Length);
if (toMesh == -1) if (toMesh == -1)
{ {
toMesh = meshes.Length; toMesh = meshes.Length;
} }
for (int i = 0; i < toMesh - fromMesh; i++) int iOffset = 0;
for (int i = 0; i < Mathf.Min(toMesh - fromMesh + iOffset, maxLength); i++)
{ {
if (i >= port.Length || i >= nameHuman.Length || i >= nameId.Length || i >= meshes.Length || i >= mats.Length)
{
Debug.LogError($"Index {i} liegt außerhalb der Array-Grenzen!");
break;
}
Debug.Log($"{i}. {nameId[i]}:{nameHuman[i]} with {port.Length} ports"); Debug.Log($"{i}. {nameId[i]}:{nameHuman[i]} with {port.Length} ports");
appendList.Add(new ChildModel(port[i], nameHuman[i], nameId[i], meshes[fromMesh + i], mats[i], offset[i], rotation[i], scale[i], ports[i], colors?[i])); appendList.Add(new ChildModel(
port[i],
nameHuman[i],
nameId[i],
meshes[fromMesh + i],
mats[i],
offset[i],
rotation[i],
scale[i],
ports[i],
colors?[i]
));
if (useSubmeshes && meshes[fromMesh + i].subMeshCount > 1)
{
Debug.LogWarning($"{i}. SUBMODEL {nameId[i]}:{nameHuman[i]}");
List<Mesh> subMeshes = GetSubmeshes(meshes[fromMesh + i]);
for (int smi = 1; smi < subMeshes.Count; smi++) // the 0th model is already loaded
{
if (i >= maxLength)
{
Debug.LogError($"Index {i} nach Submesh-Verarbeitung außerhalb der Grenzen!");
break;
}
i++;
iOffset++; // black magic
appendList.Add(new ChildModel(
port[i],
nameHuman[i],
nameId[i],
subMeshes[smi],
mats[i],
offset[i],
rotation[i],
scale[i],
ports[i],
colors?[i]
));
}
}
} }
} }
public static void LoadChildFromPackedModel(
List<ChildModel> appendList,
List<ModelElement> list,
Mesh[] meshes,
int fromMesh = 0,
int toMesh = -1,
bool useSubmeshes = true)
{
List<string> port = new List<string>();
List<string> nameHuman = new List<string>();
List<string> nameId = new List<string>();
List<Material> mats = new List<Material>();
List<Vector3> offset = new List<Vector3>();
List<Quaternion> rotation = new List<Quaternion>();
List<Vector3> scale = new List<Vector3>();
List<List<Port>> ports = new List<List<Port>>();
List<List<Color>> colors = new List<List<Color>>();
foreach (var modelElement in list)
{
port.Add(modelElement.Port);
nameHuman.Add(modelElement.NameHuman);
nameId.Add(modelElement.NameId);
mats.Add(modelElement.Mats);
offset.Add(modelElement.Offset);
rotation.Add(modelElement.Rotation);
scale.Add(modelElement.Scale);
ports.Add(modelElement.Ports);
colors.Add(modelElement.Colors);
}
LoadChildModelsFromPackedModel(appendList, port.ToArray(), nameHuman.ToArray(), nameId.ToArray(),
meshes, mats.ToArray(), offset.ToArray(), rotation.ToArray(),
scale.ToArray(), ports.ToArray(), colors.ToArray(), fromMesh, toMesh, useSubmeshes);
}
public static List<Mesh> GetSubmeshes(Mesh mesh)
{
List<Mesh> subMeshes = new List<Mesh>();
for (int i = 0; i < mesh.subMeshCount; i++)
{
int[] submeshTriangles = mesh.GetTriangles(i);
Mesh subMesh = new Mesh();
List<Vector3> vertices = new List<Vector3>();
List<int> newTriangles = new List<int>();
Dictionary<int, int> vertexMap = new Dictionary<int, int>();
// Map vertices and triangles
for (int j = 0; j < submeshTriangles.Length; j++)
{
int originalVertexIndex = submeshTriangles[j];
if (!vertexMap.ContainsKey(originalVertexIndex))
{
vertexMap.Add(originalVertexIndex, vertices.Count);
vertices.Add(mesh.vertices[originalVertexIndex]);
}
newTriangles.Add(vertexMap[originalVertexIndex]);
}
subMesh.vertices = vertices.ToArray();
subMesh.triangles = newTriangles.ToArray();
// Copy other attributes (UVs, normals, etc.)
if (mesh.uv.Length > 0)
{
List<Vector2> uvs = new List<Vector2>();
foreach (var kvp in vertexMap)
uvs.Add(mesh.uv[kvp.Key]);
subMesh.uv = uvs.ToArray();
}
subMesh.RecalculateNormals();
subMesh.RecalculateBounds();
subMeshes.Add(subMesh);
}
return subMeshes;
}
} }