public static void CalculateBbw(Vector3[] vertices, int[] indices, IndexedEdge[] edges, Vector3[] controlPoints, IndexedEdge[] controlPointEdges, out float[,] weights) { weights = new float[controlPointEdges.Length,vertices.Length]; GCHandle verticesHandle = GCHandle.Alloc(vertices, GCHandleType.Pinned); GCHandle indicesHandle = GCHandle.Alloc(indices, GCHandleType.Pinned); GCHandle edgesHandle = GCHandle.Alloc(edges, GCHandleType.Pinned); GCHandle controlPointsHandle = GCHandle.Alloc(controlPoints, GCHandleType.Pinned); GCHandle boneEdgesHandle = GCHandle.Alloc(controlPointEdges, GCHandleType.Pinned); GCHandle weightsHandle = GCHandle.Alloc(weights, GCHandleType.Pinned); /* SaveData(verticesHandle.AddrOfPinnedObject(), vertices.Length, indicesHandle.AddrOfPinnedObject(), indices.Length, edgesHandle.AddrOfPinnedObject(),edges.Length, controlPointsHandle.AddrOfPinnedObject(), controlPoints.Length, boneEdgesHandle.AddrOfPinnedObject(), controlPointEdges.Length); */ Bbw(verticesHandle.AddrOfPinnedObject(), vertices.Length, indicesHandle.AddrOfPinnedObject(), indices.Length, edgesHandle.AddrOfPinnedObject(), edges.Length, controlPointsHandle.AddrOfPinnedObject(), controlPoints.Length, boneEdgesHandle.AddrOfPinnedObject(), controlPointEdges.Length, weightsHandle.AddrOfPinnedObject()); verticesHandle.Free(); indicesHandle.Free(); edgesHandle.Free(); controlPointsHandle.Free(); boneEdgesHandle.Free(); weightsHandle.Free(); }
public override bool Equals(System.Object obj) { if (obj == null || GetType() != obj.GetType()) { return(false); } IndexedEdge p = (IndexedEdge)obj; return((index1 == p.index1) && (index2 == p.index2) || (index1 == p.index2) && (index2 == p.index1)); }
void UpdateEdges() { edges.Clear(); for (int i = 0; i < mIndexedEdges.Count; i++) { IndexedEdge indexedEdge = mIndexedEdges[i]; Edge edge = new Edge(texVertices[indexedEdge.index1], texVertices[indexedEdge.index2]); edges.Add(edge); } }
public void UpdateIndexedEdges() { indexedEdges.Clear(); for (int i = 0; i < edges.Count; i++) { Edge edge = edges[i]; IndexedEdge indexedEdge = new IndexedEdge(texVertices.IndexOf(edge.vertex1), texVertices.IndexOf(edge.vertex2)); indexedEdges.Add(indexedEdge); } }
public static void Triangulate(List <Vector2> vertices, List <IndexedEdge> edges, List <Hole> holes, ref List <int> indices) { indices.Clear(); if (vertices.Count >= 3) { InputGeometry inputGeometry = new InputGeometry(vertices.Count); for (int i = 0; i < vertices.Count; ++i) { Vector2 position = vertices[i]; inputGeometry.AddPoint(position.x, position.y); } for (int i = 0; i < edges.Count; ++i) { IndexedEdge edge = edges[i]; inputGeometry.AddSegment(edge.index1, edge.index2); } for (int i = 0; i < holes.Count; ++i) { Vector2 hole = holes[i].vertex; inputGeometry.AddHole(hole.x, hole.y); } TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh(); triangleMesh.Triangulate(inputGeometry); foreach (TriangleNet.Data.Triangle triangle in triangleMesh.Triangles) { if (triangle.P0 >= 0 && triangle.P0 < vertices.Count && triangle.P0 >= 0 && triangle.P1 < vertices.Count && triangle.P0 >= 0 && triangle.P2 < vertices.Count) { indices.Add(triangle.P0); indices.Add(triangle.P2); indices.Add(triangle.P1); } } } }
static Vector2[] SampleEdges(Vector2[] controlPoints, IndexedEdge[] controlPointEdges, int samplesPerEdge) { List <Vector2> sampledVertices = new List <Vector2>(); for (int i = 0; i < controlPointEdges.Length; i++) { IndexedEdge edge = controlPointEdges[i]; Vector2 tip = controlPoints[edge.index1]; Vector2 tail = controlPoints[edge.index2]; for (int s = 0; s < samplesPerEdge; s++) { float f = (s + 1f) / (float)(samplesPerEdge + 1f); sampledVertices.Add(f * tail + (1f - f) * tip); } } return(sampledVertices.ToArray()); }
public static void Tessellate(List <Vector2> vertices, List <IndexedEdge> indexedEdges, List <Hole> holes, List <int> indices, float tessellationAmount) { if (tessellationAmount <= 0f) { return; } indices.Clear(); if (vertices.Count >= 3) { InputGeometry inputGeometry = new InputGeometry(vertices.Count); for (int i = 0; i < vertices.Count; ++i) { Vector2 vertex = vertices[i]; inputGeometry.AddPoint(vertex.x, vertex.y); } for (int i = 0; i < indexedEdges.Count; ++i) { IndexedEdge edge = indexedEdges[i]; inputGeometry.AddSegment(edge.index1, edge.index2); } for (int i = 0; i < holes.Count; ++i) { Vector2 hole = holes[i].vertex; inputGeometry.AddHole(hole.x, hole.y); } TriangleNet.Mesh triangleMesh = new TriangleNet.Mesh(); TriangleNet.Tools.Statistic statistic = new TriangleNet.Tools.Statistic(); triangleMesh.Triangulate(inputGeometry); triangleMesh.Behavior.MinAngle = 20.0; triangleMesh.Behavior.SteinerPoints = -1; triangleMesh.Refine(true); statistic.Update(triangleMesh, 1); triangleMesh.Refine(statistic.LargestArea / tessellationAmount); triangleMesh.Renumber(); vertices.Clear(); indexedEdges.Clear(); foreach (TriangleNet.Data.Vertex vertex in triangleMesh.Vertices) { vertices.Add(new Vector2((float)vertex.X, (float)vertex.Y)); } foreach (TriangleNet.Data.Segment segment in triangleMesh.Segments) { indexedEdges.Add(new IndexedEdge(segment.P0, segment.P1)); } foreach (TriangleNet.Data.Triangle triangle in triangleMesh.Triangles) { if (triangle.P0 >= 0 && triangle.P0 < vertices.Count && triangle.P0 >= 0 && triangle.P1 < vertices.Count && triangle.P0 >= 0 && triangle.P2 < vertices.Count) { indices.Add(triangle.P0); indices.Add(triangle.P2); indices.Add(triangle.P1); } } } }
public static void GetSpriteData(Sprite sprite, out Vector2[] vertices, out IndexedEdge[] edges, out int[] indices, out Vector2 pivotPoint) { int width = 0; int height = 0; GetSpriteTextureSize(sprite, ref width, ref height); pivotPoint = Vector2.zero; Vector2[] uvs = SpriteUtility.GetSpriteUVs(sprite, false); vertices = new Vector2[uvs.Length]; for (int i = 0; i < uvs.Length; ++i) { vertices[i] = new Vector2(uvs[i].x * width, uvs[i].y * height); } ushort[] l_indices = sprite.triangles; indices = new int[l_indices.Length]; for (int i = 0; i < l_indices.Length; ++i) { indices[i] = (int)l_indices[i]; } HashSet <IndexedEdge> edgesSet = new HashSet <IndexedEdge>(); for (int i = 0; i < indices.Length; i += 3) { int index1 = indices[i]; int index2 = indices[i + 1]; int index3 = indices[i + 2]; IndexedEdge edge1 = new IndexedEdge(index1, index2); IndexedEdge edge2 = new IndexedEdge(index2, index3); IndexedEdge edge3 = new IndexedEdge(index1, index3); if (edgesSet.Contains(edge1)) { edgesSet.Remove(edge1); } else { edgesSet.Add(edge1); } if (edgesSet.Contains(edge2)) { edgesSet.Remove(edge2); } else { edgesSet.Add(edge2); } if (edgesSet.Contains(edge3)) { edgesSet.Remove(edge3); } else { edgesSet.Add(edge3); } } edges = new IndexedEdge[edgesSet.Count]; int edgeIndex = 0; foreach (IndexedEdge edge in edgesSet) { edges[edgeIndex] = edge; ++edgeIndex; } pivotPoint = GetPivotPoint(sprite); }
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) { return; } List <Vector2> controlPoints = new List <Vector2>(); List <IndexedEdge> controlPointEdges = new List <IndexedEdge>(); List <int> pins = new List <int>(); foreach (BindInfo bindInfo in bindPoses) { Vector2 tip = SpriteMeshUtils.VertexToTexCoord(spriteMesh, pivotPoint, bindInfo.position, pixelsPerUnit); Vector2 tail = SpriteMeshUtils.VertexToTexCoord(spriteMesh, pivotPoint, bindInfo.endPoint, pixelsPerUnit); if (bindInfo.boneLength <= 0f) { int index = controlPoints.Count; controlPoints.Add(tip); pins.Add(index); continue; } 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); } UnityEngine.BoneWeight[] boneWeights = BbwPlugin.CalculateBbw(m_TexVertices.ToArray(), indexedEdges.ToArray(), controlPoints.ToArray(), controlPointEdges.ToArray(), pins.ToArray()); foreach (Node node in targetNodes) { UnityEngine.BoneWeight unityBoneWeight = boneWeights[node.index]; SetBoneWeight(node, CreateBoneWeightFromUnityBoneWeight(unityBoneWeight)); } isDirty = true; }
public static void GetSpriteData(Sprite sprite, out Vector2[] vertices, out IndexedEdge[] edges, out int[] indices, out Vector2 pivotPoint) { int width = 0; int height = 0; GetSpriteTextureSize(sprite,ref width,ref height); pivotPoint = Vector2.zero; Vector2[] uvs = SpriteUtility.GetSpriteUVs(sprite,false); vertices = new Vector2[uvs.Length]; for(int i = 0; i < uvs.Length; ++i) { vertices[i] = new Vector2(uvs[i].x * width, uvs[i].y * height); } ushort[] l_indices = sprite.triangles; indices = new int[l_indices.Length]; for(int i = 0; i < l_indices.Length; ++i) { indices[i] = (int)l_indices[i]; } HashSet<IndexedEdge> edgesSet = new HashSet<IndexedEdge>(); for(int i = 0; i < indices.Length; i += 3) { int index1 = indices[i]; int index2 = indices[i+1]; int index3 = indices[i+2]; IndexedEdge edge1 = new IndexedEdge(index1,index2); IndexedEdge edge2 = new IndexedEdge(index2,index3); IndexedEdge edge3 = new IndexedEdge(index1,index3); if(edgesSet.Contains(edge1)) { edgesSet.Remove(edge1); }else{ edgesSet.Add(edge1); } if(edgesSet.Contains(edge2)) { edgesSet.Remove(edge2); }else{ edgesSet.Add(edge2); } if(edgesSet.Contains(edge3)) { edgesSet.Remove(edge3); }else{ edgesSet.Add(edge3); } } edges = new IndexedEdge[edgesSet.Count]; int edgeIndex = 0; foreach(IndexedEdge edge in edgesSet) { edges[edgeIndex] = edge; ++edgeIndex; } pivotPoint = GetPivotPoint(sprite); }
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); } } }
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<Vector3> l_vertices = texcoords.ConvertAll( v => (Vector3)v ); List<Vector3> controlPoints = new List<Vector3>(bindPoses.Count*2); List<IndexedEdge> controlPointEdges = new List<IndexedEdge>(bindPoses.Count); foreach(BindInfo bindInfo in bindPoses) { Vector3 tip = SpriteMeshUtils.VertexToTexCoord(spriteMesh,pivotPoint,bindInfo.position,pixelsPerUnit); Vector3 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(l_vertices.ToArray(), indices.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); } } }
public void CalculateAutomaticWeights(List <Vertex> targetVertices) { if (texVertices.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) { List <Vector3> vertices = new List <Vector3>(texVertices.Count); for (int i = 0; i < texVertices.Count; i++) { Vertex vertex = texVertices[i]; vertices.Add(vertex.vertex); } List <Vector3> controlPoints = new List <Vector3>(bindPoses.Count * 2); List <IndexedEdge> controlPointEdges = new List <IndexedEdge>(bindPoses.Count); foreach (BindInfo bindInfo in bindPoses) { Vector3 tip = SpriteMeshUtils.VertexToTexCoord(spriteMesh, bindInfo.position); Vector3 tail = SpriteMeshUtils.VertexToTexCoord(spriteMesh, bindInfo.endPoint); 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; UpdateIndexedEdges(); BbwPlugin.CalculateBbw(vertices.ToArray(), indices.ToArray(), indexedEdges.ToArray(), controlPoints.ToArray(), controlPointEdges.ToArray(), out weightArray); FillBoneWeights(targetVertices, weightArray); isDirty = true; } }