Example #1
0
            public void Execute()
            {
                var        dracoMesh = (DracoMesh *)dracoTempResources[meshPtrIndex];
                DracoData *data      = null;

                GetAttributeData(dracoMesh, attribute, &data, flip);
                var elementSize = DataTypeSize((DataType)data->dataType) * attribute->numComponents;

#if DRACO_MESH_DATA
                var dst    = mesh.GetVertexData <byte>(streamIndex);
                var dstPtr = ((byte *)dst.GetUnsafePtr()) + offset;
#endif
                for (var v = 0; v < dracoMesh->numVertices; v++)
                {
                    UnsafeUtility.MemCpy(dstPtr + (stride * v), ((byte *)data->data) + (elementSize * v), elementSize);
                }
                ReleaseDracoData(&data);
            }
Example #2
0
            public void Execute()
            {
                if (result[0] < 0)
                {
                    return;
                }
                var        dracoMesh = (DracoMesh *)dracoTempResources[meshPtrIndex];
                DracoData *data      = null;

                GetAttributeData(dracoMesh, attribute, &data, flip);
                var elementSize = DataTypeSize((DataType)data->dataType) * attribute->numComponents;

#if DRACO_MESH_DATA
                var dst    = mesh.GetVertexData <byte>(streamIndex);
                var dstPtr = dst.GetUnsafePtr();
#endif
                UnsafeUtility.MemCpy(dstPtr, (void *)data->data, elementSize * dracoMesh->numVertices);
                ReleaseDracoData(&data);
            }
