protected override void Draw() { if (ShowCaret) { bool isCharVisible = text.Count == 0 || text[0].Count == 0; CaretIndex = ClampIndex(CaretIndex); // If line visible if ((text.Count > 0 && text[0].Count > 0) && (CaretIndex.X >= text.VisibleLineRange.X && CaretIndex.X <= text.VisibleLineRange.Y)) { // Damned special cases Vector2I index = Vector2I.Max(CaretIndex, Vector2I.Zero); // Calculate visibilty on line IRichChar ch = text[index]; Vector2 size = ch.Size, pos = ch.Offset + text.TextOffset; BoundingBox2 textBounds = BoundingBox2.CreateFromHalfExtent(Vector2.Zero, .5f * text.Size), charBounds = BoundingBox2.CreateFromHalfExtent(pos, .5f * Vector2.Max(size, new Vector2(8f))); if (textBounds.Contains(charBounds) != ContainmentType.Disjoint) { isCharVisible = true; } } if (blink & isCharVisible) { UpdateOffset(); base.Draw(); } if (blinkTimer.ElapsedMilliseconds > 500) { blink = !blink; blinkTimer.Restart(); } } }
/// <summary> /// Adds a list of textured quads in one batch using QuadBoard data /// </summary> public static void AddQuads(IReadOnlyList <BoundedQuadBoard> quads, MatrixD[] matrixRef, BoundingBox2?mask = null, Vector2 offset = default(Vector2), float scale = 1f) { var bbPool = instance.bbPoolBack; var bbDataBack = instance.flatTriangleList; var bbBuf = instance.bbBuf; var matList = instance.matrixBuf; var matTable = instance.matrixTable; // Find matrix index in table or add it int matrixID; if (!matTable.TryGetValue(matrixRef, out matrixID)) { matrixID = matList.Count; matList.Add(matrixRef[0]); matTable.Add(matrixRef, matrixID); } int triangleCount = quads.Count * 2, bbCountStart = bbDataBack.Count; bbDataBack.EnsureCapacity(bbDataBack.Count + triangleCount); for (int i = 0; i < quads.Count; i++) { BoundedQuadBoard boundedQB = quads[i]; BoundedQuadMaterial mat = boundedQB.quadBoard.materialData; Vector2 size = boundedQB.bounds.Size * scale, center = offset + boundedQB.bounds.Center * scale; BoundingBox2 bounds = BoundingBox2.CreateFromHalfExtent(center, .5f * size); BoundingBox2? maskBox = mask; ContainmentType containment = ContainmentType.Contains; if (maskBox != null) { maskBox.Value.Contains(ref bounds, out containment); if (containment == ContainmentType.Contains) { maskBox = null; } } if (containment != ContainmentType.Disjoint) { var bbL = new FlatTriangleBillboardData { Item1 = BlendTypeEnum.PostPP, Item2 = new Vector2I(bbDataBack.Count, matrixID), Item3 = mat.textureID, Item4 = new MyTuple <Vector4, BoundingBox2?>(mat.bbColor, maskBox), Item5 = new MyTuple <Vector2, Vector2, Vector2> ( new Vector2(mat.texBounds.Max.X, mat.texBounds.Min.Y), // 1 mat.texBounds.Max, // 0 new Vector2(mat.texBounds.Min.X, mat.texBounds.Max.Y) // 3 ), Item6 = new MyTuple <Vector2, Vector2, Vector2> ( bounds.Max, new Vector2(bounds.Max.X, bounds.Min.Y), bounds.Min ), }; var bbR = new FlatTriangleBillboardData { Item1 = BlendTypeEnum.PostPP, Item2 = new Vector2I(bbDataBack.Count + 1, matrixID), Item3 = mat.textureID, Item4 = new MyTuple <Vector4, BoundingBox2?>(mat.bbColor, maskBox), Item5 = new MyTuple <Vector2, Vector2, Vector2> ( new Vector2(mat.texBounds.Max.X, mat.texBounds.Min.Y), // 1 new Vector2(mat.texBounds.Min.X, mat.texBounds.Max.Y), // 3 mat.texBounds.Min // 2 ), Item6 = new MyTuple <Vector2, Vector2, Vector2> ( bounds.Max, bounds.Min, new Vector2(bounds.Min.X, bounds.Max.Y) ), }; bbDataBack.Add(bbL); bbDataBack.Add(bbR); } } // Add more billboards to pool as needed then queue them for rendering int bbToAdd = Math.Max(bbDataBack.Count - bbPool.Count, 0); instance.AddNewBB(bbToAdd); for (int i = bbCountStart; i < bbDataBack.Count; i++) { bbBuf.Add(bbPool[i]); } MyTransparentGeometry.AddBillboards(bbBuf, false); bbBuf.Clear(); }