public OCMeshBuilder FromMesh(UnityEngine.Mesh mesh) { if (mesh == null) { return(this); } _vertices.AddRange(mesh.vertices); _colors.AddRange(mesh.colors); _normals.AddRange(mesh.normals); _uv.AddRange(mesh.uv); for (int i = 0; i < mesh.subMeshCount; ++i) { AddIndices(0, mesh.GetTriangles(i)); } return(this); }
public static object Serialize_UnityMesh(object obj, System.Type type, OverloadLevelConvertSerializer serializer) { uint version = serializer.Version; UnityEngine.Mesh mesh = (UnityEngine.Mesh)obj; int flags; if (version <= 3) { // old version, we just had 'colors' flags = 1; } else { // new version, use a flags value to report what we have if (serializer.IsWriting) { flags = 0; if (mesh.colors != null && mesh.colors.Length > 0) { flags |= 1; } if (mesh.colors32 != null && mesh.colors32.Length > 0) { flags |= 2; } serializer.SerializeOut_int32(flags); } else { flags = serializer.SerializeIn_int32(); } } serializer.SerializeX(mesh, x => x.name); serializer.SerializeX(mesh, x => x.vertices); // Note: vertices must come first since the other fields may check size invariants serializer.SerializeX(mesh, x => x.uv); serializer.SerializeX(mesh, x => x.uv2); serializer.SerializeX(mesh, x => x.uv3); serializer.SerializeX(mesh, x => x.normals); serializer.SerializeX(mesh, x => x.tangents); if ((flags & 1) != 0) { serializer.SerializeX(mesh, x => x.colors); } if ((flags & 2) != 0) { serializer.SerializeX(mesh, x => x.colors32); } if (version > 3) { serializer.SerializeX(mesh, x => x.boneWeights); serializer.SerializeX(mesh, x => x.bindposes); } if (serializer.IsWriting) { Int32 numSubmeshes = mesh.subMeshCount; serializer.SerializeOut_int32(numSubmeshes); for (Int32 i = 0; i < numSubmeshes; ++i) { Int32[] tris = mesh.GetTriangles(i); serializer.SerializeOut_array(typeof(Int32), tris); } } else { Int32 numSubmeshes = serializer.SerializeIn_int32(); mesh.subMeshCount = numSubmeshes; for (Int32 i = 0; i < numSubmeshes; ++i) { Int32[] tris = (Int32[])serializer.SerializeIn_array(typeof(Int32)); mesh.SetTriangles(tris, i); } } return(mesh); }
private static void SetGeometryFromMesh( UnityEngine.Mesh mesh, AK.Wwise.AcousticTexture[] acousticTextures, float[] occlusionValues, UnityEngine.Transform transform, ulong geometryID, ulong associatedRoomID, bool enableDiffraction, bool enableDiffractionOnBoundaryEdges, string name = "") { var vertices = mesh.vertices; // Remove duplicate vertices var vertRemap = new int[vertices.Length]; var uniqueVerts = new System.Collections.Generic.List <UnityEngine.Vector3>(); var vertDict = new System.Collections.Generic.Dictionary <UnityEngine.Vector3, int>(); for (var v = 0; v < vertices.Length; ++v) { int vertIdx = 0; if (!vertDict.TryGetValue(vertices[v], out vertIdx)) { vertIdx = uniqueVerts.Count; uniqueVerts.Add(vertices[v]); vertDict.Add(vertices[v], vertIdx); } vertRemap[v] = vertIdx; } int vertexCount = uniqueVerts.Count; var vertexArray = new UnityEngine.Vector3[vertexCount]; for (var v = 0; v < vertexCount; ++v) { var point = transform.TransformPoint(uniqueVerts[v]); vertexArray[v].x = point.x; vertexArray[v].y = point.y; vertexArray[v].z = point.z; } int surfaceCount = mesh.subMeshCount; var numTriangles = mesh.triangles.Length / 3; if ((mesh.triangles.Length % 3) != 0) { UnityEngine.Debug.LogFormat("SetGeometryFromMesh({0}): Wrong number of triangles", mesh.name); } using (var surfaceArray = new AkAcousticSurfaceArray(surfaceCount)) using (var triangleArray = new AkTriangleArray(numTriangles)) { int triangleArrayIdx = 0; for (var s = 0; s < surfaceCount; ++s) { var surface = surfaceArray[s]; var triangles = mesh.GetTriangles(s); var triangleCount = triangles.Length / 3; if ((triangles.Length % 3) != 0) { UnityEngine.Debug.LogFormat("SetGeometryFromMesh({0}): Wrong number of triangles in submesh {1}", mesh.name, s); } AK.Wwise.AcousticTexture acousticTexture = null; float occlusionValue = 1.0f; if (s < acousticTextures.Length) { acousticTexture = acousticTextures[s]; } if (s < occlusionValues.Length) { occlusionValue = occlusionValues[s]; } surface.textureID = acousticTexture == null ? AK.Wwise.AcousticTexture.InvalidId : acousticTexture.Id; surface.occlusion = occlusionValue; surface.strName = name + "_" + mesh.name + "_" + s; for (var i = 0; i < triangleCount; ++i) { var triangle = triangleArray[triangleArrayIdx]; triangle.point0 = (ushort)vertRemap[triangles[3 * i + 0]]; triangle.point1 = (ushort)vertRemap[triangles[3 * i + 1]]; triangle.point2 = (ushort)vertRemap[triangles[3 * i + 2]]; triangle.surface = (ushort)s; if (triangle.point0 != triangle.point1 && triangle.point0 != triangle.point2 && triangle.point1 != triangle.point2) { ++triangleArrayIdx; } else { UnityEngine.Debug.LogFormat("SetGeometryFromMesh({0}): Skipped degenerate triangle({1}, {2}, {3}) in submesh {4}", mesh.name, 3 * i + 0, 3 * i + 1, 3 * i + 2, s); } } } if (triangleArrayIdx > 0) { AkSoundEngine.SetGeometry( geometryID, triangleArray, (uint)triangleArrayIdx, vertexArray, (uint)vertexArray.Length, surfaceArray, (uint)surfaceArray.Count(), associatedRoomID, enableDiffraction, enableDiffractionOnBoundaryEdges); } else { UnityEngine.Debug.LogFormat("SetGeometry({0}): No valid triangle was found. Geometry was not set", mesh.name); } } }
/// <summary> /// Decimates a mesh. /// </summary> /// <param name="mesh">The mesh to decimate.</param> /// <param name="transform">The mesh transform.</param> /// <param name="quality">The desired quality.</param> /// <param name="recalculateNormals">If normals should be recalculated.</param> /// <param name="statusCallback">The optional status report callback.</param> /// <returns>The decimated mesh.</returns> public static UMesh DecimateMesh(UMesh mesh, UMatrix transform, float quality, bool recalculateNormals, DecimationAlgorithm.StatusReportCallback statusCallback = null) { if (mesh == null) { throw new ArgumentNullException("mesh"); } int subMeshCount = mesh.subMeshCount; var meshVertices = mesh.vertices; var meshNormals = mesh.normals; var meshTangents = mesh.tangents; var meshUV1 = mesh.uv; var meshUV2 = mesh.uv2; var meshUV3 = mesh.uv3; var meshUV4 = mesh.uv4; var meshColors = mesh.colors; var meshBoneWeights = mesh.boneWeights; var meshBindposes = mesh.bindposes; int totalTriangleCount = 0; var meshIndices = new int[subMeshCount][]; for (int i = 0; i < subMeshCount; i++) { meshIndices[i] = mesh.GetTriangles(i); totalTriangleCount += meshIndices[i].Length / 3; } // Transforms the vertices TransformVertices(meshVertices, ref transform); var vertices = ToSimplifyVertices(meshVertices); quality = UMath.Clamp01(quality); int targetTriangleCount = UMath.CeilToInt(totalTriangleCount * quality); var sourceMesh = new Mesh(vertices, meshIndices); if (meshNormals != null && meshNormals.Length > 0) { sourceMesh.Normals = ToSimplifyVec(meshNormals); } if (meshTangents != null && meshTangents.Length > 0) { sourceMesh.Tangents = ToSimplifyVec(meshTangents); } if (meshUV1 != null && meshUV1.Length > 0) { sourceMesh.UV1 = ToSimplifyVec(meshUV1); } if (meshUV2 != null && meshUV2.Length > 0) { sourceMesh.UV2 = ToSimplifyVec(meshUV2); } if (meshUV3 != null && meshUV3.Length > 0) { sourceMesh.UV3 = ToSimplifyVec(meshUV3); } if (meshUV4 != null && meshUV4.Length > 0) { sourceMesh.UV4 = ToSimplifyVec(meshUV4); } if (meshColors != null && meshColors.Length > 0) { sourceMesh.Colors = ToSimplifyVec(meshColors); } if (meshBoneWeights != null && meshBoneWeights.Length > 0) { sourceMesh.BoneWeights = ToSimplifyBoneWeights(meshBoneWeights); } var algorithm = MeshDecimation.CreateAlgorithm(Algorithm.Default); algorithm.MaxVertexCount = ushort.MaxValue; if (statusCallback != null) { algorithm.StatusReport += statusCallback; } //var destMesh = MeshDecimation.DecimateMeshLossless( sourceMesh); var destMesh = MeshDecimation.DecimateMesh(algorithm, sourceMesh, targetTriangleCount); var newMeshVertices = FromSimplifyVertices(destMesh.Vertices); if (statusCallback != null) { algorithm.StatusReport -= statusCallback; } return(CreateMesh(meshBindposes, newMeshVertices, destMesh, recalculateNormals)); }