Exemple #1
0
    private void GetVertexAndIndexData(
        IntPtr asset,
        ovrAvatarAssetType meshType,
        out long vertexCount,
        out IntPtr vertexBuffer,
        out uint indexCount,
        out IntPtr indexBuffer)
    {
        vertexCount  = 0;
        vertexBuffer = IntPtr.Zero;
        indexCount   = 0;
        indexBuffer  = IntPtr.Zero;

        switch (meshType)
        {
        case ovrAvatarAssetType.Mesh:
            vertexCount  = CAPI.ovrAvatarAsset_GetMeshData(asset).vertexCount;
            vertexBuffer = CAPI.ovrAvatarAsset_GetMeshData(asset).vertexBuffer;
            indexCount   = CAPI.ovrAvatarAsset_GetMeshData(asset).indexCount;
            indexBuffer  = CAPI.ovrAvatarAsset_GetMeshData(asset).indexBuffer;
            break;

        case ovrAvatarAssetType.CombinedMesh:
            vertexCount  = CAPI.ovrAvatarAsset_GetCombinedMeshData(asset).vertexCount;
            vertexBuffer = CAPI.ovrAvatarAsset_GetCombinedMeshData(asset).vertexBuffer;
            indexCount   = CAPI.ovrAvatarAsset_GetCombinedMeshData(asset).indexCount;
            indexBuffer  = CAPI.ovrAvatarAsset_GetCombinedMeshData(asset).indexBuffer;
            break;

        default:
            break;
        }
    }
