Beispiel #1
0
        /// <summary>
        /// Applies the data to a Unity mesh.
        /// </summary>
        /// <param name="renderer">Target renderer.</param>
        /// <param name="skeleton">Skeleton.</param>
        public void ApplyDataToUnityMesh(SkinnedMeshRenderer renderer, UMASkeleton skeleton)
        {
            if (renderer == null)
            {
                if (Debug.isDebugBuild)
                {
                    Debug.LogError("Renderer is null!");
                }
                return;
            }

            CreateTransforms(skeleton);

            Mesh mesh = renderer.sharedMesh;

#if UNITY_EDITOR
#if UNITY_2018_3_OR_NEWER
            if (UnityEditor.PrefabUtility.IsAddedComponentOverride(renderer))
            {
                if (Debug.isDebugBuild)
                {
                    Debug.LogError("Cannot apply changes to prefab!");
                }
            }
#else
            if (UnityEditor.PrefabUtility.IsComponentAddedToPrefabInstance(renderer))
            {
                if (Debug.isDebugBuild)
                {
                    Debug.LogError("Cannot apply changes to prefab!");
                }
            }
#endif
            if (UnityEditor.AssetDatabase.IsSubAsset(mesh))
            {
                if (Debug.isDebugBuild)
                {
                    Debug.LogError("Cannot apply changes to asset mesh!");
                }
            }
#endif
            mesh.subMeshCount = 1;
            mesh.triangles    = new int[0];

            if (OwnSharedBuffers())
            {
                ApplySharedBuffers(mesh);
            }
            else
            {
                mesh.vertices    = vertices;
                mesh.boneWeights = unityBoneWeights != null ? unityBoneWeights : UMABoneWeight.Convert(boneWeights);
                mesh.normals     = normals;
                mesh.tangents    = tangents;
                mesh.uv          = uv;
                mesh.uv2         = uv2;
                mesh.uv3         = uv3;
                mesh.uv4         = uv4;
                mesh.colors32    = colors32;
            }
            mesh.bindposes = bindPoses;

            var subMeshCount = submeshes.Length;
            mesh.subMeshCount = subMeshCount;
            for (int i = 0; i < subMeshCount; i++)
            {
                bool sharedBuffer = false;
                for (int j = 0; j < gSubmeshTris.Length; j++)
                {
                    if (gSubmeshTriIndices[j] == i)
                    {
                        sharedBuffer = true;
                        mesh.SetTriangles(gSubmeshTris[j], i);
                        gSubmeshTriIndices[j] = UNUSED_SUBMESH;
                        break;
                    }
                }

                if (!sharedBuffer)
                {
                    mesh.SetTriangles(submeshes[i].triangles, i);
                }
            }

            //Apply the blendshape data from the slot asset back to the combined UMA unity mesh.
            #region Blendshape
            mesh.ClearBlendShapes();
            if (blendShapes != null && blendShapes.Length > 0)
            {
                for (int shapeIndex = 0; shapeIndex < blendShapes.Length; shapeIndex++)
                {
                    if (blendShapes [shapeIndex] == null)
                    {
                        //Debug.LogError ("blendShapes [shapeIndex] == null!");
                        //No longer an error, this will be null if the blendshape got baked.
                        break;
                    }

                    for (int frameIndex = 0; frameIndex < blendShapes[shapeIndex].frames.Length; frameIndex++)
                    {
                        //There might be an extreme edge case where someone has the same named blendshapes on different meshes that end up on different renderers.
                        string name = blendShapes[shapeIndex].shapeName;

                        float     frameWeight   = blendShapes[shapeIndex].frames[frameIndex].frameWeight;
                        Vector3[] deltaVertices = blendShapes[shapeIndex].frames[frameIndex].deltaVertices;
                        Vector3[] deltaNormals  = blendShapes[shapeIndex].frames[frameIndex].deltaNormals;
                        Vector3[] deltaTangents = blendShapes[shapeIndex].frames[frameIndex].deltaTangents;

                        if (UMABlendFrame.isAllZero(deltaNormals))
                        {
                            deltaNormals = null;
                        }

                        if (UMABlendFrame.isAllZero(deltaTangents))
                        {
                            deltaTangents = null;
                        }

                        mesh.AddBlendShapeFrame(name, frameWeight, deltaVertices, deltaNormals, deltaTangents);
                    }
                }
            }
            #endregion

            mesh.RecalculateBounds();
            renderer.bones      = bones != null ? bones : skeleton.HashesToTransforms(boneNameHashes);
            renderer.sharedMesh = mesh;
            renderer.rootBone   = rootBone;

            if (clothSkinning != null && clothSkinning.Length > 0)
            {
                Cloth cloth = renderer.GetComponent <Cloth>();
                if (cloth != null)
                {
                    GameObject.DestroyImmediate(cloth);
                    cloth = null;
                }

                cloth = renderer.gameObject.AddComponent <Cloth>();
                UMAPhysicsAvatar physicsAvatar = renderer.gameObject.GetComponentInParent <UMAPhysicsAvatar>();
                if (physicsAvatar != null)
                {
                    cloth.sphereColliders  = physicsAvatar.SphereColliders.ToArray();
                    cloth.capsuleColliders = physicsAvatar.CapsuleColliders.ToArray();
                }

                cloth.coefficients = clothSkinning;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Initialize UMA mesh data from Unity mesh.
        /// </summary>
        /// <param name="sharedMesh">Source mesh.</param>
        public void RetrieveDataFromUnityMesh(Mesh sharedMesh)
        {
            bindPoses    = sharedMesh.bindposes;
            boneWeights  = UMABoneWeight.Convert(sharedMesh.boneWeights);
            vertices     = sharedMesh.vertices;
            vertexCount  = vertices.Length;
            normals      = sharedMesh.normals;
            tangents     = sharedMesh.tangents;
            colors32     = sharedMesh.colors32;
            uv           = sharedMesh.uv;
            uv2          = sharedMesh.uv2;
            uv3          = sharedMesh.uv3;
            uv4          = sharedMesh.uv4;
            subMeshCount = sharedMesh.subMeshCount;
            submeshes    = new SubMeshTriangles[subMeshCount];
            for (int i = 0; i < subMeshCount; i++)
            {
                submeshes[i].triangles = sharedMesh.GetTriangles(i);
            }

            //Create the blendshape data on the slot asset from the unity mesh
            #region Blendshape
            blendShapes = new UMABlendShape[sharedMesh.blendShapeCount];

            Vector3[] deltaVertices;
            Vector3[] deltaNormals;
            Vector3[] deltaTangents;

            for (int shapeIndex = 0; shapeIndex < sharedMesh.blendShapeCount; shapeIndex++)
            {
                blendShapes [shapeIndex]           = new UMABlendShape();
                blendShapes [shapeIndex].shapeName = sharedMesh.GetBlendShapeName(shapeIndex);

                int frameCount = sharedMesh.GetBlendShapeFrameCount(shapeIndex);
                blendShapes [shapeIndex].frames = new UMABlendFrame[frameCount];

                for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
                {
                    deltaVertices = new Vector3[sharedMesh.vertexCount];
                    deltaNormals  = new Vector3[sharedMesh.vertexCount];
                    deltaTangents = new Vector3[sharedMesh.vertexCount];

                    bool hasNormals  = false;
                    bool hasTangents = false;

                    //Get the delta arrays first so we can determine if we don't need the delta normals or the delta tangents.
                    sharedMesh.GetBlendShapeFrameVertices(shapeIndex, frameIndex, deltaVertices, deltaNormals, deltaTangents);

                    if (!UMABlendFrame.isAllZero(deltaNormals))
                    {
                        hasNormals = true;
                    }

                    if (!UMABlendFrame.isAllZero(deltaTangents))
                    {
                        hasTangents = true;
                    }

                    blendShapes [shapeIndex].frames [frameIndex]           = new UMABlendFrame();
                    blendShapes[shapeIndex].frames[frameIndex].frameWeight = sharedMesh.GetBlendShapeFrameWeight(shapeIndex, frameIndex);

                    blendShapes[shapeIndex].frames[frameIndex].deltaVertices = deltaVertices;
                    if (hasNormals)
                    {
                        blendShapes[shapeIndex].frames[frameIndex].deltaNormals = deltaNormals;
                    }
                    if (hasTangents)
                    {
                        blendShapes[shapeIndex].frames[frameIndex].deltaTangents = deltaTangents;
                    }
                }
            }
            #endregion
        }