////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public override void Build(IHovercastMenuState pMenuState, IBaseItemState pItemState,
													float pArcAngle, IItemVisualSettings pSettings) {
			base.Build(pMenuState, pItemState, pArcAngle, pSettings);

			////

			vOuter = new GameObject("ToggleOuter");
			vOuter.transform.SetParent(gameObject.transform, false);
			vOuter.transform.localRotation = vLabel.CanvasLocalRotation;
			vOuter.AddComponent<MeshRenderer>();

			MeshFilter outerFilt = vOuter.AddComponent<MeshFilter>();
			vOuterMeshBuilder = new MeshBuilder();
			MeshUtil.BuildQuadMesh(vOuterMeshBuilder);
			Materials.SetMeshIconCoords(vOuterMeshBuilder, GetOuterIconOffset());
			vOuterMeshBuilder.Commit();
			vOuterMeshBuilder.CommitColors(Color.clear);
			outerFilt.sharedMesh = vOuterMeshBuilder.Mesh;

			////

			vInner = new GameObject("ToggleInner");
			vInner.transform.SetParent(gameObject.transform, false);
			vInner.transform.localRotation = vLabel.CanvasLocalRotation;
			vInner.AddComponent<MeshRenderer>();

			MeshFilter innerFilt = vInner.AddComponent<MeshFilter>();
			vInnerMeshBuilder = new MeshBuilder();
			MeshUtil.BuildQuadMesh(vInnerMeshBuilder);
			Materials.SetMeshIconCoords(vInnerMeshBuilder, GetInnerIconOffset());
			vInnerMeshBuilder.Commit();
			vInnerMeshBuilder.CommitColors(Color.clear);
			innerFilt.sharedMesh = vInnerMeshBuilder.Mesh;
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public void Awake() {
			const int width = 8;

			var lblObj = new GameObject("TextEntry");
			lblObj.transform.SetParent(gameObject.transform, false);
			lblObj.transform.localRotation = Quaternion.FromToRotation(Vector3.down, Vector3.back);
			lblObj.transform.localScale = Vector3.one*0.05f;

			var lblBgObj = GameObject.CreatePrimitive(PrimitiveType.Quad);
			lblBgObj.transform.SetParent(lblObj.transform, false);
			lblBgObj.transform.localPosition = new Vector3(0, 0, 0.01f);
			lblBgObj.transform.localRotation = Quaternion.FromToRotation(Vector3.up, Vector3.back);
			lblBgObj.transform.localScale = new Vector3(width, 1, 1);

			Renderer lblRend = lblBgObj.GetComponent<Renderer>();
			lblRend.material = Materials.GetLayer(Materials.Layer.Background, -2);

			var lblMeshBuild = new MeshBuilder(lblBgObj.GetComponent<MeshFilter>().mesh);
			lblMeshBuild.CommitColors(new Color(0.1f, 0.1f, 0.1f, 0.666f));

			Color green = HoverboardItemVisualSettingsStandard.Green;
			green.a *= 0.5f;

			vTextEntry = lblObj.AddComponent<UiLabel>();
			vTextEntry.SetSize(width, 1, 60*0.6f, UiItem.Size*0.012f);
			vTextEntry.FontName = "Tahoma";
			vTextEntry.FontSize = 60;
			vTextEntry.Color = green;
			vTextEntry.Alpha = 1;
			vTextEntry.Label = "";
			vTextEntry.SetDepthHint(-1);

			ClearLetters();
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public virtual void Build(ProjectionState pProjectionState,
																IProjectionVisualSettings pSettings) {
			vProjectionState = pProjectionState;
			vSettings = (ProjectionVisualSettingsStandard)pSettings;

			////

			vSpotObj = new GameObject("Spot");
			vSpotObj.transform.SetParent(gameObject.transform, false);
			vSpotObj.transform.localScale = Vector3.zero;

			MeshFilter spotFilt = vSpotObj.AddComponent<MeshFilter>();
			vSpotMeshBuilder = new MeshBuilder(spotFilt.mesh);
			MeshUtil.BuildCircleMesh(vSpotMeshBuilder, 0.5f, 32);
			vSpotMeshBuilder.Commit();

			MeshRenderer spotRend = vSpotObj.AddComponent<MeshRenderer>();
			spotRend.sharedMaterial = 
				Materials.GetLayer(Materials.Layer.AboveText, Materials.DepthHintMax);

			////

			vLineObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
			vLineObj.name = "Line";
			vLineObj.transform.SetParent(gameObject.transform, false);
			vLineObj.transform.localScale = Vector3.zero;

			vLineMeshBuilder = new MeshBuilder(vLineObj.GetComponent<MeshFilter>().mesh);

			MeshRenderer lineRend = vLineObj.GetComponent<MeshRenderer>();
			lineRend.sharedMaterial = 
				Materials.GetLayer(Materials.Layer.AboveText, Materials.DepthHintMax);
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public virtual void Build(MenuState pMenuState, IItemVisualSettings pSettings, 
																		float pAngle0, float pAngle1) {
			vMenuState = pMenuState;
			vSettings = (ItemVisualSettingsStandard)pSettings;
			vAngle0 = pAngle0;
			vAngle1 = pAngle1;
			vMeshSteps = (int)Math.Round(Math.Max(2, (vAngle1-vAngle0)/Math.PI*60));

			////

			vBackground = new GameObject("Background");
			vBackground.transform.SetParent(gameObject.transform, false);
			vBackground.AddComponent<MeshRenderer>();
			
			MeshFilter bgFilt = vBackground.AddComponent<MeshFilter>();
			vBackgroundMeshBuilder = new MeshBuilder();
			BuildMesh(vBackgroundMeshBuilder);
			vBackgroundMeshBuilder.Commit();
			vBackgroundMeshBuilder.CommitColors(Color.clear);
			bgFilt.sharedMesh = vBackgroundMeshBuilder.Mesh;

			////

			var labelObj = new GameObject("Label");
			labelObj.transform.SetParent(gameObject.transform, false);
			labelObj.transform.localPosition = new Vector3(0, 0, InnerRadius);
			labelObj.transform.localRotation = Quaternion.FromToRotation(Vector3.back, Vector3.right);
			labelObj.transform.localScale = new Vector3((vMenuState.IsOnLeftSide ? 1 : -1), 1, 1);

			vLabel = labelObj.AddComponent<UiLabel>();
			vLabel.AlignLeft = vMenuState.IsOnLeftSide;
		}
		/*--------------------------------------------------------------------------------------------*/
		public static void BuildRingMesh(MeshBuilder pMeshBuild, float pInnerRadius, float pOuterRadius,
															float pAngle0, float pAngle1, int pSteps) {
			float angleFull = pAngle1-pAngle0;
			float angleInc = angleFull/pSteps;
			float angle = pAngle0;

			pMeshBuild.Resize((pSteps+1)*2, pSteps*6);
			pMeshBuild.ResetIndices();

			for ( int i = 0 ; i <= pSteps ; ++i ) {
				float uvx = i/(float)pSteps;

				pMeshBuild.AddVertex(GetRingPoint(pInnerRadius, angle));
				pMeshBuild.AddVertex(GetRingPoint(pOuterRadius, angle));

				pMeshBuild.AddUv(new Vector2(uvx, 0));
				pMeshBuild.AddUv(new Vector2(uvx, 1));

				if ( i > 0 ) {
					int vi = pMeshBuild.VertexIndex;
					pMeshBuild.AddTriangle(vi-3, vi-4, vi-2);
					pMeshBuild.AddTriangle(vi-1, vi-3, vi-2);
				}

				angle += angleInc;
			}
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public virtual void Build(IHovercastMenuState pMenuState, IBaseItemState pItemState,
													float pArcAngle, IItemVisualSettings pSettings) {
			vMenuState = pMenuState;
			vItemState = pItemState;
			vSelItem = (vItemState.Item as ISelectableItem);
			vSettings = (ItemVisualSettingsStandard)pSettings;

			////

			vHoverSlice = new UiHoverMeshSlice(gameObject);
			vHoverSlice.DrawOuterEdge = true;
			vHoverSlice.UpdateSize(InnerRadius, OuterRadius, pArcAngle);

			////
			
			vIcon = new GameObject("Icon");
			vIcon.transform.SetParent(gameObject.transform, false);
			vIcon.transform.localRotation = Quaternion.FromToRotation(Vector3.forward, Vector3.up)*
				Quaternion.FromToRotation(Vector3.right, Vector3.up);
			vIcon.AddComponent<MeshRenderer>();

			MeshFilter iconFilt = vIcon.AddComponent<MeshFilter>();
			vIconMeshBuilder = new MeshBuilder();
			MeshUtil.BuildQuadMesh(vIconMeshBuilder);
			Materials.SetMeshIconCoords(vIconMeshBuilder, Materials.IconOffset.Parent);
			vIconMeshBuilder.Commit();
			vIconMeshBuilder.CommitColors(Color.clear);
			iconFilt.sharedMesh = vIconMeshBuilder.Mesh;
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		protected override void UpdateMesh(MeshType pType, MeshBuilder pMeshBuild, float pAmount=1) {
			if ( pType == MeshType.Edge ) {
				MeshUtil.BuildBorderMesh(pMeshBuild, vMeshW, vMeshH, EdgeThick);
				pMeshBuild.Commit();
				return;
			}

			float inset = (pType != MeshType.Background ? EdgeThick*2 : 0);

			MeshUtil.BuildRectangleMesh(pMeshBuild, Math.Max(0, vMeshW-inset), 
				Math.Max(0, vMeshH-inset), pAmount);
			pMeshBuild.Commit();
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public virtual void Build(ICursorState pCursorState, ICursorSettings pSettings) {
			vCursorState = pCursorState;
			vSettings = (CursorSettingsStandard)pSettings;

			vRingObj = new GameObject("Ring");
			vRingObj.transform.SetParent(gameObject.transform, false);
			MeshRenderer meshRend = vRingObj.AddComponent<MeshRenderer>();
			meshRend.sharedMaterial = Materials.GetCursorLayer();
			vRingObj.AddComponent<MeshFilter>();

			vRingMeshBuilder = new MeshBuilder();
			vRingObj.GetComponent<MeshFilter>().sharedMesh = vRingMeshBuilder.Mesh;
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public static void BuildQuadMesh(MeshBuilder pMeshBuild) {
			const float size = 0.5f;

			pMeshBuild.Resize(4, 6);
			pMeshBuild.ResetIndices();

			pMeshBuild.AddVertex(new Vector3( size,  size, 0));
			pMeshBuild.AddVertex(new Vector3( size, -size, 0));
			pMeshBuild.AddVertex(new Vector3(-size, -size, 0));
			pMeshBuild.AddVertex(new Vector3(-size,  size, 0));

			pMeshBuild.AddUv(new Vector2(1, 1));
			pMeshBuild.AddUv(new Vector2(1, 0));
			pMeshBuild.AddUv(new Vector2(0, 0));
			pMeshBuild.AddUv(new Vector2(0, 1));

			pMeshBuild.AddTriangle(0, 1, 2);
			pMeshBuild.AddTriangle(0, 2, 3);
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		protected void Build(GameObject pParent) {
			vParent = pParent;
			vHoverPoints = new ReadList<Vector3>();

			Background = new GameObject("Background");
			Background.transform.SetParent(pParent.transform, false);
			Background.AddComponent<MeshRenderer>();
			Background.AddComponent<MeshFilter>();

			Edge = new GameObject("Edge");
			Edge.transform.SetParent(pParent.transform, false);
			Edge.AddComponent<MeshRenderer>();
			Edge.AddComponent<MeshFilter>();

			Highlight = new GameObject("Highlight");
			Highlight.transform.SetParent(pParent.transform, false);
			Highlight.AddComponent<MeshRenderer>();
			Highlight.AddComponent<MeshFilter>();

			Select = new GameObject("Select");
			Select.transform.SetParent(pParent.transform, false);
			Select.AddComponent<MeshRenderer>();
			Select.AddComponent<MeshFilter>();

			BackgroundMeshBuilder = new MeshBuilder();
			EdgeMeshBuilder = new MeshBuilder();
			HighlightMeshBuilder = new MeshBuilder();
			SelectMeshBuilder = new MeshBuilder();

			Background.GetComponent<MeshFilter>().sharedMesh = BackgroundMeshBuilder.Mesh;
			Edge.GetComponent<MeshFilter>().sharedMesh = EdgeMeshBuilder.Mesh;
			Highlight.GetComponent<MeshFilter>().sharedMesh = HighlightMeshBuilder.Mesh;
			Select.GetComponent<MeshFilter>().sharedMesh = SelectMeshBuilder.Mesh;

			BackgroundColor = Color.clear;
			EdgeColor = Color.clear;
			SelectColor = Color.clear;
			HighlightColor = Color.clear;

			UpdateAfterResize();
		}
		/*--------------------------------------------------------------------------------------------*/
		public static void BuildCircleMesh(MeshBuilder pMeshBuild, float pRadius, int pSteps) {
			const float angleFull = (float)Math.PI*2;
			float angleInc = angleFull/pSteps;
			float angle = 0;

			pMeshBuild.Resize(pSteps+2, pSteps*3);

			pMeshBuild.AddVertex(Vector3.zero);
			pMeshBuild.AddUv(new Vector2(0, 0));

			for ( int i = 0 ; i <= pSteps ; ++i ) {
				pMeshBuild.AddVertex(GetRingPoint(pRadius, angle));
				pMeshBuild.AddUv(new Vector2(i/(float)pSteps, 1));

				if ( i > 0 ) {
					int vi = pMeshBuild.VertexIndex;
					pMeshBuild.AddTriangle(0, vi-2, vi-1);
				}

				angle += angleInc;
			}
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public override void Build(IHoverboardPanelState pPanelState,
										IHoverboardLayoutState pLayoutState, IBaseItemState pItemState,
										IItemVisualSettings pSettings) {
			base.Build(pPanelState, pLayoutState, pItemState, pSettings);

			vLabel.AlignLeft = true;
			vLabel.transform.localPosition = new Vector3(-vItemState.Item.Width/2, 0, 0);

			////

			vOuter = new GameObject("ToggleOuter");
			vOuter.transform.SetParent(gameObject.transform, false);
			vOuter.transform.localRotation = vLabel.CanvasLocalRotation;
			vOuter.AddComponent<MeshRenderer>();

			MeshFilter outerFilt = vOuter.AddComponent<MeshFilter>();
			vOuterMeshBuilder = new MeshBuilder();
			MeshUtil.BuildQuadMesh(vOuterMeshBuilder);
			Materials.SetMeshIconCoords(vOuterMeshBuilder, GetOuterIconOffset());
			vOuterMeshBuilder.Commit();
			vOuterMeshBuilder.CommitColors(Color.clear);
			outerFilt.sharedMesh = vOuterMeshBuilder.Mesh;

			////

			vInner = new GameObject("ToggleInner");
			vInner.transform.SetParent(gameObject.transform, false);
			vInner.transform.localRotation = vLabel.CanvasLocalRotation;
			vInner.AddComponent<MeshRenderer>();

			MeshFilter innerFilt = vInner.AddComponent<MeshFilter>();
			vInnerMeshBuilder = new MeshBuilder();
			MeshUtil.BuildQuadMesh(vInnerMeshBuilder);
			Materials.SetMeshIconCoords(vInnerMeshBuilder, GetInnerIconOffset());
			vInnerMeshBuilder.Commit();
			vInnerMeshBuilder.CommitColors(Color.clear);
			innerFilt.sharedMesh = vInnerMeshBuilder.Mesh;
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public override void Build(IHoverboardPanelState pPanelState,
										IHoverboardLayoutState pLayoutState, IBaseItemState pItemState,
										IItemVisualSettings pSettings) {
			base.Build(pPanelState, pLayoutState, pItemState, pSettings);

			vLabel.AlignLeft = true;

			////

			vIcon = new GameObject("Icon");
			vIcon.transform.SetParent(gameObject.transform, false);
			vIcon.transform.localRotation = 
				vLabel.gameObject.transform.localRotation*vLabel.CanvasLocalRotation;
			vIcon.transform.localScale = GetIconScale();
			vIcon.AddComponent<MeshRenderer>();

			MeshFilter iconFilt = vIcon.AddComponent<MeshFilter>();
			vIconMeshBuilder = new MeshBuilder();
			MeshUtil.BuildQuadMesh(vIconMeshBuilder);
			Materials.SetMeshIconCoords(vIconMeshBuilder, GetIconOffset());
			vIconMeshBuilder.Commit();
			vIconMeshBuilder.CommitColors(Color.clear);
			iconFilt.sharedMesh = vIconMeshBuilder.Mesh;
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		protected virtual void BuildMesh(MeshBuilder pMeshBuild) {
			MeshUtil.BuildRingMesh(pMeshBuild, InnerRadius, OuterRadius, vAngle0, vAngle1, vMeshSteps);
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public virtual void Build(IHovercastMenuState pMenuState, IBaseItemState pItemState,
													float pArcAngle, IItemVisualSettings pSettings) {
			vMenuState = pMenuState;
			vItemState = pItemState;
			vAngle0 = -pArcAngle/2f;
			vAngle1 = pArcAngle/2f;
			vSettings = (ItemVisualSettingsStandard)pSettings;
			vSliderItem = (ISliderItem)vItemState.Item;
			vTicks = new GameObject[vSliderItem.Ticks];

			const float pi = (float)Math.PI;

			vGrabArc = pi/40f;
			vSlideDegree0 = (vAngle0+vGrabArc/2)/pi*180;
			vSlideDegrees = (vAngle1-vAngle0-vGrabArc)/pi*180;
			vZeroValue = (0-vSliderItem.RangeMin)/(vSliderItem.RangeMax-vSliderItem.RangeMin);

			////

			vHiddenSlice = new UiHoverMeshSlice(gameObject, true);
			vHiddenSlice.UpdateSize(1, 1.5f, pArcAngle);
			vHiddenSlice.UpdateBackground(Color.clear);

			var trackObj = new GameObject("Track");
			trackObj.transform.SetParent(gameObject.transform, false);
			trackObj.transform.localRotation = Quaternion.AngleAxis(vAngle0/pi*180, Vector3.up);

			vTrack = new UiItemSliderTrackRenderer(trackObj);
			vTrackSegments = new ReadList<DisplayUtil.TrackSegment>();
			vTrackCuts = new ReadList<DisplayUtil.TrackSegment>();

			////

			if ( vSliderItem.Ticks > 1 ) {
				Vector3 quadScale = new Vector3(UiHoverMeshSlice.AngleInset*2, 0.36f, 0.1f);
				float percPerTick = 1/(float)(vSliderItem.Ticks-1);

				vTickMeshBuilder = new MeshBuilder();
				MeshUtil.BuildQuadMesh(vTickMeshBuilder);
				vTickMeshBuilder.Commit();
				vTickMeshBuilder.CommitColors(Color.clear);

				for ( int i = 0 ; i < vSliderItem.Ticks ; ++i ) {
					var tickObj = new GameObject("Tick"+i);
					tickObj.transform.SetParent(gameObject.transform, false);
					tickObj.transform.localRotation = Quaternion.AngleAxis(
						vSlideDegree0+vSlideDegrees*i*percPerTick, Vector3.up);
					vTicks[i] = tickObj;

					var quadObj = new GameObject("Quad");
					quadObj.transform.SetParent(tickObj.transform, false);
					quadObj.transform.localPosition = new Vector3(0, 0, 1.25f);
					quadObj.transform.localRotation = TickQuatRot;
					quadObj.transform.localScale = quadScale;
					quadObj.AddComponent<MeshRenderer>();

					MeshFilter quadFilt = quadObj.AddComponent<MeshFilter>();
					quadFilt.sharedMesh = vTickMeshBuilder.Mesh;
				}
			}

			////

			vGrabHold = new GameObject("GrabHold");
			vGrabHold.transform.SetParent(gameObject.transform, false);

			var grabObj = new GameObject("Grab");
			grabObj.transform.SetParent(vGrabHold.transform, false);

			vGrab = grabObj.AddComponent<UiItemSliderGrabRenderer>();
			vGrab.Build(vMenuState, vItemState, vGrabArc, pSettings);

			////

			vHoverHold = new GameObject("HoverHold");
			vHoverHold.transform.SetParent(gameObject.transform, false);

			var hoverObj = new GameObject("Hover");
			hoverObj.transform.SetParent(vHoverHold.transform, false);

			vHover = new UiHoverMeshSlice(hoverObj, false, "Hover");
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		protected override void UpdateMesh(MeshType pType, MeshBuilder pMeshBuild, float pAmount=1) {
			if ( pType == MeshType.Edge ) {
				float edgeInner = (DrawOuterEdge ? vRadOuter : vRadInner-EdgeThick);
				float edgeOuter = (DrawOuterEdge ? vRadOuter+EdgeThick : vRadInner);
				MeshUtil.BuildRingMesh(pMeshBuild, edgeInner, edgeOuter, vAngle0, vAngle1, vMeshSteps);
				pMeshBuild.Commit();
				return;
			}

			float radOuter = vRadInner+(vRadOuter-vRadInner)*pAmount;

			MeshUtil.BuildRingMesh(pMeshBuild, vRadInner, radOuter, vAngle0, vAngle1, vMeshSteps);
			pMeshBuild.Commit();
		}
		/*--------------------------------------------------------------------------------------------*/
		protected abstract void UpdateMesh(MeshType pType, MeshBuilder pMeshBuild, float pAmount=1);
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public virtual void Build(IHoverboardPanelState pPanelState,
										IHoverboardLayoutState pLayoutState, IBaseItemState pItemState,
										IItemVisualSettings pSettings) {
			vPanelState = pPanelState;
			vLayoutState = pLayoutState;
			vItemState = pItemState;
			vSettings = (ItemVisualSettingsStandard)pSettings;
			vSliderItem = (ISliderItem)vItemState.Item;
			vTicks = new GameObject[vSliderItem.Ticks];

			vWidth = UiItem.Size*vSliderItem.Width;
			vHeight = UiItem.Size*vSliderItem.Height;
			vIsVert = (vHeight > vWidth);
			vGrabW = 1;
			vZeroValue = (0-vSliderItem.RangeMin)/(vSliderItem.RangeMax-vSliderItem.RangeMin);

			gameObject.transform.SetParent(gameObject.transform, false);
			gameObject.transform.localPosition = new Vector3(vWidth/2, 0, vHeight/2f);
			gameObject.transform.localRotation = Quaternion.AngleAxis((vIsVert ? 90 : 0), Vector3.up);

			if ( vIsVert ) { //swap dimensions here + rotate graphics later
				float tempW = vWidth;
				vWidth = vHeight;
				vHeight = tempW;
			}

			vSlideX0 = (vGrabW-vWidth)/2;
			vSlideW = vWidth-vGrabW;

			////

			vHiddenRect = new UiHoverMeshRectBg(gameObject);
			vHiddenRect.UpdateSize(vWidth, vHeight);

			var trackObj = new GameObject("Track");
			trackObj.transform.SetParent(gameObject.transform, false);
			trackObj.transform.localPosition = new Vector3(-vWidth/2, 0, 0);

			vTrack = new UiItemSliderTrackRenderer(trackObj);
			vTrackSegments = new ReadList<DisplayUtil.TrackSegment>();
			vTrackCuts = new ReadList<DisplayUtil.TrackSegment>();

			////

			if ( vSliderItem.Ticks > 1 ) {
				Vector3 quadScale = new Vector3(UiHoverMeshRect.SizeInset*2, 0.36f, 0.1f);
				float percPerTick = 1/(float)(vSliderItem.Ticks-1);

				vTickMeshBuilder = new MeshBuilder();
				MeshUtil.BuildQuadMesh(vTickMeshBuilder);
				vTickMeshBuilder.Commit();
				vTickMeshBuilder.CommitColors(Color.clear);

				for ( int i = 0 ; i < vSliderItem.Ticks ; ++i ) {
					GameObject tickObj = new GameObject("Tick"+i);
					tickObj.transform.SetParent(gameObject.transform, false);
					tickObj.transform.localPosition = Vector3.right*(vSlideX0+vSlideW*i*percPerTick);
					tickObj.transform.localRotation = TickQuatRot;
					tickObj.transform.localScale = quadScale;
					tickObj.AddComponent<MeshRenderer>();

					MeshFilter tickFilt = tickObj.AddComponent<MeshFilter>();
					tickFilt.sharedMesh = vTickMeshBuilder.Mesh;

					vTicks[i] = tickObj;
				}
			}

			////

			vGrabHold = new GameObject("GrabHold");
			vGrabHold.transform.SetParent(gameObject.transform, false);
			vGrabHold.transform.localRotation = Quaternion.Inverse(gameObject.transform.localRotation);

			var grabObj = new GameObject("Grab");
			grabObj.transform.SetParent(vGrabHold.transform, false);

			vGrab = grabObj.AddComponent<UiItemSliderGrabRenderer>();
			vGrab.IsVert = vIsVert;
			vGrab.Build(vPanelState, vLayoutState, vItemState, vSettings);

			if ( vIsVert ) {
				vGrab.SetCustomSize(vHeight, vGrabW, false);
			}
			else {
				vGrab.SetCustomSize(vGrabW, vHeight, false);
			}

			////

			vHoverHold = new GameObject("HoverHold");
			vHoverHold.transform.SetParent(gameObject.transform, false);

			var hoverObj = new GameObject("Hover");
			hoverObj.transform.SetParent(vHoverHold.transform, false);

			vHover = new UiHoverMeshRect(hoverObj, "Hover");
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public static void BuildBorderMesh(MeshBuilder pMeshBuild, float pWidth, float pHeight, 
																					float pThickness) {
			float innerW = pWidth/2-pThickness;
			float innerH = pHeight/2-pThickness;
			float outerW = pWidth/2;
			float outerH = pHeight/2;

			pMeshBuild.Resize(8, 24);
			pMeshBuild.ResetIndices();

			pMeshBuild.AddVertex(new Vector3( outerW,  outerH, 0)); 
			pMeshBuild.AddVertex(new Vector3( outerW, -outerH, 0));
			pMeshBuild.AddVertex(new Vector3(-outerW, -outerH, 0));
			pMeshBuild.AddVertex(new Vector3(-outerW,  outerH, 0));
			pMeshBuild.AddVertex(new Vector3( innerW,  innerH, 0));
			pMeshBuild.AddVertex(new Vector3( innerW, -innerH, 0)); 
			pMeshBuild.AddVertex(new Vector3(-innerW, -innerH, 0));
			pMeshBuild.AddVertex(new Vector3(-innerW,  innerH, 0));

			pMeshBuild.AddTriangle(0, 1, 4);
			pMeshBuild.AddTriangle(1, 5, 4);
			pMeshBuild.AddTriangle(1, 2, 5);
			pMeshBuild.AddTriangle(2, 6, 5);
			pMeshBuild.AddTriangle(2, 3, 6);
			pMeshBuild.AddTriangle(3, 7, 6);
			pMeshBuild.AddTriangle(3, 4, 7);
			pMeshBuild.AddTriangle(3, 0, 4);

			pMeshBuild.AddRemainingUvs(Vector2.zero);
		}
		/*--------------------------------------------------------------------------------------------*/
		public static void BuildRectangleMesh(MeshBuilder pMeshBuild, float pWidth, float pHeight, 
																						float pAmount) {
			float fullW;
			float fullH;

			if ( pWidth >= pHeight ) {
				fullH = pHeight*pAmount;
				fullW = pWidth-(pHeight-fullH);
			}
			else {
				fullW = pWidth*pAmount;
				fullH = pHeight-(pWidth-fullW);
			}

			float halfW = fullW/2f;
			float halfH = fullH/2f;

			pMeshBuild.Resize(4, 6);
			pMeshBuild.ResetIndices();

			pMeshBuild.AddVertex(new Vector3( halfW,  halfH, 0));
			pMeshBuild.AddVertex(new Vector3( halfW, -halfH, 0)); 
			pMeshBuild.AddVertex(new Vector3(-halfW, -halfH, 0));
			pMeshBuild.AddVertex(new Vector3(-halfW,  halfH, 0));

			pMeshBuild.AddTriangle(0, 1, 2);
			pMeshBuild.AddTriangle(0, 2, 3);

			pMeshBuild.AddRemainingUvs(Vector2.zero);
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		protected override void UpdateMesh(MeshType pType, MeshBuilder pMeshBuild, float pAmount=1) {
			MeshUtil.BuildRectangleMesh(pMeshBuild, vMeshW, vMeshH, pAmount);
			pMeshBuild.Commit();
		}
		////////////////////////////////////////////////////////////////////////////////////////////////
		/*--------------------------------------------------------------------------------------------*/
		public static void SetMeshIconCoords(MeshBuilder pMeshBuild, IconOffset pOffset) {
			Vector2[] uvList = pMeshBuild.Uvs;
			const float step = 1/8f;
			float offset = step*(int)pOffset;
			var uvCenter = new Vector2(0.5f, 0.5f);
			const float cheatToCenterAmount = 0.015f;

			for ( int i = 0 ; i < uvList.Length ; i++ ) {
				Vector2 uv = uvList[i];
				uv = Vector2.Lerp(uv, uvCenter, cheatToCenterAmount);
				uv.x *= step;
				uv.x += offset;
				pMeshBuild.Uvs[i] = uv;
			}
		}