Exemple #2
0
    private void SetSkinnedBindPose(IntPtr asset, ovrAvatarAssetType meshType)
    {
        switch (meshType)
        {
        case ovrAvatarAssetType.Mesh:
            skinnedBindPose = CAPI.ovrAvatarAsset_GetMeshData(asset).skinnedBindPose;
            break;

        case ovrAvatarAssetType.CombinedMesh:
            skinnedBindPose = CAPI.ovrAvatarAsset_GetCombinedMeshData(asset).skinnedBindPose;
            break;

        default:
            break;
        }
    }
    public OvrAvatarAssetMesh(UInt64 _assetId, IntPtr asset, ovrAvatarAssetType meshType)
    {
        assetID   = _assetId;
        mesh      = new Mesh();
        mesh.name = "Procedural Geometry for asset " + _assetId;

        switch (meshType)
        {
        case ovrAvatarAssetType.Mesh:
        {
            ovrAvatarMeshAssetData meshAssetData = CAPI.ovrAvatarAsset_GetMeshData(asset);

            AvatarLogger.Log(
                "OvrAvatarAssetMesh: "
                + _assetId
                + " "
                + meshType.ToString()
                + " VertexCount:"
                + meshAssetData.vertexCount);


            long         vertexCount = (long)meshAssetData.vertexCount;
            Vector3[]    vertices    = new Vector3[vertexCount];
            Vector3[]    normals     = new Vector3[vertexCount];
            Vector4[]    tangents    = new Vector4[vertexCount];
            Vector2[]    uv          = new Vector2[vertexCount];
            Color[]      colors      = new Color[vertexCount];
            BoneWeight[] boneWeights = new BoneWeight[vertexCount];

            long vertexSize        = (long)Marshal.SizeOf(typeof(ovrAvatarMeshVertex));
            long vertexBufferStart = meshAssetData.vertexBuffer.ToInt64();

            for (long i = 0; i < vertexCount; i++)
            {
                long offset = vertexSize * i;

                ovrAvatarMeshVertex vertex = (ovrAvatarMeshVertex)Marshal.PtrToStructure(new IntPtr(vertexBufferStart + offset), typeof(ovrAvatarMeshVertex));
                vertices[i] = new Vector3(vertex.x, vertex.y, -vertex.z);
                normals[i]  = new Vector3(vertex.nx, vertex.ny, -vertex.nz);
                tangents[i] = new Vector4(vertex.tx, vertex.ty, -vertex.tz, vertex.tw);
                uv[i]       = new Vector2(vertex.u, vertex.v);
                colors[i]   = new Color(0, 0, 0, 1);

                boneWeights[i].boneIndex0 = vertex.blendIndices[0];
                boneWeights[i].boneIndex1 = vertex.blendIndices[1];
                boneWeights[i].boneIndex2 = vertex.blendIndices[2];
                boneWeights[i].boneIndex3 = vertex.blendIndices[3];
                boneWeights[i].weight0    = vertex.blendWeights[0];
                boneWeights[i].weight1    = vertex.blendWeights[1];
                boneWeights[i].weight2    = vertex.blendWeights[2];
                boneWeights[i].weight3    = vertex.blendWeights[3];
            }

            mesh.vertices    = vertices;
            mesh.normals     = normals;
            mesh.uv          = uv;
            mesh.tangents    = tangents;
            mesh.boneWeights = boneWeights;
            mesh.colors      = colors;

            skinnedBindPose = meshAssetData.skinnedBindPose;

            ulong   indexCount     = meshAssetData.indexCount;
            Int16[] indices        = new Int16[indexCount];
            IntPtr  indexBufferPtr = meshAssetData.indexBuffer;
            Marshal.Copy(indexBufferPtr, indices, 0, (int)indexCount);
            Int32[] triangles = new Int32[indexCount];
            for (ulong i = 0; i < indexCount; i += 3)
            {
                triangles[i + 2] = (Int32)indices[i];
                triangles[i + 1] = (Int32)indices[i + 1];
                triangles[i]     = (Int32)indices[i + 2];
            }
            mesh.triangles = triangles;

            UInt32 jointCount = skinnedBindPose.jointCount;
            jointNames = new string[jointCount];
            for (UInt32 i = 0; i < jointCount; i++)
            {
                jointNames[i] = Marshal.PtrToStringAnsi(skinnedBindPose.jointNames[i]);
            }
        }
        break;

        case ovrAvatarAssetType.CombinedMesh:
        {
            ovrAvatarMeshAssetDataV2 meshAssetData = CAPI.ovrAvatarAsset_GetCombinedMeshData(asset);

            AvatarLogger.Log(
                "OvrAvatarAssetMesh: "
                + _assetId
                + " "
                + meshType.ToString()
                + " VertexCount:"
                + meshAssetData.vertexCount);

            long         vertexCount = (long)meshAssetData.vertexCount;
            Vector3[]    vertices    = new Vector3[vertexCount];
            Vector3[]    normals     = new Vector3[vertexCount];
            Vector4[]    tangents    = new Vector4[vertexCount];
            Vector2[]    uv          = new Vector2[vertexCount];
            Color[]      colors      = new Color[vertexCount];
            BoneWeight[] boneWeights = new BoneWeight[vertexCount];

            long vertexSize        = (long)Marshal.SizeOf(typeof(ovrAvatarMeshVertexV2));
            long vertexBufferStart = meshAssetData.vertexBuffer.ToInt64();

            for (long i = 0; i < vertexCount; i++)
            {
                long offset = vertexSize * i;

                ovrAvatarMeshVertexV2 vertex = (ovrAvatarMeshVertexV2)Marshal.PtrToStructure(new IntPtr(vertexBufferStart + offset), typeof(ovrAvatarMeshVertexV2));
                vertices[i] = new Vector3(vertex.x, vertex.y, -vertex.z);
                normals[i]  = new Vector3(vertex.nx, vertex.ny, -vertex.nz);
                tangents[i] = new Vector4(vertex.tx, vertex.ty, -vertex.tz, vertex.tw);
                uv[i]       = new Vector2(vertex.u, vertex.v);
                colors[i]   = new Color(vertex.r, vertex.g, vertex.b, vertex.a);

                boneWeights[i].boneIndex0 = vertex.blendIndices[0];
                boneWeights[i].boneIndex1 = vertex.blendIndices[1];
                boneWeights[i].boneIndex2 = vertex.blendIndices[2];
                boneWeights[i].boneIndex3 = vertex.blendIndices[3];
                boneWeights[i].weight0    = vertex.blendWeights[0];
                boneWeights[i].weight1    = vertex.blendWeights[1];
                boneWeights[i].weight2    = vertex.blendWeights[2];
                boneWeights[i].weight3    = vertex.blendWeights[3];
            }

            mesh.vertices    = vertices;
            mesh.normals     = normals;
            mesh.uv          = uv;
            mesh.tangents    = tangents;
            mesh.boneWeights = boneWeights;
            mesh.colors      = colors;

            skinnedBindPose = meshAssetData.skinnedBindPose;

            ulong   indexCount     = meshAssetData.indexCount;
            Int16[] indices        = new Int16[indexCount];
            IntPtr  indexBufferPtr = meshAssetData.indexBuffer;
            Marshal.Copy(indexBufferPtr, indices, 0, (int)indexCount);
            Int32[] triangles = new Int32[indexCount];
            for (ulong i = 0; i < indexCount; i += 3)
            {
                triangles[i + 2] = (Int32)indices[i];
                triangles[i + 1] = (Int32)indices[i + 1];
                triangles[i]     = (Int32)indices[i + 2];
            }
            mesh.triangles = triangles;

            UInt32 jointCount = skinnedBindPose.jointCount;
            jointNames = new string[jointCount];
            for (UInt32 i = 0; i < jointCount; i++)
            {
                jointNames[i] = Marshal.PtrToStringAnsi(skinnedBindPose.jointNames[i]);
            }
        }
        break;

        default:
            throw new Exception("Bad Mesh Asset Type");
        }
    }
