Linefy is an fast, robust, cross-platform, drawing library for thick, colored, textured Lines, Polylines, Dots. The package includes the Polygonal Mesh, wich can import or create, manipulate polygon-based meshes. Using it, you can display the edged wireframe (which looks the same as in 3D software) and recalculate the high quality normals without gaps. Linefy works in runtime, edit-mode, and allow to draw on Scene View (Editor.OnSceneGUI), so it good starting point to developing high performance, nice looking, custom editors. Pack contains custom Vector3 handle and Matrix4x4 handle.
Encapsulates an array of Line structures. You can set the initial count of lines in constructor or change it using the count property.
using UnityEngine;
using Linefy;
[ExecuteInEditMode]
public class LinefyDemo_QuickStart : MonoBehaviour {
Lines lines;
private void Update() {
if (lines == null) {
lines = new Lines(2);
lines.transparent = true;
lines.feather = 3;
lines.widthMultiplier = 20;
lines[0] = new Line(Vector3.zero, Vector3.one, Color.red, Color.yellow, 1);
lines[1] = new Line(Vector3.up, Vector3.right, Color.green, Color.cyan, 1);
}
lines.Draw();
}
}
result:
using UnityEngine;
using Linefy;
[ExecuteInEditMode]
public class LinefyDemo_QuickStart : MonoBehaviour {
Lines lines;
private void Update() {
if (lines == null) {
lines = new Lines(2);
lines.transparent = true;
lines.feather = 3;
lines.widthMultiplier = 20;
lines.SetPosition(0, Vector3.zero, Vector3.up);
lines.SetPosition(1, Vector3.right, Vector3.one);
lines.SetColor(0, Color.yellow, Color.red);
lines.SetColor(1, Color.black, Color.white);
lines.SetWidth(0, 1, 2);
lines.SetWidth(1, 2, 1);
}
lines.Draw();
}
}
result:
using UnityEngine;
using Linefy;
[ExecuteInEditMode]
public class LinefyDemo_QuickStart : MonoBehaviour {
Lines lines;
public Texture2D texture;
private void Update() {
if (lines == null) {
lines = new Lines(2);
lines.transparent = true;
lines.feather = 3;
lines.widthMultiplier = 40;
lines.texture = texture;
lines[0] = new Line(Vector3.zero, Vector3.up );
lines[1] = new Line(Vector3.right, Vector3.one );
lines.SetTextureOffset(0, 0, 0.5f);
lines.SetTextureOffset(1, 0.5f, 1f);
}
lines.Draw();
}
result:
Encapsulates an array of PolylineVertex. The difference from the Lines class is Polyline use vertices strips to draw lines and generate the rounded corners between its. You can set the initial count of lines in constructor or change it using the Count property.
using UnityEngine;
using Linefy;
[ExecuteInEditMode]
public class LinefyDemo_QuickStart : MonoBehaviour {
Lines lines;
private void Update() {
if (polyline == null) {
polyline = new Polyline(4);
polyline[0] = new PolylineVertex(new Vector3(0, 0.5f, 0), new Color32(93,255,0, 255), 1);
polyline[1] = new PolylineVertex(new Vector3(0.5f, 1, 0), new Color32(92, 140, 255, 255), 1);
polyline[2] = new PolylineVertex(new Vector3(1, 0.5f, 0), new Color32(0, 255, 223, 255), 1);
polyline[3] = new PolylineVertex(new Vector3(0.5f, 0, 0), new Color32(178, 0, 255, 255), 1);
polyline.transparent = true;
polyline.feather = 3;
polyline.widthMultiplier = 20;
polyline.isClosed = true;
}
polyline.Draw();
}
}
result:
using UnityEngine;
using Linefy;
[ExecuteInEditMode]
public class LinefyDemo_QuickStart_Polylines : MonoBehaviour {
Polyline polyline;
public Texture2D texture;
private void Update() {
if (polyline == null) {
polyline = new Polyline(4);
polyline.transparent = true;
polyline.feather = 3;
polyline.widthMultiplier = 20;
polyline.isClosed = false;
polyline.texture = texture;
polyline.SetPosition(0, new Vector3(0, 0f, 0));
polyline.SetPosition(1, new Vector3(1, 1f, 0));
polyline.SetPosition(2, new Vector3(2, 0f, 0));
polyline.SetPosition(3, new Vector3(3, 1f, 0));
polyline.SetColor(0, new Color32(93, 255, 0, 255));
polyline.SetColor(1, new Color32(92, 140, 255, 255));
polyline.SetColor(2, new Color32(0, 255, 223, 255));
polyline.SetColor(3, new Color32(178, 0, 255, 255));
polyline.SetTextureOffset(0,0.03f);
polyline.SetTextureOffset(1, 0.33f);
polyline.SetTextureOffset(2, 0.66f);
polyline.SetTextureOffset(3, 0.97f);
polyline.SetWidth(0, 2f);
polyline.SetWidth(3, 2f);
}
//polyline.texture = texture;
polyline.Draw();
}
}
result:
Encapsulates an array of Dot structures. Should be used in conjunctions with DotsAtlas. If custom DotsAtlas not provided, will be used default atlas.
using UnityEngine;
using Linefy;
[ExecuteInEditMode]
public class LinefyDemo_QuickStart_Dots : MonoBehaviour {
Dots dots;
private void Update() {
if (dots == null ) {
dots = new Dots(4);
dots.widthMultiplier = 50;
dots.transparent = true;
dots[0] = new Dot(new Vector3(0, 0.5f, 0), 1, 3, Color.red);
dots[1] = new Dot(new Vector3(0.5f, 1, 0), 1, 19, Color.green);
dots[2] = new Dot(new Vector3(1, 0.5f, 0), 1, 35, Color.blue);
dots[3] = new Dot(new Vector3(0.5f, 0, 0), 1, 51, Color.white);
}
dots.Draw(transform.localToWorldMatrix);
}
}
result:
using UnityEngine;
using Linefy;
[ExecuteInEditMode]
public class LinefyDemo_QuickStart_Dots : MonoBehaviour {
Dots dots;
private void Update() {
if (dots == null ) {
dots = new Dots(4);
dots.widthMultiplier = 20;
dots.transparent = true;
dots.SetRectIndex(0, 3);
dots.SetRectIndex(1, 3);
dots.SetRectIndex(2, 3);
dots.SetRectIndex(3, 3);
dots.SetPosition(0, new Vector3(0, 0, 0));
dots.SetPosition(1, new Vector3(1, 0, 0));
dots.SetPosition(2, new Vector3(2, 0, 0));
dots.SetPosition(3, new Vector3(3, 0, 0));
dots.SetWidth(0, 1);
dots.SetWidth(1, 1.5f);
dots.SetWidth(2, 2);
dots.SetWidth(3, 2.5f);
dots.SetColor(0, Color.white);
dots.SetColor(1, Color.Lerp(Color.white, Color.red, 0.33f));
dots.SetColor(2, Color.Lerp(Color.white, Color.red, 0.66f));
dots.SetColor(3, Color.red);
}
dots.Draw(transform.localToWorldMatrix);
}
}
result:
A base class for Lines and Polyline.
A base class for Lines, Polyline, Dots.
Every class derived from PrimitivesGroup has own associated serializable stuct. You can save or load object state from this struct using methods:
in Assets/Plugins/Linefy/(can be deleted) Examples/Clews/Clews.unity example scene demonstrates how to store Polyline`s data in custom asset.
A runtime-representation of 3d geometric object with polygon-based topology made up of faces, edges, and vertices. Technically PolygonalMesh is an high-level wrapper for mesh designed to relieves of need takes care of normals recalculation and polygons`s triangulation. Once PolygonalMesh created, you only need to set the positions of the vertices and all the necessary calculations will occur internally. Also, a PolygonalMesh encapsulates a Lines object within itself, which stores the edges of the object (Wireframe).
There are two uses of PolygonalMesh:
There are two way to create PolygonalMesh using SerializedPolygonalMesh:
result:
This is the only constructor of PolygonalMesh
public PolygonalMesh( SerializedPolygonalMesh serializableData )
public methothod and propertyes:
Stores serialization-freindly snapshot of PolygonalMesh. Also it is intermediate stage of PolygonalMesh creation.
Due ScriptableObject limitation this class does not have constructors, but two initialization function.
public void ReadObjFromFile (string filePath, SmoothingGroupsImportMode sgMode, bool flipNormals, float scaleFactor, bool swapYZ)
public void BuildProcedural(Vector3[] posData, Vector2[] uvsData, Color[] colorsData, Polygon[] polygonsData)
Assets/Plugins/Linefy/(can be deleted) Examples/CreatePolygonalMeshProcedural/ an example-scene that demonstrates the procedural creation of various objects.
A base class. Encapsulates itself one UnityEngine.Mesh and two custom materials who switches by transparent property. The Draw() method is a wrapper over the UnityEngine.Graphics.DrawMesh() method and has similar arguments. Call Draw() method after assigning parameters to actually draw a stuff.
foo.Draw(transform.LocalToWorldMatrix);
an asset that describes texture slicing. Each sliced rect has its own index(displaying on top left corner of rect), which can be used to draw Dots.
using UnityEngine;
using Linefy;
[ExecuteInEditMode]
public class LinefyDemo_QuickStart : MonoBehaviour {
public float viewOffset;
Dots dots;
public DotsAtlas atlas;
public bool transparent;
private void Update() {
ExampleCustomAtlas();
}
void ExampleCustomAtlas() {
if (dots == null) {
dots = new Dots(10);
dots.widthMultiplier = 40;
for (int i = 0; i<dots.count; i++) {
dots[i] = new Dot(new Vector3(i, 0, 0), 1, i, Color.white);
}
}
dots.transparent = transparent;
dots.atlas = atlas;
dots.Draw(transform.localToWorldMatrix);
}
}
the same Dots instance with different atlas
To create new atlas
There is a default atlas located in Assets/Plugins/Linefy/Resources/Default Dots Atlas.asset . Please do not delete or modyfy it.
Is an component that incapsulate one PolygonalMesh and serialize its propertyes. Propertyes displayed on its inspector and equals to PolygonalMesh properties.
to create PolygonalMeshRenderer drag and drop PolygonalMeshAsset on SceneView.
The storage-asset which encapsulates SerializedPolygonalMesh. Its does serialize and displayed importing settings and statistic.
To draw objects in the spaces of the screen, use a special matrix that is oriented to the camera and placed on its near clipping plane. There are two helper functions for creating these matrices.
Matrix4x4 Linefy.Utilites.NearClipPlaneGUISpaceMatrix(Camera cam, float offset)
and
Matrix4x4 Linefy.Utilites.NearClipPlaneScreenSpaceMatrix(Camera cam, float offset)
where
this component calculate GUI and Screen space matrices and keeps it as public fields
Drawing on Scene View are identical to regular runtime drawing exept
methods should be used insted LinefyDrawcall.Draw(). Please note to draw in SceneView should be used Editor.OnSceneGUI() callback .
[CustomEditor(typeof(HandlesQuickStart))]
public class HandlesQuickStartEditor : Editor {
Vector3 p0 = new Vector3(0, 0, 0);
Vector3 p1 = new Vector3(0, 1, 0);
Vector3 p2 = new Vector3(1, 1, 0);
Vector3 p3 = new Vector3(1, 0, 0);
Polyline contour;
PolygonalMesh fill;
void OnEnable() {
contour = new Polyline(4, true, 1, true);
contour.widthMultiplier = 8;
contour.SetPosition(0, p0);
contour.SetPosition(1, p1);
contour.SetPosition(2, p2);
contour.SetPosition(3, p3);
contour.viewOffset = 0.1f;
Polygon fillPolygon = new Polygon(4);
fillPolygon[0] = new PolygonCorner(0, 0, 0);
fillPolygon[1] = new PolygonCorner(1, 0, 0);
fillPolygon[2] = new PolygonCorner(2, 0, 0);
fillPolygon[3] = new PolygonCorner(3, 0, 0);
fill = PolygonalMesh.BuildProcedural(new Vector3[4] {p0, p1, p2, p3 }, null, new Color[1] { new Color(0, 1, 0, 0.5f) }, new Polygon[] { fillPolygon });
}
void OnSceneGUI() {
OnSceneGUIGraphics.DrawWorldspace(contour);
OnSceneGUIGraphics.DrawWorldspace(fill);
}
}
result:
Linefy includes two custom editor handles: Vector3Handle and Matrix4x4Handle. They are implemented as ordinary Handles, except for drawing methods. Unlike other Handles, it does not use the GL or Handles classes for drawing, but only the Linefy classes. Common Handles properties such as color, centerColor are ignored, with the exception of Handles.matrix.
Vector3 handle.
Matrix4x4 transformation handle . Its action is similar to UnityEngine.Transform handles. To switch modes, use the Move, Rotate, and Scale tools. Hold the shift key to move the handle in screen coordinates.
[CustomEditor(typeof(HandlesQuickStart))]
public class HandlesQuickStartEditor : Editor {
Matrix4x4 tm = Matrix4x4.identity;
Vector3 p0 = new Vector3(0, 0, 0);
Vector3 p1 = new Vector3(0, 1, 0);
Vector3 p2 = new Vector3(1, 1, 0);
Vector3 p3 = new Vector3(1, 0, 0);
Matrix4x4Handle tmHandle;
Vector3Handle h0;
Vector3Handle h1;
Vector3Handle h2;
Vector3Handle h3;
Polyline contour;
PolygonalMesh fill;
void OnEnable() {
h0 = new Vector3Handle(0);
h1 = new Vector3Handle(1);
h2 = new Vector3Handle(2);
h3 = new Vector3Handle(3);
contour = new Polyline(4, true, 1, true);
contour.widthMultiplier = 4;
Polygon fillPolygon = new Polygon(4);
fillPolygon[0] = new PolygonCorner(0, 0, 0);
fillPolygon[1] = new PolygonCorner(1, 0, 0);
fillPolygon[2] = new PolygonCorner(2, 0, 0);
fillPolygon[3] = new PolygonCorner(3, 0, 0);
fill = PolygonalMesh.BuildProcedural(new Vector3[4], null, new Color[1] { new Color(0, 1, 0, 0.5f) }, new Polygon[] { fillPolygon });
tmHandle = new Matrix4x4Handle("tm", 0, null, null, null);
}
void OnSceneGUI() {
tmHandle.DrawOnSceneGUI(ref tm, 2, true);
Handles.matrix = tm;
p0 = h0.DrawOnSceneGUI(p0);
p1 = h1.DrawOnSceneGUI(p1);
p2 = h2.DrawOnSceneGUI(p2);
p3 = h3.DrawOnSceneGUI(p3);
contour.SetPosition(0, p0);
contour.SetPosition(1, p1);
contour.SetPosition(2, p2);
contour.SetPosition(3, p3);
fill.SetPosition(0, p0);
fill.SetPosition(1, p1);
fill.SetPosition(2, p2);
fill.SetPosition(3, p3);
OnSceneGUIGraphics.DrawWorldspace(contour, Handles.matrix);
OnSceneGUIGraphics.DrawWorldspace(fill, Handles.matrix);
}
}
result:
Describes single line of Lines.
Describes one vertex of Polyline .
Describes one dot of Dots .