예제 #1
0
    /// <summary>
    ///     Sends the mesh filter's triangles and their acoustic texture to Spatial Audio
    /// </summary>
    /// <param name="acousticTexture"></param>
    /// <param name="meshFilter"></param>
    public static void AddGeometrySet(AK.Wwise.AcousticTexture acousticTexture, UnityEngine.MeshFilter meshFilter, ulong roomID, bool enableDiffraction, bool enableDiffractionOnBoundaryEdges)
    {
        if (!AkSoundEngine.IsInitialized())
        {
            return;
        }

        if (meshFilter == null)
        {
            UnityEngine.Debug.Log("AddGeometrySet(): No mesh found!");
        }
        else
        {
            var mesh      = meshFilter.sharedMesh;
            var vertices  = mesh.vertices;
            var triangles = mesh.triangles;

            // 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;

            using (var surfaceArray = new AkAcousticSurfaceArray(1))
            {
                var surface = surfaceArray[0];
                surface.textureID            = acousticTexture.Id;
                surface.reflectorChannelMask = unchecked ((uint)-1);
                surface.strName = meshFilter.gameObject.name;

                using (var vertexArray = new AkVertexArray(vertexCount))
                {
                    for (var v = 0; v < vertexCount; ++v)
                    {
                        var point = meshFilter.transform.TransformPoint(uniqueVerts[v]);
                        using (var akVert = vertexArray[v])
                        {
                            akVert.X = point.x;
                            akVert.Y = point.y;
                            akVert.Z = point.z;
                        }
                    }

                    var numTriangles = mesh.triangles.Length / 3;
                    using (var triangleArray = new AkTriangleArray(numTriangles))
                    {
                        for (var i = 0; i < numTriangles; ++i)
                        {
                            using (var triangle = triangleArray[i])
                            {
                                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)0;
                            }
                        }

                        AkSoundEngine.SetGeometry(GetAkGeometrySetID(meshFilter), triangleArray, (uint)triangleArray.Count(), vertexArray, (uint)vertexArray.Count(), surfaceArray, (uint)surfaceArray.Count(), roomID, enableDiffraction, enableDiffractionOnBoundaryEdges);
                    }
                }
            }
        }
    }
    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);
                }
            }
    }