Exemple #4
0
    void Update()
    {
        if (Instance == null)
        {
            return;
        }
#if AVATAR_DEBUG
        // Call before ovrAvatarMessage_Pop which flushes the state
        CAPI.ovrAvatar_DrawDebugLines();
#endif

        // Dispatch waiting avatar spec request
        if (avatarSpecificationQueue.Count > 0 &&
            (avatarSpecRequestAvailable ||
             Time.time - lastDispatchedAvatarSpecRequestTime >= AVATAR_SPEC_REQUEST_TIMEOUT))
        {
            avatarSpecRequestAvailable = false;
            AvatarSpecRequestParams avatarSpec = avatarSpecificationQueue.Dequeue();
            DispatchAvatarSpecificationRequest(avatarSpec);
            lastDispatchedAvatarSpecRequestTime = Time.time;
            AvatarLogger.Log("Avatar spec request dispatched: " + avatarSpec._userId);
        }

        IntPtr message = CAPI.ovrAvatarMessage_Pop();
        if (message == IntPtr.Zero)
        {
            return;
        }

        ovrAvatarMessageType messageType = CAPI.ovrAvatarMessage_GetType(message);
        switch (messageType)
        {
        case ovrAvatarMessageType.AssetLoaded:
        {
            ovrAvatarMessage_AssetLoaded assetMessage = CAPI.ovrAvatarMessage_GetAssetLoaded(message);
            IntPtr             asset       = assetMessage.asset;
            UInt64             assetID     = assetMessage.assetID;
            ovrAvatarAssetType assetType   = CAPI.ovrAvatarAsset_GetType(asset);
            OvrAvatarAsset     assetData   = null;
            IntPtr             avatarOwner = IntPtr.Zero;

            switch (assetType)
            {
            case ovrAvatarAssetType.Mesh:
                assetData = new OvrAvatarAssetMesh(assetID, asset, ovrAvatarAssetType.Mesh);
                break;

            case ovrAvatarAssetType.Texture:
                assetData = new OvrAvatarAssetTexture(assetID, asset);
                break;

            case ovrAvatarAssetType.Material:
                assetData = new OvrAvatarAssetMaterial(assetID, asset);
                break;

            case ovrAvatarAssetType.CombinedMesh:
                avatarOwner = CAPI.ovrAvatarAsset_GetAvatar(asset);
                assetData   = new OvrAvatarAssetMesh(assetID, asset, ovrAvatarAssetType.CombinedMesh);
                break;

            case ovrAvatarAssetType.FailedLoad:
                AvatarLogger.LogWarning("Asset failed to load from SDK " + assetID);
                break;

            default:
                throw new NotImplementedException(string.Format("Unsupported asset type format {0}", assetType.ToString()));
            }

            HashSet <assetLoadedCallback> callbackSet;
            if (assetType == ovrAvatarAssetType.CombinedMesh)
            {
                if (!assetCache.ContainsKey(assetID))
                {
                    assetCache.Add(assetID, assetData);
                }

                combinedMeshLoadedCallback callback;
                if (combinedMeshLoadedCallbacks.TryGetValue(avatarOwner, out callback))
                {
                    callback(asset);
                    combinedMeshLoadedCallbacks.Remove(avatarOwner);
                }
                else
                {
                    AvatarLogger.LogWarning("Loaded a combined mesh with no owner: " + assetMessage.assetID);
                }
            }
            else
            {
                if (assetData != null && assetLoadedCallbacks.TryGetValue(assetMessage.assetID, out callbackSet))
                {
                    assetCache.Add(assetID, assetData);

                    foreach (var callback in callbackSet)
                    {
                        callback(assetData);
                    }

                    assetLoadedCallbacks.Remove(assetMessage.assetID);
                }
            }
            break;
        }

        case ovrAvatarMessageType.AvatarSpecification:
        {
            avatarSpecRequestAvailable = true;
            ovrAvatarMessage_AvatarSpecification spec = CAPI.ovrAvatarMessage_GetAvatarSpecification(message);
            HashSet <specificationCallback>      callbackSet;
            if (specificationCallbacks.TryGetValue(spec.oculusUserID, out callbackSet))
            {
                foreach (var callback in callbackSet)
                {
                    callback(spec.avatarSpec);
                }

                specificationCallbacks.Remove(spec.oculusUserID);
            }
            else
            {
                AvatarLogger.LogWarning("Error, got an avatar specification callback from a user id we don't have a record for: " + spec.oculusUserID);
            }
            break;
        }

        default:
            throw new NotImplementedException("Unhandled ovrAvatarMessageType: " + messageType);
        }
        CAPI.ovrAvatarMessage_Free(message);
    }
