Skip to content

Instantly share code, notes, and snippets.

@wblackall
Last active December 11, 2015 08:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wblackall/4574573 to your computer and use it in GitHub Desktop.
Save wblackall/4574573 to your computer and use it in GitHub Desktop.
How to draw a trapezoid from scratch!
using UnityEngine;
using System;
public class TrapezoidSprite : FSprite
{
public float trapezoidWidth;
public float trapezoidHeight;
public float insetFromSide;
public TrapezoidSprite (string imageName, float width, float height, float inset) : base() {
trapezoidWidth = width;
trapezoidHeight = height;
insetFromSide = inset;
// This initializes the sprite with a specified texture and indicates
// that we want to use triangles to draw the trapezoid. The third parameter is 3 because
// we are going to construct the trapezoid out of three triangles.
Init(FFacetType.Triangle, Futile.atlasManager.GetElementWithName(imageName),3);
// Just necessary setup code
_isAlphaDirty = true;
UpdateLocalVertices();
}
// Call this method if you make a change and want to redraw
public void Refresh() {
_isMeshDirty = true;
}
override public void PopulateRenderLayer()
{
if(_isOnStage && _firstFacetIndex != -1) // if this is false, the sprite hasn't been initiated correctly yet
{
// _isMeshDirty is set to true when things need to be rerendered,
// so we need to set it to false here because that's what we're doing.
_isMeshDirty = false;
// Since each facet (triangle) has 3 vertices, the first vertex index
// is the index of the first facet multiplied by 3.
int vertexIndex0 = _firstFacetIndex * 3;
// This array contains the vertices that are used to draw the triangles.
// The size of this array is 9 because there are 3 facets (triangles)
// with 3 vertices each (thus, 3 * 3 vertices total)
Vector3[] triangleVertices = _renderLayer.vertices;
// This array contains the vertices that are used to apply the texture to the triangles.
// The size of this array is 9 because there are 3 facets (triangles)
// with 3 vertices each (thus, 3 * 3 vertices total).
Vector2[] triangleUVVertices = _renderLayer.uvs;
// This array contains the actual local vertices of the trapezoid.
Vector2[] trapezoidVertices = new Vector2[5];
// This array contains the vertices on the texture that will be
// stretched to fit right on top of the trapezoidVertices.
Vector2[] textureUVVertices = new Vector2[5];
// This holds the colors of each vertex for each triangle.
Color[] colors = _renderLayer.colors;
// Here we create all the vertices of the trapezoid.
trapezoidVertices[0] = new Vector2(0, 0);
trapezoidVertices[1] = new Vector2(insetFromSide, trapezoidHeight);
trapezoidVertices[2] = new Vector2(trapezoidWidth / 2f, 0);
trapezoidVertices[3] = new Vector2(trapezoidWidth - insetFromSide, trapezoidHeight);
trapezoidVertices[4] = new Vector2(trapezoidWidth, 0);
// Offset the vertices so that (0, 0) is the middle of the trapezoid
// instead of the bottom left vertex.
for (int i = 0; i < 5; i++) {
trapezoidVertices[i].x -= trapezoidWidth / 2f;
trapezoidVertices[i].y -= trapezoidHeight / 2f;
}
// This is the width of the specific image in relative uv values
// (not the width of the image in pixels)
float uvWidth = (_element.uvTopRight.x - _element.uvTopLeft.x);
textureUVVertices[0] = new Vector2(_element.uvBottomLeft.x, _element.uvBottomLeft.y);
textureUVVertices[1] = new Vector2(_element.uvTopLeft.x, _element.uvTopLeft.y);
textureUVVertices[2] = new Vector2(_element.uvBottomLeft.x + uvWidth / 2f, _element.uvBottomLeft.y);
textureUVVertices[3] = new Vector2(_element.uvTopRight.x, _element.uvTopRight.y);
textureUVVertices[4] = new Vector2(_element.uvBottomRight.x, _element.uvBottomRight.y);
// This just colors all the vertices on all the triangles
// to whatever color is set for the sprite.
for (int i = 0; i < 9; i++) {
colors[vertexIndex0 + i] = _alphaColor;
}
// Here is where we construct the three triangles. We just tell it
// which vertices on the trapezoid to use for each triangle and it
// applies those values to the rendering matrix.
_concatenatedMatrix.ApplyVector3FromLocalVector2(ref triangleVertices[vertexIndex0 + 0], trapezoidVertices[0],0);
_concatenatedMatrix.ApplyVector3FromLocalVector2(ref triangleVertices[vertexIndex0 + 1], trapezoidVertices[1],0);
_concatenatedMatrix.ApplyVector3FromLocalVector2(ref triangleVertices[vertexIndex0 + 2], trapezoidVertices[2],0);
_concatenatedMatrix.ApplyVector3FromLocalVector2(ref triangleVertices[vertexIndex0 + 3], trapezoidVertices[1],0);
_concatenatedMatrix.ApplyVector3FromLocalVector2(ref triangleVertices[vertexIndex0 + 4], trapezoidVertices[2],0);
_concatenatedMatrix.ApplyVector3FromLocalVector2(ref triangleVertices[vertexIndex0 + 5], trapezoidVertices[3],0);
_concatenatedMatrix.ApplyVector3FromLocalVector2(ref triangleVertices[vertexIndex0 + 6], trapezoidVertices[2],0);
_concatenatedMatrix.ApplyVector3FromLocalVector2(ref triangleVertices[vertexIndex0 + 7], trapezoidVertices[3],0);
_concatenatedMatrix.ApplyVector3FromLocalVector2(ref triangleVertices[vertexIndex0 + 8], trapezoidVertices[4],0);
// Here is where we actually assign the points on the texture to
// the points on the triangles. In other words, we are stretching the
// texture so that the points on the texture line up with the vertices
// of the trapezoid. Since we're drawing it with triangles, we have
// to do this for each triangle so the renderer knows how to "paint" them.
triangleUVVertices[vertexIndex0 + 0] = textureUVVertices[0];
triangleUVVertices[vertexIndex0 + 1] = textureUVVertices[1];
triangleUVVertices[vertexIndex0 + 2] = textureUVVertices[2];
triangleUVVertices[vertexIndex0 + 3] = textureUVVertices[1];
triangleUVVertices[vertexIndex0 + 4] = textureUVVertices[2];
triangleUVVertices[vertexIndex0 + 5] = textureUVVertices[3];
triangleUVVertices[vertexIndex0 + 6] = textureUVVertices[2];
triangleUVVertices[vertexIndex0 + 7] = textureUVVertices[3];
triangleUVVertices[vertexIndex0 + 8] = textureUVVertices[4];
// This just tells the renderer that we made changes.
_renderLayer.HandleVertsChange();
}
}
}
using UnityEngine;
using System.Collections;
public class WTMain : MonoBehaviour {
public float offset = 0;
TrapezoidSprite sprite;
float widthChange = 9;
float heightChange = 10;
float insetChange = 11;
void Start() {
FutileParams fp = new FutileParams(true, true, false, false);
fp.AddResolutionLevel(1024, 1.0f, 1.0f, "");
fp.origin = Vector2.zero;
fp.backgroundColor = new Color(0.12f, 0.12f, 0.12f, 1.0f);
Futile.instance.Init(fp);
Futile.instance.SignalUpdate += HandleUpdate;
sprite = new TrapezoidSprite("Futile_White", 300, 100, 75);
sprite.x = Futile.screen.halfWidth;
sprite.y = Futile.screen.halfHeight;
Futile.stage.AddChild(sprite);
}
public void HandleUpdate() {
// Uncomment this stuff to see the trapezoid morph before your very eyes!
/*sprite.trapezoidWidth += widthChange;
sprite.trapezoidHeight += heightChange;
sprite.insetFromSide += insetChange;
if (sprite.trapezoidWidth > 500) {
sprite.trapezoidWidth = 500;
widthChange *= -1;
}
if (sprite.trapezoidHeight > 500) {
sprite.trapezoidHeight = 500;
heightChange *= -1;
}
if (sprite.insetFromSide > sprite.trapezoidWidth / 2f) {
sprite.insetFromSide = sprite.trapezoidWidth / 2f;
insetChange *= -1;
}
if (sprite.trapezoidWidth < 50) {
sprite.trapezoidWidth = 50;
widthChange *= -1;
}
if (sprite.trapezoidHeight < 50) {
sprite.trapezoidHeight = 50;
heightChange *= -1;
}
if (sprite.insetFromSide < -100) {
sprite.insetFromSide = -100;
insetChange *= -1;
}
sprite.Refresh();*/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment