public static SpriteMesh CreateSpriteMesh(Sprite sprite) { SpriteMesh spriteMesh = SpriteMeshPostprocessor.GetSpriteMeshFromSprite(sprite); SpriteMeshData spriteMeshData = null; if (!spriteMesh && sprite) { string spritePath = AssetDatabase.GetAssetPath(sprite); string directory = Path.GetDirectoryName(spritePath); string assetPath = AssetDatabase.GenerateUniqueAssetPath(directory + Path.DirectorySeparatorChar + sprite.name + ".asset"); spriteMesh = ScriptableObject.CreateInstance <SpriteMesh>(); InitFromSprite(spriteMesh, sprite); AssetDatabase.CreateAsset(spriteMesh, assetPath); spriteMeshData = ScriptableObject.CreateInstance <SpriteMeshData>(); spriteMeshData.name = spriteMesh.name + "_Data"; spriteMeshData.hideFlags = HideFlags.HideInHierarchy; InitFromSprite(spriteMeshData, sprite); AssetDatabase.AddObjectToAsset(spriteMeshData, assetPath); UpdateAssets(spriteMesh, spriteMeshData); AssetDatabase.SaveAssets(); AssetDatabase.ImportAsset(assetPath); Selection.activeObject = spriteMesh; } return(spriteMesh); }
public void SetSpriteMesh(SpriteMesh _spriteMesh, SpriteMeshInstance _spriteMeshInstance) { spriteMesh = _spriteMesh; spriteMeshInstance = _spriteMeshInstance; spriteMeshData = SpriteMeshUtils.LoadSpriteMeshData(_spriteMesh); RevertChanges(); }
void CreateBlendShapeCache(SpriteMeshData spriteMeshData) { DestroyBlendShapeCache(""); List <BlendShapeFrame> frameClones = new List <BlendShapeFrame>(); foreach (BlendShape blendShape in spriteMeshData.blendshapes) { frameClones.Clear(); foreach (BlendShapeFrame frame in blendShape.frames) { BlendShapeFrame frameClone = ScriptableObject.CreateInstance <BlendShapeFrame>(); frameClone.hideFlags = HideFlags.DontSave; EditorUtility.CopySerialized(frame, frameClone); frameClones.Add(frameClone); } BlendShape blendShapeClone = CreateBlendshape(blendShape.name); blendShapeClone.frames = frameClones.ToArray(); } }
public static bool NeedsOverride(SpriteMesh spriteMesh) { if (!spriteMesh || !spriteMesh.sprite) { return(false); } SpriteMeshData spriteMeshData = LoadSpriteMeshData(spriteMesh); if (!spriteMeshData) { return(false); } ushort[] triangles = spriteMesh.sprite.triangles; if (triangles.Length != spriteMeshData.indices.Length) { return(true); } for (int i = 0; i < triangles.Length; i++) { if (spriteMeshData.indices[i] != triangles[i]) { return(true); } } return(false); }
public static BlendShape CreateBlendShape(SpriteMesh spriteMesh, string blendshapeName) { BlendShape l_blendshape = null; SpriteMeshData spriteMeshData = LoadSpriteMeshData(spriteMesh); if (spriteMeshData) { l_blendshape = BlendShape.Create(blendshapeName); l_blendshape.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(l_blendshape, spriteMeshData); List <BlendShape> l_blendshapes = new List <BlendShape>(spriteMeshData.blendshapes); l_blendshapes.Add(l_blendshape); spriteMeshData.blendshapes = l_blendshapes.ToArray(); EditorUtility.SetDirty(spriteMeshData); EditorUtility.SetDirty(l_blendshape); } return(l_blendshape); }
static void SetBindPoses(SpriteMeshData spriteMeshData, SpriteMesh.BindInfo[] bindPoses) { if (bindPoses != null && bindPoses.Length > 0) { BindInfo[] array = new BindInfo[bindPoses.Length]; for (int i = 0; i < array.Length; ++i) { BindInfo b = new BindInfo(); b.bindPose = bindPoses[i].bindPose; b.boneLength = bindPoses[i].boneLength; b.color = bindPoses[i].color; b.name = bindPoses[i].name; b.path = bindPoses[i].path; b.zOrder = bindPoses[i].zOrder; array[i] = b; } FieldInfo fieldInfo = typeof(SpriteMeshData).GetField("m_BindPoses", BindingFlags.Instance | BindingFlags.NonPublic); if (fieldInfo != null) { fieldInfo.SetValue(spriteMeshData, array); } EditorUtility.SetDirty(spriteMeshData); } }
public static Vector3[] GetMeshVertices(Sprite sprite, SpriteMeshData spriteMeshData) { float pixelsPerUnit = GetSpritePixelsPerUnit(sprite); return((new List <Vector2>(spriteMeshData.vertices)) .ConvertAll(v => TexCoordToVertex(spriteMeshData.pivotPoint, v, pixelsPerUnit)).ToArray()); }
public static SpriteMeshInstance CreateSpriteMeshInstance(SpriteMesh spriteMesh, GameObject gameObject, bool undo = true) { SpriteMeshInstance spriteMeshInstance = null; if (spriteMesh && gameObject) { if (undo) { spriteMeshInstance = Undo.AddComponent <SpriteMeshInstance>(gameObject); } else { spriteMeshInstance = gameObject.AddComponent <SpriteMeshInstance>(); } spriteMeshInstance.spriteMesh = spriteMesh; spriteMeshInstance.sharedMaterial = defaultMaterial; SpriteMeshData spriteMeshData = SpriteMeshUtils.LoadSpriteMeshData(spriteMesh); List <Bone2D> bones = new List <Bone2D>(); List <string> paths = new List <string>(); Vector4 zero = new Vector4(0f, 0f, 0f, 1f); foreach (BindInfo bindInfo in spriteMeshData.bindPoses) { Matrix4x4 m = spriteMeshInstance.transform.localToWorldMatrix * bindInfo.bindPose.inverse; GameObject bone = new GameObject(bindInfo.name); if (undo) { Undo.RegisterCreatedObjectUndo(bone, Undo.GetCurrentGroupName()); } Bone2D boneComponent = bone.AddComponent <Bone2D>(); boneComponent.localLength = bindInfo.boneLength; bone.transform.position = m * zero; bone.transform.rotation = m.GetRotation(); bone.transform.parent = gameObject.transform; bones.Add(boneComponent); paths.Add(bindInfo.path); } BoneUtils.ReconstructHierarchy(bones, paths); spriteMeshInstance.bones = bones; SpriteMeshUtils.UpdateRenderer(spriteMeshInstance, undo); EditorUtility.SetDirty(spriteMeshInstance); } return(spriteMeshInstance); }
void UpdateSpriteMeshData() { m_SpriteMeshData = null; if (m_SpriteMeshProperty != null && m_SpriteMeshProperty.objectReferenceValue) { m_SpriteMeshData = SpriteMeshUtils.LoadSpriteMeshData(m_SpriteMeshProperty.objectReferenceValue as SpriteMesh); } }
void OnPreprocessTexture() { if (!s_Initialized) { return; } string guid = AssetDatabase.AssetPathToGUID(assetPath); if (s_SpriteMeshToTextureCache.ContainsValue(guid)) { TextureImporter textureImporter = (TextureImporter)assetImporter; SerializedObject textureImporterSO = new SerializedObject(textureImporter); SerializedProperty textureImporterSprites = textureImporterSO.FindProperty("m_SpriteSheet.m_Sprites"); foreach (KeyValuePair <string, string> pair in s_SpriteMeshToTextureCache) { if (pair.Value == guid) { SpriteMesh spriteMesh = LoadSpriteMesh(AssetDatabase.GUIDToAssetPath(pair.Key)); SpriteMeshData spriteMeshData = SpriteMeshUtils.LoadSpriteMeshData(spriteMesh); if (spriteMesh && spriteMeshData && spriteMesh.sprite && spriteMeshData.vertices.Length > 0) { SerializedProperty spriteProp = null; int i = 0; string name = ""; while (i < textureImporterSprites.arraySize && name != spriteMesh.sprite.name) { spriteProp = textureImporterSprites.GetArrayElementAtIndex(i); name = spriteProp.FindPropertyRelative("m_Name").stringValue; ++i; } if (name == spriteMesh.sprite.name) { Rect textureRect = SpriteMeshUtils.CalculateSpriteRect(spriteMesh, 5); spriteProp.FindPropertyRelative("m_Rect").rectValue = textureRect; spriteProp.FindPropertyRelative("m_Alignment").intValue = 9; spriteProp.FindPropertyRelative("m_Pivot").vector2Value = Vector2.Scale(spriteMeshData.pivotPoint - textureRect.position, new Vector2(1f / textureRect.size.x, 1f / textureRect.size.y)); textureImporter.userData = textureImporter.assetTimeStamp.ToString(); } } } } textureImporterSO.ApplyModifiedProperties(); } }
static void Upgrade_003(SerializedObject spriteMeshSO) { SpriteMesh spriteMesh = spriteMeshSO.targetObject as SpriteMesh; SpriteMeshData spriteMeshData = SpriteMeshUtils.LoadSpriteMeshData(spriteMesh); if (spriteMesh.sprite && spriteMeshData) { TextureImporter textureImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(spriteMesh.sprite)) as TextureImporter; float maxImporterSize = textureImporter.maxTextureSize; int width = 1; int height = 1; SpriteMeshUtils.GetWidthAndHeight(textureImporter, ref width, ref height); int maxSize = Mathf.Max(width, height); float factor = maxSize / maxImporterSize; if (factor > 1f) { SerializedObject spriteMeshDataSO = new SerializedObject(spriteMeshData); SerializedProperty smdPivotPointProp = spriteMeshDataSO.FindProperty("m_PivotPoint"); SerializedProperty smdVerticesProp = spriteMeshDataSO.FindProperty("m_Vertices"); SerializedProperty smdHolesProp = spriteMeshDataSO.FindProperty("m_Holes"); spriteMeshDataSO.Update(); smdPivotPointProp.vector2Value = spriteMeshData.pivotPoint * factor; for (int i = 0; i < spriteMeshData.vertices.Length; ++i) { smdVerticesProp.GetArrayElementAtIndex(i).vector2Value = spriteMeshData.vertices[i] * factor; } for (int i = 0; i < spriteMeshData.holes.Length; ++i) { smdHolesProp.GetArrayElementAtIndex(i).vector2Value = spriteMeshData.holes[i] * factor; } spriteMeshDataSO.ApplyModifiedProperties(); EditorUtility.SetDirty(spriteMeshData); } } }
static int FindBindInfo(BindInfo bindInfo, SpriteMeshData spriteMeshData) { if (bindInfo && spriteMeshData) { for (int i = 0; i < spriteMeshData.bindPoses.Length; ++i) { BindInfo l_bindInfo = spriteMeshData.bindPoses[i]; if (bindInfo.name == l_bindInfo.name /*&& Mathf.Approximately(bindInfo.boneLength,l_bindInfo.boneLength)*/) { return(i); } } } return(-1); }
static void DoSpriteOverride(SpriteMesh spriteMesh, Sprite sprite) { SpriteMeshData spriteMeshData = SpriteMeshUtils.LoadSpriteMeshData(spriteMesh); if (spriteMeshData) { Rect rect = SpriteMeshUtils.CalculateSpriteRect(spriteMesh, 5); Rect spriteRect = sprite.rect; Vector2 factor = new Vector2(spriteRect.width / rect.width, spriteRect.height / rect.height); Vector2[] newVertices = new List <Vector2>(spriteMeshData.vertices).ConvertAll(v => MathUtils.ClampPositionInRect(Vector2.Scale(v, factor), spriteRect) - spriteRect.position).ToArray(); ushort[] newIndices = new List <int>(spriteMeshData.indices).ConvertAll <ushort>(i => (ushort)i).ToArray(); sprite.OverrideGeometry(newVertices, newIndices); } }
static void InitFromSprite(SpriteMeshData spriteMeshData, Sprite sprite) { Vector2[] vertices; IndexedEdge[] edges; int[] indices; Vector2 pivotPoint; if (sprite) { GetSpriteData(sprite, out vertices, out edges, out indices, out pivotPoint); spriteMeshData.vertices = vertices; spriteMeshData.edges = edges; spriteMeshData.indices = indices; spriteMeshData.pivotPoint = pivotPoint; } }
public static Rect CalculateSpriteRect(SpriteMesh spriteMesh, int padding) { int width = 0; int height = 0; GetSpriteTextureSize(spriteMesh.sprite, ref width, ref height); SpriteMeshData spriteMeshData = LoadSpriteMeshData(spriteMesh); Rect rect = spriteMesh.sprite.rect; if (spriteMeshData) { Vector2 min = new Vector2(float.MaxValue, float.MaxValue); Vector2 max = new Vector2(float.MinValue, float.MinValue); for (int i = 0; i < spriteMeshData.vertices.Length; i++) { Vector2 v = spriteMeshData.vertices[i]; if (v.x < min.x) { min.x = v.x; } if (v.y < min.y) { min.y = v.y; } if (v.x > max.x) { max.x = v.x; } if (v.y > max.y) { max.y = v.y; } } rect.position = min - Vector2.one * padding; rect.size = (max - min) + Vector2.one * padding * 2f; rect = MathUtils.ClampRect(rect, new Rect(0f, 0f, width, height)); } return(rect); }
void DoSpriteOverride(SpriteMesh spriteMesh, Sprite sprite) { TextureImporter textureImporter = (TextureImporter)assetImporter; #if UNITY_5_1 || UNITY_5_2 || UNITY_5_3_OR_NEWER Debug.Assert(textureImporter.spriteImportMode == SpriteImportMode.Single || textureImporter.spriteImportMode == SpriteImportMode.Multiple, "Incompatible Sprite Mode. Use Single or Multiple."); #endif SpriteMeshData spriteMeshData = SpriteMeshUtils.LoadSpriteMeshData(spriteMesh); if (spriteMeshData) { Vector2 factor = Vector2.one; Rect spriteRect = sprite.rect; Rect rectTextureSpace = new Rect(); if (textureImporter.spriteImportMode == SpriteImportMode.Single) { int width = 0; int height = 0; SpriteMeshUtils.GetSpriteTextureSize(spriteMesh.sprite, ref width, ref height); rectTextureSpace = new Rect(0, 0, width, height); } else if (textureImporter.spriteImportMode == SpriteImportMode.Multiple) { rectTextureSpace = SpriteMeshUtils.CalculateSpriteRect(spriteMesh, 5); } factor = new Vector2(spriteRect.width / rectTextureSpace.width, spriteRect.height / rectTextureSpace.height); Vector2[] newVertices = new List <Vector2>(spriteMeshData.vertices).ConvertAll(v => MathUtils.ClampPositionInRect(Vector2.Scale(v, factor), spriteRect) - spriteRect.position) .ToArray(); ushort[] newIndices = new List <int>(spriteMeshData.indices).ConvertAll <ushort>(i => (ushort)i).ToArray(); sprite.OverrideGeometry(newVertices, newIndices); } }
public static SpriteMeshData LoadSpriteMeshData(SpriteMesh spriteMesh) { if (spriteMesh) { UnityEngine.Object[] assets = AssetDatabase.LoadAllAssetsAtPath(AssetDatabase.GetAssetPath(spriteMesh)); foreach (UnityEngine.Object asset in assets) { SpriteMeshData data = asset as SpriteMeshData; if (data) { return(data); } } } return(null); }
static bool Bindeable(SpriteMeshInstance targetSpriteMeshInstance, SpriteMeshInstance destinationSpriteMeshInstance) { bool bindeable = false; if (targetSpriteMeshInstance && destinationSpriteMeshInstance && targetSpriteMeshInstance.spriteMesh && destinationSpriteMeshInstance.spriteMesh && targetSpriteMeshInstance.spriteMesh != destinationSpriteMeshInstance.spriteMesh && destinationSpriteMeshInstance.cachedSkinnedRenderer) { SpriteMeshData targetData = SpriteMeshUtils.LoadSpriteMeshData(targetSpriteMeshInstance.spriteMesh); SpriteMeshData destinationData = SpriteMeshUtils.LoadSpriteMeshData(destinationSpriteMeshInstance.spriteMesh); bindeable = true; if (destinationData.bindPoses.Length >= targetData.bindPoses.Length) { for (int i = 0; i < targetData.bindPoses.Length; ++i) { if (bindeable) { BindInfo bindInfo = targetData.bindPoses[i]; if (FindBindInfo(bindInfo, destinationData) < 0) { bindeable = false; } } } } else { bindeable = false; } } return(bindeable); }
public static void DestroyBlendShapes(SpriteMeshData spriteMeshData, bool undo, string undoName) { if (spriteMeshData) { if (undo && !string.IsNullOrEmpty(undoName)) { Undo.RegisterCompleteObjectUndo(spriteMeshData, undoName); } foreach (BlendShape blendShape in spriteMeshData.blendshapes) { foreach (BlendShapeFrame frame in blendShape.frames) { if (undo) { Undo.DestroyObjectImmediate(frame); } else { GameObject.DestroyImmediate(frame, true); } } if (undo) { Undo.DestroyObjectImmediate(blendShape); } else { GameObject.DestroyImmediate(blendShape, true); } } spriteMeshData.blendshapes = new BlendShape[0]; } }
void UpdateSpriteMeshData() { m_SpriteMeshData = null; if(m_SpriteMeshProperty != null && m_SpriteMeshProperty.objectReferenceValue) { m_SpriteMeshData = SpriteMeshUtils.LoadSpriteMeshData(m_SpriteMeshProperty.objectReferenceValue as SpriteMesh); } }
static int FindBindInfo(BindInfo bindInfo, SpriteMeshData spriteMeshData) { if(bindInfo && spriteMeshData) { for(int i = 0; i < spriteMeshData.bindPoses.Length; ++i) { BindInfo l_bindInfo = spriteMeshData.bindPoses[i]; if(bindInfo.name == l_bindInfo.name /*&& Mathf.Approximately(bindInfo.boneLength,l_bindInfo.boneLength)*/) { return i; } } } return -1; }
public static void UpdateAssets(SpriteMesh spriteMesh, SpriteMeshData spriteMeshData) { if (spriteMesh && spriteMeshData) { string spriteMeshPath = AssetDatabase.GetAssetPath(spriteMesh); SerializedObject spriteMeshSO = new SerializedObject(spriteMesh); SerializedProperty sharedMeshProp = spriteMeshSO.FindProperty("m_SharedMesh"); if (!spriteMesh.sharedMesh) { Mesh mesh = new Mesh(); mesh.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(mesh, spriteMeshPath); spriteMeshSO.Update(); sharedMeshProp.objectReferenceValue = mesh; spriteMeshSO.ApplyModifiedProperties(); EditorUtility.SetDirty(mesh); } spriteMesh.sharedMesh.name = spriteMesh.name; spriteMeshData.hideFlags = HideFlags.HideInHierarchy; EditorUtility.SetDirty(spriteMeshData); int width = 0; int height = 0; GetSpriteTextureSize(spriteMesh.sprite, ref width, ref height); Vector3[] vertices = GetMeshVertices(spriteMesh.sprite, spriteMeshData); Vector2 textureWidthHeightInv = new Vector2(1f / width, 1f / height); Vector2[] uvs = (new List <Vector2>(spriteMeshData.vertices)).ConvertAll(v => Vector2.Scale(v, textureWidthHeightInv)).ToArray(); Vector3[] normals = (new List <Vector3>(vertices)).ConvertAll(v => Vector3.back).ToArray(); BoneWeight[] boneWeightsData = spriteMeshData.boneWeights; if (boneWeightsData.Length != spriteMeshData.vertices.Length) { boneWeightsData = new BoneWeight[spriteMeshData.vertices.Length]; } List <UnityEngine.BoneWeight> boneWeights = new List <UnityEngine.BoneWeight>(boneWeightsData.Length); List <float> verticesOrder = new List <float>(spriteMeshData.vertices.Length); for (int i = 0; i < boneWeightsData.Length; i++) { BoneWeight boneWeight = boneWeightsData[i]; List <KeyValuePair <int, float> > pairs = new List <KeyValuePair <int, float> >(); pairs.Add(new KeyValuePair <int, float>(boneWeight.boneIndex0, boneWeight.weight0)); pairs.Add(new KeyValuePair <int, float>(boneWeight.boneIndex1, boneWeight.weight1)); pairs.Add(new KeyValuePair <int, float>(boneWeight.boneIndex2, boneWeight.weight2)); pairs.Add(new KeyValuePair <int, float>(boneWeight.boneIndex3, boneWeight.weight3)); pairs = pairs.OrderByDescending(s => s.Value).ToList(); UnityEngine.BoneWeight boneWeight2 = new UnityEngine.BoneWeight(); boneWeight2.boneIndex0 = Mathf.Max(0, pairs[0].Key); boneWeight2.boneIndex1 = Mathf.Max(0, pairs[1].Key); boneWeight2.boneIndex2 = Mathf.Max(0, pairs[2].Key); boneWeight2.boneIndex3 = Mathf.Max(0, pairs[3].Key); boneWeight2.weight0 = pairs[0].Value; boneWeight2.weight1 = pairs[1].Value; boneWeight2.weight2 = pairs[2].Value; boneWeight2.weight3 = pairs[3].Value; boneWeights.Add(boneWeight2); float vertexOrder = i; if (spriteMeshData.bindPoses.Length > 0) { vertexOrder = spriteMeshData.bindPoses[boneWeight2.boneIndex0].zOrder * boneWeight2.weight0 + spriteMeshData.bindPoses[boneWeight2.boneIndex1].zOrder * boneWeight2.weight1 + spriteMeshData.bindPoses[boneWeight2.boneIndex2].zOrder * boneWeight2.weight2 + spriteMeshData.bindPoses[boneWeight2.boneIndex3].zOrder * boneWeight2.weight3; } verticesOrder.Add(vertexOrder); } List <WeightedTriangle> weightedTriangles = new List <WeightedTriangle>(spriteMeshData.indices.Length / 3); for (int i = 0; i < spriteMeshData.indices.Length; i += 3) { int p1 = spriteMeshData.indices[i]; int p2 = spriteMeshData.indices[i + 1]; int p3 = spriteMeshData.indices[i + 2]; weightedTriangles.Add(new WeightedTriangle(p1, p2, p3, verticesOrder[p1], verticesOrder[p2], verticesOrder[p3])); } weightedTriangles = weightedTriangles.OrderBy(t => t.weight).ToList(); List <int> indices = new List <int>(spriteMeshData.indices.Length); for (int i = 0; i < weightedTriangles.Count; ++i) { WeightedTriangle t = weightedTriangles[i]; indices.Add(t.p1); indices.Add(t.p2); indices.Add(t.p3); } List <Matrix4x4> bindposes = (new List <BindInfo>(spriteMeshData.bindPoses)).ConvertAll(p => p.bindPose); for (int i = 0; i < bindposes.Count; i++) { Matrix4x4 bindpose = bindposes [i]; bindpose.m23 = 0f; bindposes[i] = bindpose; } spriteMesh.sharedMesh.Clear(); spriteMesh.sharedMesh.vertices = vertices; spriteMesh.sharedMesh.uv = uvs; spriteMesh.sharedMesh.triangles = indices.ToArray(); spriteMesh.sharedMesh.normals = normals; spriteMesh.sharedMesh.boneWeights = boneWeights.ToArray(); spriteMesh.sharedMesh.bindposes = bindposes.ToArray(); spriteMesh.sharedMesh.RecalculateBounds(); #if UNITY_5_6_OR_NEWER spriteMesh.sharedMesh.RecalculateTangents(); #endif RebuildBlendShapes(spriteMesh); } }
public static void RebuildBlendShapes(SpriteMesh spriteMesh, Mesh mesh) { if (!mesh) { return; } if (!spriteMesh) { return; } BlendShape[] blendShapes = null; SpriteMeshData spriteMeshData = LoadSpriteMeshData(spriteMesh); if (spriteMeshData) { blendShapes = spriteMeshData.blendshapes; } if (spriteMesh.sharedMesh.vertexCount != mesh.vertexCount) { return; } if (blendShapes != null) { #if !(UNITY_5_0 || UNITY_5_1 || UNITY_5_2) List <string> blendShapeNames = new List <string>(); mesh.ClearBlendShapes(); Vector3[] from = mesh.vertices; for (int i = 0; i < blendShapes.Length; i++) { BlendShape blendshape = blendShapes[i]; if (blendshape) { string blendShapeName = blendshape.name; if (blendShapeNames.Contains(blendShapeName)) { Debug.LogWarning("Found repeated BlendShape name '" + blendShapeName + "' in SpriteMesh: " + spriteMesh.name); } else { blendShapeNames.Add(blendShapeName); for (int j = 0; j < blendshape.frames.Length; j++) { BlendShapeFrame l_blendshapeFrame = blendshape.frames[j]; if (l_blendshapeFrame && from.Length == l_blendshapeFrame.vertices.Length) { Vector3[] deltaVertices = GetDeltaVertices(from, l_blendshapeFrame.vertices); mesh.AddBlendShapeFrame(blendShapeName, l_blendshapeFrame.weight, deltaVertices, null, null); } } } } } mesh.UploadMeshData(false); EditorUtility.SetDirty(mesh); #endif } }
static void SetBindPoses(SpriteMeshData spriteMeshData, SpriteMesh.BindInfo[] bindPoses) { if(bindPoses != null && bindPoses.Length > 0) { BindInfo[] array = new BindInfo[bindPoses.Length]; for(int i = 0; i < array.Length; ++i) { BindInfo b = new BindInfo(); b.bindPose = bindPoses[i].bindPose; b.boneLength = bindPoses[i].boneLength; b.color = bindPoses[i].color; b.name = bindPoses[i].name; b.path = bindPoses[i].path; b.zOrder = bindPoses[i].zOrder; array[i] = b; } FieldInfo fieldInfo = typeof(SpriteMeshData).GetField("m_BindPoses",BindingFlags.Instance | BindingFlags.NonPublic); if(fieldInfo != null) { fieldInfo.SetValue(spriteMeshData,array); } EditorUtility.SetDirty(spriteMeshData); } }
static void InitFromSprite(SpriteMeshData spriteMeshData, Sprite sprite) { Vector2[] vertices; IndexedEdge[] edges; int[] indices; Vector2 pivotPoint; if(sprite) { GetSpriteData(sprite, out vertices, out edges, out indices, out pivotPoint); spriteMeshData.vertices = vertices; spriteMeshData.edges = edges; spriteMeshData.indices = indices; spriteMeshData.pivotPoint = pivotPoint; } }
public static void UpdateAssets(SpriteMesh spriteMesh, SpriteMeshData spriteMeshData) { if(spriteMesh && spriteMeshData) { string spriteMeshPath = AssetDatabase.GetAssetPath(spriteMesh); SerializedObject spriteMeshSO = new SerializedObject(spriteMesh); SerializedProperty sharedMeshProp = spriteMeshSO.FindProperty("m_SharedMesh"); SerializedProperty sharedMaterialsProp = spriteMeshSO.FindProperty("m_SharedMaterials"); if(!spriteMesh.sharedMesh) { Mesh mesh = new Mesh(); mesh.hideFlags = HideFlags.HideInHierarchy; AssetDatabase.AddObjectToAsset(mesh,spriteMeshPath); spriteMeshSO.Update(); sharedMeshProp.objectReferenceValue = mesh; spriteMeshSO.ApplyModifiedProperties(); EditorUtility.SetDirty(mesh); } spriteMesh.sharedMesh.name = spriteMesh.name; if(spriteMesh.sharedMaterials.Length == 0) { Material material = new Material(Shader.Find("Sprites/Default")); material.mainTexture = SpriteUtility.GetSpriteTexture(spriteMesh.sprite,false); AssetDatabase.AddObjectToAsset(material,spriteMeshPath); spriteMeshSO.Update(); sharedMaterialsProp.arraySize = 1; sharedMaterialsProp.GetArrayElementAtIndex(0).objectReferenceValue = material; spriteMeshSO.ApplyModifiedProperties(); } for (int i = 0; i < spriteMesh.sharedMaterials.Length; i++) { Material material = spriteMesh.sharedMaterials [i]; if(material) { if(spriteMesh.sprite) { material.mainTexture = SpriteUtility.GetSpriteTexture(spriteMesh.sprite,false); } material.name = spriteMesh.name + "_" + i; material.hideFlags = HideFlags.HideInHierarchy; EditorUtility.SetDirty(material); } } spriteMeshData.hideFlags = HideFlags.HideInHierarchy; EditorUtility.SetDirty(spriteMeshData); int width = 0; int height = 0; GetSpriteTextureSize(spriteMesh.sprite,ref width,ref height); float pixelsPerUnit = GetSpritePixelsPerUnit(spriteMesh.sprite); Vector2 textureWidthHeightInv = new Vector2(1f/width,1f/height); Vector3[] vertices = (new List<Vector2>(spriteMeshData.vertices)).ConvertAll( v => TexCoordToVertex(spriteMeshData.pivotPoint,v,pixelsPerUnit)).ToArray(); Vector2[] uvs = (new List<Vector2>(spriteMeshData.vertices)).ConvertAll( v => Vector2.Scale(v,textureWidthHeightInv)).ToArray(); Vector3[] normals = (new List<Vector3>(vertices)).ConvertAll( v => Vector3.back ).ToArray(); BoneWeight[] boneWeightsData = spriteMeshData.boneWeights; if(boneWeightsData.Length != spriteMeshData.vertices.Length) { boneWeightsData = new BoneWeight[spriteMeshData.vertices.Length]; } List<UnityEngine.BoneWeight> boneWeights = new List<UnityEngine.BoneWeight>(boneWeightsData.Length); List<float> verticesOrder = new List<float>(spriteMeshData.vertices.Length); for (int i = 0; i < boneWeightsData.Length; i++) { BoneWeight boneWeight = boneWeightsData[i]; List< KeyValuePair<int,float> > pairs = new List<KeyValuePair<int, float>>(); pairs.Add(new KeyValuePair<int, float>(boneWeight.boneIndex0,boneWeight.weight0)); pairs.Add(new KeyValuePair<int, float>(boneWeight.boneIndex1,boneWeight.weight1)); pairs.Add(new KeyValuePair<int, float>(boneWeight.boneIndex2,boneWeight.weight2)); pairs.Add(new KeyValuePair<int, float>(boneWeight.boneIndex3,boneWeight.weight3)); pairs = pairs.OrderByDescending(s=>s.Value).ToList(); UnityEngine.BoneWeight boneWeight2 = new UnityEngine.BoneWeight(); boneWeight2.boneIndex0 = Mathf.Max(0,pairs[0].Key); boneWeight2.boneIndex1 = Mathf.Max(0,pairs[1].Key); boneWeight2.boneIndex2 = Mathf.Max(0,pairs[2].Key); boneWeight2.boneIndex3 = Mathf.Max(0,pairs[3].Key); boneWeight2.weight0 = pairs[0].Value; boneWeight2.weight1 = pairs[1].Value; boneWeight2.weight2 = pairs[2].Value; boneWeight2.weight3 = pairs[3].Value; boneWeights.Add(boneWeight2); float vertexOrder = i; if(spriteMeshData.bindPoses.Length > 0) { vertexOrder = spriteMeshData.bindPoses[boneWeight2.boneIndex0].zOrder * boneWeight2.weight0 + spriteMeshData.bindPoses[boneWeight2.boneIndex1].zOrder * boneWeight2.weight1 + spriteMeshData.bindPoses[boneWeight2.boneIndex2].zOrder * boneWeight2.weight2 + spriteMeshData.bindPoses[boneWeight2.boneIndex3].zOrder * boneWeight2.weight3; } verticesOrder.Add(vertexOrder); } List<WeightedTriangle> weightedTriangles = new List<WeightedTriangle>(spriteMeshData.indices.Length / 3); for(int i = 0; i < spriteMeshData.indices.Length; i+=3) { int p1 = spriteMeshData.indices[i]; int p2 = spriteMeshData.indices[i+1]; int p3 = spriteMeshData.indices[i+2]; weightedTriangles.Add(new WeightedTriangle(p1,p2,p3, verticesOrder[p1], verticesOrder[p2], verticesOrder[p3])); } weightedTriangles = weightedTriangles.OrderBy( t => t.weight ).ToList(); List<int> indices = new List<int>(spriteMeshData.indices.Length); for(int i = 0; i < weightedTriangles.Count; ++i) { WeightedTriangle t = weightedTriangles[i]; indices.Add(t.p1); indices.Add(t.p2); indices.Add(t.p3); } spriteMesh.sharedMesh.Clear(); spriteMesh.sharedMesh.vertices = vertices; spriteMesh.sharedMesh.uv = uvs; spriteMesh.sharedMesh.triangles = indices.ToArray(); spriteMesh.sharedMesh.normals = normals; spriteMesh.sharedMesh.boneWeights = boneWeights.ToArray(); spriteMesh.sharedMesh.bindposes = (new List<BindInfo>(spriteMeshData.bindPoses)).ConvertAll( p => p.bindPose ).ToArray(); spriteMesh.sharedMesh.RecalculateBounds(); } }
static void HandleDragAndDrop(bool createOnEnter, Transform parent) { switch (Event.current.type) { case EventType.DragUpdated: if (!init) { spriteMesh = GetSpriteMesh(); if (createOnEnter) { parentTransform = null; CreateInstance(); } Event.current.Use(); init = true; } if (instance) { instance.transform.position = instancePosition; SpriteMeshInstance l_currentDestination = GetClosestBindeableIntersectingSpriteMeshInstance(); if (currentDestination != l_currentDestination) { currentDestination = l_currentDestination; if (currentDestination) { List <Bone2D> destinationBones = currentDestination.bones; List <Bone2D> newBones = new List <Bone2D>(); SpriteMeshData data = SpriteMeshUtils.LoadSpriteMeshData(instance.spriteMesh); for (int i = 0; i < data.bindPoses.Length; ++i) { BindInfo bindInfo = data.bindPoses[i]; int index = FindBindInfo(bindInfo, currentDestination); if (index >= 0 && index < destinationBones.Count) { newBones.Add(destinationBones[index]); } } instance.transform.parent = currentDestination.transform.parent; instance.bones = newBones; SpriteMeshUtils.UpdateRenderer(instance, false); foreach (Bone2D bone in s_InstanceBones) { bone.hideFlags = HideFlags.HideAndDontSave; bone.gameObject.SetActive(false); } } else { foreach (Bone2D bone in s_InstanceBones) { bone.hideFlags = HideFlags.None; bone.gameObject.SetActive(true); } instance.transform.parent = null; instance.bones = s_InstanceBones; SpriteMeshUtils.UpdateRenderer(instance, false); } SceneView.RepaintAll(); } } break; case EventType.DragExited: if (instance) { GameObject.DestroyImmediate(instance.gameObject); Event.current.Use(); } Cleanup(); break; case EventType.DragPerform: if (!createOnEnter) { CreateInstance(); } if (instance) { if (currentDestination) { foreach (Bone2D bone in s_InstanceBones) { if (bone) { GameObject.DestroyImmediate(bone.gameObject); } } } Undo.RegisterCreatedObjectUndo(instance.gameObject, "create SpriteMeshInstance"); } Cleanup(); break; } if (instance) { DragAndDrop.visualMode = DragAndDropVisualMode.Copy; } }
static void Upgrade_002(SerializedObject spriteMeshSO) { spriteMeshSO.Update(); SpriteMesh spriteMesh = spriteMeshSO.targetObject as SpriteMesh; SerializedProperty sharedMeshProp = spriteMeshSO.FindProperty("m_SharedMesh"); SerializedProperty sharedMaterialsProp = spriteMeshSO.FindProperty("m_SharedMaterials"); SerializedProperty pivotPointProp = spriteMeshSO.FindProperty("pivotPoint"); SerializedProperty texVerticesProp = spriteMeshSO.FindProperty("texVertices"); SerializedProperty edgesProp = spriteMeshSO.FindProperty("edges"); SerializedProperty holesProp = spriteMeshSO.FindProperty("holes"); SerializedProperty indicesProp = spriteMeshSO.FindProperty("indices"); string path = AssetDatabase.GetAssetPath(spriteMeshSO.targetObject); GameObject go = AssetDatabase.LoadAssetAtPath(path, typeof(GameObject)) as GameObject; if (go) { Object.DestroyImmediate(go, true); } Material material = AssetDatabase.LoadAssetAtPath(path, typeof(Material)) as Material; if (material) { sharedMaterialsProp.arraySize = 1; sharedMaterialsProp.GetArrayElementAtIndex(0).objectReferenceValue = material; material.hideFlags = HideFlags.HideInHierarchy; EditorUtility.SetDirty(material); } Mesh mesh = AssetDatabase.LoadAssetAtPath(path, typeof(Mesh)) as Mesh; if (mesh) { mesh.hideFlags = HideFlags.HideInHierarchy; sharedMeshProp.objectReferenceValue = mesh; EditorUtility.SetDirty(mesh); } spriteMeshSO.ApplyModifiedProperties(); SpriteMeshData spriteMeshData = SpriteMeshUtils.LoadSpriteMeshData(spriteMesh); if (!spriteMeshData) { spriteMeshData = ScriptableObject.CreateInstance <SpriteMeshData>(); AssetDatabase.AddObjectToAsset(spriteMeshData, path); } if (spriteMeshData) { spriteMeshData.name = spriteMeshSO.targetObject.name + "_Data"; spriteMeshData.hideFlags = HideFlags.HideInHierarchy; SerializedObject spriteMeshDataSO = new SerializedObject(spriteMeshData); SerializedProperty smdPivotPointProp = spriteMeshDataSO.FindProperty("m_PivotPoint"); SerializedProperty smdVerticesProp = spriteMeshDataSO.FindProperty("m_Vertices"); SerializedProperty smdBoneWeightsProp = spriteMeshDataSO.FindProperty("m_BoneWeights"); SerializedProperty smdEdgesProp = spriteMeshDataSO.FindProperty("m_Edges"); SerializedProperty smdHolesProp = spriteMeshDataSO.FindProperty("m_Holes"); SerializedProperty smdIndicesProp = spriteMeshDataSO.FindProperty("m_Indices"); spriteMeshDataSO.Update(); smdPivotPointProp.vector2Value = pivotPointProp.vector2Value; smdVerticesProp.arraySize = texVerticesProp.arraySize; smdBoneWeightsProp.arraySize = texVerticesProp.arraySize; for (int i = 0; i < smdVerticesProp.arraySize; ++i) { SerializedProperty vertexProp = texVerticesProp.GetArrayElementAtIndex(i); SerializedProperty vertexPositionProp = vertexProp.FindPropertyRelative("vertex"); SerializedProperty boneWeightProp = vertexProp.FindPropertyRelative("boneWeight"); SerializedProperty boneIndex0Prop = boneWeightProp.FindPropertyRelative("boneIndex0"); SerializedProperty boneIndex1Prop = boneWeightProp.FindPropertyRelative("boneIndex1"); SerializedProperty boneIndex2Prop = boneWeightProp.FindPropertyRelative("boneIndex2"); SerializedProperty boneIndex3Prop = boneWeightProp.FindPropertyRelative("boneIndex3"); SerializedProperty boneWeight0Prop = boneWeightProp.FindPropertyRelative("weight0"); SerializedProperty boneWeight1Prop = boneWeightProp.FindPropertyRelative("weight1"); SerializedProperty boneWeight2Prop = boneWeightProp.FindPropertyRelative("weight2"); SerializedProperty boneWeight3Prop = boneWeightProp.FindPropertyRelative("weight3"); SerializedProperty smdVertexProp = smdVerticesProp.GetArrayElementAtIndex(i); SerializedProperty smdBoneWeightProp = smdBoneWeightsProp.GetArrayElementAtIndex(i); SerializedProperty smdBoneIndex0Prop = smdBoneWeightProp.FindPropertyRelative("boneIndex0"); SerializedProperty smdBoneIndex1Prop = smdBoneWeightProp.FindPropertyRelative("boneIndex1"); SerializedProperty smdBoneIndex2Prop = smdBoneWeightProp.FindPropertyRelative("boneIndex2"); SerializedProperty smdBoneIndex3Prop = smdBoneWeightProp.FindPropertyRelative("boneIndex3"); SerializedProperty smdBoneWeight0Prop = smdBoneWeightProp.FindPropertyRelative("weight0"); SerializedProperty smdBoneWeight1Prop = smdBoneWeightProp.FindPropertyRelative("weight1"); SerializedProperty smdBoneWeight2Prop = smdBoneWeightProp.FindPropertyRelative("weight2"); SerializedProperty smdBoneWeight3Prop = smdBoneWeightProp.FindPropertyRelative("weight3"); smdVertexProp.vector2Value = vertexPositionProp.vector2Value; smdBoneIndex0Prop.intValue = boneIndex0Prop.intValue; smdBoneIndex1Prop.intValue = boneIndex1Prop.intValue; smdBoneIndex2Prop.intValue = boneIndex2Prop.intValue; smdBoneIndex3Prop.intValue = boneIndex3Prop.intValue; smdBoneWeight0Prop.floatValue = boneWeight0Prop.floatValue; smdBoneWeight1Prop.floatValue = boneWeight1Prop.floatValue; smdBoneWeight2Prop.floatValue = boneWeight2Prop.floatValue; smdBoneWeight3Prop.floatValue = boneWeight3Prop.floatValue; } smdEdgesProp.arraySize = edgesProp.arraySize; for (int i = 0; i < smdEdgesProp.arraySize; ++i) { SerializedProperty edgeProp = edgesProp.GetArrayElementAtIndex(i); SerializedProperty smdEdgeProp = smdEdgesProp.GetArrayElementAtIndex(i); smdEdgeProp.FindPropertyRelative("index1").intValue = edgeProp.FindPropertyRelative("index1").intValue; smdEdgeProp.FindPropertyRelative("index2").intValue = edgeProp.FindPropertyRelative("index2").intValue; } smdHolesProp.arraySize = holesProp.arraySize; for (int i = 0; i < smdHolesProp.arraySize; ++i) { SerializedProperty holeProp = holesProp.GetArrayElementAtIndex(i); SerializedProperty smdHoleProp = smdHolesProp.GetArrayElementAtIndex(i); smdHoleProp.vector2Value = holeProp.FindPropertyRelative("vertex").vector2Value; } smdIndicesProp.arraySize = indicesProp.arraySize; for (int i = 0; i < smdIndicesProp.arraySize; ++i) { smdIndicesProp.GetArrayElementAtIndex(i).intValue = indicesProp.GetArrayElementAtIndex(i).intValue; } spriteMeshDataSO.ApplyModifiedProperties(); //Can't find the way to make SerializedProperty work with Matrix4x4, so we use reflection SetBindPoses(spriteMeshData, GetBindPoses(spriteMesh)); } }