public virtual void Update() { // Clear fields if missing information to render. if (skeletonDataAsset == null || skeletonDataAsset.GetSkeletonData(false) == null) { Clear(); return; } // Initialize fields. if (skeleton == null || skeleton.Data != skeletonDataAsset.GetSkeletonData(false)) { Initialize(); } UpdateSkeleton(); // Count quads. int quadCount = 0; List <Slot> drawOrder = skeleton.DrawOrder; for (int i = 0, n = drawOrder.Count; i < n; i++) { Slot slot = drawOrder[i]; Attachment attachment = slot.Attachment; if (attachment is RegionAttachment) { quadCount++; } } // Ensure mesh data is the right size. Vector3[] vertices = this.vertices; int vertexCount = quadCount * 4; bool newTriangles = vertexCount > vertices.Length; if (newTriangles) { // Not enough vertices, increase size. this.vertices = vertices = new Vector3[vertexCount]; colors = new Color32[vertexCount]; uvs = new Vector2[vertexCount]; triangles = new int[quadCount * 6]; mesh.Clear(); for (int i = 0, n = quadCount; i < n; i++) { int index = i * 6; int vertex = i * 4; triangles[index] = vertex; triangles[index + 1] = vertex + 2; triangles[index + 2] = vertex + 1; triangles[index + 3] = vertex + 2; triangles[index + 4] = vertex + 3; triangles[index + 5] = vertex + 1; } } else { // Too many vertices, zero the extra. Vector3 zero = new Vector3(0, 0, 0); for (int i = vertexCount, n = lastVertexCount; i < n; i++) { vertices[i] = zero; } } lastVertexCount = vertexCount; // Setup mesh. float[] vertexPositions = this.vertexPositions; int vertexIndex = 0; Color32 color = new Color32(); for (int i = 0, n = drawOrder.Count; i < n; i++) { Slot slot = drawOrder[i]; RegionAttachment regionAttachment = slot.Attachment as RegionAttachment; if (regionAttachment == null) { continue; } regionAttachment.ComputeVertices(skeleton.X, skeleton.Y, slot.Bone, vertexPositions); vertices[vertexIndex] = new Vector3(vertexPositions[RegionAttachment.X1], vertexPositions[RegionAttachment.Y1], 0); vertices[vertexIndex + 1] = new Vector3(vertexPositions[RegionAttachment.X4], vertexPositions[RegionAttachment.Y4], 0); vertices[vertexIndex + 2] = new Vector3(vertexPositions[RegionAttachment.X2], vertexPositions[RegionAttachment.Y2], 0); vertices[vertexIndex + 3] = new Vector3(vertexPositions[RegionAttachment.X3], vertexPositions[RegionAttachment.Y3], 0); color.a = (byte)(skeleton.A * slot.A * 255); color.r = (byte)(skeleton.R * slot.R * color.a); color.g = (byte)(skeleton.G * slot.G * color.a); color.b = (byte)(skeleton.B * slot.B * color.a); colors[vertexIndex] = color; colors[vertexIndex + 1] = color; colors[vertexIndex + 2] = color; colors[vertexIndex + 3] = color; float[] regionUVs = regionAttachment.UVs; uvs[vertexIndex] = new Vector2(regionUVs[RegionAttachment.X1], 1 - regionUVs[RegionAttachment.Y1]); uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], 1 - regionUVs[RegionAttachment.Y4]); uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], 1 - regionUVs[RegionAttachment.Y2]); uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], 1 - regionUVs[RegionAttachment.Y3]); vertexIndex += 4; } mesh.vertices = vertices; mesh.colors32 = colors; mesh.uv = uvs; if (newTriangles) { mesh.triangles = triangles; } }
public virtual void Update() { SkeletonData skeletonData = skeletonDataAsset.GetSkeletonData(false); // Clear fields if missing information to render. if (skeletonDataAsset == null || skeletonData == null) { Clear(); return; } // Initialize fields. if (skeleton == null || skeleton.Data != skeletonData) { Initialize(); } UpdateSkeleton(); // Count quads and submeshes. int quadCount = 0, submeshQuadCount = 0; Material lastMaterial = null; submeshMaterials.Clear(); List <Slot> drawOrder = skeleton.DrawOrder; for (int i = 0, n = drawOrder.Count; i < n; i++) { RegionAttachment regionAttachment = drawOrder[i].Attachment as RegionAttachment; if (regionAttachment == null) { continue; } // Add submesh when material changes. Material material = (Material)regionAttachment.RendererObject; if (lastMaterial != material && lastMaterial != null) { addSubmesh(lastMaterial, quadCount, submeshQuadCount, false); submeshQuadCount = 0; } lastMaterial = material; quadCount++; submeshQuadCount++; } addSubmesh(lastMaterial, quadCount, submeshQuadCount, true); // Set materials. if (submeshMaterials.Count == sharedMaterials.Length) { submeshMaterials.CopyTo(sharedMaterials); } else { sharedMaterials = submeshMaterials.ToArray(); } renderer.sharedMaterials = sharedMaterials; // Ensure mesh data is the right size. Mesh mesh = this.mesh; Vector3[] vertices = this.vertices; int vertexCount = quadCount * 4; bool newTriangles = vertexCount > vertices.Length; if (newTriangles) { // Not enough vertices, increase size. this.vertices = vertices = new Vector3[vertexCount]; this.colors = new Color32[vertexCount]; this.uvs = new Vector2[vertexCount]; mesh.Clear(); } else { // Too many vertices, zero the extra. Vector3 zero = new Vector3(0, 0, 0); for (int i = vertexCount, n = lastVertexCount; i < n; i++) { vertices[i] = zero; } } lastVertexCount = vertexCount; // Setup mesh. float[] vertexPositions = this.vertexPositions; Vector2[] uvs = this.uvs; Color32[] colors = this.colors; int vertexIndex = 0; Color32 color = new Color32(); for (int i = 0, n = drawOrder.Count; i < n; i++) { Slot slot = drawOrder[i]; RegionAttachment regionAttachment = slot.Attachment as RegionAttachment; if (regionAttachment == null) { continue; } regionAttachment.ComputeVertices(skeleton.X, skeleton.Y, slot.Bone, vertexPositions); vertices[vertexIndex] = new Vector3(vertexPositions[RegionAttachment.X1], vertexPositions[RegionAttachment.Y1], 0); vertices[vertexIndex + 1] = new Vector3(vertexPositions[RegionAttachment.X4], vertexPositions[RegionAttachment.Y4], 0); vertices[vertexIndex + 2] = new Vector3(vertexPositions[RegionAttachment.X2], vertexPositions[RegionAttachment.Y2], 0); vertices[vertexIndex + 3] = new Vector3(vertexPositions[RegionAttachment.X3], vertexPositions[RegionAttachment.Y3], 0); color.a = (byte)(skeleton.A * slot.A * 255); color.r = (byte)(skeleton.R * slot.R * color.a); color.g = (byte)(skeleton.G * slot.G * color.a); color.b = (byte)(skeleton.B * slot.B * color.a); colors[vertexIndex] = color; colors[vertexIndex + 1] = color; colors[vertexIndex + 2] = color; colors[vertexIndex + 3] = color; float[] regionUVs = regionAttachment.UVs; uvs[vertexIndex] = new Vector2(regionUVs[RegionAttachment.X1], regionUVs[RegionAttachment.Y1]); uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]); uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]); uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]); vertexIndex += 4; } mesh.vertices = vertices; mesh.colors32 = colors; mesh.uv = uvs; mesh.subMeshCount = submeshMaterials.Count; for (int i = 0; i < mesh.subMeshCount; ++i) { mesh.SetTriangles(submeshIndexes[i], i); } if (calculateNormals) { mesh.RecalculateNormals(); if (calculateTangents) { Vector4[] tangents = this.tangents; int count = mesh.normals.Length; if (tangents.Length != count) { this.tangents = tangents = new Vector4[count]; } for (int i = 0; i < count; i++) { tangents[i] = new Vector4(1, 0, 0, 1); } mesh.tangents = tangents; } } }
public virtual void Update() { // Clear fields if missing information to render. if (skeletonDataAsset == null || skeletonDataAsset.GetSkeletonData(false) == null) { Clear(); return; } // Initialize fields. if (skeleton == null || skeleton.Data != skeletonDataAsset.GetSkeletonData(false)) { Initialize(); } UpdateSkeleton(); // Count quads. int quadCount = 0; List <Slot> drawOrder = skeleton.DrawOrder; for (int i = 0, n = drawOrder.Count; i < n; i++) { Slot slot = drawOrder[i]; Attachment attachment = slot.Attachment; if (attachment is RegionAttachment) { quadCount++; } } // Ensure mesh data is the right size. if (quadCount > vertices.Length / 4) { vertices = new Vector3[quadCount * 4]; colors = new Color[quadCount * 4]; uvs = new Vector2[quadCount * 4]; triangles = new int[quadCount * 6]; mesh.Clear(); for (int i = 0, n = quadCount; i < n; i++) { int index = i * 6; int vertexIndex = i * 4; triangles[index] = vertexIndex; triangles[index + 1] = vertexIndex + 2; triangles[index + 2] = vertexIndex + 1; triangles[index + 3] = vertexIndex + 2; triangles[index + 4] = vertexIndex + 3; triangles[index + 5] = vertexIndex + 1; } } else { Vector3 zero = new Vector3(0, 0, 0); for (int i = quadCount * 4, n = vertices.Length; i < n; i++) { vertices[i] = zero; } } // Setup mesh. float[] vertexPositions = this.vertexPositions; int quadIndex = 0; Color color = new Color(); for (int i = 0, n = drawOrder.Count; i < n; i++) { Slot slot = drawOrder[i]; Attachment attachment = slot.Attachment; if (attachment is RegionAttachment) { RegionAttachment regionAttachment = (RegionAttachment)attachment; regionAttachment.ComputeVertices(skeleton.X, skeleton.Y, slot.Bone, vertexPositions); int vertexIndex = quadIndex * 4; vertices[vertexIndex] = new Vector3(vertexPositions[RegionAttachment.X1], vertexPositions[RegionAttachment.Y1], 0); vertices[vertexIndex + 1] = new Vector3(vertexPositions[RegionAttachment.X4], vertexPositions[RegionAttachment.Y4], 0); vertices[vertexIndex + 2] = new Vector3(vertexPositions[RegionAttachment.X2], vertexPositions[RegionAttachment.Y2], 0); vertices[vertexIndex + 3] = new Vector3(vertexPositions[RegionAttachment.X3], vertexPositions[RegionAttachment.Y3], 0); color.a = skeleton.A * slot.A; color.r = skeleton.R * slot.R * color.a; color.g = skeleton.G * slot.G * color.a; color.b = skeleton.B * slot.B * color.a; colors[vertexIndex] = color; colors[vertexIndex + 1] = color; colors[vertexIndex + 2] = color; colors[vertexIndex + 3] = color; float[] regionUVs = regionAttachment.UVs; uvs[vertexIndex] = new Vector2(regionUVs[RegionAttachment.X1], 1 - regionUVs[RegionAttachment.Y1]); uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], 1 - regionUVs[RegionAttachment.Y4]); uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], 1 - regionUVs[RegionAttachment.Y2]); uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], 1 - regionUVs[RegionAttachment.Y3]); quadIndex++; } } mesh.vertices = vertices; mesh.colors = colors; mesh.uv = uvs; mesh.triangles = triangles; renderer.sharedMaterial = skeletonDataAsset.atlasAsset.material; }
/* */ private void UpdateMesh() { int quadIndex = 0; int drawCount = skeleton.DrawOrder.Count; Color currentColor = new Color(); for (int i = 0; i < drawCount; i++) { Slot slot = skeleton.DrawOrder[i]; Attachment attachment = slot.Attachment; if (attachment is RegionAttachment) { RegionAttachment regionAttachment = attachment as RegionAttachment; regionAttachment.ComputeVertices(slot.Bone, vertexPositions); int vertexIndex = quadIndex * 4; vertices[vertexIndex + 0] = new Vector3(vertexPositions[RegionAttachment.X1], vertexPositions[RegionAttachment.Y1], 0); vertices[vertexIndex + 1] = new Vector3(vertexPositions[RegionAttachment.X4], vertexPositions[RegionAttachment.Y4], 0); vertices[vertexIndex + 2] = new Vector3(vertexPositions[RegionAttachment.X2], vertexPositions[RegionAttachment.Y2], 0); vertices[vertexIndex + 3] = new Vector3(vertexPositions[RegionAttachment.X3], vertexPositions[RegionAttachment.Y3], 0); float[] regionUVs = regionAttachment.UVs; uvs[vertexIndex + 0] = new Vector2(regionUVs[RegionAttachment.X1], regionUVs[RegionAttachment.Y1]); uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]); uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]); uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]); currentColor.a = skeleton.A * slot.A; currentColor.r = skeleton.R * slot.R * slot.A; currentColor.g = skeleton.G * slot.G * slot.A; currentColor.b = skeleton.B * slot.B * slot.A; colors[vertexIndex] = currentColor; colors[vertexIndex + 1] = currentColor; colors[vertexIndex + 2] = currentColor; colors[vertexIndex + 3] = currentColor; int index = quadIndex * 6; triangles[index + 0] = vertexIndex; triangles[index + 1] = vertexIndex + 2; triangles[index + 2] = vertexIndex + 1; triangles[index + 3] = vertexIndex + 2; triangles[index + 4] = vertexIndex + 3; triangles[index + 5] = vertexIndex + 1; quadIndex++; } } mesh.Clear(); mesh.vertices = vertices; mesh.colors = colors; mesh.uv = uvs; mesh.triangles = triangles; if (skeletonDataAsset.normalGenerationMode != tk2dSpriteCollection.NormalGenerationMode.None) { mesh.RecalculateNormals(); if (skeletonDataAsset.normalGenerationMode == tk2dSpriteCollection.NormalGenerationMode.NormalsAndTangents) { Vector4[] tangents = new Vector4[mesh.normals.Length]; for (int t = 0; t < tangents.Length; ++t) { tangents[t] = new Vector4(1, 0, 0, 1); } mesh.tangents = tangents; } } renderer.sharedMaterial = skeletonDataAsset.spritesData.inst.materials[0]; }
private void UpdateMesh() { int quadIndex = 0; int drawCount = skeleton.DrawOrder.Count; Color32 color = new Color32(); for (int i = 0; i < drawCount; i++) { Slot slot = skeleton.DrawOrder[i]; Attachment attachment = slot.Attachment; if (attachment is RegionAttachment) { RegionAttachment regionAttachment = attachment as RegionAttachment; regionAttachment.ComputeVertices(skeleton.X, skeleton.Y, slot.Bone, vertexPositions); int vertexIndex = quadIndex * 4; vertices[vertexIndex + 0] = new Vector3(vertexPositions[RegionAttachment.X1], vertexPositions[RegionAttachment.Y1], 0); vertices[vertexIndex + 1] = new Vector3(vertexPositions[RegionAttachment.X4], vertexPositions[RegionAttachment.Y4], 0); vertices[vertexIndex + 2] = new Vector3(vertexPositions[RegionAttachment.X2], vertexPositions[RegionAttachment.Y2], 0); vertices[vertexIndex + 3] = new Vector3(vertexPositions[RegionAttachment.X3], vertexPositions[RegionAttachment.Y3], 0); float[] regionUVs = regionAttachment.UVs; uvs[vertexIndex + 0] = new Vector2(regionUVs[RegionAttachment.X1], regionUVs[RegionAttachment.Y1]); uvs[vertexIndex + 1] = new Vector2(regionUVs[RegionAttachment.X4], regionUVs[RegionAttachment.Y4]); uvs[vertexIndex + 2] = new Vector2(regionUVs[RegionAttachment.X2], regionUVs[RegionAttachment.Y2]); uvs[vertexIndex + 3] = new Vector2(regionUVs[RegionAttachment.X3], regionUVs[RegionAttachment.Y3]); color.a = (byte)(skeleton.A * slot.A * 255); color.r = (byte)(skeleton.R * slot.R * color.a); color.g = (byte)(skeleton.G * slot.G * color.a); color.b = (byte)(skeleton.B * slot.B * color.a); colors[vertexIndex] = color; colors[vertexIndex + 1] = color; colors[vertexIndex + 2] = color; colors[vertexIndex + 3] = color; quadIndex++; } } mesh.Clear(); mesh.vertices = vertices; mesh.colors32 = colors; mesh.uv = uvs; mesh.subMeshCount = submeshIndices.Count; for (int i = 0; i < mesh.subMeshCount; ++i) { mesh.SetTriangles(submeshIndices[i], i); } if (skeletonDataAsset.normalGenerationMode != tk2dSpriteCollection.NormalGenerationMode.None) { mesh.RecalculateNormals(); if (skeletonDataAsset.normalGenerationMode == tk2dSpriteCollection.NormalGenerationMode.NormalsAndTangents) { Vector4[] tangents = new Vector4[mesh.normals.Length]; for (int i = 0; i < tangents.Length; i++) { tangents[i] = new Vector4(1, 0, 0, 1); } mesh.tangents = tangents; } } #if UNITY_EDITOR UpdateEditorGizmo(); #endif }
/// <summary> /// Renders the graphic to the screen buffer. /// </summary> public override void Render(float x, float y, Camera camera) { _vertexArray.Clear(); Texture texture = null; _transform.Scale = new Vector2f(ScaleX * Scale, ScaleY * Scale); _transform.Rotation = -Angle; // TODO: is reversing angles ideal? _transform.Position = new Vector2f(X + x - (camera.X - FP.HalfWidth) * ScrollX, Y + y - (camera.Y - FP.HalfHeight) * ScrollY); _transform.Origin = new Vector2f(OriginX, OriginY); foreach (Slot slot in _skeleton.Slots) { Attachment attachment = slot.Attachment; RegionAttachment regionAttachment = attachment as RegionAttachment; if (regionAttachment == null) { continue; } regionAttachment.ComputeVertices(slot.Skeleton.X, slot.Skeleton.Y, slot.Bone, _vertexPositions); float R = _skeleton.R * slot.R * 255; float G = _skeleton.G * slot.G * 255; float B = _skeleton.B * slot.B * 255; float A = _skeleton.A * slot.A * 255; Vertex[] vertices = new Vertex[] { new Vertex(), new Vertex(), new Vertex(), new Vertex() }; unchecked // screw you C# { vertices[0].Color.R = (byte)R; vertices[0].Color.G = (byte)G; vertices[0].Color.B = (byte)B; vertices[0].Color.A = (byte)A; vertices[1].Color.R = (byte)R; vertices[1].Color.G = (byte)G; vertices[1].Color.B = (byte)B; vertices[1].Color.A = (byte)A; vertices[2].Color.R = (byte)R; vertices[2].Color.G = (byte)G; vertices[2].Color.B = (byte)B; vertices[2].Color.A = (byte)A; vertices[3].Color.R = (byte)R; vertices[3].Color.G = (byte)G; vertices[3].Color.B = (byte)B; vertices[3].Color.A = (byte)A; } vertices[0].Position.X = _vertexPositions[RegionAttachment.X1]; vertices[0].Position.Y = _vertexPositions[RegionAttachment.Y1]; vertices[1].Position.X = _vertexPositions[RegionAttachment.X2]; vertices[1].Position.Y = _vertexPositions[RegionAttachment.Y2]; vertices[2].Position.X = _vertexPositions[RegionAttachment.X3]; vertices[2].Position.Y = _vertexPositions[RegionAttachment.Y3]; vertices[3].Position.X = _vertexPositions[RegionAttachment.X4]; vertices[3].Position.Y = _vertexPositions[RegionAttachment.Y4]; // SMFL doesn't handle batching for us, so we'll just force a single texture per skeleton. texture = (Texture)regionAttachment.RendererObject; Vector2u size = texture.Size; vertices[0].TexCoords.X = regionAttachment.UVs[RegionAttachment.X1] * size.X; vertices[0].TexCoords.Y = regionAttachment.UVs[RegionAttachment.Y1] * size.Y; vertices[1].TexCoords.X = regionAttachment.UVs[RegionAttachment.X2] * size.X; vertices[1].TexCoords.Y = regionAttachment.UVs[RegionAttachment.Y2] * size.Y; vertices[2].TexCoords.X = regionAttachment.UVs[RegionAttachment.X3] * size.X; vertices[2].TexCoords.Y = regionAttachment.UVs[RegionAttachment.Y3] * size.Y; vertices[3].TexCoords.X = regionAttachment.UVs[RegionAttachment.X4] * size.X; vertices[3].TexCoords.Y = regionAttachment.UVs[RegionAttachment.Y4] * size.Y; _vertexArray.Append(vertices[0]); _vertexArray.Append(vertices[1]); _vertexArray.Append(vertices[2]); _vertexArray.Append(vertices[3]); } var states = new RenderStates(); states.Texture = texture; states.Transform = _transform.Transform; FP.Screen.Draw(_vertexArray, states); }
public static Rectangle GenerateBoundingBox(this SkeletonData self) { Skeleton skeleton = new Skeleton(self); skeleton.UpdateWorldTransform(); Vector2 minPoint = new Vector2(); Vector2 maxPoint = new Vector2(); bool firstSlot = true; float[] vertices = new float[8]; foreach (Slot slot in skeleton.DrawOrder) { RegionAttachment regionAttachment = slot.Attachment as RegionAttachment; if (regionAttachment == null || regionAttachment.Name.ToLower().IndexOf("tail") >= 0) { continue; } regionAttachment.ComputeVertices(skeleton.X, skeleton.Y, slot.Bone, vertices); if (firstSlot) { minPoint.X = maxPoint.X = vertices[RegionAttachment.X1]; minPoint.Y = maxPoint.Y = vertices[RegionAttachment.Y1]; firstSlot = false; } foreach (int index in regionAttachmentXIndexes) { float value = vertices[index]; if (value < minPoint.X) { minPoint.X = value; } else if (value > maxPoint.X) { maxPoint.X = value; } } foreach (int index in regionAttachmentYIndexes) { float value = vertices[index]; if (value < minPoint.Y) { minPoint.Y = value; } else if (value > maxPoint.Y) { maxPoint.Y = value; } } } return(new Rectangle( (int)minPoint.X, (int)(-maxPoint.Y), (int)(maxPoint.X - minPoint.X), (int)(maxPoint.Y - minPoint.Y) )); }