/// <summary> /// Creates a linker texture for the given key. /// </summary> private static _LinkerTexture _CreateTexture(_LinkerKey Key) { double grabberwidth = Key.ChildBorderWidth; double handlelength = 0.4; double handlewidth = 0.1; double grabbermaxangle = Math.PI / 8; double partangle = grabbermaxangle / 2.0; double maxheight = handlewidth / 2.0; double innerwidth = Key.ChildRadius - grabberwidth; double maxgrabberwidth = Key.ChildRadius - Math.Cos(grabbermaxangle) * innerwidth; double posheight = Math.Sin(grabbermaxangle) * Key.ChildRadius; if (posheight > maxheight) { maxheight = posheight; } Vector size = new Vector(maxgrabberwidth + handlelength, maxheight * 2.0); double grabbercenter = -Key.ChildRadius + maxgrabberwidth; double midcenter = 0.5 * size.Y; Drawer dr = Drawer.Create(delegate(Vector Point) { Point.X *= size.X; Point.Y *= size.Y; Vector grabberdif = (Point - new Vector(grabbercenter, midcenter)); double grabberdis = grabberdif.Length; double grabberang = grabberdif.Angle; if (grabberdis < innerwidth) { return Color.Transparent; } if (grabberdis < Key.ChildRadius) { double angdif = Math.Abs(grabberang); if (angdif < grabbermaxangle - partangle) { return Color.RGBA(0.9, 0.9, 0.9, 1.0); } if (angdif < grabbermaxangle) { return Color.RGBA(0.9, 0.9, 0.9, 0.5); } } if (Math.Abs(Point.Y - midcenter) < handlewidth / 2.0) { double a = (Point.X - maxgrabberwidth) / handlelength; return Color.RGBA(0.9, 0.9, 0.9, 1.0 - a * a); } return Color.Transparent; }); return new _LinkerTexture() { Size = size, ChildCenterOffset = grabbercenter, Texture = Texture.Define(dr, size.X / size.Y, 0.7) }; }
/// <summary> /// Draws a "linker" between two linked driftoids. Driftoids and view should already be set up. /// </summary> public static void DrawLinker(LinkedDriftoid Parent, LinkedDriftoid Child) { _LinkerKey lk = new _LinkerKey() { ChildRadius = Child.Radius, ChildBorderWidth = Child.BorderWidth }; _LinkerTexture lt; if (!_LinkerTextures.TryGetValue(lk, out lt)) { _LinkerTextures[lk] = lt = _CreateTexture(lk); } Vector dif = Parent.Position - Child.Position; Texture.Bind2D(lt.Texture.ID); GL.PushMatrix(); GL.Translate(Child.Position.X, Child.Position.Y, 0.0); GL.Rotate(dif.Angle * 180 / Math.PI, 0.0, 0.0, 1.0); GL.Translate(-lt.ChildCenterOffset, 0.0, 0.0); GL.Scale(lt.Size.X / 2.0, lt.Size.Y / 2.0, 1.0); GL.Translate(1.0, 0.0, 0.0); GL.Begin(BeginMode.Quads); GL.Vertex2(-1.0f, -1.0f); GL.TexCoord2(0f, 0f); GL.Vertex2(-1.0f, 1.0f); GL.TexCoord2(1f, 0f); GL.Vertex2(1.0f, 1.0f); GL.TexCoord2(1f, 1f); GL.Vertex2(1.0f, -1.0f); GL.TexCoord2(0f, 1f); GL.End(); GL.PopMatrix(); }