/// <summary> /// Applies the data to a Unity mesh. /// </summary> /// <param name="renderer">Target renderer.</param> public void CopyDataToUnityMesh(SkinnedMeshRenderer renderer) { Mesh mesh = renderer.sharedMesh; mesh.subMeshCount = 1; mesh.triangles = new int[0]; mesh.vertices = vertices; mesh.boneWeights = 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++) { mesh.SetTriangles(submeshes[i].triangles, i); } renderer.bones = bones; renderer.rootBone = rootBone; mesh.RecalculateBounds(); renderer.sharedMesh = mesh; }
public static UMAMeshData ShallowInstanceMesh(UMAMeshData source, BitArray[] triangleMask = null) { var target = new UMAMeshData(); target.bindPoses = source.bindPoses; target.boneNameHashes = source.boneNameHashes; target.unityBoneWeights = UMABoneWeight.Convert(source.boneWeights); target.colors32 = source.colors32; target.normals = source.normals; target.rootBoneHash = source.rootBoneHash; target.subMeshCount = source.subMeshCount; target.tangents = source.tangents; target.umaBoneCount = source.umaBoneCount; target.umaBones = source.umaBones; target.uv = source.uv; target.uv2 = source.uv2; target.uv3 = source.uv3; target.uv4 = source.uv4; target.vertexCount = source.vertexCount; target.vertices = source.vertices; target.blendShapes = source.blendShapes; if (triangleMask != null) { target.submeshes = new SubMeshTriangles[source.subMeshCount]; for (int i = 0; i < source.subMeshCount; i++) { int sourceLength = source.submeshes[i].triangles.Length; int triangleLength = sourceLength - (UMAUtils.GetCardinality(triangleMask[i]) * 3); int[] destTriangles = new int[triangleLength]; MaskedCopyIntArrayAdd(source.submeshes[i].triangles, 0, destTriangles, 0, sourceLength, 0, triangleMask[i]); target.submeshes[i].triangles = destTriangles; } } else { target.submeshes = source.submeshes; } if (source.clothSkinningSerialized != null && source.clothSkinningSerialized.Length != 0) { target.clothSkinning = new ClothSkinningCoefficient[source.clothSkinningSerialized.Length]; for (int i = 0; i < source.clothSkinningSerialized.Length; i++) { ConvertData(ref source.clothSkinningSerialized[i], ref target.clothSkinning[i]); } } else { target.clothSkinning = null; } return(target); }
/// <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) { CreateTransforms(skeleton); Mesh mesh = renderer.sharedMesh; #if UNITY_EDITOR if (UnityEditor.PrefabUtility.IsComponentAddedToPrefabInstance(renderer)) { Debug.LogError("Cannot apply changes to prefab!"); } if (UnityEditor.AssetDatabase.IsSubAsset(mesh)) { 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; #if !UNITY_4_6 mesh.uv3 = uv3; mesh.uv4 = uv4; #endif mesh.colors32 = colors32; } mesh.bindposes = bindPoses; var subMeshCount = submeshes.Length; mesh.subMeshCount = subMeshCount; for (int i = 0; i < subMeshCount; i++) { mesh.SetTriangles(submeshes[i].triangles, i); } mesh.RecalculateBounds(); renderer.bones = bones != null ? bones : skeleton.HashesToTransforms(boneNameHashes); renderer.sharedMesh = mesh; renderer.rootBone = rootBone; }
/// <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]; 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++) { blendShapes [shapeIndex].frames [frameIndex] = new UMABlendFrame(sharedMesh.vertexCount); blendShapes[shapeIndex].frames[frameIndex].frameWeight = sharedMesh.GetBlendShapeFrameWeight(shapeIndex, frameIndex); sharedMesh.GetBlendShapeFrameVertices(shapeIndex, frameIndex, blendShapes [shapeIndex].frames [frameIndex].deltaVertices, blendShapes [shapeIndex].frames [frameIndex].deltaNormals, blendShapes [shapeIndex].frames [frameIndex].deltaTangents); } } #endregion }
/// <summary> /// Initialize UMA mesh data from Unity mesh. /// </summary> /// <param name="renderer">Source renderer.</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; #if !UNITY_4_6 uv3 = sharedMesh.uv3; uv4 = sharedMesh.uv4; #endif subMeshCount = sharedMesh.subMeshCount; submeshes = new SubMeshTriangles[subMeshCount]; for (int i = 0; i < subMeshCount; i++) { submeshes[i].triangles = sharedMesh.GetTriangles(i); } }
public static UMAMeshData ShallowInstanceMesh(UMAMeshData source) { var target = new UMAMeshData(); target.bindPoses = source.bindPoses; target.boneNameHashes = source.boneNameHashes; target.unityBoneWeights = UMABoneWeight.Convert(source.boneWeights); target.colors32 = source.colors32; target.normals = source.normals; target.rootBoneHash = source.rootBoneHash; target.subMeshCount = source.subMeshCount; target.submeshes = source.submeshes; target.tangents = source.tangents; target.umaBoneCount = source.umaBoneCount; target.umaBones = source.umaBones; target.uv = source.uv; target.uv2 = source.uv2; target.uv3 = source.uv3; target.uv4 = source.uv4; target.vertexCount = source.vertexCount; target.vertices = source.vertices; target.blendShapes = source.blendShapes; if (source.clothSkinningSerialized != null && source.clothSkinningSerialized.Length != 0) { target.clothSkinning = new ClothSkinningCoefficient[source.clothSkinningSerialized.Length]; for (int i = 0; i < source.clothSkinningSerialized.Length; i++) { ConvertData(ref source.clothSkinningSerialized[i], ref target.clothSkinning[i]); } } else { target.clothSkinning = null; } return(target); }
private void ApplySharedBuffers(Mesh mesh) { // Thanks for providing these awesome List<> methods rather than listening // to every one of your users who told you to use Array and size, Unity! gVertices.SetActiveSize(vertexCount); mesh.SetVertices(gVertices); // Whoops, looks like they also forgot one! Job well done. #if USE_UNSAFE_CODE unsafe { fixed(void *pBoneWeights = gBoneWeightsArray) { UIntPtr *lengthPtr = (UIntPtr *)pBoneWeights - 1; try { *lengthPtr = (UIntPtr)vertexCount; mesh.boneWeights = gBoneWeightsArray; } finally { *lengthPtr = (UIntPtr)MAX_VERTEX_COUNT; } } } #else if (unityBoneWeights != null) { mesh.boneWeights = unityBoneWeights; } else { mesh.boneWeights = UMABoneWeight.Convert(boneWeights); } #endif if (normals != null) { gNormals.SetActiveSize(vertexCount); mesh.SetNormals(gNormals); } if (tangents != null) { gTangents.SetActiveSize(vertexCount); mesh.SetTangents(gTangents); } if (uv != null) { gUV.SetActiveSize(vertexCount); mesh.SetUVs(0, gUV); } if (uv2 != null) { gUV2.SetActiveSize(vertexCount); mesh.SetUVs(1, gUV2); } if (uv3 != null) { gUV3.SetActiveSize(vertexCount); mesh.SetUVs(2, gUV3); } if (uv4 != null) { gUV4.SetActiveSize(vertexCount); mesh.SetUVs(3, gUV4); } if (colors32 != null) { gColors32.SetActiveSize(vertexCount); mesh.SetColors(gColors32); } }
/// <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; } }
/// <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 }
/// <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) { CreateTransforms(skeleton); Mesh mesh = renderer.sharedMesh; #if UNITY_EDITOR if (UnityEditor.PrefabUtility.IsComponentAddedToPrefabInstance(renderer)) { Debug.LogError("Cannot apply changes to prefab!"); } if (UnityEditor.AssetDatabase.IsSubAsset(mesh)) { 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++) { 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!"); 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; mesh.AddBlendShapeFrame(name, blendShapes [shapeIndex].frames [frameIndex].frameWeight, blendShapes [shapeIndex].frames [frameIndex].deltaVertices, blendShapes [shapeIndex].frames [frameIndex].deltaNormals, blendShapes [shapeIndex].frames [frameIndex].deltaTangents); } } } #endregion mesh.RecalculateBounds(); renderer.bones = bones != null ? bones : skeleton.HashesToTransforms(boneNameHashes); renderer.sharedMesh = mesh; renderer.rootBone = rootBone; }