Example #3
0
    // Creates a Unity mesh from the decoded Draco mesh.
    public unsafe Mesh CreateUnityMesh(DracoMesh *dracoMesh)
    {
        float startTime = Time.realtimeSinceStartup;
        int   numFaces  = dracoMesh->numFaces;

        int[]     newTriangles = new int[dracoMesh->numFaces * 3];
        Vector3[] newVertices  = new Vector3[dracoMesh->numVertices];
        Vector2[] newUVs       = null;
        Vector3[] newNormals   = null;
        Color[]   newColors    = null;
        byte[]    newGenerics  = null;

        // Copy face indices.
        DracoData *indicesData;

        GetMeshIndices(dracoMesh, &indicesData);
        int elementSize =
            DataTypeSize((DracoMeshLoader.DataType)indicesData->dataType);
        int *indices    = (int *)(indicesData->data);
        var  indicesPtr = UnsafeUtility.AddressOf(ref newTriangles[0]);

        UnsafeUtility.MemCpy(indicesPtr, indices,
                             newTriangles.Length * elementSize);
        ReleaseDracoData(&indicesData);

        // Copy positions.
        DracoAttribute *attr = null;

        GetAttributeByType(dracoMesh, AttributeType.POSITION, 0, &attr);
        DracoData *posData = null;

        GetAttributeData(dracoMesh, attr, &posData);
        elementSize = DataTypeSize((DracoMeshLoader.DataType)posData->dataType) *
                      attr->numComponents;
        var newVerticesPtr = UnsafeUtility.AddressOf(ref newVertices[0]);

        UnsafeUtility.MemCpy(newVerticesPtr, (void *)posData->data,
                             dracoMesh->numVertices * elementSize);
        ReleaseDracoData(&posData);
        ReleaseDracoAttribute(&attr);

        // Copy normals.
        if (GetAttributeByType(dracoMesh, AttributeType.NORMAL, 0, &attr))
        {
            DracoData *normData = null;
            if (GetAttributeData(dracoMesh, attr, &normData))
            {
                elementSize =
                    DataTypeSize((DracoMeshLoader.DataType)normData->dataType) *
                    attr->numComponents;
                newNormals = new Vector3[dracoMesh->numVertices];
                var newNormalsPtr = UnsafeUtility.AddressOf(ref newNormals[0]);
                UnsafeUtility.MemCpy(newNormalsPtr, (void *)normData->data,
                                     dracoMesh->numVertices * elementSize);
                Debug.Log("Decoded mesh normals.");
                ReleaseDracoData(&normData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Copy texture coordinates.
        if (GetAttributeByType(dracoMesh, AttributeType.TEX_COORD, 0, &attr))
        {
            DracoData *texData = null;
            if (GetAttributeData(dracoMesh, attr, &texData))
            {
                elementSize =
                    DataTypeSize((DracoMeshLoader.DataType)texData->dataType) *
                    attr->numComponents;
                newUVs = new Vector2[dracoMesh->numVertices];
                var newUVsPtr = UnsafeUtility.AddressOf(ref newUVs[0]);
                UnsafeUtility.MemCpy(newUVsPtr, (void *)texData->data,
                                     dracoMesh->numVertices * elementSize);
                Debug.Log("Decoded mesh texcoords.");
                ReleaseDracoData(&texData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Copy colors.
        if (GetAttributeByType(dracoMesh, AttributeType.COLOR, 0, &attr))
        {
            DracoData *colorData = null;
            if (GetAttributeData(dracoMesh, attr, &colorData))
            {
                elementSize =
                    DataTypeSize((DracoMeshLoader.DataType)colorData->dataType) *
                    attr->numComponents;
                newColors = new Color[dracoMesh->numVertices];
                var newColorsPtr = UnsafeUtility.AddressOf(ref newColors[0]);
                UnsafeUtility.MemCpy(newColorsPtr, (void *)colorData->data,
                                     dracoMesh->numVertices * elementSize);
                Debug.Log("Decoded mesh colors.");
                ReleaseDracoData(&colorData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Copy generic data. This script does not do anyhting with the generic
        // data.
        if (GetAttributeByType(dracoMesh, AttributeType.GENERIC, 0, &attr))
        {
            DracoData *genericData = null;
            if (GetAttributeData(dracoMesh, attr, &genericData))
            {
                elementSize =
                    DataTypeSize((DracoMeshLoader.DataType)genericData->dataType) *
                    attr->numComponents;
                newGenerics = new byte[dracoMesh->numVertices * elementSize];
                var newGenericPtr = UnsafeUtility.AddressOf(ref newGenerics[0]);
                UnsafeUtility.MemCpy(newGenericPtr, (void *)genericData->data,
                                     dracoMesh->numVertices * elementSize);
                Debug.Log("Decoded mesh generic data.");
                ReleaseDracoData(&genericData);
                ReleaseDracoAttribute(&attr);
            }
        }

        float copyDecodedDataTimeMilli =
            (Time.realtimeSinceStartup - startTime) * 1000.0f;

        Debug.Log("copyDecodedDataTimeMilli: " +
                  copyDecodedDataTimeMilli.ToString());

        startTime = Time.realtimeSinceStartup;
        Mesh mesh = new Mesh();

#if UNITY_2017_3_OR_NEWER
        mesh.indexFormat = (newVertices.Length > System.UInt16.MaxValue)
        ? UnityEngine.Rendering.IndexFormat.UInt32
        : UnityEngine.Rendering.IndexFormat.UInt16;
#else
        if (newVertices.Length > System.UInt16.MaxValue)
        {
            throw new System.Exception("Draco meshes with more than 65535 vertices are only supported from Unity 2017.3 onwards.");
        }
#endif

        mesh.vertices = newVertices;
        mesh.SetTriangles(newTriangles, 0, true);
        if (newUVs != null)
        {
            mesh.uv = newUVs;
        }
        if (newNormals != null)
        {
            mesh.normals = newNormals;
        }
        else
        {
            mesh.RecalculateNormals();
            Debug.Log("Mesh doesn't have normals, recomputed.");
        }
        if (newColors != null)
        {
            mesh.colors = newColors;
        }

        float convertTimeMilli =
            (Time.realtimeSinceStartup - startTime) * 1000.0f;
        Debug.Log("convertTimeMilli: " + convertTimeMilli.ToString());
        return(mesh);
    }
    // Creates a Unity mesh from the decoded Draco mesh.
    public unsafe AsyncMesh CreateAsyncMesh(DracoMesh *dracoMesh, MeshAttributes attributes)
    {
        int numFaces = dracoMesh->numFaces;

        AsyncMesh mesh = new AsyncMesh();

        mesh.tris  = new int[dracoMesh->numFaces * 3];
        mesh.verts = new Vector3[dracoMesh->numVertices];

        // Copy face indices.
        DracoData *indicesData;

        GetMeshIndices(dracoMesh, &indicesData);
        int elementSize =
            DataTypeSize((GLTFUtilityDracoLoader.DataType)indicesData->dataType);
        int *indices    = (int * )(indicesData->data);
        var  indicesPtr = UnsafeUtility.AddressOf(ref mesh.tris[0]);

        UnsafeUtility.MemCpy(indicesPtr, indices,
                             mesh.tris.Length * elementSize);
        ReleaseDracoData(&indicesData);

        DracoAttribute *attr = null;

        // Copy positions.
        if (GetAttributeByUniqueId(dracoMesh, attributes.pos, &attr))
        {
            DracoData *posData = null;
            GetAttributeData(dracoMesh, attr, &posData);
            elementSize = DataTypeSize((GLTFUtilityDracoLoader.DataType)posData->dataType) *
                          attr->numComponents;
            var newVerticesPtr = UnsafeUtility.AddressOf(ref mesh.verts[0]);
            UnsafeUtility.MemCpy(newVerticesPtr, (void * )posData->data,
                                 dracoMesh->numVertices * elementSize);
            ReleaseDracoData(&posData);
            ReleaseDracoAttribute(&attr);
        }

        // Copy normals.
        if (GetAttributeByUniqueId(dracoMesh, attributes.norms, &attr))
        {
            DracoData *normData = null;
            if (GetAttributeData(dracoMesh, attr, &normData))
            {
                elementSize =
                    DataTypeSize((GLTFUtilityDracoLoader.DataType)normData->dataType) *
                    attr->numComponents;
                mesh.norms = new Vector3[dracoMesh->numVertices];
                var newNormalsPtr = UnsafeUtility.AddressOf(ref mesh.norms[0]);
                UnsafeUtility.MemCpy(newNormalsPtr, (void * )normData->data,
                                     dracoMesh->numVertices * elementSize);
                ReleaseDracoData(&normData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Copy texture coordinates.
        if (GetAttributeByUniqueId(dracoMesh, attributes.uv, &attr))
        {
            DracoData *texData = null;
            if (GetAttributeData(dracoMesh, attr, &texData))
            {
                elementSize =
                    DataTypeSize((GLTFUtilityDracoLoader.DataType)texData->dataType) *
                    attr->numComponents;
                mesh.uv = new Vector2[dracoMesh->numVertices];
                var newUVsPtr = UnsafeUtility.AddressOf(ref mesh.uv[0]);
                UnsafeUtility.MemCpy(newUVsPtr, (void * )texData->data,
                                     dracoMesh->numVertices * elementSize);
                ReleaseDracoData(&texData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Copy colors.
        if (GetAttributeByUniqueId(dracoMesh, attributes.col, &attr))
        {
            DracoData *colorData = null;
            if (GetAttributeData(dracoMesh, attr, &colorData))
            {
                elementSize =
                    DataTypeSize((GLTFUtilityDracoLoader.DataType)colorData->dataType) *
                    attr->numComponents;
                mesh.colors = new Color[dracoMesh->numVertices];
                var newColorsPtr = UnsafeUtility.AddressOf(ref mesh.colors[0]);
                UnsafeUtility.MemCpy(newColorsPtr, (void * )colorData->data,
                                     dracoMesh->numVertices * elementSize);
                ReleaseDracoData(&colorData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Copy weights.
        Vector4[] weights = null;
        if (GetAttributeByUniqueId(dracoMesh, attributes.weights, &attr))
        {
            DracoData *weightData = null;
            if (GetAttributeData(dracoMesh, attr, &weightData))
            {
                elementSize =
                    DataTypeSize((GLTFUtilityDracoLoader.DataType)weightData->dataType) *
                    attr->numComponents;
                if (attr->dataType == 9)
                {
                    weights = new Vector4[dracoMesh->numVertices];
                    var newWeightsPtr = UnsafeUtility.AddressOf(ref weights[0]);
                    UnsafeUtility.MemCpy(newWeightsPtr, (void * )weightData->data,
                                         dracoMesh->numVertices * elementSize);
                }
                else if (attr->dataType == 4)
                {
                    var newWeightsInt = new Vector4 <UInt16> [dracoMesh->numVertices];
                    var newWeightsPtr = UnsafeUtility.AddressOf(ref newWeightsInt[0]);
                    UnsafeUtility.MemCpy(newWeightsPtr, (void * )weightData->data,
                                         dracoMesh->numVertices * elementSize);
                    weights = newWeightsInt.Select(x => new Vector4(x.x, x.y, x.z, x.w)).ToArray();
                }

                ReleaseDracoData(&weightData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Copy joints.
        Vector4[] joints = null;
        if (GetAttributeByUniqueId(dracoMesh, attributes.joints, &attr))
        {
            DracoData *jointData = null;
            if (GetAttributeData(dracoMesh, attr, &jointData))
            {
                elementSize =
                    DataTypeSize((GLTFUtilityDracoLoader.DataType)jointData->dataType) *
                    attr->numComponents;
                if (attr->dataType == 9)
                {
                    joints = new Vector4[dracoMesh->numVertices];
                    var newJointsPtr = UnsafeUtility.AddressOf(ref joints[0]);
                    UnsafeUtility.MemCpy(newJointsPtr, (void * )jointData->data,
                                         dracoMesh->numVertices * elementSize);
                }
                else if (attr->dataType == 4)
                {
                    var newJointsInt = new Vector4 <UInt16> [dracoMesh->numVertices];
                    var newJointsPtr = UnsafeUtility.AddressOf(ref newJointsInt[0]);
                    UnsafeUtility.MemCpy(newJointsPtr, (void * )jointData->data,
                                         dracoMesh->numVertices * elementSize);
                    joints = newJointsInt.Select(x => new Vector4(x.x, x.y, x.z, x.w)).ToArray();
                }

                ReleaseDracoData(&jointData);
                ReleaseDracoAttribute(&attr);
            }
        }

/* #if UNITY_2017_3_OR_NEWER
 *              mesh.indexFormat = (newVertices.Length > System.UInt16.MaxValue) ?
 *                      UnityEngine.Rendering.IndexFormat.UInt32 :
 *                      UnityEngine.Rendering.IndexFormat.UInt16;
 #else
 *              if (newVertices.Length > System.UInt16.MaxValue) {
 *                      throw new System.Exception("Draco meshes with more than 65535 vertices are only supported from Unity 2017.3 onwards.");
 *              }
 #endif */

        if (joints != null && weights != null)
        {
            if (joints.Length == weights.Length)
            {
                BoneWeight[] boneWeights = new BoneWeight[weights.Length];
                for (int k = 0; k < boneWeights.Length; k++)
                {
                    NormalizeWeights(ref weights[k]);
                    boneWeights[k].weight0    = weights[k].x;
                    boneWeights[k].weight1    = weights[k].y;
                    boneWeights[k].weight2    = weights[k].z;
                    boneWeights[k].weight3    = weights[k].w;
                    boneWeights[k].boneIndex0 = Mathf.RoundToInt(joints[k].x);
                    boneWeights[k].boneIndex1 = Mathf.RoundToInt(joints[k].y);
                    boneWeights[k].boneIndex2 = Mathf.RoundToInt(joints[k].z);
                    boneWeights[k].boneIndex3 = Mathf.RoundToInt(joints[k].w);
                }
                mesh.boneWeights = boneWeights;
            }
            else
            {
                Debug.LogWarning("Draco: joints and weights not same length. Skipped");
            }
        }
        return(mesh);
    }
    // Creates a Unity mesh from the decoded Draco mesh.
    public unsafe Mesh CreateUnityMesh(DracoMesh *dracoMesh)
    {
        int numFaces = dracoMesh->numFaces;

        int[]     newTriangles = new int[dracoMesh->numFaces * 3];
        Vector3[] newVertices  = new Vector3[dracoMesh->numVertices];
        Vector2[] newUVs       = null;
        Vector3[] newNormals   = null;
        Vector4[] newWeights   = null;
        Vector4[] newJoints    = null;
        Color[]   newColors    = null;

        // Copy face indices.
        DracoData *indicesData;

        GetMeshIndices(dracoMesh, &indicesData);
        int elementSize =
            DataTypeSize((GLTFUtilityDracoLoader.DataType)indicesData->dataType);
        int *indices    = (int * )(indicesData->data);
        var  indicesPtr = UnsafeUtility.AddressOf(ref newTriangles[0]);

        UnsafeUtility.MemCpy(indicesPtr, indices,
                             newTriangles.Length * elementSize);
        ReleaseDracoData(&indicesData);

        // Copy positions.
        DracoAttribute *attr = null;

        GetAttributeByType(dracoMesh, AttributeType.POSITION, 0, &attr);
        DracoData *posData = null;

        GetAttributeData(dracoMesh, attr, &posData);
        elementSize = DataTypeSize((GLTFUtilityDracoLoader.DataType)posData->dataType) *
                      attr->numComponents;
        var newVerticesPtr = UnsafeUtility.AddressOf(ref newVertices[0]);

        UnsafeUtility.MemCpy(newVerticesPtr, (void * )posData->data,
                             dracoMesh->numVertices * elementSize);
        ReleaseDracoData(&posData);
        ReleaseDracoAttribute(&attr);

        // Copy normals.
        if (GetAttributeByType(dracoMesh, AttributeType.NORMAL, 0, &attr))
        {
            DracoData *normData = null;
            if (GetAttributeData(dracoMesh, attr, &normData))
            {
                elementSize =
                    DataTypeSize((GLTFUtilityDracoLoader.DataType)normData->dataType) *
                    attr->numComponents;
                newNormals = new Vector3[dracoMesh->numVertices];
                var newNormalsPtr = UnsafeUtility.AddressOf(ref newNormals[0]);
                UnsafeUtility.MemCpy(newNormalsPtr, (void * )normData->data,
                                     dracoMesh->numVertices * elementSize);
                ReleaseDracoData(&normData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Copy texture coordinates.
        if (GetAttributeByType(dracoMesh, AttributeType.TEX_COORD, 0, &attr))
        {
            DracoData *texData = null;
            if (GetAttributeData(dracoMesh, attr, &texData))
            {
                elementSize =
                    DataTypeSize((GLTFUtilityDracoLoader.DataType)texData->dataType) *
                    attr->numComponents;
                newUVs = new Vector2[dracoMesh->numVertices];
                var newUVsPtr = UnsafeUtility.AddressOf(ref newUVs[0]);
                UnsafeUtility.MemCpy(newUVsPtr, (void * )texData->data,
                                     dracoMesh->numVertices * elementSize);
                ReleaseDracoData(&texData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Copy colors.
        if (GetAttributeByType(dracoMesh, AttributeType.COLOR, 0, &attr))
        {
            DracoData *colorData = null;
            if (GetAttributeData(dracoMesh, attr, &colorData))
            {
                elementSize =
                    DataTypeSize((GLTFUtilityDracoLoader.DataType)colorData->dataType) *
                    attr->numComponents;
                newColors = new Color[dracoMesh->numVertices];
                var newColorsPtr = UnsafeUtility.AddressOf(ref newColors[0]);
                UnsafeUtility.MemCpy(newColorsPtr, (void * )colorData->data,
                                     dracoMesh->numVertices * elementSize);
                ReleaseDracoData(&colorData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Copy weights.
        if (GetAttributeByType(dracoMesh, AttributeType.GENERIC, 1, &attr))
        {
            DracoData *weightData = null;
            if (GetAttributeData(dracoMesh, attr, &weightData))
            {
                elementSize =
                    DataTypeSize((GLTFUtilityDracoLoader.DataType)weightData->dataType) *
                    attr->numComponents;
                if (attr->dataType == 9)
                {
                    newWeights = new Vector4[dracoMesh->numVertices];
                    var newWeightsPtr = UnsafeUtility.AddressOf(ref newWeights[0]);
                    UnsafeUtility.MemCpy(newWeightsPtr, (void * )weightData->data,
                                         dracoMesh->numVertices * elementSize);
                }
                else if (attr->dataType == 4)
                {
                    var newWeightsInt = new Vector4 <UInt16> [dracoMesh->numVertices];
                    var newWeightsPtr = UnsafeUtility.AddressOf(ref newWeightsInt[0]);
                    UnsafeUtility.MemCpy(newWeightsPtr, (void * )weightData->data,
                                         dracoMesh->numVertices * elementSize);
                    newWeights = newWeightsInt.Select(x => new Vector4(x.x, x.y, x.z, x.w)).ToArray();
                }

                ReleaseDracoData(&weightData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Copy joints.
        if (GetAttributeByType(dracoMesh, AttributeType.GENERIC, 0, &attr))
        {
            DracoData *jointData = null;
            if (GetAttributeData(dracoMesh, attr, &jointData))
            {
                elementSize =
                    DataTypeSize((GLTFUtilityDracoLoader.DataType)jointData->dataType) *
                    attr->numComponents;
                if (attr->dataType == 9)
                {
                    newJoints = new Vector4[dracoMesh->numVertices];
                    var newJointsPtr = UnsafeUtility.AddressOf(ref newJoints[0]);
                    UnsafeUtility.MemCpy(newJointsPtr, (void * )jointData->data,
                                         dracoMesh->numVertices * elementSize);
                }
                else if (attr->dataType == 4)
                {
                    var newJointsInt = new Vector4 <UInt16> [dracoMesh->numVertices];
                    var newJointsPtr = UnsafeUtility.AddressOf(ref newJointsInt[0]);
                    UnsafeUtility.MemCpy(newJointsPtr, (void * )jointData->data,
                                         dracoMesh->numVertices * elementSize);
                    newJoints = newJointsInt.Select(x => new Vector4(x.x, x.y, x.z, x.w)).ToArray();
                }

                ReleaseDracoData(&jointData);
                ReleaseDracoAttribute(&attr);
            }
        }

        // Dirty fix:
        // If any value in weights is above 1.5, swap weights and joints.
        // I honestly have no clue where the correct uniqueIDs are supposed to come from.
        if (newWeights != null && newJoints != null)
        {
            if (newWeights.Any(x => x.x > 1.5f || x.y > 1.5f || x.z > 1.5f || x.w > 1.5f))
            {
                Vector4[] temp = newWeights;
                newWeights = newJoints;
                newJoints  = temp;
            }
        }

        Mesh mesh = new Mesh();

#if UNITY_2017_3_OR_NEWER
        mesh.indexFormat = (newVertices.Length > System.UInt16.MaxValue) ?
                           UnityEngine.Rendering.IndexFormat.UInt32 :
                           UnityEngine.Rendering.IndexFormat.UInt16;
#else
        if (newVertices.Length > System.UInt16.MaxValue)
        {
            throw new System.Exception("Draco meshes with more than 65535 vertices are only supported from Unity 2017.3 onwards.");
        }
#endif

        mesh.vertices = newVertices;
        mesh.SetTriangles(newTriangles, 0, true);
        if (newUVs != null)
        {
            mesh.uv = newUVs;
        }
        if (newNormals != null)
        {
            mesh.normals = newNormals;
        }
        else
        {
            mesh.RecalculateNormals();
            Debug.Log("Mesh doesn't have normals, recomputed.");
        }
        if (newColors != null)
        {
            mesh.colors = newColors;
        }
        if (newJoints != null && newWeights != null)
        {
            if (newJoints.Length == newWeights.Length)
            {
                BoneWeight[] boneWeights = new BoneWeight[newWeights.Length];
                for (int k = 0; k < boneWeights.Length; k++)
                {
                    NormalizeWeights(ref newWeights[k]);
                    boneWeights[k].weight0    = newWeights[k].x;
                    boneWeights[k].weight1    = newWeights[k].y;
                    boneWeights[k].weight2    = newWeights[k].z;
                    boneWeights[k].weight3    = newWeights[k].w;
                    boneWeights[k].boneIndex0 = Mathf.RoundToInt(newJoints[k].x);
                    boneWeights[k].boneIndex1 = Mathf.RoundToInt(newJoints[k].y);
                    boneWeights[k].boneIndex2 = Mathf.RoundToInt(newJoints[k].z);
                    boneWeights[k].boneIndex3 = Mathf.RoundToInt(newJoints[k].w);
                }
                mesh.boneWeights = boneWeights;
            }
            else
            {
                Debug.LogWarning("Draco: joints and weights not same length. Skipped");
            }
        }
        return(mesh);
    }