Exemple #5
0
    public OvrAvatarAssetMesh(UInt64 _assetId, IntPtr asset, ovrAvatarAssetType meshType)
    {
        assetID   = _assetId;
        mesh      = new Mesh();
        mesh.name = "Procedural Geometry for asset " + _assetId;

        SetSkinnedBindPose(asset, meshType);

        long   vertexCount  = 0;
        IntPtr vertexBuffer = IntPtr.Zero;
        uint   indexCount   = 0;
        IntPtr indexBuffer  = IntPtr.Zero;

        GetVertexAndIndexData(asset, meshType, out vertexCount, out vertexBuffer, out indexCount, out indexBuffer);

        AvatarLogger.Log("OvrAvatarAssetMesh: " + _assetId + " " + meshType.ToString() + " VertexCount:" + vertexCount);

        Vector3[]    vertices    = new Vector3[vertexCount];
        Vector3[]    normals     = new Vector3[vertexCount];
        Vector4[]    tangents    = new Vector4[vertexCount];
        Vector2[]    uv          = new Vector2[vertexCount];
        Color[]      colors      = new Color[vertexCount];
        BoneWeight[] boneWeights = new BoneWeight[vertexCount];

        long vertexBufferStart = vertexBuffer.ToInt64();

        // We have different underlying vertex types to unpack, so switch on mesh type.
        switch (meshType)
        {
        case ovrAvatarAssetType.Mesh:
        {
            long vertexSize = (long)Marshal.SizeOf(typeof(ovrAvatarMeshVertex));

            for (long i = 0; i < vertexCount; i++)
            {
                long offset = vertexSize * i;

                ovrAvatarMeshVertex vertex = (ovrAvatarMeshVertex)Marshal.PtrToStructure(new IntPtr(vertexBufferStart + offset), typeof(ovrAvatarMeshVertex));
                vertices[i] = new Vector3(vertex.x, vertex.y, -vertex.z);
                normals[i]  = new Vector3(vertex.nx, vertex.ny, -vertex.nz);
                tangents[i] = new Vector4(vertex.tx, vertex.ty, -vertex.tz, vertex.tw);
                uv[i]       = new Vector2(vertex.u, vertex.v);
                colors[i]   = new Color(0, 0, 0, 1);

                boneWeights[i].boneIndex0 = vertex.blendIndices[0];
                boneWeights[i].boneIndex1 = vertex.blendIndices[1];
                boneWeights[i].boneIndex2 = vertex.blendIndices[2];
                boneWeights[i].boneIndex3 = vertex.blendIndices[3];
                boneWeights[i].weight0    = vertex.blendWeights[0];
                boneWeights[i].weight1    = vertex.blendWeights[1];
                boneWeights[i].weight2    = vertex.blendWeights[2];
                boneWeights[i].weight3    = vertex.blendWeights[3];
            }
        }
        break;

        case ovrAvatarAssetType.CombinedMesh:
        {
            long vertexSize = (long)Marshal.SizeOf(typeof(ovrAvatarMeshVertexV2));

            for (long i = 0; i < vertexCount; i++)
            {
                long offset = vertexSize * i;

                ovrAvatarMeshVertexV2 vertex = (ovrAvatarMeshVertexV2)Marshal.PtrToStructure(new IntPtr(vertexBufferStart + offset), typeof(ovrAvatarMeshVertexV2));
                vertices[i] = new Vector3(vertex.x, vertex.y, -vertex.z);
                normals[i]  = new Vector3(vertex.nx, vertex.ny, -vertex.nz);
                tangents[i] = new Vector4(vertex.tx, vertex.ty, -vertex.tz, vertex.tw);
                uv[i]       = new Vector2(vertex.u, vertex.v);
                colors[i]   = new Color(vertex.r, vertex.g, vertex.b, vertex.a);

                boneWeights[i].boneIndex0 = vertex.blendIndices[0];
                boneWeights[i].boneIndex1 = vertex.blendIndices[1];
                boneWeights[i].boneIndex2 = vertex.blendIndices[2];
                boneWeights[i].boneIndex3 = vertex.blendIndices[3];
                boneWeights[i].weight0    = vertex.blendWeights[0];
                boneWeights[i].weight1    = vertex.blendWeights[1];
                boneWeights[i].weight2    = vertex.blendWeights[2];
                boneWeights[i].weight3    = vertex.blendWeights[3];
            }
        }
        break;

        default:
            throw new Exception("Bad Mesh Asset Type");
        }

        mesh.vertices    = vertices;
        mesh.normals     = normals;
        mesh.uv          = uv;
        mesh.tangents    = tangents;
        mesh.boneWeights = boneWeights;
        mesh.colors      = colors;

        LoadBlendShapes(asset, vertexCount);
        LoadSubmeshes(asset, indexBuffer, indexCount);

        UInt32 jointCount = skinnedBindPose.jointCount;

        jointNames = new string[jointCount];
        for (UInt32 i = 0; i < jointCount; i++)
        {
            jointNames[i] = Marshal.PtrToStringAnsi(skinnedBindPose.jointNames[i]);
        }
    }
