/// <summary> /// Creates a new mesh. /// </summary> /// <param name="vertices">The mesh vertices.</param> /// <param name="indices">The mesh sub-mesh indices.</param> /// <param name="normals">The mesh normals.</param> /// <param name="tangents">The mesh tangents.</param> /// <param name="colors">The mesh colors.</param> /// <param name="boneWeights">The mesh bone-weights.</param> /// <param name="uvs2D">The mesh 2D UV sets.</param> /// <param name="uvs3D">The mesh 3D UV sets.</param> /// <param name="uvs4D">The mesh 4D UV sets.</param> /// <param name="bindposes">The mesh bindposes.</param> /// <returns>The created mesh.</returns> public static Mesh CreateMesh(Vector3[] vertices, int[][] indices, Vector3[] normals, Vector4[] tangents, Color[] colors, BoneWeight[] boneWeights, List <Vector2>[] uvs2D, List <Vector3>[] uvs3D, List <Vector4>[] uvs4D, Matrix4x4[] bindposes, BlendShape[] blendShapes) { if (vertices == null) { throw new ArgumentNullException(nameof(vertices)); } else if (indices == null) { throw new ArgumentNullException(nameof(indices)); } var newMesh = new Mesh(); int subMeshCount = indices.Length; #if UNITY_MESH_INDEXFORMAT_SUPPORT IndexFormat indexFormat; var indexMinMax = MeshUtils.GetSubMeshIndexMinMax(indices, out indexFormat); newMesh.indexFormat = indexFormat; #endif if (bindposes != null && bindposes.Length > 0) { newMesh.bindposes = bindposes; } newMesh.subMeshCount = subMeshCount; newMesh.vertices = vertices; if (normals != null && normals.Length > 0) { newMesh.normals = normals; } if (tangents != null && tangents.Length > 0) { newMesh.tangents = tangents; } if (colors != null && colors.Length > 0) { newMesh.colors = colors; } if (boneWeights != null && boneWeights.Length > 0) { newMesh.boneWeights = boneWeights; } if (uvs2D != null) { for (int uvChannel = 0; uvChannel < uvs2D.Length; uvChannel++) { if (uvs2D[uvChannel] != null && uvs2D[uvChannel].Count > 0) { newMesh.SetUVs(uvChannel, uvs2D[uvChannel]); } } } if (uvs3D != null) { for (int uvChannel = 0; uvChannel < uvs3D.Length; uvChannel++) { if (uvs3D[uvChannel] != null && uvs3D[uvChannel].Count > 0) { newMesh.SetUVs(uvChannel, uvs3D[uvChannel]); } } } if (uvs4D != null) { for (int uvChannel = 0; uvChannel < uvs4D.Length; uvChannel++) { if (uvs4D[uvChannel] != null && uvs4D[uvChannel].Count > 0) { newMesh.SetUVs(uvChannel, uvs4D[uvChannel]); } } } if (blendShapes != null) { MeshUtils.ApplyMeshBlendShapes(newMesh, blendShapes); } for (int subMeshIndex = 0; subMeshIndex < subMeshCount; subMeshIndex++) { var subMeshTriangles = indices[subMeshIndex]; #if UNITY_MESH_INDEXFORMAT_SUPPORT var minMax = indexMinMax[subMeshIndex]; if (indexFormat == UnityEngine.Rendering.IndexFormat.UInt16 && minMax.y > ushort.MaxValue) { int baseVertex = minMax.x; for (int index = 0; index < subMeshTriangles.Length; index++) { subMeshTriangles[index] -= baseVertex; } newMesh.SetTriangles(subMeshTriangles, subMeshIndex, false, baseVertex); } else { newMesh.SetTriangles(subMeshTriangles, subMeshIndex, false, 0); } #else newMesh.SetTriangles(subMeshTriangles, subMeshIndex, false); #endif } newMesh.RecalculateBounds(); return(newMesh); }
/// <summary> /// Creates a new mesh. /// </summary> /// <param name="vertices">The mesh vertices.</param> /// <param name="indices">The mesh sub-mesh indices.</param> /// <param name="normals">The mesh normals.</param> /// <param name="tangents">The mesh tangents.</param> /// <param name="colors">The mesh colors.</param> /// <param name="boneWeights">The mesh bone-weights.</param> /// <param name="uvs2D">The mesh 2D UV sets.</param> /// <param name="uvs3D">The mesh 3D UV sets.</param> /// <param name="uvs4D">The mesh 4D UV sets.</param> /// <param name="bindposes">The mesh bindposes.</param> /// <returns>The created mesh.</returns> public static Mesh CreateMesh(Vector3[] vertices, int[][] indices, Vector3[] normals, Vector4[] tangents, Color[] colors, BoneWeight[] boneWeights, List <Vector2>[] uvs2D, List <Vector3>[] uvs3D, List <Vector4>[] uvs4D, Matrix4x4[] bindposes, BlendShape[] blendShapes) { var newMesh = new Mesh(); int subMeshCount = indices.Length; #if UNITY_MESH_INDEXFORMAT_SUPPORT IndexFormat indexFormat; var indexMinMax = MeshUtils.GetSubMeshIndexMinMax(indices, out indexFormat); newMesh.indexFormat = indexFormat; #endif if (bindposes != null && bindposes.Length > 0) { newMesh.bindposes = bindposes; } newMesh.subMeshCount = subMeshCount; newMesh.vertices = vertices; // If after assigning normals blendshapes are assigned, then blendshapes do not work correctly // In URP and HDRP configurations, so we add blendshapes first and then assign normals if (blendShapes != null) { MeshUtils.ApplyMeshBlendShapes(newMesh, blendShapes); } if (normals != null && normals.Length > 0) { newMesh.normals = normals; } if (tangents != null && tangents.Length > 0) { newMesh.tangents = tangents; } if (colors != null && colors.Length > 0) { newMesh.colors = colors; } if (boneWeights != null && boneWeights.Length > 0) { newMesh.boneWeights = boneWeights; } if (uvs2D != null) { for (int uvChannel = 0; uvChannel < uvs2D.Length; uvChannel++) { if (uvs2D[uvChannel] != null && uvs2D[uvChannel].Count > 0) { newMesh.SetUVs(uvChannel, uvs2D[uvChannel]); } } } if (uvs3D != null) { for (int uvChannel = 0; uvChannel < uvs3D.Length; uvChannel++) { if (uvs3D[uvChannel] != null && uvs3D[uvChannel].Count > 0) { newMesh.SetUVs(uvChannel, uvs3D[uvChannel]); } } } if (uvs4D != null) { for (int uvChannel = 0; uvChannel < uvs4D.Length; uvChannel++) { if (uvs4D[uvChannel] != null && uvs4D[uvChannel].Count > 0) { newMesh.SetUVs(uvChannel, uvs4D[uvChannel]); } } } //if (blendShapes != null) //{ // MeshUtils.ApplyMeshBlendShapes(newMesh, blendShapes); //baw did //} for (int subMeshIndex = 0; subMeshIndex < subMeshCount; subMeshIndex++) { var subMeshTriangles = indices[subMeshIndex]; #if UNITY_MESH_INDEXFORMAT_SUPPORT var minMax = indexMinMax[subMeshIndex]; if (indexFormat == UnityEngine.Rendering.IndexFormat.UInt16 && minMax.y > ushort.MaxValue) { int baseVertex = minMax.x; for (int index = 0; index < subMeshTriangles.Length; index++) { subMeshTriangles[index] -= baseVertex; } newMesh.SetTriangles(subMeshTriangles, subMeshIndex, false, baseVertex); } else { newMesh.SetTriangles(subMeshTriangles, subMeshIndex, false, 0); } #else newMesh.SetTriangles(subMeshTriangles, subMeshIndex, false); #endif } newMesh.RecalculateBounds(); return(newMesh); }