public void InitFromOutline(float detail, float alphaTolerance, bool holeDetection, float tessellation, string undoName) { Clear(undoName); float pixelsPerUnit = SpriteMeshUtils.GetSpritePixelsPerUnit(spriteMesh.sprite); float factor = pixelsPerUnit / spriteMesh.sprite.pixelsPerUnit; Vector2 position = rect.position / factor; Vector2 size = rect.size / factor; Rect l_rect = new Rect(position.x, position.y, size.x, size.y); Texture2D texture = SpriteUtility.GetSpriteTexture(spriteMesh.sprite, false); Rect clampedRect = MathUtils.ClampRect(MathUtils.OrderMinMax(l_rect), new Rect(0f, 0f, texture.width, texture.height)); List <Vector2> l_texcoords; List <IndexedEdge> l_indexedEdges; List <int> l_indices; SpriteMeshUtils.InitFromOutline(texture, clampedRect, detail, alphaTolerance, holeDetection, out l_texcoords, out l_indexedEdges, out l_indices); SpriteMeshUtils.Tessellate(l_texcoords, l_indexedEdges, holes, l_indices, tessellation * 10f); nodes = l_texcoords.ConvertAll(v => Node.Create(l_texcoords.IndexOf(v))); edges = l_indexedEdges.ConvertAll(e => Edge.Create(nodes[e.index1], nodes[e.index2])); m_TexVertices = l_texcoords.ConvertAll(v => v * factor); boneWeights = l_texcoords.ConvertAll(v => BoneWeight.Create()); indices = l_indices; isDirty = true; m_DirtyVertices = true; }
public void RevertChanges() { Clear(""); if (spriteMesh && spriteMeshData) { pivotPoint = spriteMeshData.pivotPoint; rect = SpriteMeshUtils.GetRect(spriteMesh.sprite); m_TexVertices = spriteMeshData.vertices.ToList(); nodes = m_TexVertices.ConvertAll(v => Node.Create(m_TexVertices.IndexOf(v))); boneWeights = spriteMeshData.boneWeights.ToList(); edges = spriteMeshData.edges.ToList().ConvertAll(e => Edge.Create(nodes[e.index1], nodes[e.index2])); holes = spriteMeshData.holes.ToList().ConvertAll(h => new Hole(h)); indices = spriteMeshData.indices.ToList(); bindPoses = spriteMeshData.bindPoses.ToList().ConvertAll(b => b.Clone() as BindInfo); CreateBlendShapeCache(spriteMeshData); if (boneWeights.Count != nodes.Count) { boneWeights = nodes.ConvertAll(n => BoneWeight.Create()); } m_DirtyVertices = true; } }
public Node AddNode(Vector2 position, Edge edge) { Node node = Node.Create(nodes.Count); nodes.Add(node); if (edge) { edges.Add(Edge.Create(edge.node1, node)); edges.Add(Edge.Create(edge.node2, node)); edges.Remove(edge); } m_TexVertices.Add(position); boneWeights.Add(BoneWeight.Create()); if (blendshapes.Count > 0) { List <Vector3> frameVertices = new List <Vector3>(nodes.Count); Vector3 vertex = ToVertex(position); foreach (BlendShape blendShape in blendshapes) { foreach (BlendShapeFrame frame in blendShape.frames) { RegisterObjectUndo(frame, Undo.GetCurrentGroupName()); frameVertices.Clear(); frameVertices.AddRange(frame.vertices); frameVertices.Add(vertex); frame.vertices = frameVertices.ToArray(); } } } Triangulate(); m_DirtyVertices = true; return(node); }
void DoVerticesInspector() { if (spriteMeshCache.selection.Count > 0) { string[] names = spriteMeshCache.GetBoneNames("Unassigned"); BoneWeight boneWeight = BoneWeight.Create(); EditorGUI.BeginChangeCheck(); bool mixedBoneIndex0 = false; bool mixedBoneIndex1 = false; bool mixedBoneIndex2 = false; bool mixedBoneIndex3 = false; bool changedIndex0 = false; bool changedIndex1 = false; bool changedIndex2 = false; bool changedIndex3 = false; bool mixedWeight = false; if (spriteMeshCache.multiselection) { mixedWeight = true; int boneIndex = -1; mixedBoneIndex0 = IsMixedBoneIndex(0, out boneIndex); if (!mixedBoneIndex0) { boneWeight.boneIndex0 = boneIndex; } mixedBoneIndex1 = IsMixedBoneIndex(1, out boneIndex); if (!mixedBoneIndex1) { boneWeight.boneIndex1 = boneIndex; } mixedBoneIndex2 = IsMixedBoneIndex(2, out boneIndex); if (!mixedBoneIndex2) { boneWeight.boneIndex2 = boneIndex; } mixedBoneIndex3 = IsMixedBoneIndex(3, out boneIndex); if (!mixedBoneIndex3) { boneWeight.boneIndex3 = boneIndex; } } else { boneWeight = spriteMeshCache.GetBoneWeight(spriteMeshCache.selectedNode); } EditorGUI.BeginChangeCheck(); EditorGUI.BeginChangeCheck(); boneWeight = EditorGUIExtra.Weight(boneWeight, 0, names, mixedBoneIndex0, mixedWeight); changedIndex0 = EditorGUI.EndChangeCheck(); EditorGUI.BeginChangeCheck(); boneWeight = EditorGUIExtra.Weight(boneWeight, 1, names, mixedBoneIndex1, mixedWeight); changedIndex1 = EditorGUI.EndChangeCheck(); EditorGUI.BeginChangeCheck(); boneWeight = EditorGUIExtra.Weight(boneWeight, 2, names, mixedBoneIndex2, mixedWeight); changedIndex2 = EditorGUI.EndChangeCheck(); EditorGUI.BeginChangeCheck(); boneWeight = EditorGUIExtra.Weight(boneWeight, 3, names, mixedBoneIndex3, mixedWeight); changedIndex3 = EditorGUI.EndChangeCheck(); if (EditorGUI.EndChangeCheck()) { spriteMeshCache.RegisterUndo("modify weights"); if (spriteMeshCache.multiselection) { List <Node> selectedNodes = spriteMeshCache.selectedNodes; foreach (Node node in selectedNodes) { BoneWeight l_boneWeight = spriteMeshCache.GetBoneWeight(node); if (!mixedBoneIndex0 || changedIndex0) { l_boneWeight.SetWeight(0, boneWeight.boneIndex0, l_boneWeight.weight0); } if (!mixedBoneIndex1 || changedIndex1) { l_boneWeight.SetWeight(1, boneWeight.boneIndex1, l_boneWeight.weight1); } if (!mixedBoneIndex2 || changedIndex2) { l_boneWeight.SetWeight(2, boneWeight.boneIndex2, l_boneWeight.weight2); } if (!mixedBoneIndex3 || changedIndex3) { l_boneWeight.SetWeight(3, boneWeight.boneIndex3, l_boneWeight.weight3); } spriteMeshCache.SetBoneWeight(node, l_boneWeight); } } else { spriteMeshCache.SetBoneWeight(spriteMeshCache.selectedNode, boneWeight); } } EditorGUI.showMixedValue = false; } }
public void CalculateAutomaticWeights(List <Node> targetNodes) { float pixelsPerUnit = SpriteMeshUtils.GetSpritePixelsPerUnit(spriteMesh.sprite); if (nodes.Count <= 0) { Debug.Log("Cannot calculate automatic weights from a SpriteMesh with no vertices."); return; } if (bindPoses.Count <= 0) { Debug.Log("Cannot calculate automatic weights. Specify bones to the SpriteMeshInstance."); return; } if (spriteMesh && bindPoses.Count > 1) { List <Vector2> controlPoints = new List <Vector2>(bindPoses.Count * 2); List <IndexedEdge> controlPointEdges = new List <IndexedEdge>(bindPoses.Count); foreach (BindInfo bindInfo in bindPoses) { Vector2 tip = SpriteMeshUtils.VertexToTexCoord(spriteMesh, pivotPoint, bindInfo.position, pixelsPerUnit); Vector2 tail = SpriteMeshUtils.VertexToTexCoord(spriteMesh, pivotPoint, bindInfo.endPoint, pixelsPerUnit); int index1 = -1; if (!ContainsVector(tip, controlPoints, 0.01f, out index1)) { index1 = controlPoints.Count; controlPoints.Add(tip); } int index2 = -1; if (!ContainsVector(tail, controlPoints, 0.01f, out index2)) { index2 = controlPoints.Count; controlPoints.Add(tail); } IndexedEdge edge = new IndexedEdge(index1, index2); controlPointEdges.Add(edge); } float[,] weightArray; BbwPlugin.CalculateBbw(m_TexVertices.ToArray(), indexedEdges.ToArray(), controlPoints.ToArray(), controlPointEdges.ToArray(), out weightArray); FillBoneWeights(targetNodes, weightArray); isDirty = true; } else { BoneWeight boneWeight = BoneWeight.Create(); boneWeight.boneIndex0 = 0; boneWeight.weight0 = 1f; foreach (Node node in targetNodes) { SetBoneWeight(node, boneWeight); } } }