Exemple #6
0
    // Update is called once per frame
    void Update()
    {
        IntPtr message = CAPI.ovrAvatarMessage_Pop();

        if (message == IntPtr.Zero)
        {
            return;
        }

        ovrAvatarMessageType messageType = CAPI.ovrAvatarMessage_GetType(message);

        switch (messageType)
        {
        case ovrAvatarMessageType.AssetLoaded:
        {
            ovrAvatarMessage_AssetLoaded assetMessage = CAPI.ovrAvatarMessage_GetAssetLoaded(message);
            IntPtr             asset     = assetMessage.asset;
            UInt64             assetID   = assetMessage.assetID;
            ovrAvatarAssetType assetType = CAPI.ovrAvatarAsset_GetType(asset);
            OvrAvatarAsset     assetData;
            switch (assetType)
            {
            case ovrAvatarAssetType.Mesh:
                assetData = new OvrAvatarAssetMesh(assetID, asset);
                break;

            case ovrAvatarAssetType.Texture:
                assetData = new OvrAvatarAssetTexture(assetID, asset);
                break;

            case ovrAvatarAssetType.Material:
                assetData = new OvrAvatarAssetMaterial(assetID, asset);
                break;

            default:
                throw new NotImplementedException(string.Format("Unsupported asset type format {0}", assetType.ToString()));
            }

            HashSet <assetLoadedCallback> callbackSet;
            if (assetLoadedCallbacks.TryGetValue(assetMessage.assetID, out callbackSet))
            {
                assetCache.Add(assetID, assetData);

                foreach (var callback in callbackSet)
                {
                    callback(assetData);
                }

                assetLoadedCallbacks.Remove(assetMessage.assetID);
            }
            else
            {
                Debug.LogWarning("Loaded an asset with no owner: " + assetMessage.assetID);
            }

            break;
        }

        case ovrAvatarMessageType.AvatarSpecification:
        {
            ovrAvatarMessage_AvatarSpecification spec = CAPI.ovrAvatarMessage_GetAvatarSpecification(message);
            HashSet <specificationCallback>      callbackSet;
            if (specificationCallbacks.TryGetValue(spec.oculusUserID, out callbackSet))
            {
                foreach (var callback in callbackSet)
                {
                    callback(spec.avatarSpec);
                }

                specificationCallbacks.Remove(spec.oculusUserID);
            }
            else
            {
                Debug.LogWarning("Error, got an avatar specification callback from a user id we don't have a record for: " + spec.oculusUserID);
            }
            break;
        }

        default:
            throw new NotImplementedException("Unhandled ovrAvatarMessageType: " + messageType);
        }
        CAPI.ovrAvatarMessage_Free(message);
    }