public static void Create(Vector3 pos, string text, ColorRgba color)
		{
			GameObject pe = new GameObject(GameRes.Data.Prefabs.PowerupEffect_Prefab);
			pe.GetComponent<PowerupEffect>().Text = text;
			pe.GetComponent<TextRenderer>().ColorTint = color;
			pe.Transform.Pos = pos;
			Scene.Current.RegisterObj(pe);
		}
Example #2
0
        public PixelData(int width, int height, ColorRgba[] data)
        {
            if (data == null) throw new ArgumentNullException("data");
            if (width < 0) throw new ArgumentException("Width may not be negative.", "width");
            if (height < 0) throw new ArgumentException("Height may not be negative.", "height");

            this.SetPixelDataRgba(data, width, height);
        }
Example #3
0
		public PixelData(int width, int height, ColorRgba backColor)
		{
			if (width < 0) throw new ArgumentException("Width may not be negative.", "width");
			if (height < 0) throw new ArgumentException("Height may not be negative.", "height");

			this.width = width;
			this.height = height;
			this.data = new ColorRgba[width * height];

			for (int i = 0; i < this.data.Length; i++)
				this.data[i] = backColor;
		}
Example #4
0
		/// <summary>
		/// Extracts a Bitmaps pixel data.
		/// </summary>
		/// <param name="bm"></param>
		/// <returns></returns>
		public static ColorRgba[] GetPixelDataRgba(this Bitmap bm)
		{
			int[] argbValues = GetPixelDataIntArgb(bm);

			// Convert to ColorRGBA
			ColorRgba[] result = new ColorRgba[argbValues.Length];
			unchecked
			{
				for (int i = 0; i < argbValues.Length; i++)
					result[i].SetIntArgb(argbValues[i]);
			}
			return result;
		}
Example #5
0
        public static void VisualizeAtlas(Bitmap bitmap, List<Rect> atlas)
        {
            ColorRgba atlasColor = new ColorRgba(255, 128, 128, 164);

            // Draw atlas rects
            if (atlas != null)
            {
                Pen atlasPen = new Pen(Color.FromArgb(atlasColor.A, atlasColor.R, atlasColor.G, atlasColor.B));
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    foreach (Rect r in atlas) g.DrawRectangle(atlasPen, r.X, r.Y, r.W, r.H);
                }
            }
        }
		void ICmpInitializable.OnInit(Component.InitContext context)
		{
			if (context == InitContext.Activate && DualityApp.ExecContext != DualityApp.ExecutionContext.Editor)
			{
				this.fade = 1.0f;

				TextRenderer r = this.GameObj.Renderer as TextRenderer;
				r.ColorTint = r.ColorTint.WithAlpha(MathF.Rnd.NextFloat(0.125f, 1.0f));
				this.baseColor = r.ColorTint;

				float scale = MathF.Rnd.NextFloat(1.0f, 3.0f) * MathF.Rnd.NextFloat(0.5f, 1.0f);
				this.GameObj.Transform.RelativeScale = Vector3.One * scale;
				this.GameObj.Transform.RelativeVel += MathF.Rnd.NextVector3(1.0f / scale);
				this.GameObj.Transform.RelativeAngleVel += MathF.Rnd.NextFloat(-0.005f, 0.005f) / scale;
			}
		}
        void ICmpUpdatable.OnUpdate()
        {
            Trigger trig = this.GameObj.GetComponent<Trigger>();
            SpriteRenderer sprite = this.GameObj.GetComponent<SpriteRenderer>();

            if (trig.Triggered && !this.wasTriggered)
            {
                this.oldColorTint = sprite.ColorTint;
                sprite.ColorTint = ColorRgba.Mix(this.oldColorTint, ColorRgba.Red, 0.5f);
            }
            else if (!trig.Triggered && this.wasTriggered)
            {
                sprite.ColorTint = this.oldColorTint;
            }
            this.wasTriggered = trig.Triggered;
        }
		public static void SetPixelDataArgb(this PixelData pixelData, int[] data, int width = -1, int height = -1)
		{
			if (width < 0) width = pixelData.Width;
			if (height < 0) height = pixelData.Height;
			if (data.Length != width * height) throw new ArgumentException("Data length doesn't match width * height", "pixelData");

			ColorRgba[] tempData = new ColorRgba[width * height];
			Parallel.ForEach(Partitioner.Create(0, tempData.Length), range =>
			{
				for (int i = range.Item1; i < range.Item2; i++)
				{
					tempData[i].A = (byte)((data[i] & 0xFF000000) >> 24);
					tempData[i].R = (byte)((data[i] & 0x00FF0000) >> 16);
					tempData[i].G = (byte)((data[i] & 0x0000FF00) >> 8);
					tempData[i].B = (byte)((data[i] & 0x000000FF) >> 0);
				}
			});

			pixelData.SetData(tempData, width, height);
		}
Example #9
0
		public PixelData Read(Stream stream)
		{
			ColorRgba[] rawColorData;
			int width;
			int height;
			PixelData pixelData = new PixelData();

			using (Bitmap bitmap = Bitmap.FromStream(stream) as Bitmap)
			{
				// Retrieve data
				BitmapData bitmapData = bitmap.LockBits(
					new Rectangle(0, 0, bitmap.Width, bitmap.Height),
					ImageLockMode.ReadOnly,
					PixelFormat.Format32bppArgb);
			
				int pixelCount = bitmapData.Width * bitmapData.Height;
				int[] argbValues = new int[pixelCount];
				Marshal.Copy(bitmapData.Scan0, argbValues, 0, pixelCount);
				bitmap.UnlockBits(bitmapData);
				
				width = bitmapData.Width;
				height = bitmapData.Height;
				rawColorData = new ColorRgba[width * height];
				Parallel.ForEach(Partitioner.Create(0, rawColorData.Length), range =>
				{
					for (int i = range.Item1; i < range.Item2; i++)
					{
						rawColorData[i].A = (byte)((argbValues[i] & 0xFF000000) >> 24);
						rawColorData[i].R = (byte)((argbValues[i] & 0x00FF0000) >> 16);
						rawColorData[i].G = (byte)((argbValues[i] & 0x0000FF00) >> 8);
						rawColorData[i].B = (byte)((argbValues[i] & 0x000000FF) >> 0);
					}
				});
			}

			pixelData.SetData(rawColorData, width, height);
			pixelData.ColorTransparentPixels();

			return pixelData;
		}
Example #10
0
        protected void PrepareVerticesSmooth(ref VertexC1P3T4A1[] vertices, IDrawDevice device, float curAnimFrameFade, ColorRgba mainClr, Rect uvRect, Rect uvRectNext)
        {
            Vector3 posTemp = this.gameobj.Transform.Pos;
            float scaleTemp = 1.0f;
            device.PreprocessCoords(ref posTemp, ref scaleTemp);

            Vector2 xDot, yDot;
            MathF.GetTransformDotVec(this.GameObj.Transform.Angle, scaleTemp, out xDot, out yDot);

            Rect rectTemp = this.rect.Transformed(this.gameobj.Transform.Scale, this.gameobj.Transform.Scale);
            Vector2 edge1 = rectTemp.TopLeft;
            Vector2 edge2 = rectTemp.BottomLeft;
            Vector2 edge3 = rectTemp.BottomRight;
            Vector2 edge4 = rectTemp.TopRight;

            MathF.TransformDotVec(ref edge1, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge2, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge3, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge4, ref xDot, ref yDot);

            if (vertices == null || vertices.Length != 4) vertices = new VertexC1P3T4A1[4];

            vertices[0].Pos.X = posTemp.X + edge1.X;
            vertices[0].Pos.Y = posTemp.Y + edge1.Y;
            vertices[0].Pos.Z = posTemp.Z + this.VertexZOffset;
            vertices[0].TexCoord.X = uvRect.X;
            vertices[0].TexCoord.Y = uvRect.Y;
            vertices[0].TexCoord.Z = uvRectNext.X;
            vertices[0].TexCoord.W = uvRectNext.Y;
            vertices[0].Color = mainClr;
            vertices[0].Attrib = curAnimFrameFade;

            vertices[1].Pos.X = posTemp.X + edge2.X;
            vertices[1].Pos.Y = posTemp.Y + edge2.Y;
            vertices[1].Pos.Z = posTemp.Z + this.VertexZOffset;
            vertices[1].TexCoord.X = uvRect.X;
            vertices[1].TexCoord.Y = uvRect.BottomY;
            vertices[1].TexCoord.Z = uvRectNext.X;
            vertices[1].TexCoord.W = uvRectNext.BottomY;
            vertices[1].Color = mainClr;
            vertices[1].Attrib = curAnimFrameFade;

            vertices[2].Pos.X = posTemp.X + edge3.X;
            vertices[2].Pos.Y = posTemp.Y + edge3.Y;
            vertices[2].Pos.Z = posTemp.Z + this.VertexZOffset;
            vertices[2].TexCoord.X = uvRect.RightX;
            vertices[2].TexCoord.Y = uvRect.BottomY;
            vertices[2].TexCoord.Z = uvRectNext.RightX;
            vertices[2].TexCoord.W = uvRectNext.BottomY;
            vertices[2].Color = mainClr;
            vertices[2].Attrib = curAnimFrameFade;

            vertices[3].Pos.X = posTemp.X + edge4.X;
            vertices[3].Pos.Y = posTemp.Y + edge4.Y;
            vertices[3].Pos.Z = posTemp.Z + this.VertexZOffset;
            vertices[3].TexCoord.X = uvRect.RightX;
            vertices[3].TexCoord.Y = uvRect.Y;
            vertices[3].TexCoord.Z = uvRectNext.RightX;
            vertices[3].TexCoord.W = uvRectNext.Y;
            vertices[3].Color = mainClr;
            vertices[3].Attrib = curAnimFrameFade;

            if (this.pixelGrid)
            {
                vertices[0].Pos.X = MathF.Round(vertices[0].Pos.X);
                vertices[1].Pos.X = MathF.Round(vertices[1].Pos.X);
                vertices[2].Pos.X = MathF.Round(vertices[2].Pos.X);
                vertices[3].Pos.X = MathF.Round(vertices[3].Pos.X);

                if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2)
                {
                    vertices[0].Pos.X += 0.5f;
                    vertices[1].Pos.X += 0.5f;
                    vertices[2].Pos.X += 0.5f;
                    vertices[3].Pos.X += 0.5f;
                }

                vertices[0].Pos.Y = MathF.Round(vertices[0].Pos.Y);
                vertices[1].Pos.Y = MathF.Round(vertices[1].Pos.Y);
                vertices[2].Pos.Y = MathF.Round(vertices[2].Pos.Y);
                vertices[3].Pos.Y = MathF.Round(vertices[3].Pos.Y);

                if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2)
                {
                    vertices[0].Pos.Y += 0.5f;
                    vertices[1].Pos.Y += 0.5f;
                    vertices[2].Pos.Y += 0.5f;
                    vertices[3].Pos.Y += 0.5f;
                }
            }
        }
Example #11
0
 /// <summary>
 /// Creates a new complex Material.
 /// </summary>
 /// <param name="technique">The <see cref="Duality.Resources.DrawTechnique"/> to use.</param>
 /// <param name="mainColor">The <see cref="MainColor"/> to use.</param>
 /// <param name="textures">A set of <see cref="Duality.Resources.Texture">Textures</see> to use.</param>
 /// <param name="uniforms">A set of <see cref="Duality.Resources.ShaderFieldInfo">uniform values</see> to use.</param>
 public Material(ContentRef <DrawTechnique> technique, ColorRgba mainColor, Dictionary <string, ContentRef <Texture> > textures = null, Dictionary <string, float[]> uniforms = null)
 {
     this.info = new BatchInfo(technique, mainColor, textures, uniforms);
 }
Example #12
0
        /// <summary>
        /// Picks all <see cref="Duality.ICmpRenderer">ICmpRenderers</see> contained within the specified
        /// rectangular area.
        /// </summary>
        /// <param name="x">x-Coordinate of the Rect.</param>
        /// <param name="y">y-Coordinate of the Rect.</param>
        /// <param name="w">Width of the Rect.</param>
        /// <param name="h">Height of the Rect.</param>
        /// <returns>A set of all <see cref="Duality.ICmpRenderer">ICmpRenderers</see> that have been picked.</returns>
        public HashSet <ICmpRenderer> PickRenderersIn(int x, int y, int w, int h)
        {
            Rect dstRect = new Rect(x, y, w, h);
            Rect srcRect = new Rect(DualityApp.TargetResolution);

            if (!dstRect.Intersects(srcRect))
            {
                return(new HashSet <ICmpRenderer>());
            }
            dstRect = dstRect.Intersection(srcRect);

            this.RenderPickingMap();

            x = Math.Max((int)dstRect.X, 0);
            y = Math.Max((int)dstRect.Y, 0);
            w = Math.Min((int)dstRect.W, this.pickingTex.PixelWidth - x);
            h = Math.Min((int)dstRect.H, this.pickingTex.PixelHeight - y);

            HashSet <ICmpRenderer> result = new HashSet <ICmpRenderer>();
            int rendererIdLast            = 0;

            unsafe
            {
                fixed(byte *pDataBegin = this.pickingBuffer)
                {
                    for (int j = 0; j < h; ++j)
                    {
                        byte *pData = pDataBegin + 4 * (x + (y + j) * this.pickingTex.PixelWidth);
                        for (int i = 0; i < w; ++i)
                        {
                            int rendererId = (*pData << 16) |
                                             (*(pData + 1) << 8) |
                                             (*(pData + 2) << 0);
                            if (rendererId != rendererIdLast)
                            {
                                if (rendererId - 1 > this.pickingMap.Count)
                                {
                                    Log.Core.WriteWarning("Unexpected picking result: {0}", ColorRgba.FromIntArgb(rendererId));
                                }
                                else if (rendererId != 0 && !(this.pickingMap[rendererId - 1] as Component).Disposed)
                                {
                                    result.Add(this.pickingMap[rendererId - 1]);
                                }
                                rendererIdLast = rendererId;
                            }
                            pData += 4;
                        }
                    }
                }
            }

            return(result);
        }
Example #13
0
        private void PrepareNextFrame()
        {
            byte[] internalBuffer = new byte[8];

            if (streams[0].ReadUInt8(ref internalBuffer) == 1)
            {
                for (int i = 0; i < 256; i++)
                {
                    byte r = streams[3].ReadUInt8(ref internalBuffer);
                    byte g = streams[3].ReadUInt8(ref internalBuffer);
                    byte b = streams[3].ReadUInt8(ref internalBuffer);
                    /*byte a =*/ streams[3].ReadUInt8(ref internalBuffer);
                    palette[i] = new ColorRgba(r, g, b);
                }
            }

            for (int y = 0; y < height; y++)
            {
                byte c;
                int  x = 0;
                while ((c = streams[0].ReadUInt8(ref internalBuffer)) != 128)
                {
                    if (c < 128)
                    {
                        int u;
                        if (c == 0x00)
                        {
                            u = streams[0].ReadInt16(ref internalBuffer);
                        }
                        else
                        {
                            u = c;
                        }

                        for (int i = 0; i < u; i++)
                        {
                            byte pixel = streams[3].ReadUInt8(ref internalBuffer);
                            currentBuffer[y * width + x] = pixel;
                            x++;
                        }
                    }
                    else
                    {
                        int u;
                        if (c == 0x81)
                        {
                            u = streams[0].ReadInt16(ref internalBuffer);
                        }
                        else
                        {
                            u = c - 106;
                        }

                        int n = streams[1].ReadInt16(ref internalBuffer) + (streams[2].ReadUInt8(ref internalBuffer) + y - 127) * width;
                        for (int i = 0; i < u; i++)
                        {
                            currentBuffer[y * width + x] = lastBuffer[n];
                            x++;
                            n++;
                        }
                    }
                }
            }

            for (int i = 0; i < currentBuffer.Length; i++)
            {
                currentFrame.MainLayer.Data[i] = palette[currentBuffer[i]];
            }

            videoTexture.LoadData(currentFrame, TextureSizeMode.NonPowerOfTwo);

            Buffer.BlockCopy(currentBuffer, 0, lastBuffer, 0, currentBuffer.Length);
        }
Example #14
0
        protected void PrepareVertices(ref VertexC1P3T2[] vertices, IDrawDevice device, ColorRgba mainClr, Rect uvRect)
        {
            Vector3 posTemp   = this.gameobj.Transform.Pos;
            float   scaleTemp = 1.0f;

            device.PreprocessCoords(ref posTemp, ref scaleTemp);

            Vector2 xDot, yDot;

            MathF.GetTransformDotVec(this.GameObj.Transform.Angle, scaleTemp, out xDot, out yDot);

            Rect    rectTemp = this.rect.Transform(this.gameobj.Transform.Scale, this.gameobj.Transform.Scale);
            Vector2 edge1    = rectTemp.TopLeft;
            Vector2 edge2    = rectTemp.BottomLeft;
            Vector2 edge3    = rectTemp.BottomRight;
            Vector2 edge4    = rectTemp.TopRight;

            MathF.TransformDotVec(ref edge1, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge2, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge3, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge4, ref xDot, ref yDot);

            if (vertices == null || vertices.Length != 4)
            {
                vertices = new VertexC1P3T2[4];
            }

            vertices[0].Pos.X      = posTemp.X + edge1.X;
            vertices[0].Pos.Y      = posTemp.Y + edge1.Y;
            vertices[0].Pos.Z      = posTemp.Z + this.VertexZOffset;
            vertices[0].TexCoord.X = uvRect.X;
            vertices[0].TexCoord.Y = uvRect.Y;
            vertices[0].Color      = mainClr;

            vertices[1].Pos.X      = posTemp.X + edge2.X;
            vertices[1].Pos.Y      = posTemp.Y + edge2.Y;
            vertices[1].Pos.Z      = posTemp.Z + this.VertexZOffset;
            vertices[1].TexCoord.X = uvRect.X;
            vertices[1].TexCoord.Y = uvRect.MaximumY;
            vertices[1].Color      = mainClr;

            vertices[2].Pos.X      = posTemp.X + edge3.X;
            vertices[2].Pos.Y      = posTemp.Y + edge3.Y;
            vertices[2].Pos.Z      = posTemp.Z + this.VertexZOffset;
            vertices[2].TexCoord.X = uvRect.MaximumX;
            vertices[2].TexCoord.Y = uvRect.MaximumY;
            vertices[2].Color      = mainClr;

            vertices[3].Pos.X      = posTemp.X + edge4.X;
            vertices[3].Pos.Y      = posTemp.Y + edge4.Y;
            vertices[3].Pos.Z      = posTemp.Z + this.VertexZOffset;
            vertices[3].TexCoord.X = uvRect.MaximumX;
            vertices[3].TexCoord.Y = uvRect.Y;
            vertices[3].Color      = mainClr;

            if (this.pixelGrid)
            {
                vertices[0].Pos.X = MathF.Round(vertices[0].Pos.X);
                vertices[1].Pos.X = MathF.Round(vertices[1].Pos.X);
                vertices[2].Pos.X = MathF.Round(vertices[2].Pos.X);
                vertices[3].Pos.X = MathF.Round(vertices[3].Pos.X);

                if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2)
                {
                    vertices[0].Pos.X += 0.5f;
                    vertices[1].Pos.X += 0.5f;
                    vertices[2].Pos.X += 0.5f;
                    vertices[3].Pos.X += 0.5f;
                }

                vertices[0].Pos.Y = MathF.Round(vertices[0].Pos.Y);
                vertices[1].Pos.Y = MathF.Round(vertices[1].Pos.Y);
                vertices[2].Pos.Y = MathF.Round(vertices[2].Pos.Y);
                vertices[3].Pos.Y = MathF.Round(vertices[3].Pos.Y);

                if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2)
                {
                    vertices[0].Pos.Y += 0.5f;
                    vertices[1].Pos.Y += 0.5f;
                    vertices[2].Pos.Y += 0.5f;
                    vertices[3].Pos.Y += 0.5f;
                }
            }
        }
Example #15
0
 /// <summary>
 /// Emits sets of vertices for glyphs and icons based on this formatted text. To render it, use each set of vertices combined with
 /// the corresponding Fonts <see cref="Material"/>.
 /// </summary>
 /// <param name="vertText">One set of vertices for each Font that is available to this ForattedText.</param>
 /// <param name="vertIcons">A set of icon vertices.</param>
 /// <param name="x">An X-Offset applied to the position of each emitted vertex.</param>
 /// <param name="y">An Y-Offset applied to the position of each emitted vertex.</param>
 /// <param name="z">An Z-Offset applied to the position of each emitted vertex.</param>
 /// <param name="clr">The color value that is applied to each emitted vertex.</param>
 /// <param name="angle">An angle by which the text is rotated (before applying the offset).</param>
 /// <param name="scale">A factor by which the text is scaled (before applying the offset).</param>
 /// <returns>
 /// Returns an array of vertex counts for each emitted vertex array. 
 /// Index 0 represents the number of emitted icon vertices, Index n represents the number of vertices emitted using Font n - 1.
 /// </returns>
 public int[] EmitVertices(ref VertexC1P3T2[][] vertText, ref VertexC1P3T2[] vertIcons, float x, float y, float z, ColorRgba clr, float angle = 0.0f, float scale = 1.0f)
 {
     Vector2 xDot, yDot;
     MathF.GetTransformDotVec(angle, scale, out xDot, out yDot);
     return this.EmitVertices(ref vertText, ref vertIcons, x, y, z, clr, xDot, yDot);
 }
Example #16
0
            public RenderState(FormattedText parent)
            {
                this.parent = parent;
                this.vertTextIndex = new int[this.parent.fonts != null ? this.parent.fonts.Length : 0];
                this.font = (this.parent.fonts != null && this.parent.fonts.Length > 0) ? this.parent.fonts[0].Res : null;
                this.color = ColorRgba.White;
                this.lineAlign = parent.lineAlign;

                this.PeekLineStats();
                this.offset.X = this.lineBeginX;
            }
 /// <summary>
 /// Colors the log entry with the specified value.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="entry"></param>
 /// <param name="color"></param>
 public static T WithColor <T>(this T entry, ColorRgba color) where T : VisualLogEntry
 {
     entry.Color = color;
     return(entry);
 }
Example #18
0
        protected void PrepareVerticesSmooth(ref VertexC1P3T4A1[] vertices, IDrawDevice device, float curAnimFrameFade, ColorRgba mainClr, Rect uvRect, Rect uvRectNext)
        {
            Vector3 pos = this.gameobj.Transform.Pos;

            Vector2 xDot, yDot;

            MathF.GetTransformDotVec(this.gameobj.Transform.Angle, this.gameobj.Transform.Scale, out xDot, out yDot);

            Rect    rectTemp = rect.Transformed(gameobj.Transform.Scale, gameobj.Transform.Scale);
            Vector2 edge1    = rectTemp.TopLeft;
            Vector2 edge2    = rectTemp.BottomLeft;
            Vector2 edge3    = rectTemp.BottomRight;
            Vector2 edge4    = rectTemp.TopRight;

            MathF.TransformDotVec(ref edge1, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge2, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge3, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge4, ref xDot, ref yDot);

            float left       = uvRect.X;
            float right      = uvRect.RightX;
            float top        = uvRect.Y;
            float bottom     = uvRect.BottomY;
            float nextLeft   = uvRectNext.X;
            float nextRight  = uvRectNext.RightX;
            float nextTop    = uvRectNext.Y;
            float nextBottom = uvRectNext.BottomY;

            if ((flipMode & FlipMode.Horizontal) != FlipMode.None)
            {
                edge1.X = -edge1.X;
                edge2.X = -edge2.X;
                edge3.X = -edge3.X;
                edge4.X = -edge4.X;
            }
            if ((flipMode & FlipMode.Vertical) != FlipMode.None)
            {
                edge1.Y = -edge1.Y;
                edge2.Y = -edge2.Y;
                edge3.Y = -edge3.Y;
                edge4.Y = -edge4.Y;
            }

            if (vertices == null /*|| vertices.Length != 4*/)
            {
                vertices = new VertexC1P3T4A1[4];
            }

            vertices[0].Pos.X      = pos.X + edge1.X;
            vertices[0].Pos.Y      = pos.Y + edge1.Y;
            vertices[0].Pos.Z      = pos.Z + VertexZOffset;
            vertices[0].TexCoord.X = left;
            vertices[0].TexCoord.Y = top;
            vertices[0].TexCoord.Z = nextLeft;
            vertices[0].TexCoord.W = nextTop;
            vertices[0].Color      = mainClr;
            vertices[0].Attrib     = curAnimFrameFade;

            vertices[1].Pos.X      = pos.X + edge2.X;
            vertices[1].Pos.Y      = pos.Y + edge2.Y;
            vertices[1].Pos.Z      = pos.Z + VertexZOffset;
            vertices[1].TexCoord.X = left;
            vertices[1].TexCoord.Y = bottom;
            vertices[1].TexCoord.Z = nextLeft;
            vertices[1].TexCoord.W = nextBottom;
            vertices[1].Color      = mainClr;
            vertices[1].Attrib     = curAnimFrameFade;

            vertices[2].Pos.X      = pos.X + edge3.X;
            vertices[2].Pos.Y      = pos.Y + edge3.Y;
            vertices[2].Pos.Z      = pos.Z + VertexZOffset;
            vertices[2].TexCoord.X = right;
            vertices[2].TexCoord.Y = bottom;
            vertices[2].TexCoord.Z = nextRight;
            vertices[2].TexCoord.W = nextBottom;
            vertices[2].Color      = mainClr;
            vertices[2].Attrib     = curAnimFrameFade;

            vertices[3].Pos.X      = pos.X + edge4.X;
            vertices[3].Pos.Y      = pos.Y + edge4.Y;
            vertices[3].Pos.Z      = pos.Z + VertexZOffset;
            vertices[3].TexCoord.X = right;
            vertices[3].TexCoord.Y = top;
            vertices[3].TexCoord.Z = nextRight;
            vertices[3].TexCoord.W = nextTop;
            vertices[3].Color      = mainClr;
            vertices[3].Attrib     = curAnimFrameFade;

            if (pixelGrid)
            {
                vertices[0].Pos.X = MathF.Round(vertices[0].Pos.X);
                vertices[1].Pos.X = MathF.Round(vertices[1].Pos.X);
                vertices[2].Pos.X = MathF.Round(vertices[2].Pos.X);
                vertices[3].Pos.X = MathF.Round(vertices[3].Pos.X);

                if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2)
                {
                    vertices[0].Pos.X += 0.5f;
                    vertices[1].Pos.X += 0.5f;
                    vertices[2].Pos.X += 0.5f;
                    vertices[3].Pos.X += 0.5f;
                }

                vertices[0].Pos.Y = MathF.Round(vertices[0].Pos.Y);
                vertices[1].Pos.Y = MathF.Round(vertices[1].Pos.Y);
                vertices[2].Pos.Y = MathF.Round(vertices[2].Pos.Y);
                vertices[3].Pos.Y = MathF.Round(vertices[3].Pos.Y);

                if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2)
                {
                    vertices[0].Pos.Y += 0.5f;
                    vertices[1].Pos.Y += 0.5f;
                    vertices[2].Pos.Y += 0.5f;
                    vertices[3].Pos.Y += 0.5f;
                }
            }
        }
Example #19
0
        public static Geometry FromFileSystemEntry(FileSystemEntry entry)
        {
            var geometry = new Geometry();

            using (var stream = entry.Open())
                using (var reader = new StreamReader(stream))
                {
                    string        line;
                    int           image       = 0;
                    float         thickness   = 0;
                    Matrix2x2     rotMat      = new Matrix2x2();
                    Vector2       translation = new Vector2();
                    ColorRgba     color       = new ColorRgba(0, 0, 0, 0);
                    GeometryStyle style       = GeometryStyle.Undefined;
                    var           tris        = new List <Triangle2D>();
                    var           lines       = new List <Line2D>();

                    Action ApplyStyle = () =>
                    {
                        switch (style)
                        {
                        //no data parsed yet
                        case GeometryStyle.Undefined:
                            break;

                        case GeometryStyle.TexturedTri:
                            geometry.Entries.Add(new GeometryTexturedTriangles(new List <Triangle2D>(tris), color, image, rotMat, translation));
                            tris.Clear();
                            break;

                        case GeometryStyle.SolidTri:
                            geometry.Entries.Add(new GeometrySolidTriangles(new List <Triangle2D>(tris), color));
                            tris.Clear();
                            break;

                        case GeometryStyle.Line:
                            geometry.Entries.Add(new GeometryLines(new List <Line2D>(lines), color, thickness));
                            lines.Clear();
                            break;
                        }

                        style = GeometryStyle.Undefined;
                    };

                    while ((line = reader.ReadLine()) != null)
                    {
                        line = line.Trim();

                        var lineMode = line.First();
                        line = line.TrimStart('c', 's', 'l', 't');
                        var paramList = line.Split(':');

                        //trim each entry of the param list
                        for (var i = 0; i < paramList.Length; ++i)
                        {
                            paramList[i] = paramList[i].Trim();
                        }

                        switch (lineMode)
                        {
                        //Clear - Finish the last geometry
                        case 'c':
                            ApplyStyle();
                            break;

                        //Style - Header for the following data
                        case 's':
                            //Check that we have atleast 1 param
                            if (paramList.Length < 1)
                            {
                                throw new InvalidDataException();
                            }

                            //Check which style we are using
                            switch (paramList.First())
                            {
                            //this is the solid triangle style
                            case "s":
                                if (paramList.Length != 5)
                                {
                                    throw new InvalidDataException();
                                }

                                style = GeometryStyle.SolidTri;
                                color = new ColorRgba(
                                    Convert.ToByte(paramList[1]),
                                    Convert.ToByte(paramList[2]),
                                    Convert.ToByte(paramList[3]),
                                    Convert.ToByte(paramList[4]));
                                break;

                            //this is the line style
                            case "l":
                                if (paramList.Length != 6)
                                {
                                    throw new InvalidDataException();
                                }

                                style     = GeometryStyle.Line;
                                thickness = ParseUtility.ParseFloat(paramList[1]);
                                color     = new ColorRgba(
                                    Convert.ToByte(paramList[2]),
                                    Convert.ToByte(paramList[3]),
                                    Convert.ToByte(paramList[4]),
                                    Convert.ToByte(paramList[5]));
                                break;

                            //this is the textured triangle style
                            case "tc":
                                if (paramList.Length != 12)
                                {
                                    throw new InvalidDataException();
                                }

                                style = GeometryStyle.TexturedTri;
                                color = new ColorRgba(
                                    Convert.ToByte(paramList[1]),
                                    Convert.ToByte(paramList[2]),
                                    Convert.ToByte(paramList[3]),
                                    Convert.ToByte(paramList[4]));
                                //image id used
                                image = Convert.ToInt32(paramList[5]);
                                //transformation parameters, to map the geometry above the texture
                                rotMat = new Matrix2x2(
                                    ParseUtility.ParseFloat(paramList[6]),
                                    ParseUtility.ParseFloat(paramList[7]),
                                    ParseUtility.ParseFloat(paramList[8]),
                                    ParseUtility.ParseFloat(paramList[9]));
                                translation.X = ParseUtility.ParseFloat(paramList[10]);
                                translation.Y = ParseUtility.ParseFloat(paramList[11]);
                                break;
                            }
                            break;

                        //A line
                        case 'l':
                            lines.Add(new Line2D(
                                          new Vector2(ParseUtility.ParseFloat(paramList[0]), ParseUtility.ParseFloat(paramList[1])),
                                          new Vector2(ParseUtility.ParseFloat(paramList[2]), ParseUtility.ParseFloat(paramList[3]))));
                            break;

                        //A triangle
                        case 't':
                            tris.Add(new Triangle2D(
                                         new Vector2(ParseUtility.ParseFloat(paramList[0]), ParseUtility.ParseFloat(paramList[1])),
                                         new Vector2(ParseUtility.ParseFloat(paramList[2]), ParseUtility.ParseFloat(paramList[3])),
                                         new Vector2(ParseUtility.ParseFloat(paramList[4]), ParseUtility.ParseFloat(paramList[5]))));
                            break;
                        }
                    }

                    ApplyStyle();
                }

            geometry.CalculateBoundings();
            return(geometry);
        }
Example #20
0
 public void DrawMaterial(string name, int frame, float x, float y, Alignment alignment, ColorRgba color, float scaleX = 1f, float scaleY = 1f)
 {
     if (metadata.Graphics.TryGetValue(name, out GraphicResource res))
     {
         res.Draw(canvas, frame, x, y, alignment, color, scaleX, scaleY);
     }
 }
		protected override void OnCollectStateWorldOverlayDrawcalls(Canvas canvas)
		{
			base.OnCollectStateWorldOverlayDrawcalls(canvas);

			// Assure we know how to display the current selection
			this.ValidateSelectionStats();

			List<ObjectEditorSelObj> transformObjSel = this.allObjSel.Where(s => s.HasTransform).ToList();
			Point cursorPos = this.PointToClient(Cursor.Position);
			canvas.PushState();
			canvas.State.ZOffset = -1.0f;
			
			// Draw indirectly selected object overlay
			canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, ColorRgba.Lerp(this.FgColor, this.BgColor, 0.75f)));
			this.DrawSelectionMarkers(canvas, this.indirectObjSel);
			if (this.mouseoverObject != null && (this.mouseoverAction == ObjectEditorAction.RectSelect || this.mouseoverSelect) && !transformObjSel.Contains(this.mouseoverObject)) 
				this.DrawSelectionMarkers(canvas, new [] { this.mouseoverObject });

			// Draw selected object overlay
			canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, this.FgColor));
			this.DrawSelectionMarkers(canvas, transformObjSel);

			// Draw overall selection boundary
			if (transformObjSel.Count > 1)
			{
				float midZ = transformObjSel.Average(t => t.Pos.Z);
				float maxZDiff = transformObjSel.Max(t => MathF.Abs(t.Pos.Z - midZ));
				if (maxZDiff > 0.001f)
				{
					canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, ColorRgba.Lerp(this.FgColor, this.BgColor, 0.5f)));
					canvas.DrawSphere(
						this.selectionCenter.X, 
						this.selectionCenter.Y, 
						this.selectionCenter.Z, 
						this.selectionRadius);
				}
				else
				{
					canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, ColorRgba.Lerp(this.FgColor, this.BgColor, 0.5f)));
					canvas.DrawCircle(
						this.selectionCenter.X, 
						this.selectionCenter.Y, 
						this.selectionCenter.Z, 
						this.selectionRadius);
				}
			}

			// Draw scale action dots
			bool canMove = this.actionObjSel.Any(s => s.IsActionAvailable(ObjectEditorAction.Move));
			bool canScale = (canMove && this.actionObjSel.Count > 1) || this.actionObjSel.Any(s => s.IsActionAvailable(ObjectEditorAction.Scale));
			if (canScale)
			{
				float dotR = 3.0f / this.GetScaleAtZ(this.selectionCenter.Z);
				canvas.State.ZOffset -= 0.1f;
				canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Solid, this.FgColor));
				canvas.FillCircle(
					this.selectionCenter.X + this.selectionRadius, 
					this.selectionCenter.Y, 
					this.selectionCenter.Z,
					dotR);
				canvas.FillCircle(
					this.selectionCenter.X - this.selectionRadius, 
					this.selectionCenter.Y, 
					this.selectionCenter.Z,
					dotR);
				canvas.FillCircle(
					this.selectionCenter.X, 
					this.selectionCenter.Y + this.selectionRadius, 
					this.selectionCenter.Z,
					dotR);
				canvas.FillCircle(
					this.selectionCenter.X, 
					this.selectionCenter.Y - this.selectionRadius, 
					this.selectionCenter.Z,
					dotR);
				canvas.State.ZOffset += 0.1f;
			}

			if (this.action != ObjectEditorAction.None)
			{
				// Draw action lock axes
				this.DrawLockedAxes(canvas, this.selectionCenter.X, this.selectionCenter.Y, this.selectionCenter.Z, this.selectionRadius * 4);
			}

			canvas.PopState();
		}
Example #22
0
        void IGraphicsBackend.BeginRendering(IDrawDevice device, RenderOptions options, RenderStats stats)
        {
            DebugCheckOpenGLErrors();

            this.currentDevice = device;
            this.renderStats   = stats;

            // Prepare the target surface for rendering
            NativeRenderTarget.Bind(options.Target as NativeRenderTarget);

            // Determine whether masked blending should use alpha-to-coverage mode
            if (NativeRenderTarget.BoundRT != null)
            {
                this.useAlphaToCoverageBlend = NativeRenderTarget.BoundRT.Samples > 0;
            }
            else if (GraphicsBackend.ActiveInstance.ActiveWindow != null)
            {
                this.useAlphaToCoverageBlend = GraphicsBackend.ActiveInstance.ActiveWindow.IsMultisampled;
            }
            else
            {
                this.useAlphaToCoverageBlend = GraphicsBackend.ActiveInstance.DefaultGraphicsMode.Samples > 0;
            }

            if (this.primaryVBO == 0)
            {
                GL.GenBuffers(1, out this.primaryVBO);
            }
            GL.BindBuffer(BufferTarget.ArrayBuffer, this.primaryVBO);

            // Setup viewport
            Rect viewportRect = options.Viewport;

            GL.Viewport((int)viewportRect.X, (int)viewportRect.Y, (int)viewportRect.W, (int)viewportRect.H);
            GL.Scissor((int)viewportRect.X, (int)viewportRect.Y, (int)viewportRect.W, (int)viewportRect.H);

            // Clear buffers
            ClearBufferMask glClearMask = 0;
            ColorRgba       clearColor  = options.ClearColor;

            if ((options.ClearFlags & ClearFlag.Color) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.ColorBufferBit;
            }
            if ((options.ClearFlags & ClearFlag.Depth) != ClearFlag.None)
            {
                glClearMask |= ClearBufferMask.DepthBufferBit;
            }
            GL.ClearColor(clearColor.R / 255.0f, clearColor.G / 255.0f, clearColor.B / 255.0f, clearColor.A / 255.0f);
            GL.ClearDepth((double)options.ClearDepth);             // The "float version" is from OpenGL 4.1..
            GL.Clear(glClearMask);

            // Configure Rendering params
            if (options.RenderMode == RenderMatrix.OrthoScreen)
            {
                GL.Enable(EnableCap.ScissorTest);
                GL.Enable(EnableCap.DepthTest);
                GL.DepthFunc(DepthFunction.Always);
            }
            else
            {
                GL.Enable(EnableCap.ScissorTest);
                GL.Enable(EnableCap.DepthTest);
                GL.DepthFunc(DepthFunction.Lequal);
            }

            OpenTK.Matrix4 openTkModelView;
            Matrix4        modelView = options.ModelViewMatrix;

            GetOpenTKMatrix(ref modelView, out openTkModelView);

            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadMatrix(ref openTkModelView);

            OpenTK.Matrix4 openTkProjection;
            Matrix4        projection = options.ProjectionMatrix;

            GetOpenTKMatrix(ref projection, out openTkProjection);

            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadMatrix(ref openTkProjection);

            if (NativeRenderTarget.BoundRT != null)
            {
                if (options.RenderMode == RenderMatrix.OrthoScreen)
                {
                    GL.Translate(0.0f, viewportRect.H * 0.5f, 0.0f);
                }
                GL.Scale(1.0f, -1.0f, 1.0f);
                if (options.RenderMode == RenderMatrix.OrthoScreen)
                {
                    GL.Translate(0.0f, -viewportRect.H * 0.5f, 0.0f);
                }
            }
        }
Example #23
0
        public override void Draw(Canvas target, Vector3 basePos, float baseRotation, float baseScale)
        {
            float originRadius       = 5.0f;
            float vectorThickness    = 4.0f;
            float borderRadius       = DefaultOutlineWidth;
            float vectorLengthFactor = 1.0f;

            // Scale anti-proportional to perspective scale in order to keep a constant size
            // in screen space even when actually drawing in world space.
            {
                float   scale   = 1.0f;
                Vector3 posTemp = this.origin + basePos;
                target.DrawDevice.PreprocessCoords(ref posTemp, ref scale);
                originRadius    /= scale;
                borderRadius    /= scale;
                vectorThickness /= scale;
                if (this.invariantScale)
                {
                    vectorLengthFactor /= scale;
                }
            }


            // Determine base and target positions
            Vector3 originPos = this.origin;
            Vector3 targetPos = this.origin + new Vector3(this.vec * vectorLengthFactor);

            MathF.TransformCoord(ref originPos.X, ref originPos.Y, baseRotation, baseScale);
            MathF.TransformCoord(ref targetPos.X, ref targetPos.Y, baseRotation, baseScale);
            originPos += basePos;
            targetPos += basePos;

            // Downscale vector arrow, if too small for display otherwise
            float vectorLen      = (targetPos.Xy - originPos.Xy).Length;
            float vectorLenScale = MathF.Clamp(vectorLen / (vectorThickness * 7.0f), 0.0f, 1.0f);

            vectorThickness *= vectorLenScale;

            // Create arrow polygon
            Vector2 dirForward = (targetPos.Xy - originPos.Xy).Normalized;
            Vector2 dirLeft    = dirForward.PerpendicularLeft;
            Vector2 dirRight   = -dirLeft;

            Vector2[] arrow = new Vector2[7];
            arrow[0] = dirLeft * vectorThickness * 0.5f;
            arrow[1] = dirLeft * vectorThickness * 0.5f + dirForward * (vectorLen - vectorThickness * 2);
            arrow[2] = dirLeft * vectorThickness * 1.25f + dirForward * (vectorLen - vectorThickness * 2);
            arrow[3] = dirForward * vectorLen;
            arrow[4] = dirRight * vectorThickness * 1.25f + dirForward * (vectorLen - vectorThickness * 2);
            arrow[5] = dirRight * vectorThickness * 0.5f + dirForward * (vectorLen - vectorThickness * 2);
            arrow[6] = dirRight * vectorThickness * 0.5f;
            Vector2[] arrowHead = new Vector2[3];
            arrowHead[0] = arrow[2];
            arrowHead[1] = arrow[3];
            arrowHead[2] = arrow[4];
            Vector2[] arrowLine = new Vector2[4];
            arrowLine[0] = arrow[0];
            arrowLine[1] = arrow[1];
            arrowLine[2] = arrow[5];
            arrowLine[3] = arrow[6];

            // Draw vector and outline
            ColorRgba areaColor    = target.State.ColorTint * this.Color;
            ColorRgba outlineColor = areaColor * ColorRgba.Black;

            target.State.ColorTint = areaColor;
            target.FillPolygon(
                arrowLine,
                originPos.X,
                originPos.Y,
                originPos.Z);
            target.FillPolygon(
                arrowHead,
                originPos.X,
                originPos.Y,
                originPos.Z);
            if (target.DrawDevice.DepthWrite)
            {
                target.State.ZOffset -= 0.1f;
            }
            target.State.ColorTint = outlineColor;
            target.FillPolygonOutline(
                arrow,
                borderRadius,
                originPos.X,
                originPos.Y,
                originPos.Z);

            // Draw origin and outline
            if (target.DrawDevice.DepthWrite)
            {
                target.State.ZOffset -= 0.1f;
            }
            target.State.ColorTint = areaColor;
            target.FillCircle(
                originPos.X,
                originPos.Y,
                originPos.Z,
                originRadius - borderRadius * 0.5f);
            if (target.DrawDevice.DepthWrite)
            {
                target.State.ZOffset -= 0.1f;
            }
            target.State.ColorTint = outlineColor;
            target.FillCircleSegment(
                originPos.X,
                originPos.Y,
                originPos.Z,
                originRadius,
                0.0f,
                MathF.RadAngle360,
                borderRadius);
        }
        private static void DrawTileHighlights(Canvas canvas, ICmpTilemapRenderer renderer, Point2 origin, IReadOnlyGrid<bool> highlight, ColorRgba fillTint, ColorRgba outlineTint, TileHighlightMode mode, List<Vector2[]> outlineCache = null)
        {
            if (highlight.Width == 0 || highlight.Height == 0) return;

            // Generate strippled line texture if not available yet
            if (strippledLineTex == null)
            {
                PixelData pixels = new PixelData(8, 1);
                for (int i = 0; i < pixels.Width / 2; i++)
                    pixels[i, 0] = ColorRgba.White;
                for (int i = pixels.Width / 2; i < pixels.Width; i++)
                    pixels[i, 0] = ColorRgba.TransparentWhite;

                using (Pixmap pixmap = new Pixmap(pixels))
                {
                    strippledLineTex = new Texture(pixmap,
                        TextureSizeMode.Default,
                        TextureMagFilter.Nearest,
                        TextureMinFilter.Nearest,
                        TextureWrapMode.Repeat,
                        TextureWrapMode.Repeat,
                        TexturePixelFormat.Rgba);
                }
            }

            BatchInfo defaultMaterial = new BatchInfo(DrawTechnique.Alpha, canvas.State.Material.MainColor);
            BatchInfo strippleMaterial = new BatchInfo(DrawTechnique.Alpha, canvas.State.Material.MainColor, strippledLineTex);
            bool uncertain = (mode & TileHighlightMode.Uncertain) != 0;
            bool selection = (mode & TileHighlightMode.Selection) != 0;

            Component component = renderer as Component;
            Transform transform = component.GameObj.Transform;
            Tilemap tilemap = renderer.ActiveTilemap;
            Tileset tileset = tilemap != null ? tilemap.Tileset.Res : null;
            Vector2 tileSize = tileset != null ? tileset.TileSize : Tileset.DefaultTileSize;
            Rect localRect = renderer.LocalTilemapRect;

            // Determine the object's local coordinate system (rotated, scaled) in world space
            Vector2 worldAxisX = Vector2.UnitX;
            Vector2 worldAxisY = Vector2.UnitY;
            MathF.TransformCoord(ref worldAxisX.X, ref worldAxisX.Y, transform.Angle, transform.Scale);
            MathF.TransformCoord(ref worldAxisY.X, ref worldAxisY.Y, transform.Angle, transform.Scale);

            Vector2 localOriginPos = tileSize * origin;
            Vector2 worldOriginPos = localOriginPos.X * worldAxisX + localOriginPos.Y * worldAxisY;

            canvas.PushState();
            {
                // Configure the canvas so our shapes are properly rotated and scaled
                canvas.State.TransformHandle = -localRect.TopLeft;
                canvas.State.TransformAngle = transform.Angle;
                canvas.State.TransformScale = new Vector2(transform.Scale);

                // Fill all highlighted tiles that are currently visible
                {
                    canvas.State.SetMaterial(defaultMaterial);
                    canvas.State.ColorTint = fillTint * ColorRgba.White.WithAlpha(selection ? 0.2f : 0.375f);

                    // Determine tile visibility
                    Vector2 worldTilemapOriginPos = localRect.TopLeft;
                    MathF.TransformCoord(ref worldTilemapOriginPos.X, ref worldTilemapOriginPos.Y, transform.Angle, transform.Scale);
                    TilemapCulling.TileInput cullingIn = new TilemapCulling.TileInput
                    {
                        // Remember: All these transform values are in world space
                        TilemapPos = transform.Pos + new Vector3(worldTilemapOriginPos) + new Vector3(worldOriginPos),
                        TilemapScale = transform.Scale,
                        TilemapAngle = transform.Angle,
                        TileCount = new Point2(highlight.Width, highlight.Height),
                        TileSize = tileSize
                    };
                    TilemapCulling.TileOutput cullingOut = TilemapCulling.GetVisibleTileRect(canvas.DrawDevice, cullingIn);
                    int renderedTileCount = cullingOut.VisibleTileCount.X * cullingOut.VisibleTileCount.Y;

                    // Draw all visible highlighted tiles
                    {
                        Point2 tileGridPos = cullingOut.VisibleTileStart;
                        Vector2 renderStartPos = worldOriginPos + tileGridPos.X * tileSize.X * worldAxisX + tileGridPos.Y * tileSize.Y * worldAxisY;;
                        Vector2 renderPos = renderStartPos;
                        Vector2 tileXStep = worldAxisX * tileSize.X;
                        Vector2 tileYStep = worldAxisY * tileSize.Y;
                        int lineMergeCount = 0;
                        int totalRects = 0;
                        for (int tileIndex = 0; tileIndex < renderedTileCount; tileIndex++)
                        {
                            bool current = highlight[tileGridPos.X, tileGridPos.Y];
                            if (current)
                            {
                                // Try to merge consecutive rects in the same line to reduce drawcalls / CPU load
                                bool hasNext = (tileGridPos.X + 1 < highlight.Width) && ((tileGridPos.X + 1 - cullingOut.VisibleTileStart.X) < cullingOut.VisibleTileCount.X);
                                bool next = hasNext ? highlight[tileGridPos.X + 1, tileGridPos.Y] : false;
                                if (next)
                                {
                                    lineMergeCount++;
                                }
                                else
                                {
                                    totalRects++;
                                    canvas.FillRect(
                                        transform.Pos.X + renderPos.X - lineMergeCount * tileXStep.X,
                                        transform.Pos.Y + renderPos.Y - lineMergeCount * tileXStep.Y,
                                        transform.Pos.Z,
                                        tileSize.X * (1 + lineMergeCount),
                                        tileSize.Y);
                                    lineMergeCount = 0;
                                }
                            }

                            tileGridPos.X++;
                            renderPos += tileXStep;
                            if ((tileGridPos.X - cullingOut.VisibleTileStart.X) >= cullingOut.VisibleTileCount.X)
                            {
                                tileGridPos.X = cullingOut.VisibleTileStart.X;
                                tileGridPos.Y++;
                                renderPos = renderStartPos;
                                renderPos += tileYStep * (tileGridPos.Y - cullingOut.VisibleTileStart.Y);
                            }
                        }
                    }
                }

                // Draw highlight area outlines, unless flagged as uncertain
                if (!uncertain)
                {
                    // Determine the outlines of individual highlighted tile patches
                    if (outlineCache == null) outlineCache = new List<Vector2[]>();
                    if (outlineCache.Count == 0)
                    {
                        GetTileAreaOutlines(highlight, tileSize, ref outlineCache);
                    }

                    // Draw outlines around all highlighted tile patches
                    canvas.State.SetMaterial(selection ? strippleMaterial : defaultMaterial);
                    canvas.State.ColorTint = outlineTint;
                    foreach (Vector2[] outline in outlineCache)
                    {
                        // For strippled-line display, determine total length of outline
                        if (selection)
                        {
                            float totalLength = 0.0f;
                            for (int i = 1; i < outline.Length; i++)
                            {
                                totalLength += (outline[i - 1] - outline[i]).Length;
                            }
                            canvas.State.TextureCoordinateRect = new Rect(totalLength / strippledLineTex.PixelWidth, 1.0f);
                        }

                        // Draw the outline
                        canvas.DrawPolygon(
                            outline,
                            transform.Pos.X + worldOriginPos.X,
                            transform.Pos.Y + worldOriginPos.Y,
                            transform.Pos.Z);
                    }
                }

                // If this is an uncertain highlight, i.e. not actually reflecting the represented action,
                // draw a gizmo to indicate this for the user.
                if (uncertain)
                {
                    Vector2 highlightSize = new Vector2(highlight.Width * tileSize.X, highlight.Height * tileSize.Y);
                    Vector2 highlightCenter = highlightSize * 0.5f;

                    Vector3 circlePos = transform.Pos + new Vector3(worldOriginPos + worldAxisX * highlightCenter + worldAxisY * highlightCenter);
                    float circleRadius = MathF.Min(tileSize.X, tileSize.Y) * 0.2f;

                    canvas.State.SetMaterial(defaultMaterial);
                    canvas.State.ColorTint = outlineTint;
                    canvas.FillCircle(
                        circlePos.X,
                        circlePos.Y,
                        circlePos.Z,
                        circleRadius);
                }
            }
            canvas.PopState();
        }
        protected void PrepareVerticesLightSmooth(ref VertexC1P3T4A4A1[] vertices, IDrawDevice device, float curAnimFrameFade, ColorRgba mainClr, Rect uvRect, Rect uvRectNext, DrawTechnique tech)
        {
            bool perPixel = tech is LightingTechnique;

            Vector3 pos       = this.GameObj.Transform.Pos;
            Vector3 posTemp   = pos;
            float   scaleTemp = 1.0f;

            device.PreprocessCoords(ref posTemp, ref scaleTemp);

            Vector2 xDot, yDot;
            float   rotation = this.GameObj.Transform.Angle;

            MathF.GetTransformDotVec(rotation, out xDot, out yDot);

            Rect    rectTemp = this.rect.Transformed(this.GameObj.Transform.Scale, this.GameObj.Transform.Scale);
            Vector2 edge1    = rectTemp.TopLeft;
            Vector2 edge2    = rectTemp.BottomLeft;
            Vector2 edge3    = rectTemp.BottomRight;
            Vector2 edge4    = rectTemp.TopRight;

            MathF.TransformDotVec(ref edge1, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge2, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge3, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge4, ref xDot, ref yDot);

            // Using Per-Vertex Lighting? Calculate vertex light values
            Vector4[] vertexLight = null;
            if (!perPixel)
            {
                vertexLight = new Vector4[4];
                Light.GetLightAtWorldPos(pos + new Vector3(edge1), out vertexLight[0], this.vertexTranslucency);
                Light.GetLightAtWorldPos(pos + new Vector3(edge2), out vertexLight[1], this.vertexTranslucency);
                Light.GetLightAtWorldPos(pos + new Vector3(edge3), out vertexLight[2], this.vertexTranslucency);
                Light.GetLightAtWorldPos(pos + new Vector3(edge4), out vertexLight[3], this.vertexTranslucency);
            }

            Vector2.Multiply(ref edge1, scaleTemp, out edge1);
            Vector2.Multiply(ref edge2, scaleTemp, out edge2);
            Vector2.Multiply(ref edge3, scaleTemp, out edge3);
            Vector2.Multiply(ref edge4, scaleTemp, out edge4);

            // Using Per-Pixel Lighting? Pass objRotation Matrix via vertex attribute.
            Vector4 objRotMat = Vector4.Zero;

            if (perPixel)
            {
                objRotMat = new Vector4((float)Math.Cos(-rotation), -(float)Math.Sin(-rotation), (float)Math.Sin(-rotation), (float)Math.Cos(-rotation));
            }

            if (vertices == null || vertices.Length != 4)
            {
                vertices = new VertexC1P3T4A4A1[4];
            }

            // Calculate UV coordinates
            float left       = uvRect.X;
            float right      = uvRect.RightX;
            float top        = uvRect.Y;
            float bottom     = uvRect.BottomY;
            float nextLeft   = uvRectNext.X;
            float nextRight  = uvRectNext.RightX;
            float nextTop    = uvRectNext.Y;
            float nextBottom = uvRectNext.BottomY;

            if ((this.flipMode & FlipMode.Horizontal) != FlipMode.None)
            {
                MathF.Swap(ref left, ref right);
                MathF.Swap(ref nextLeft, ref nextRight);
            }
            if ((this.flipMode & FlipMode.Vertical) != FlipMode.None)
            {
                MathF.Swap(ref top, ref bottom);
                MathF.Swap(ref nextTop, ref nextBottom);
            }

            // Directly pass World Position with each vertex, see note in Light.cs
            vertices[0].Pos.X      = posTemp.X + edge1.X;
            vertices[0].Pos.Y      = posTemp.Y + edge1.Y;
            vertices[0].Pos.Z      = posTemp.Z + this.VertexZOffset;
            vertices[0].TexCoord.X = left;
            vertices[0].TexCoord.Y = top;
            vertices[0].TexCoord.Z = nextLeft;
            vertices[0].TexCoord.W = nextTop;
            vertices[0].Color      = mainClr;
            vertices[0].Attrib     = perPixel ? objRotMat : vertexLight[0];
            vertices[0].Attrib2    = curAnimFrameFade;

            vertices[1].Pos.X      = posTemp.X + edge2.X;
            vertices[1].Pos.Y      = posTemp.Y + edge2.Y;
            vertices[1].Pos.Z      = posTemp.Z + this.VertexZOffset;
            vertices[1].TexCoord.X = left;
            vertices[1].TexCoord.Y = bottom;
            vertices[1].TexCoord.Z = nextLeft;
            vertices[1].TexCoord.W = nextBottom;
            vertices[1].Color      = mainClr;
            vertices[1].Attrib     = perPixel ? objRotMat : vertexLight[1];
            vertices[1].Attrib2    = curAnimFrameFade;

            vertices[2].Pos.X      = posTemp.X + edge3.X;
            vertices[2].Pos.Y      = posTemp.Y + edge3.Y;
            vertices[2].Pos.Z      = posTemp.Z + this.VertexZOffset;
            vertices[2].TexCoord.X = right;
            vertices[2].TexCoord.Y = bottom;
            vertices[2].TexCoord.Z = nextRight;
            vertices[2].TexCoord.W = nextBottom;
            vertices[2].Color      = mainClr;
            vertices[2].Attrib     = perPixel ? objRotMat : vertexLight[2];
            vertices[2].Attrib2    = curAnimFrameFade;

            vertices[3].Pos.X      = posTemp.X + edge4.X;
            vertices[3].Pos.Y      = posTemp.Y + edge4.Y;
            vertices[3].Pos.Z      = posTemp.Z + this.VertexZOffset;
            vertices[3].TexCoord.X = right;
            vertices[3].TexCoord.Y = top;
            vertices[3].TexCoord.Z = nextRight;
            vertices[3].TexCoord.W = nextTop;
            vertices[3].Color      = mainClr;
            vertices[3].Attrib     = perPixel ? objRotMat : vertexLight[3];
            vertices[3].Attrib2    = curAnimFrameFade;

            if (this.pixelGrid)
            {
                vertices[0].Pos.X = MathF.Round(vertices[0].Pos.X);
                vertices[1].Pos.X = MathF.Round(vertices[1].Pos.X);
                vertices[2].Pos.X = MathF.Round(vertices[2].Pos.X);
                vertices[3].Pos.X = MathF.Round(vertices[3].Pos.X);

                if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2)
                {
                    vertices[0].Pos.X += 0.5f;
                    vertices[1].Pos.X += 0.5f;
                    vertices[2].Pos.X += 0.5f;
                    vertices[3].Pos.X += 0.5f;
                }

                vertices[0].Pos.Y = MathF.Round(vertices[0].Pos.Y);
                vertices[1].Pos.Y = MathF.Round(vertices[1].Pos.Y);
                vertices[2].Pos.Y = MathF.Round(vertices[2].Pos.Y);
                vertices[3].Pos.Y = MathF.Round(vertices[3].Pos.Y);

                if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2)
                {
                    vertices[0].Pos.Y += 0.5f;
                    vertices[1].Pos.Y += 0.5f;
                    vertices[2].Pos.Y += 0.5f;
                    vertices[3].Pos.Y += 0.5f;
                }
            }
        }
Example #26
0
        public override void Draw(IDrawDevice device)
        {
            if (this.particles == null)
            {
                return;
            }

            Texture tex = this.RetrieveTexture();

            if (tex == null)
            {
                return;
            }

            Vector2 particleHalfSize = this.particleSize * 0.5f;
            float   objAngle;
            float   objScale;
            Vector3 objPos;

            if (this.worldSpace)
            {
                objAngle = 0.0f;
                objScale = 1.0f;
                objPos   = Vector3.Zero;
            }
            else
            {
                objAngle = this.GameObj.Transform.Angle;
                objScale = this.GameObj.Transform.Scale;
                objPos   = this.GameObj.Transform.Pos;
            }

            Vector2 objXDot, objYDot;

            MathF.GetTransformDotVec(objAngle, objScale, out objXDot, out objYDot);

            if (this.vertexBuffer == null)
            {
                this.vertexBuffer = new RawList <VertexC1P3T2>(this.particles.Count * 4);
            }
            this.vertexBuffer.Count = this.vertexBuffer.Count = this.particles.Count * 4;

            VertexC1P3T2[] vertexData    = this.vertexBuffer.Data;
            Particle[]     particleData  = this.particles.Data;
            int            particleCount = this.particles.Count;

            for (int i = 0; i < particleCount; i++)
            {
                ColorRgba color = particleData[i].Color;
                float     alpha = (float)color.A / 255.0f;
                if (this.fadeOutAt < 1.0f)
                {
                    alpha *= MathF.Clamp((1.0f - particleData[i].AgeFactor) / this.fadeOutAt, 0.0f, 1.0f);
                }
                if (this.fadeInAt > 0.0f)
                {
                    alpha *= MathF.Clamp(particleData[i].AgeFactor / this.fadeInAt, 0.0f, 1.0f);
                }
                color.A = (byte)(alpha * 255.0f);

                Rect uvRect;
                tex.LookupAtlas(particleData[i].SpriteIndex, out uvRect);

                Vector3 particlePos = particleData[i].Position;
                MathF.TransformDotVec(ref particlePos, ref objXDot, ref objYDot);
                particlePos += objPos;

                float particleAngle = objAngle + particleData[i].Angle;
                float particleScale = objScale;

                device.PreprocessCoords(ref particlePos, ref particleScale);

                Vector2 xDot, yDot;
                MathF.GetTransformDotVec(particleAngle, particleScale, out xDot, out yDot);

                Vector2 edgeTopLeft     = new Vector2(-particleHalfSize.X, -particleHalfSize.Y);
                Vector2 edgeBottomLeft  = new Vector2(-particleHalfSize.X, particleHalfSize.Y);
                Vector2 edgeBottomRight = new Vector2(particleHalfSize.X, particleHalfSize.Y);
                Vector2 edgeTopRight    = new Vector2(particleHalfSize.X, -particleHalfSize.Y);

                MathF.TransformDotVec(ref edgeTopLeft, ref xDot, ref yDot);
                MathF.TransformDotVec(ref edgeBottomLeft, ref xDot, ref yDot);
                MathF.TransformDotVec(ref edgeBottomRight, ref xDot, ref yDot);
                MathF.TransformDotVec(ref edgeTopRight, ref xDot, ref yDot);

                int vertexBaseIndex = i * 4;
                vertexData[vertexBaseIndex + 0].Pos.X      = particlePos.X + edgeTopLeft.X;
                vertexData[vertexBaseIndex + 0].Pos.Y      = particlePos.Y + edgeTopLeft.Y;
                vertexData[vertexBaseIndex + 0].Pos.Z      = particlePos.Z;
                vertexData[vertexBaseIndex + 0].TexCoord.X = uvRect.X;
                vertexData[vertexBaseIndex + 0].TexCoord.Y = uvRect.Y;
                vertexData[vertexBaseIndex + 0].Color      = color;

                vertexData[vertexBaseIndex + 1].Pos.X      = particlePos.X + edgeBottomLeft.X;
                vertexData[vertexBaseIndex + 1].Pos.Y      = particlePos.Y + edgeBottomLeft.Y;
                vertexData[vertexBaseIndex + 1].Pos.Z      = particlePos.Z;
                vertexData[vertexBaseIndex + 1].TexCoord.X = uvRect.X;
                vertexData[vertexBaseIndex + 1].TexCoord.Y = uvRect.BottomY;
                vertexData[vertexBaseIndex + 1].Color      = color;

                vertexData[vertexBaseIndex + 2].Pos.X      = particlePos.X + edgeBottomRight.X;
                vertexData[vertexBaseIndex + 2].Pos.Y      = particlePos.Y + edgeBottomRight.Y;
                vertexData[vertexBaseIndex + 2].Pos.Z      = particlePos.Z;
                vertexData[vertexBaseIndex + 2].TexCoord.X = uvRect.RightX;
                vertexData[vertexBaseIndex + 2].TexCoord.Y = uvRect.BottomY;
                vertexData[vertexBaseIndex + 2].Color      = color;

                vertexData[vertexBaseIndex + 3].Pos.X      = particlePos.X + edgeTopRight.X;
                vertexData[vertexBaseIndex + 3].Pos.Y      = particlePos.Y + edgeTopRight.Y;
                vertexData[vertexBaseIndex + 3].Pos.Z      = particlePos.Z;
                vertexData[vertexBaseIndex + 3].TexCoord.X = uvRect.RightX;
                vertexData[vertexBaseIndex + 3].TexCoord.Y = uvRect.Y;
                vertexData[vertexBaseIndex + 3].Color      = color;
            }

            device.AddVertices(this.material, VertexMode.Quads, vertexData, this.vertexBuffer.Count);
        }
Example #27
0
            public Element NextElement(bool stopAtLineBreak = false)
            {
                if (this.elemIndex >= this.parent.elements.Length) return null;
                Element elem = this.parent.elements[this.elemIndex];

                if (elem is TextElement && this.font != null)
                {
                    TextElement textElem = elem as TextElement;

                    string textToDisplay;
                    string fittingText;
                    // Word wrap by glyph / word
                    if (this.parent.maxWidth > 0 && this.parent.wrapMode != WrapMode.Element)
                    {
                        FitTextMode fitMode = FitTextMode.ByChar;
                        if (this.parent.wrapMode == WrapMode.Word)
                            fitMode = (this.lineAlign == Alignment.Right) ? FitTextMode.ByWordLeadingSpace : FitTextMode.ByWordTrailingSpace;
                        textToDisplay = textElem.Text.Substring(this.curElemWrapIndex, textElem.Text.Length - this.curElemWrapIndex);
                        fittingText = this.font.FitText(textToDisplay, this.lineAvailWidth - (this.offset.X - this.lineBeginX), fitMode);

                        // If by-word results in instant line break: Do it by glyph instead
                        if (this.offset.X == this.lineBeginX && fittingText.Length == 0 && this.parent.wrapMode == WrapMode.Word)
                            fittingText = this.font.FitText(textToDisplay, this.lineAvailWidth - (this.offset.X - this.lineBeginX), FitTextMode.ByChar);

                        // If doing it by glyph results in an instant line break: Use at least one glyph anyway
                        if (this.lineAvailWidth == this.parent.maxWidth &&
                            this.offset.X == this.lineBeginX &&
                            this.parent.maxHeight == 0 &&
                            fittingText.Length == 0) fittingText = textToDisplay.Substring(0, 1);
                    }
                    // No word wrap (or by whole element)
                    else
                    {
                        textToDisplay = textElem.Text;
                        fittingText = textElem.Text;
                    }
                    Vector2 textElemSize = this.font.MeasureText(fittingText);

                    // Perform word wrap by whole Element
                    if (this.parent.maxWidth > 0 && this.parent.wrapMode == WrapMode.Element)
                    {
                        if ((this.lineAvailWidth < this.parent.maxWidth || this.offset.X > this.lineBeginX || this.parent.maxHeight > 0) &&
                            this.offset.X + textElemSize.X > this.lineAvailWidth)
                        {
                            if (stopAtLineBreak)	return null;
                            else					this.PerformNewLine();
                            if (this.offset.Y + this.lineHeight > this.parent.maxHeight) return null;
                        }
                    }

                    this.curElemText = fittingText;
                    this.curElemVertTextIndex = this.vertTextIndex[this.fontIndex];
                    this.curElemOffset = this.offset;

                    // If it all fits: Stop wrap mode, proceed with next element
                    if (fittingText.Length == textToDisplay.Length)
                    {
                        this.curElemWrapIndex = 0;
                        this.elemIndex++;
                    }
                    // If only some part fits: Move wrap index & return
                    else if (fittingText.Length > 0)
                    {
                        this.curElemWrapIndex += fittingText.Length;
                    }
                    // If nothing fits: Begin a new line & return
                    else
                    {
                        if (stopAtLineBreak)	return null;
                        else					this.PerformNewLine();
                        if (this.parent.maxHeight != 0 && this.offset.Y + this.lineHeight > this.parent.maxHeight) return null;
                    }

                    this.vertTextIndex[this.fontIndex] += fittingText.Length * 4;
                    this.offset.X += textElemSize.X;
                    this.lineWidth += textElemSize.X;
                    this.lineHeight = Math.Max(this.lineHeight, this.font.LineSpacing);
                    this.lineBaseLine = Math.Max(this.lineBaseLine, this.font.BaseLine);
                }
                else if (elem is TextElement && this.font == null)
                {
                    this.elemIndex++;
                }
                else if (elem is IconElement)
                {
                    IconElement iconElem = elem as IconElement;
                    bool iconValid = this.parent.icons != null && iconElem.IconIndex >= 0 && iconElem.IconIndex < this.parent.icons.Length;
                    Icon icon = iconValid ? this.parent.icons[iconElem.IconIndex] : new Icon();

                    // Word Wrap
                    if (this.parent.maxWidth > 0)
                    {
                        while ((this.lineAvailWidth < this.parent.maxWidth || this.offset.X > this.lineBeginX || this.parent.maxHeight > 0) &&
                            this.offset.X - this.lineBeginX + icon.size.X > this.lineAvailWidth)
                        {
                            if (stopAtLineBreak)	return null;
                            else					this.PerformNewLine();
                            if (this.offset.Y + this.lineHeight > this.parent.maxHeight) return null;
                        }
                    }

                    this.curElemVertIconIndex = this.vertIconIndex;
                    this.curElemOffset = this.offset;

                    this.vertIconIndex += 4;
                    this.offset.X += icon.size.X;
                    this.lineWidth += icon.size.X;
                    this.lineHeight = Math.Max(this.lineHeight, icon.size.Y);
                    this.lineBaseLine = Math.Max(this.lineBaseLine, (int)Math.Round(icon.size.Y));
                    this.elemIndex++;
                }
                else if (elem is FontChangeElement)
                {
                    FontChangeElement fontChangeElem = elem as FontChangeElement;
                    this.fontIndex = fontChangeElem.FontIndex;

                    bool fontValid = this.parent.fonts != null && this.fontIndex >= 0 && this.fontIndex < this.parent.fonts.Length;
                    ContentRef<Font> font = fontValid ? this.parent.fonts[this.fontIndex] : null;
                    this.font = font.Res;
                    this.elemIndex++;
                }
                else if (elem is ColorChangeElement)
                {
                    ColorChangeElement colorChangeElem = elem as ColorChangeElement;
                    this.color = colorChangeElem.Color;
                    this.elemIndex++;
                }
                else if (elem is AlignChangeElement)
                {
                    AlignChangeElement alignChangeElem = elem as AlignChangeElement;
                    this.lineAlign = alignChangeElem.Align;
                    this.elemIndex++;
                }
                else if (elem is NewLineElement)
                {
                    this.elemIndex++;
                    if (stopAtLineBreak)	return null;
                    else					this.PerformNewLine();
                    if (this.parent.maxHeight != 0 && this.offset.Y + this.lineHeight > this.parent.maxHeight) return null;
                }

                return elem;
            }
Example #28
0
        public override void Draw(IDrawDevice device)
        {
            // Determine basic working data
            Tilemap tilemap   = this.ActiveTilemap;
            Tileset tileset   = tilemap != null ? tilemap.Tileset.Res : null;
            Point2  tileCount = tilemap != null ? tilemap.Size : new Point2(1, 1);
            Vector2 tileSize  = tileset != null ? tileset.TileSize : Tileset.DefaultTileSize;

            // Early-out, if insufficient
            if (tilemap == null)
            {
                return;
            }
            if (tileset == null)
            {
                return;
            }

            // Determine the total size and origin of the rendered Tilemap
            Vector2 renderTotalSize = tileCount * tileSize;
            Vector2 renderOrigin    = Vector2.Zero;

            this.origin.ApplyTo(ref renderOrigin, ref renderTotalSize);
            MathF.TransformCoord(ref renderOrigin.X, ref renderOrigin.Y, this.GameObj.Transform.Angle, this.GameObj.Transform.Scale);

            // Determine Tile visibility
            TilemapCulling.TileInput cullingIn = new TilemapCulling.TileInput
            {
                // Remember: All these transform values are in world space
                TilemapPos   = this.GameObj.Transform.Pos + new Vector3(renderOrigin),
                TilemapScale = this.GameObj.Transform.Scale,
                TilemapAngle = this.GameObj.Transform.Angle,
                TileCount    = tileCount,
                TileSize     = tileSize
            };
            TilemapCulling.TileOutput cullingOut = TilemapCulling.GetVisibleTileRect(device, cullingIn);
            int renderedTileCount = cullingOut.VisibleTileCount.X * cullingOut.VisibleTileCount.Y;

            // Determine rendering parameters
            Material  material  = (tileset != null ? tileset.RenderMaterial : null) ?? Material.Checkerboard.Res;
            ColorRgba mainColor = this.colorTint;

            // Reserve the required space for vertex data in our locally cached buffer
            if (this.vertices == null)
            {
                this.vertices = new RawList <VertexC1P3T2>();
            }
            this.vertices.Count = renderedTileCount * 4;
            VertexC1P3T2[] vertexData = this.vertices.Data;

            // Determine and adjust data for Z offset generation
            float depthPerTile = -cullingIn.TileSize.Y * cullingIn.TilemapScale * this.tileDepthScale;

            if (this.tileDepthMode == TileDepthOffsetMode.Flat)
            {
                depthPerTile = 0.0f;
            }

            float originDepthOffset = Rect.Align(this.origin, 0, 0, 0, tileCount.Y * depthPerTile).Y;

            if (this.tileDepthMode == TileDepthOffsetMode.World)
            {
                originDepthOffset += (this.GameObj.Transform.Pos.Y / (float)tileSize.Y) * depthPerTile;
            }

            float renderBaseOffset = this.offset + this.tileDepthOffset * depthPerTile + originDepthOffset;

            // Prepare vertex generation data
            Vector2 tileXStep    = cullingOut.XAxisWorld * cullingIn.TileSize.X;
            Vector2 tileYStep    = cullingOut.YAxisWorld * cullingIn.TileSize.Y;
            Vector3 renderPos    = cullingOut.RenderOriginWorld;
            float   renderOffset = renderBaseOffset;
            Point2  tileGridPos  = cullingOut.VisibleTileStart;

            // Prepare vertex data array for batch-submitting
            IReadOnlyGrid <Tile> tiles = tilemap.Tiles;

            TileInfo[] tileData           = tileset.TileData.Data;
            int        submittedTileCount = 0;
            int        vertexBaseIndex    = 0;

            for (int tileIndex = 0; tileIndex < renderedTileCount; tileIndex++)
            {
                Tile tile = tiles[tileGridPos.X, tileGridPos.Y];
                if (tile.Index < tileData.Length)
                {
                    Rect  uvRect           = tileData[tile.Index].TexCoord0;
                    bool  visualEmpty      = tileData[tile.Index].IsVisuallyEmpty;
                    int   tileBaseOffset   = tileData[tile.Index].DepthOffset;
                    float localDepthOffset = (tile.DepthOffset + tileBaseOffset) * depthPerTile;

                    if (!visualEmpty)
                    {
                        vertexData[vertexBaseIndex + 0].Pos.X       = renderPos.X;
                        vertexData[vertexBaseIndex + 0].Pos.Y       = renderPos.Y;
                        vertexData[vertexBaseIndex + 0].Pos.Z       = renderPos.Z;
                        vertexData[vertexBaseIndex + 0].DepthOffset = renderOffset + localDepthOffset;
                        vertexData[vertexBaseIndex + 0].TexCoord.X  = uvRect.X;
                        vertexData[vertexBaseIndex + 0].TexCoord.Y  = uvRect.Y;
                        vertexData[vertexBaseIndex + 0].Color       = mainColor;

                        vertexData[vertexBaseIndex + 1].Pos.X       = renderPos.X + tileYStep.X;
                        vertexData[vertexBaseIndex + 1].Pos.Y       = renderPos.Y + tileYStep.Y;
                        vertexData[vertexBaseIndex + 1].Pos.Z       = renderPos.Z;
                        vertexData[vertexBaseIndex + 1].DepthOffset = renderOffset + localDepthOffset + depthPerTile;
                        vertexData[vertexBaseIndex + 1].TexCoord.X  = uvRect.X;
                        vertexData[vertexBaseIndex + 1].TexCoord.Y  = uvRect.Y + uvRect.H;
                        vertexData[vertexBaseIndex + 1].Color       = mainColor;

                        vertexData[vertexBaseIndex + 2].Pos.X       = renderPos.X + tileXStep.X + tileYStep.X;
                        vertexData[vertexBaseIndex + 2].Pos.Y       = renderPos.Y + tileXStep.Y + tileYStep.Y;
                        vertexData[vertexBaseIndex + 2].Pos.Z       = renderPos.Z;
                        vertexData[vertexBaseIndex + 2].DepthOffset = renderOffset + localDepthOffset + depthPerTile;
                        vertexData[vertexBaseIndex + 2].TexCoord.X  = uvRect.X + uvRect.W;
                        vertexData[vertexBaseIndex + 2].TexCoord.Y  = uvRect.Y + uvRect.H;
                        vertexData[vertexBaseIndex + 2].Color       = mainColor;

                        vertexData[vertexBaseIndex + 3].Pos.X       = renderPos.X + tileXStep.X;
                        vertexData[vertexBaseIndex + 3].Pos.Y       = renderPos.Y + tileXStep.Y;
                        vertexData[vertexBaseIndex + 3].Pos.Z       = renderPos.Z;
                        vertexData[vertexBaseIndex + 3].DepthOffset = renderOffset + localDepthOffset;
                        vertexData[vertexBaseIndex + 3].TexCoord.X  = uvRect.X + uvRect.W;
                        vertexData[vertexBaseIndex + 3].TexCoord.Y  = uvRect.Y;
                        vertexData[vertexBaseIndex + 3].Color       = mainColor;

                        bool vertical = tileData[tile.Index].IsVertical;
                        if (vertical)
                        {
                            vertexData[vertexBaseIndex + 0].DepthOffset += depthPerTile;
                            vertexData[vertexBaseIndex + 3].DepthOffset += depthPerTile;
                        }

                        submittedTileCount++;
                        vertexBaseIndex += 4;
                    }
                }

                tileGridPos.X++;
                renderPos.X += tileXStep.X;
                renderPos.Y += tileXStep.Y;
                if ((tileGridPos.X - cullingOut.VisibleTileStart.X) >= cullingOut.VisibleTileCount.X)
                {
                    tileGridPos.X = cullingOut.VisibleTileStart.X;
                    tileGridPos.Y++;
                    renderPos    = cullingOut.RenderOriginWorld;
                    renderPos.X += tileYStep.X * (tileGridPos.Y - cullingOut.VisibleTileStart.Y);
                    renderPos.Y += tileYStep.Y * (tileGridPos.Y - cullingOut.VisibleTileStart.Y);
                    renderOffset = renderBaseOffset + tileGridPos.Y * depthPerTile;
                }
            }

            // Submit all the vertices as one draw batch
            device.AddVertices(
                material,
                VertexMode.Quads,
                vertexData,
                submittedTileCount * 4);

            Profile.AddToStat(@"Duality\Stats\Render\Tilemaps\NumTiles", renderedTileCount);
            Profile.AddToStat(@"Duality\Stats\Render\Tilemaps\NumVertices", submittedTileCount * 4);
        }
		protected void PrepareVerticesLightSmooth(ref VertexC1P3T4A4A1[] vertices, IDrawDevice device, float curAnimFrameFade, ColorRgba mainClr, Rect uvRect, Rect uvRectNext, DrawTechnique tech)
		{
			bool perPixel = tech is LightingTechnique;

			Vector3 pos = this.GameObj.Transform.Pos;
			Vector3 posTemp = pos;
			float scaleTemp = 1.0f;
			device.PreprocessCoords(ref posTemp, ref scaleTemp);

			Vector2 xDot, yDot;
			float rotation = this.GameObj.Transform.Angle;
			MathF.GetTransformDotVec(rotation, out xDot, out yDot);

			Rect rectTemp = this.rect.Transformed(this.GameObj.Transform.Scale, this.GameObj.Transform.Scale);
			Vector2 edge1 = rectTemp.TopLeft;
			Vector2 edge2 = rectTemp.BottomLeft;
			Vector2 edge3 = rectTemp.BottomRight;
			Vector2 edge4 = rectTemp.TopRight;

			MathF.TransformDotVec(ref edge1, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge2, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge3, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge4, ref xDot, ref yDot);

			// Using Per-Vertex Lighting? Calculate vertex light values
			Vector4[] vertexLight = null;
			if (!perPixel)
			{
				vertexLight = new Vector4[4];
				Light.GetLightAtWorldPos(pos + new Vector3(edge1), out vertexLight[0], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge2), out vertexLight[1], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge3), out vertexLight[2], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge4), out vertexLight[3], this.vertexTranslucency);
			}

			Vector2.Multiply(ref edge1, scaleTemp, out edge1);
			Vector2.Multiply(ref edge2, scaleTemp, out edge2);
			Vector2.Multiply(ref edge3, scaleTemp, out edge3);
			Vector2.Multiply(ref edge4, scaleTemp, out edge4);

			// Using Per-Pixel Lighting? Pass objRotation Matrix via vertex attribute.
			Vector4 objRotMat = Vector4.Zero;
			if (perPixel)
				objRotMat = new Vector4((float)Math.Cos(-rotation), -(float)Math.Sin(-rotation), (float)Math.Sin(-rotation), (float)Math.Cos(-rotation));

			if (vertices == null || vertices.Length != 4) vertices = new VertexC1P3T4A4A1[4];
			
			// Calculate UV coordinates
			float left       = uvRect.X;
			float right      = uvRect.RightX;
			float top        = uvRect.Y;
			float bottom     = uvRect.BottomY;
			float nextLeft   = uvRectNext.X;
			float nextRight  = uvRectNext.RightX;
			float nextTop    = uvRectNext.Y;
			float nextBottom = uvRectNext.BottomY;

			if ((this.flipMode & FlipMode.Horizontal) != FlipMode.None)
			{
				MathF.Swap(ref left, ref right);
				MathF.Swap(ref nextLeft, ref nextRight);
			}
			if ((this.flipMode & FlipMode.Vertical) != FlipMode.None)
			{
				MathF.Swap(ref top, ref bottom);
				MathF.Swap(ref nextTop, ref nextBottom);
			}

			// Directly pass World Position with each vertex, see note in Light.cs
			vertices[0].Pos.X = posTemp.X + edge1.X;
			vertices[0].Pos.Y = posTemp.Y + edge1.Y;
			vertices[0].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[0].TexCoord.X = left;
			vertices[0].TexCoord.Y = top;
			vertices[0].TexCoord.Z = nextLeft;
			vertices[0].TexCoord.W = nextTop;
			vertices[0].Color = mainClr;
			vertices[0].Attrib = perPixel ? objRotMat : vertexLight[0];
			vertices[0].Attrib2 = curAnimFrameFade;

			vertices[1].Pos.X = posTemp.X + edge2.X;
			vertices[1].Pos.Y = posTemp.Y + edge2.Y;
			vertices[1].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[1].TexCoord.X = left;
			vertices[1].TexCoord.Y = bottom;
			vertices[1].TexCoord.Z = nextLeft;
			vertices[1].TexCoord.W = nextBottom;
			vertices[1].Color = mainClr;
			vertices[1].Attrib = perPixel ? objRotMat : vertexLight[1];
			vertices[1].Attrib2 = curAnimFrameFade;

			vertices[2].Pos.X = posTemp.X + edge3.X;
			vertices[2].Pos.Y = posTemp.Y + edge3.Y;
			vertices[2].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[2].TexCoord.X = right;
			vertices[2].TexCoord.Y = bottom;
			vertices[2].TexCoord.Z = nextRight;
			vertices[2].TexCoord.W = nextBottom;
			vertices[2].Color = mainClr;
			vertices[2].Attrib = perPixel ? objRotMat : vertexLight[2];
			vertices[2].Attrib2 = curAnimFrameFade;
				
			vertices[3].Pos.X = posTemp.X + edge4.X;
			vertices[3].Pos.Y = posTemp.Y + edge4.Y;
			vertices[3].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[3].TexCoord.X = right;
			vertices[3].TexCoord.Y = top;
			vertices[3].TexCoord.Z = nextRight;
			vertices[3].TexCoord.W = nextTop;
			vertices[3].Color = mainClr;
			vertices[3].Attrib = perPixel ? objRotMat : vertexLight[3];
			vertices[3].Attrib2 = curAnimFrameFade;
			
			if (this.pixelGrid)
			{
				vertices[0].Pos.X = MathF.Round(vertices[0].Pos.X);
				vertices[1].Pos.X = MathF.Round(vertices[1].Pos.X);
				vertices[2].Pos.X = MathF.Round(vertices[2].Pos.X);
				vertices[3].Pos.X = MathF.Round(vertices[3].Pos.X);

				if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2)
				{
					vertices[0].Pos.X += 0.5f;
					vertices[1].Pos.X += 0.5f;
					vertices[2].Pos.X += 0.5f;
					vertices[3].Pos.X += 0.5f;
				}

				vertices[0].Pos.Y = MathF.Round(vertices[0].Pos.Y);
				vertices[1].Pos.Y = MathF.Round(vertices[1].Pos.Y);
				vertices[2].Pos.Y = MathF.Round(vertices[2].Pos.Y);
				vertices[3].Pos.Y = MathF.Round(vertices[3].Pos.Y);

				if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2)
				{
					vertices[0].Pos.Y += 0.5f;
					vertices[1].Pos.Y += 0.5f;
					vertices[2].Pos.Y += 0.5f;
					vertices[3].Pos.Y += 0.5f;
				}
			}
		}
Example #30
0
        public void MergeTiles(string path, int offset, int count)
        {
            ContentRef <Material> material;
            PixelData             mask;

            ContentResolver.Current.RequestTileset(path, out material, out mask);

            Materials.Add(material);

            PixelData texture = material.Res.MainTexture.Res.BasePixmap.Res.MainLayer;

            int width  = (texture.Width / TileSize);
            int height = (texture.Height / TileSize);

            isMaskEmpty.Length  += count;
            isMaskFilled.Length += count;
            isTileFilled.Length += count;

            int partStart = defaultLayerTiles.Count;

            for (int i = 0; i < count; i++)
            {
                int ty = (offset + i) / width;
                int tx = (offset + i) % width;

                BitArray tileMask   = new BitArray(TileSize * TileSize);
                bool     maskEmpty  = true;
                bool     maskFilled = true;
                bool     tileFilled = true;
                for (int x = 0; x < TileSize; x++)
                {
                    for (int y = 0; y < TileSize; y++)
                    {
                        ColorRgba px = mask[tx * TileSize + x, ty *TileSize + y];
                        // Consider any fully white or fully transparent pixel in the masks as non-solid and all others as solid
                        bool masked = (px != ColorRgba.White && px.A > 0);
                        tileMask[x + TileSize * y] = masked;
                        maskEmpty  &= !masked;
                        maskFilled &= masked;

                        ColorRgba pxTex = texture[tx * TileSize + x, ty *TileSize + y];
                        masked      = (pxTex.A > 20);
                        tileFilled &= masked;
                    }
                }

                masks.Add(tileMask);

                int idx = (partStart + i);
                isMaskEmpty[idx]  = maskEmpty;
                isMaskFilled[idx] = maskFilled;

                isTileFilled[idx] = tileFilled || !maskEmpty;

                defaultLayerTiles.Add(new LayerTile {
                    TileID = idx,

                    Material       = material,
                    MaterialOffset = new Point2(tx * TileSize, ty * TileSize),
                    MaterialAlpha  = 255
                });
            }

            IsValid = true;
        }
Example #31
0
        public TileSet(string path)
        {
            Materials = new RawList <ContentRef <Material> >();

            ContentRef <Material> material;
            PixelData             mask;

            ContentResolver.Current.RequestTileset(path, out material, out mask);

            Materials.Add(material);

            TileSize = DefaultTileSize;

            PixelData texture = material.Res.MainTexture.Res.BasePixmap.Res.MainLayer;

            int width  = (texture.Width / TileSize);
            int height = (texture.Height / TileSize);

            TilesPerRow = width;
            int tileCount = width * height;

            masks        = new RawList <BitArray>();
            isMaskEmpty  = new BitArray(tileCount);
            isMaskFilled = new BitArray(tileCount);

            isTileFilled = new BitArray(tileCount);

            defaultLayerTiles = new RawList <LayerTile>();

            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    BitArray tileMask   = new BitArray(TileSize * TileSize);
                    bool     maskEmpty  = true;
                    bool     maskFilled = true;
                    bool     tileFilled = true;
                    for (int x = 0; x < TileSize; x++)
                    {
                        for (int y = 0; y < TileSize; y++)
                        {
                            ColorRgba px = mask[j * TileSize + x, i *TileSize + y];
                            // Consider any fully white or fully transparent pixel in the masks as non-solid and all others as solid
                            bool masked = (px != ColorRgba.White && px.A > 0);
                            tileMask[x + TileSize * y] = masked;
                            maskEmpty  &= !masked;
                            maskFilled &= masked;

                            ColorRgba pxTex = texture[j * TileSize + x, i *TileSize + y];
                            masked      = (pxTex.A > 20);
                            tileFilled &= masked;
                        }
                    }

                    masks.Add(tileMask);

                    int idx = (j + width * i);
                    isMaskEmpty[idx]  = maskEmpty;
                    isMaskFilled[idx] = maskFilled;

                    isTileFilled[idx] = tileFilled || !maskEmpty;

                    defaultLayerTiles.Add(new LayerTile {
                        TileID = idx,

                        Material       = material,
                        MaterialOffset = new Point2(TileSize * ((i * width + j) % TilesPerRow), TileSize * ((i * width + j) / TilesPerRow)),
                        MaterialAlpha  = 255
                    });
                }
            }

            IsValid = true;
        }
		protected void PrepareVerticesLight(ref VertexC1P3T2A4[] vertices, IDrawDevice device, ColorRgba mainClr, Rect uvRect, DrawTechnique tech)
		{
			bool perPixel = tech is LightingTechnique;

			Vector3 pos = this.GameObj.Transform.Pos;
			Vector3 posTemp = pos;
			float scaleTemp = 1.0f;
			device.PreprocessCoords(ref posTemp, ref scaleTemp);

			Vector2 xDot, yDot;
			float rotation = this.GameObj.Transform.Angle;
			MathF.GetTransformDotVec(rotation, out xDot, out yDot);

			Rect rectTemp = this.rect.Transform(this.GameObj.Transform.Scale, this.GameObj.Transform.Scale);
			Vector2 edge1 = rectTemp.TopLeft;
			Vector2 edge2 = rectTemp.BottomLeft;
			Vector2 edge3 = rectTemp.BottomRight;
			Vector2 edge4 = rectTemp.TopRight;

			MathF.TransformDotVec(ref edge1, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge2, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge3, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge4, ref xDot, ref yDot);

			// Using Per-Vertex Lighting? Calculate vertex light values
			Vector4[] vertexLight = null;
			if (!perPixel)
			{
				vertexLight = new Vector4[4];
				Light.GetLightAtWorldPos(pos + new Vector3(edge1), out vertexLight[0], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge2), out vertexLight[1], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge3), out vertexLight[2], this.vertexTranslucency);
				Light.GetLightAtWorldPos(pos + new Vector3(edge4), out vertexLight[3], this.vertexTranslucency);
			}

			Vector2.Multiply(ref edge1, scaleTemp, out edge1);
			Vector2.Multiply(ref edge2, scaleTemp, out edge2);
			Vector2.Multiply(ref edge3, scaleTemp, out edge3);
			Vector2.Multiply(ref edge4, scaleTemp, out edge4);

			// Using Per-Pixel Lighting? Pass objRotation Matrix via vertex attribute.
			Vector4 objRotMat = Vector4.Zero;
			if (perPixel)
				objRotMat = new Vector4((float)Math.Cos(-rotation), -(float)Math.Sin(-rotation), (float)Math.Sin(-rotation), (float)Math.Cos(-rotation));

			if (vertices == null || vertices.Length != 4) vertices = new VertexC1P3T2A4[4];

			vertices[0].Pos.X = posTemp.X + edge1.X;
			vertices[0].Pos.Y = posTemp.Y + edge1.Y;
			vertices[0].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[0].TexCoord.X = uvRect.X;
			vertices[0].TexCoord.Y = uvRect.Y;
			vertices[0].Color = mainClr;
			vertices[0].Attrib = perPixel ? objRotMat : vertexLight[0];

			vertices[1].Pos.X = posTemp.X + edge2.X;
			vertices[1].Pos.Y = posTemp.Y + edge2.Y;
			vertices[1].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[1].TexCoord.X = uvRect.X;
			vertices[1].TexCoord.Y = uvRect.MaximumY;
			vertices[1].Color = mainClr;
			vertices[1].Attrib = perPixel ? objRotMat : vertexLight[1];

			vertices[2].Pos.X = posTemp.X + edge3.X;
			vertices[2].Pos.Y = posTemp.Y + edge3.Y;
			vertices[2].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[2].TexCoord.X = uvRect.MaximumX;
			vertices[2].TexCoord.Y = uvRect.MaximumY;
			vertices[2].Color = mainClr;
			vertices[2].Attrib = perPixel ? objRotMat : vertexLight[2];
				
			vertices[3].Pos.X = posTemp.X + edge4.X;
			vertices[3].Pos.Y = posTemp.Y + edge4.Y;
			vertices[3].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[3].TexCoord.X = uvRect.MaximumX;
			vertices[3].TexCoord.Y = uvRect.Y;
			vertices[3].Color = mainClr;
			vertices[3].Attrib = perPixel ? objRotMat : vertexLight[3];
		}
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            Color brightChecker = Color.FromArgb(224, 224, 224);
            Color darkChecker   = Color.FromArgb(192, 192, 192);

            e.Graphics.FillRectangle(new HatchBrush(HatchStyle.LargeCheckerBoard, brightChecker, darkChecker), this.rectPanel);
            if (this.value != null)
            {
                Color val      = Color.FromArgb(this.value.ToIntArgb());
                Color valSolid = Color.FromArgb(255, val);
                e.Graphics.FillRectangle(
                    new SolidBrush(val),
                    this.rectPanel.X,
                    this.rectPanel.Y,
                    this.rectPanel.Width / 2,
                    this.rectPanel.Height);
                e.Graphics.FillRectangle(
                    new SolidBrush(valSolid),
                    this.rectPanel.X + this.rectPanel.Width / 2,
                    this.rectPanel.Y,
                    this.rectPanel.Width / 2,
                    this.rectPanel.Height);

                ColorRgba    rgba      = this.value.ConvertTo <ColorRgba>();
                Color        textColor = rgba.GetLuminance() > 0.5f ? Color.Black : Color.White;
                StringFormat format    = StringFormat.GenericDefault;
                format.Alignment     = StringAlignment.Center;
                format.LineAlignment = StringAlignment.Center;
                format.Trimming      = StringTrimming.EllipsisCharacter;
                e.Graphics.DrawString(
                    string.Format("{0}, {1}, {2}, {3}", rgba.R, rgba.G, rgba.B, rgba.A),
                    this.ControlRenderer.FontRegular,
                    new SolidBrush(Color.FromArgb(128, textColor)),
                    this.rectPanel,
                    format);
            }
            e.Graphics.DrawRectangle(SystemPens.ControlLightLight,
                                     this.rectPanel.X + 1,
                                     this.rectPanel.Y + 1,
                                     this.rectPanel.Width - 2,
                                     this.rectPanel.Height - 2);
            e.Graphics.DrawRectangle(SystemPens.ControlDark, this.rectPanel);

            ButtonState buttonCDiagState = ButtonState.Disabled;

            if (!this.ReadOnly && this.Enabled)
            {
                if (this.buttonCDiagPressed)
                {
                    buttonCDiagState = ButtonState.Pressed;
                }
                else if (this.buttonCDiagHovered)
                {
                    buttonCDiagState = ButtonState.Hot;
                }
                else
                {
                    buttonCDiagState = ButtonState.Normal;
                }
            }
            ControlRenderer.DrawButton(
                e.Graphics,
                this.rectCDiagButton,
                buttonCDiagState,
                null,
                Properties.GeneralResCache.ColorWheel);

            ButtonState buttonCPickState = ButtonState.Disabled;

            if (!this.ReadOnly && this.Enabled)
            {
                if (this.buttonCPickPressed)
                {
                    buttonCPickState = ButtonState.Pressed;
                }
                else if (this.buttonCPickHovered)
                {
                    buttonCPickState = ButtonState.Hot;
                }
                else
                {
                    buttonCPickState = ButtonState.Normal;
                }
            }
            ControlRenderer.DrawButton(
                e.Graphics,
                this.rectCPickButton,
                buttonCPickState,
                null,
                Properties.GeneralResCache.ColorPick);
        }
Example #34
0
            /// <summary>
            /// Sets the layers pixel data in the ColorRgba format. Note that the specified data will be copied and thus modifying it
            /// outside won't affect the Layer it has been inserted into.
            /// </summary>
            /// <param name="pixelData"></param>
            /// <param name="width"></param>
            /// <param name="height"></param>
            public void SetPixelDataRgba(ColorRgba[] pixelData, int width = -1, int height = -1)
            {
                if (width < 0) width = this.width;
                if (height < 0) height = this.height;
                if (pixelData.Length != width * height) throw new ArgumentException("Data length doesn't match width * height", "pixelData");

                this.width = width;
                this.height = height;
                this.data = pixelData.Clone() as ColorRgba[];
            }
        public override void OnWorldOverlayDrawcalls(Canvas canvas)
        {
            RigidBody body = this.Environment.ActiveBody;

            if (body == null)
            {
                return;
            }

            DesignTimeObjectData designTimeData = DesignTimeObjectData.Get(body.GameObj);

            if (designTimeData.IsHidden)
            {
                return;
            }

            float knobSize      = 7.0f;
            float worldKnobSize = knobSize / MathF.Max(0.0001f, canvas.DrawDevice.GetScaleAtZ(0.0f));

            // Determine the color in which we'll draw the interaction markers
            ColorRgba markerColor = this.Environment.FgColor;

            canvas.State.ZOffset = -1.0f;

            // Prepare the transform matrix for this object, so
            // we can move the RigidBody vertices into world space quickly
            Transform transform = body.GameObj.Transform;
            Vector2   bodyPos   = transform.Pos.Xy;
            Vector2   bodyDotX;
            Vector2   bodyDotY;

            MathF.GetTransformDotVec(transform.Angle, transform.Scale, out bodyDotX, out bodyDotY);

            // Draw an interaction indicator for every vertex of the active bodies shapes
            Vector3 mousePosWorld = this.Environment.ActiveWorldPos;

            foreach (ShapeInfo shape in body.Shapes)
            {
                if (shape is CircleShapeInfo)
                {
                    CircleShapeInfo circle = shape as CircleShapeInfo;

                    Vector2 circleWorldPos = circle.Position;
                    MathF.TransformDotVec(ref circleWorldPos, ref bodyDotX, ref bodyDotY);
                    circleWorldPos = bodyPos + circleWorldPos;

                    // Draw the circles center as a vertex
                    if (this.activeVertex == 0 && this.activeShape == shape)
                    {
                        canvas.State.ColorTint = markerColor;
                    }
                    else
                    {
                        canvas.State.ColorTint = markerColor.WithAlpha(0.75f);
                    }

                    canvas.FillRect(
                        circleWorldPos.X - worldKnobSize * 0.5f,
                        circleWorldPos.Y - worldKnobSize * 0.5f,
                        worldKnobSize,
                        worldKnobSize);
                }
                else
                {
                    Vector2[] vertices = this.GetVertices(shape);
                    if (vertices == null)
                    {
                        continue;
                    }

                    Vector2[] worldVertices = new Vector2[vertices.Length];

                    // Transform the shapes vertices into world space
                    for (int index = 0; index < vertices.Length; index++)
                    {
                        Vector2 vertex = vertices[index];
                        MathF.TransformDotVec(ref vertex, ref bodyDotX, ref bodyDotY);
                        worldVertices[index] = bodyPos + vertex;
                    }

                    // Draw the vertices
                    for (int i = 0; i < worldVertices.Length; i++)
                    {
                        if (this.activeVertex == i && this.activeShape == shape)
                        {
                            canvas.State.ColorTint = markerColor;
                        }
                        else
                        {
                            canvas.State.ColorTint = markerColor.WithAlpha(0.75f);
                        }

                        canvas.FillRect(
                            worldVertices[i].X - worldKnobSize * 0.5f,
                            worldVertices[i].Y - worldKnobSize * 0.5f,
                            worldKnobSize,
                            worldKnobSize);
                    }
                }
            }

            // Interaction indicator for an existing vertex
            if (this.activeVertex != -1)
            {
                canvas.State.ColorTint = markerColor;
                canvas.DrawRect(
                    this.activeEdgeWorldPos.X - worldKnobSize,
                    this.activeEdgeWorldPos.Y - worldKnobSize,
                    worldKnobSize * 2.0f,
                    worldKnobSize * 2.0f);
            }
            // Interaction indicator for a vertex-to-be-created
            else if (this.activeEdge != -1)
            {
                canvas.State.ColorTint = markerColor.WithAlpha(0.35f);
                canvas.FillRect(
                    this.activeEdgeWorldPos.X - worldKnobSize * 0.5f,
                    this.activeEdgeWorldPos.Y - worldKnobSize * 0.5f,
                    worldKnobSize * 1.0f,
                    worldKnobSize * 1.0f);
                canvas.State.ColorTint = markerColor;
                canvas.DrawRect(
                    this.activeEdgeWorldPos.X - worldKnobSize,
                    this.activeEdgeWorldPos.Y - worldKnobSize,
                    worldKnobSize * 2.0f,
                    worldKnobSize * 2.0f);
            }
        }
Example #36
0
            private ColorRgba[] InternalRescale(int w, int h, FilterMethod filter)
            {
                if (this.width == w && this.height == h) return null;

                ColorRgba[]	tempDestData	= new ColorRgba[w * h];
                if (filter == FilterMethod.Nearest)
                {
                    // Don't use Parallel.For here, the overhead is too big and the compiler
                    // does a great job optimizing this piece of code without, so don't get in the way.
                    for (int i = 0; i < tempDestData.Length; i++)
                    {
                        int y = i / w;
                        int x = i - (y * w);

                        int xTmp	= (x * this.width) / w;
                        int yTmp	= (y * this.height) / h;
                        int nTmp	= xTmp + (yTmp * this.width);
                        tempDestData[i] = this.data[nTmp];
                    }
                }
                else if (filter == FilterMethod.Linear)
                {
                    //for (int i = 0; i < tempDestData.Length; i++)
                    System.Threading.Tasks.Parallel.For(0, tempDestData.Length, i =>
                    {
                        int y = i / w;
                        int x = i - (y * w);

                        float	xRatio	= ((float)(x * this.width) / (float)w) + 0.5f;
                        float	yRatio	= ((float)(y * this.height) / (float)h) + 0.5f;
                        int		xTmp	= (int)xRatio;
                        int		yTmp	= (int)yRatio;
                        xRatio -= xTmp;
                        yRatio -= yTmp;

                        int		xTmp2	= xTmp + 1;
                        int		yTmp2	= yTmp + 1;
                        xTmp = xTmp < this.width ? xTmp : this.width - 1;
                        yTmp = (yTmp < this.height ? yTmp : this.height - 1) * this.width;
                        xTmp2 = xTmp2 < this.width ? xTmp2 : this.width - 1;
                        yTmp2 = (yTmp2 < this.height ? yTmp2 : this.height - 1) * this.width;

                        int		nTmp0	= xTmp + yTmp;
                        int		nTmp1	= xTmp2 + yTmp;
                        int		nTmp2	= xTmp + yTmp2;
                        int		nTmp3	= xTmp2 + yTmp2;

                        tempDestData[i].R =
                            (byte)
                            (
                                ((float)this.data[nTmp0].R * (1.0f - xRatio) * (1.0f - yRatio)) +
                                ((float)this.data[nTmp1].R * xRatio * (1.0f - yRatio)) +
                                ((float)this.data[nTmp2].R * yRatio * (1.0f - xRatio)) +
                                ((float)this.data[nTmp3].R * xRatio * yRatio)
                            );
                        tempDestData[i].G =
                            (byte)
                            (
                                ((float)this.data[nTmp0].G * (1.0f - xRatio) * (1.0f - yRatio)) +
                                ((float)this.data[nTmp1].G * xRatio * (1.0f - yRatio)) +
                                ((float)this.data[nTmp2].G * yRatio * (1.0f - xRatio)) +
                                ((float)this.data[nTmp3].G * xRatio * yRatio)
                            );
                        tempDestData[i].B =
                            (byte)
                            (
                                ((float)this.data[nTmp0].B * (1.0f - xRatio) * (1.0f - yRatio)) +
                                ((float)this.data[nTmp1].B * xRatio * (1.0f - yRatio)) +
                                ((float)this.data[nTmp2].B * yRatio * (1.0f - xRatio)) +
                                ((float)this.data[nTmp3].B * xRatio * yRatio)
                            );
                        tempDestData[i].A =
                            (byte)
                            (
                                ((float)this.data[nTmp0].A * (1.0f - xRatio) * (1.0f - yRatio)) +
                                ((float)this.data[nTmp1].A * xRatio * (1.0f - yRatio)) +
                                ((float)this.data[nTmp2].A * yRatio * (1.0f - xRatio)) +
                                ((float)this.data[nTmp3].A * xRatio * yRatio)
                            );
                    });
                }

                return tempDestData;
            }
Example #37
0
        protected void PrepareVertices(ref VertexC1P3T2[] vertices, IDrawDevice device, ColorRgba mainClr, Rect uvRect)
        {
            Vector3 posTemp = this.gameobj.Transform.Pos;
            float scaleTemp = 1.0f;
            device.PreprocessCoords(ref posTemp, ref scaleTemp);

            Vector2 xDot, yDot;
            MathF.GetTransformDotVec(this.GameObj.Transform.Angle, scaleTemp, out xDot, out yDot);

            Rect rectTemp = this.rect.Transform(this.gameobj.Transform.Scale, this.gameobj.Transform.Scale);
            Vector2 edge1 = rectTemp.TopLeft;
            Vector2 edge2 = rectTemp.BottomLeft;
            Vector2 edge3 = rectTemp.BottomRight;
            Vector2 edge4 = rectTemp.TopRight;

            MathF.TransformDotVec(ref edge1, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge2, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge3, ref xDot, ref yDot);
            MathF.TransformDotVec(ref edge4, ref xDot, ref yDot);

            if (vertices == null || vertices.Length != 4) vertices = new VertexC1P3T2[4];

            vertices[0].SetVertex(posTemp.X + edge1.X,
                                    posTemp.Y + edge1.Y,
                                    posTemp.Z + this.VertexZOffset,
                                    uvRect.X, uvRect.Y, mainClr);

            vertices[1].SetVertex(posTemp.X + edge2.X,
                                    posTemp.Y + edge2.Y,
                                    posTemp.Z + this.VertexZOffset,
                                    uvRect.X, uvRect.MaximumY, mainClr);

            vertices[2].SetVertex(posTemp.X + edge3.X,
                                    posTemp.Y + edge3.Y,
                                    posTemp.Z + this.VertexZOffset,
                                    uvRect.MaximumX, uvRect.MaximumY, mainClr);

            vertices[3].SetVertex(posTemp.X + edge4.X,
                                    posTemp.Y + edge4.Y,
                                    posTemp.Z + this.VertexZOffset,
                                    uvRect.MaximumX, uvRect.Y, mainClr);

            if (this.pixelGrid)
            {
                vertices[0].Pos.X = MathF.Round(vertices[0].Pos.X);
                vertices[1].Pos.X = MathF.Round(vertices[1].Pos.X);
                vertices[2].Pos.X = MathF.Round(vertices[2].Pos.X);
                vertices[3].Pos.X = MathF.Round(vertices[3].Pos.X);

                if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2)
                {
                    vertices[0].Pos.X += 0.5f;
                    vertices[1].Pos.X += 0.5f;
                    vertices[2].Pos.X += 0.5f;
                    vertices[3].Pos.X += 0.5f;
                }

                vertices[0].Pos.Y = MathF.Round(vertices[0].Pos.Y);
                vertices[1].Pos.Y = MathF.Round(vertices[1].Pos.Y);
                vertices[2].Pos.Y = MathF.Round(vertices[2].Pos.Y);
                vertices[3].Pos.Y = MathF.Round(vertices[3].Pos.Y);

                if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2)
                {
                    vertices[0].Pos.Y += 0.5f;
                    vertices[1].Pos.Y += 0.5f;
                    vertices[2].Pos.Y += 0.5f;
                    vertices[3].Pos.Y += 0.5f;
                }
            }
        }
Example #38
0
 /// <summary>
 /// Sets the color of all transparent pixels to the specified color.
 /// </summary>
 /// <param name="transparentColor"></param>
 public void ColorTransparentPixels(ColorRgba transparentColor)
 {
     for (int i = 0; i < this.data.Length; i++)
     {
         if (this.data[i].A != 0) continue;
         this.data[i] = transparentColor;
     }
 }
Example #39
0
 /// <summary>
 /// Creates a new single-texture Material.
 /// </summary>
 /// <param name="technique">The <see cref="Duality.Resources.DrawTechnique"/> to use.</param>
 /// <param name="mainColor">The <see cref="MainColor"/> to use.</param>
 /// <param name="mainTex">The main <see cref="Duality.Resources.Texture"/> to use.</param>
 public Material(ContentRef <DrawTechnique> technique, ColorRgba mainColor, ContentRef <Texture> mainTex)
 {
     this.info = new BatchInfo(technique, mainColor, mainTex);
 }
Example #40
0
		protected void PrepareVertices(ref VertexC1P3T2[] vertices, IDrawDevice device, ColorRgba mainClr, Rect uvRect)
		{
			Vector3 posTemp = this.gameobj.Transform.Pos;
			float scaleTemp = 1.0f;
			device.PreprocessCoords(ref posTemp, ref scaleTemp);

			Vector2 xDot, yDot;
			MathF.GetTransformDotVec(this.GameObj.Transform.Angle, scaleTemp, out xDot, out yDot);

			Rect rectTemp = this.rect.Transformed(this.gameobj.Transform.Scale, this.gameobj.Transform.Scale);

			Vector2 edge1 = rectTemp.TopLeft;
			Vector2 edge2 = rectTemp.BottomLeft;
			Vector2 edge3 = rectTemp.BottomRight;
			Vector2 edge4 = rectTemp.TopRight;

			MathF.TransformDotVec(ref edge1, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge2, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge3, ref xDot, ref yDot);
			MathF.TransformDotVec(ref edge4, ref xDot, ref yDot);
            
			float left   = uvRect.X;
			float right  = uvRect.RightX;
			float top    = uvRect.Y;
			float bottom = uvRect.BottomY;

			if ((this.flipMode & FlipMode.Horizontal) != FlipMode.None)
				MathF.Swap(ref left, ref right);
			if ((this.flipMode & FlipMode.Vertical) != FlipMode.None)
				MathF.Swap(ref top, ref bottom);

			if (vertices == null || vertices.Length != 4) vertices = new VertexC1P3T2[4];

			vertices[0].Pos.X = posTemp.X + edge1.X;
			vertices[0].Pos.Y = posTemp.Y + edge1.Y;
			vertices[0].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[0].TexCoord.X = left;
			vertices[0].TexCoord.Y = top;
			vertices[0].Color = mainClr;

			vertices[1].Pos.X = posTemp.X + edge2.X;
			vertices[1].Pos.Y = posTemp.Y + edge2.Y;
			vertices[1].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[1].TexCoord.X = left;
			vertices[1].TexCoord.Y = bottom;
			vertices[1].Color = mainClr;

			vertices[2].Pos.X = posTemp.X + edge3.X;
			vertices[2].Pos.Y = posTemp.Y + edge3.Y;
			vertices[2].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[2].TexCoord.X = right;
			vertices[2].TexCoord.Y = bottom;
			vertices[2].Color = mainClr;
				
			vertices[3].Pos.X = posTemp.X + edge4.X;
			vertices[3].Pos.Y = posTemp.Y + edge4.Y;
			vertices[3].Pos.Z = posTemp.Z + this.VertexZOffset;
			vertices[3].TexCoord.X = right;
			vertices[3].TexCoord.Y = top;
			vertices[3].Color = mainClr;

			if (this.pixelGrid)
			{
				vertices[0].Pos.X = MathF.Round(vertices[0].Pos.X);
				vertices[1].Pos.X = MathF.Round(vertices[1].Pos.X);
				vertices[2].Pos.X = MathF.Round(vertices[2].Pos.X);
				vertices[3].Pos.X = MathF.Round(vertices[3].Pos.X);

				if (MathF.RoundToInt(device.TargetSize.X) != (MathF.RoundToInt(device.TargetSize.X) / 2) * 2)
				{
					vertices[0].Pos.X += 0.5f;
					vertices[1].Pos.X += 0.5f;
					vertices[2].Pos.X += 0.5f;
					vertices[3].Pos.X += 0.5f;
				}

				vertices[0].Pos.Y = MathF.Round(vertices[0].Pos.Y);
				vertices[1].Pos.Y = MathF.Round(vertices[1].Pos.Y);
				vertices[2].Pos.Y = MathF.Round(vertices[2].Pos.Y);
				vertices[3].Pos.Y = MathF.Round(vertices[3].Pos.Y);

				if (MathF.RoundToInt(device.TargetSize.Y) != (MathF.RoundToInt(device.TargetSize.Y) / 2) * 2)
				{
					vertices[0].Pos.Y += 0.5f;
					vertices[1].Pos.Y += 0.5f;
					vertices[2].Pos.Y += 0.5f;
					vertices[3].Pos.Y += 0.5f;
				}
			}
		}
Example #41
0
        private void DrawLocalAngleConstraint(Canvas canvas, RigidBody body, Vector2 anchor, float minAngle, float maxAngle, float currentAngle, float radius)
        {
            Vector3 bodyPos = body.GameObj.Transform.Pos;

            ColorRgba clr    = this.JointColor;
            ColorRgba clrErr = this.JointErrorColor;

            Vector2 anchorToWorld = body.GameObj.Transform.GetWorldVector(anchor);
            Vector2 angleVecMin   = Vector2.FromAngleLength(minAngle, radius);
            Vector2 angleVecMax   = Vector2.FromAngleLength(maxAngle, radius);
            Vector2 errorVec      = Vector2.FromAngleLength(currentAngle, radius);
            float   angleDistMin  = MathF.Abs(currentAngle - minAngle);
            float   angleDistMax  = MathF.Abs(currentAngle - maxAngle);
            float   angleRange    = maxAngle - minAngle;
            bool    hasError      = angleDistMin > angleDistMax ? angleDistMin >= angleRange : angleDistMax >= angleRange;

            if (hasError)
            {
                float circleBegin = currentAngle;
                float circleEnd   = angleDistMin < angleDistMax ? minAngle : maxAngle;
                if (MathF.TurnDir(circleBegin, circleEnd) < 0)
                {
                    MathF.Swap(ref circleBegin, ref circleEnd);
                    circleEnd = circleBegin + MathF.CircularDist(circleBegin, circleEnd);
                }

                canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clrErr));
                canvas.DrawLine(
                    bodyPos.X + anchorToWorld.X,
                    bodyPos.Y + anchorToWorld.Y,
                    bodyPos.Z,
                    bodyPos.X + anchorToWorld.X + errorVec.X,
                    bodyPos.Y + anchorToWorld.Y + errorVec.Y,
                    bodyPos.Z);
                canvas.DrawCircleSegment(
                    bodyPos.X + anchorToWorld.X,
                    bodyPos.Y + anchorToWorld.Y,
                    bodyPos.Z,
                    radius,
                    circleBegin,
                    circleEnd);
                this.DrawLocalText(canvas, body,
                                   string.Format("{0:F0}°", MathF.RadToDeg(currentAngle)),
                                   anchorToWorld + errorVec,
                                   Vector2.UnitY,
                                   errorVec.Angle);
            }
            canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr));
            canvas.DrawCircleSegment(
                bodyPos.X + anchorToWorld.X,
                bodyPos.Y + anchorToWorld.Y,
                bodyPos.Z,
                radius,
                minAngle,
                maxAngle);
            canvas.DrawLine(
                bodyPos.X + anchorToWorld.X,
                bodyPos.Y + anchorToWorld.Y,
                bodyPos.Z,
                bodyPos.X + anchorToWorld.X + angleVecMin.X,
                bodyPos.Y + anchorToWorld.Y + angleVecMin.Y,
                bodyPos.Z);
            canvas.DrawLine(
                bodyPos.X + anchorToWorld.X,
                bodyPos.Y + anchorToWorld.Y,
                bodyPos.Z,
                bodyPos.X + anchorToWorld.X + angleVecMax.X,
                bodyPos.Y + anchorToWorld.Y + angleVecMax.Y,
                bodyPos.Z);
            this.DrawLocalText(canvas, body,
                               string.Format("{0:F0}°", MathF.RadToDeg(minAngle)),
                               anchorToWorld + angleVecMin,
                               angleVecMin.Angle);
            this.DrawLocalText(canvas, body,
                               string.Format("{0:F0}°", MathF.RadToDeg(maxAngle)),
                               anchorToWorld + angleVecMax,
                               angleVecMax.Angle);
        }
Example #42
0
        protected internal override void OnCollectDrawcalls(Canvas canvas)
        {
            base.OnCollectDrawcalls(canvas);
            IDrawDevice device = canvas.DrawDevice;

            float   scaleTemp = 1.0f;
            Vector3 posTemp   = Vector3.Zero;

            device.PreprocessCoords(ref posTemp, ref scaleTemp);
            if (posTemp.Z <= canvas.DrawDevice.NearZ)
            {
                return;
            }

            float alphaTemp = 0.5f;

            alphaTemp *= (float)Math.Min(1.0d, ((posTemp.Z - device.NearZ) / (device.NearZ * 5.0f)));
            if (alphaTemp <= 0.005f)
            {
                return;
            }

            float stepTemp     = 4.0f * this.gridSize * MathF.Max(0.25f, MathF.Pow(2.0f, -MathF.Round(1.0f - MathF.Log(1.0f / scaleTemp, 2.0f))));
            float scaledStep   = stepTemp * scaleTemp;
            float viewBoundRad = device.TargetSize.Length * 0.5f;
            int   lineCount    = (2 + (int)MathF.Ceiling(viewBoundRad * 2 / scaledStep)) * 4;

            ColorRgba gridColor = this.FgColor.WithAlpha(alphaTemp);

            VertexC1P3[] vertices = new VertexC1P3[lineCount * 4];

            float beginPos;
            float pos;
            int   lineIndex;
            int   vertOff = 0;

            beginPos  = posTemp.X % scaledStep - (lineCount / 8) * scaledStep;
            pos       = beginPos;
            lineIndex = 0;
            for (int x = 0; x < lineCount; x++)
            {
                bool primaryLine   = lineIndex % 4 == 0;
                bool secondaryLine = lineIndex % 4 == 2;

                vertices[vertOff + x * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f));

                vertices[vertOff + x * 2 + 0].Pos.X = pos;
                vertices[vertOff + x * 2 + 0].Pos.Y = -viewBoundRad;
                vertices[vertOff + x * 2 + 0].Pos.Z = posTemp.Z + 1;

                vertices[vertOff + x * 2 + 1]       = vertices[vertOff + x * 2 + 0];
                vertices[vertOff + x * 2 + 1].Pos.Y = viewBoundRad;

                pos += scaledStep / 4;
                lineIndex++;
            }
            vertOff += lineCount * 2;

            beginPos  = posTemp.Y % scaledStep - (lineCount / 8) * scaledStep;
            pos       = beginPos;
            lineIndex = 0;
            for (int y = 0; y < lineCount; y++)
            {
                bool primaryLine   = lineIndex % 4 == 0;
                bool secondaryLine = lineIndex % 4 == 2;

                vertices[vertOff + y * 2 + 0].Color = primaryLine ? gridColor : gridColor.WithAlpha(alphaTemp * (secondaryLine ? 0.5f : 0.25f));

                vertices[vertOff + y * 2 + 0].Pos.X = -viewBoundRad;
                vertices[vertOff + y * 2 + 0].Pos.Y = pos;
                vertices[vertOff + y * 2 + 0].Pos.Z = posTemp.Z + 1;

                vertices[vertOff + y * 2 + 1]       = vertices[vertOff + y * 2 + 0];
                vertices[vertOff + y * 2 + 1].Pos.X = viewBoundRad;

                pos += scaledStep / 4;
                lineIndex++;
            }
            vertOff += lineCount * 2;

            device.AddVertices(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White), VertexMode.Lines, vertices);
        }
 /// <summary>
 /// Replaces a Bitmaps pixel data.
 /// </summary>
 /// <param name="bm"></param>
 /// <param name="pixelData"></param>
 public static void SetPixelDataRgba(this Bitmap bm, ColorRgba[] pixelData)
 {
     int[] argbValues = new int[pixelData.Length];
     unchecked
     {
         for (int i = 0; i < pixelData.Length; i++)
             argbValues[i] = pixelData[i].ToIntArgb();
     }
     SetPixelDataIntArgb(bm, argbValues);
 }
Example #44
0
        private void DrawWorldAxisConstraint(Canvas canvas, RigidBody body, Vector2 worldAxis, Vector2 localAnchor, Vector2 worldAnchor, float min = 1, float max = -1)
        {
            Vector3 bodyPos = body.GameObj.Transform.Pos;

            worldAxis = worldAxis.Normalized;
            bool infinite = false;

            if (min > max)
            {
                min      = -10000000.0f;
                max      = 10000000.0f;
                infinite = true;
            }
            Vector2 anchorToWorld = body.GameObj.Transform.GetWorldVector(localAnchor);
            float   axisVal       = Vector2.Dot(bodyPos.Xy + anchorToWorld - worldAnchor, worldAxis);
            Vector2 basePos       = MathF.PointLineNearestPoint(
                bodyPos.X + anchorToWorld.X,
                bodyPos.Y + anchorToWorld.Y,
                worldAnchor.X + worldAxis.X * min,
                worldAnchor.Y + worldAxis.Y * min,
                worldAnchor.X + worldAxis.X * max,
                worldAnchor.Y + worldAxis.Y * max,
                infinite);
            float   errorVal = (bodyPos.Xy + anchorToWorld - basePos).Length;
            Vector2 errorVec = basePos - bodyPos.Xy;
            bool    hasError = errorVal >= 1.0f;

            ColorRgba clr    = this.JointColor;
            ColorRgba clrErr = this.JointErrorColor;

            if (hasError)
            {
                canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clrErr));
                canvas.DrawLine(
                    bodyPos.X + anchorToWorld.X,
                    bodyPos.Y + anchorToWorld.Y,
                    bodyPos.Z,
                    basePos.X,
                    basePos.Y,
                    bodyPos.Z);
                this.DrawLocalText(canvas, body,
                                   string.Format("{0:F1}", errorVal),
                                   errorVec * 0.5f,
                                   new Vector2(0.5f, 0.0f),
                                   errorVec.PerpendicularLeft.Angle);
            }

            canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, clr));
            canvas.DrawLine(
                worldAnchor.X + worldAxis.X * min,
                worldAnchor.Y + worldAxis.Y * min,
                bodyPos.Z,
                worldAnchor.X + worldAxis.X * max,
                worldAnchor.Y + worldAxis.Y * max,
                bodyPos.Z);
            if (!infinite)
            {
                canvas.DrawLine(
                    worldAnchor.X + worldAxis.X * min + worldAxis.PerpendicularLeft.X * 5.0f,
                    worldAnchor.Y + worldAxis.Y * min + worldAxis.PerpendicularLeft.Y * 5.0f,
                    bodyPos.Z,
                    worldAnchor.X + worldAxis.X * min + worldAxis.PerpendicularRight.X * 5.0f,
                    worldAnchor.Y + worldAxis.Y * min + worldAxis.PerpendicularRight.Y * 5.0f,
                    bodyPos.Z);
                canvas.DrawLine(
                    worldAnchor.X + worldAxis.X * max + worldAxis.PerpendicularLeft.X * 5.0f,
                    worldAnchor.Y + worldAxis.Y * max + worldAxis.PerpendicularLeft.Y * 5.0f,
                    bodyPos.Z,
                    worldAnchor.X + worldAxis.X * max + worldAxis.PerpendicularRight.X * 5.0f,
                    worldAnchor.Y + worldAxis.Y * max + worldAxis.PerpendicularRight.Y * 5.0f,
                    bodyPos.Z);
            }
        }
Example #45
0
 /// <summary>
 /// Extracts a rectangular region of this Layer. If the extracted region is bigger than the original Layer,
 /// all new space is filled with a background color.
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="w"></param>
 /// <param name="h"></param>
 /// <param name="backColor"></param>
 public void SubImage(int x, int y, int w, int h, ColorRgba backColor)
 {
     Layer tempLayer = new Layer(w, h, backColor);
     this.DrawOnto(tempLayer, BlendMode.Solid, -x, -y);
     tempLayer.CopyTo(this);
 }
        protected internal override void OnCollectWorldOverlayDrawcalls(Canvas canvas)
        {
            base.OnCollectWorldOverlayDrawcalls(canvas);
            List <RigidBody> visibleColliders = this.QueryVisibleColliders().ToList();

            RigidBody selectedBody = this.QuerySelectedCollider();

            canvas.State.SetMaterial(new BatchInfo(DrawTechnique.Alpha, ColorRgba.White));
            canvas.State.TextFont           = Font.GenericMonospace10;
            canvas.State.TextInvariantScale = true;
            canvas.State.ZOffset            = this.depthOffset;
            Font textFont = canvas.State.TextFont.Res;

            // Retrieve selected shapes
            ObjectEditorCamViewState editorState = this.View.ActiveState as ObjectEditorCamViewState;

            object[] editorSelectedObjects = editorState != null?editorState.SelectedObjects.Select(item => item.ActualObject).ToArray() : new object[0];

            bool isAnyBodySelected  = (selectedBody != null);
            bool isAnyShapeSelected = isAnyBodySelected && editorSelectedObjects.OfType <ShapeInfo>().Any();

            // Draw Shape layer
            foreach (RigidBody body in visibleColliders)
            {
                if (!body.Shapes.Any())
                {
                    continue;
                }

                Vector3 objPos   = body.GameObj.Transform.Pos;
                float   objAngle = body.GameObj.Transform.Angle;
                float   objScale = body.GameObj.Transform.Scale;

                bool isBodySelected = (body == selectedBody);

                float bodyAlpha  = isBodySelected ? 1.0f : (isAnyBodySelected ? 0.5f : 1.0f);
                float maxDensity = body.Shapes.Max(s => s.Density);
                float minDensity = body.Shapes.Min(s => s.Density);
                float avgDensity = (maxDensity + minDensity) * 0.5f;

                int shapeIndex = 0;
                foreach (ShapeInfo shape in body.Shapes)
                {
                    CircleShapeInfo circle = shape as CircleShapeInfo;
                    PolyShapeInfo   poly   = shape as PolyShapeInfo;
                    ChainShapeInfo  chain  = shape as ChainShapeInfo;
                    LoopShapeInfo   loop   = shape as LoopShapeInfo;

                    bool isShapeSelected = isBodySelected && editorSelectedObjects.Contains(shape);

                    float     shapeAlpha      = bodyAlpha * (isShapeSelected ? 1.0f : (isAnyShapeSelected && isBodySelected ? 0.75f : 1.0f));
                    float     densityRelative = MathF.Abs(maxDensity - minDensity) < 0.01f ? 1.0f : shape.Density / avgDensity;
                    ColorRgba shapeColor      = shape.IsSensor ? this.ShapeSensorColor : this.ShapeColor;
                    ColorRgba fontColor       = this.FgColor;

                    if (!body.IsAwake)
                    {
                        shapeColor = shapeColor.ToHsva().WithSaturation(0.0f).ToRgba();
                    }
                    if (!shape.IsValid)
                    {
                        shapeColor = this.ShapeErrorColor;
                    }

                    // Draw the shape itself
                    ColorRgba fillColor    = shapeColor.WithAlpha((0.25f + densityRelative * 0.25f) * shapeAlpha);
                    ColorRgba outlineColor = ColorRgba.Lerp(shapeColor, fontColor, isShapeSelected ? 0.75f : 0.25f).WithAlpha(shapeAlpha);
                    this.DrawShape(canvas, body.GameObj.Transform, shape, fillColor, outlineColor);

                    // Calculate the center coordinate
                    Vector2 shapeCenter = Vector2.Zero;
                    if (circle != null)
                    {
                        shapeCenter = circle.Position * objScale;
                    }
                    else
                    {
                        Vector2[] shapeVertices = null;
                        if (poly != null)
                        {
                            shapeVertices = poly.Vertices;
                        }
                        else if (loop != null)
                        {
                            shapeVertices = loop.Vertices;
                        }
                        else if (chain != null)
                        {
                            shapeVertices = chain.Vertices;
                        }

                        for (int i = 0; i < shapeVertices.Length; i++)
                        {
                            shapeCenter += shapeVertices[i];
                        }

                        shapeCenter /= shapeVertices.Length;
                    }
                    MathF.TransformCoord(ref shapeCenter.X, ref shapeCenter.Y, objAngle, objScale);

                    // Draw shape index
                    if (body == selectedBody)
                    {
                        string  indexText = shapeIndex.ToString();
                        Vector2 textSize  = textFont.MeasureText(indexText);
                        canvas.State.ColorTint = fontColor.WithAlpha((shapeAlpha + 1.0f) * 0.5f);
                        canvas.DrawText(indexText,
                                        objPos.X + shapeCenter.X,
                                        objPos.Y + shapeCenter.Y,
                                        0.0f);
                    }

                    shapeIndex++;
                }

                // Draw center of mass
                if (body.BodyType == BodyType.Dynamic)
                {
                    Vector2 localMassCenter = body.LocalMassCenter;
                    MathF.TransformCoord(ref localMassCenter.X, ref localMassCenter.Y, objAngle, objScale);

                    float size = this.GetScreenConstantScale(canvas, 6.0f);

                    canvas.State.ColorTint = this.MassCenterColor.WithAlpha(bodyAlpha);
                    canvas.DrawLine(
                        objPos.X + localMassCenter.X - size,
                        objPos.Y + localMassCenter.Y,
                        0.0f,
                        objPos.X + localMassCenter.X + size,
                        objPos.Y + localMassCenter.Y,
                        0.0f);
                    canvas.DrawLine(
                        objPos.X + localMassCenter.X,
                        objPos.Y + localMassCenter.Y - size,
                        0.0f,
                        objPos.X + localMassCenter.X,
                        objPos.Y + localMassCenter.Y + size,
                        0.0f);
                }

                // Draw transform center
                {
                    float size = this.GetScreenConstantScale(canvas, 3.0f);
                    canvas.State.ColorTint = this.ObjectCenterColor.WithAlpha(bodyAlpha);
                    canvas.FillCircle(objPos.X, objPos.Y, 0.0f, size);
                }
            }
        }
Example #47
0
 /// <summary>
 /// Extracts a rectangular region of this Layer. If the extracted region is bigger than the original Layer,
 /// all new space is filled with a background color.
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="w"></param>
 /// <param name="h"></param>
 /// <param name="backColor"></param>
 public Layer CloneSubImage(int x, int y, int w, int h, ColorRgba backColor)
 {
     Layer tempLayer = new Layer(w, h, backColor);
     this.DrawOnto(tempLayer, BlendMode.Solid, -x, -y);
     return tempLayer;
 }
 private void DrawShape(Canvas canvas, Transform transform, ShapeInfo shape, ColorRgba fillColor, ColorRgba outlineColor)
 {
     if (shape is CircleShapeInfo)
     {
         this.DrawShape(canvas, transform, shape as CircleShapeInfo, fillColor, outlineColor);
     }
     else if (shape is LoopShapeInfo)
     {
         this.DrawShape(canvas, transform, shape as LoopShapeInfo, fillColor, outlineColor);
     }
     else if (shape is ChainShapeInfo)
     {
         this.DrawShape(canvas, transform, shape as ChainShapeInfo, fillColor, outlineColor);
     }
     else if (shape is PolyShapeInfo)
     {
         this.DrawShape(canvas, transform, shape as PolyShapeInfo, fillColor, outlineColor);
     }
 }
Example #49
0
            /// <summary>
            /// Performs a drawing operation from this Layer to a target layer.
            /// </summary>
            /// <param name="target"></param>
            /// <param name="blend"></param>
            /// <param name="destX"></param>
            /// <param name="destY"></param>
            /// <param name="width"></param>
            /// <param name="height"></param>
            /// <param name="srcX"></param>
            /// <param name="srcY"></param>
            /// <param name="colorTint"></param>
            public void DrawOnto(Layer target, BlendMode blend, int destX, int destY, int width, int height, int srcX, int srcY, ColorRgba colorTint)
            {
                if (colorTint == ColorRgba.White)
                {
                    this.DrawOnto(target, blend, destX, destY, width, height, srcX, srcY);
                    return;
                }
                if (width == -1) width = this.width;
                if (height == -1) height = this.height;

                int beginX = MathF.Max(0, -destX, -srcX);
                int beginY = MathF.Max(0, -destY, -srcY);
                int endX = MathF.Min(width, this.width, target.width - destX, this.width - srcX);
                int endY = MathF.Min(height, this.height, target.height - destY, this.height - srcY);
                if (endX - beginX < 1) return;
                if (endY - beginY < 1) return;

                ColorRgba clrSource;
                ColorRgba clrTarget;
                System.Threading.Tasks.Parallel.For(beginX, endX, i =>
                //for (int i = beginX; i < endX; i++)
                {
                    for (int j = beginY; j < endY; j++)
                    {
                        int sourceN = srcX + i + this.width * (srcY + j);
                        int targetN = destX + i + target.width * (destY + j);

                        clrSource = this.data[sourceN] * colorTint;

                        if (blend == BlendMode.Solid)
                        {
                            target.data[targetN] = clrSource;
                        }
                        else if (blend == BlendMode.Mask)
                        {
                            if (clrSource.A >= 0) target.data[targetN] = this.data[sourceN];
                        }
                        else if (blend == BlendMode.Add)
                        {
                            clrTarget	= target.data[targetN];
                            float alphaTemp = (float)clrSource.A / 255.0f;
                            target.data[targetN].R = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrTarget.R + clrSource.R * alphaTemp)));
                            target.data[targetN].G = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrTarget.G + clrSource.G * alphaTemp)));
                            target.data[targetN].B = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrTarget.B + clrSource.B * alphaTemp)));
                            target.data[targetN].A = (byte)Math.Min(255, Math.Max(0, (int)clrTarget.A + (int)clrSource.A));
                        }
                        else if (blend == BlendMode.Alpha)
                        {
                            clrTarget	= target.data[targetN];
                            float alphaTemp = (float)clrSource.A / 255.0f;
                            target.data[targetN].R = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrTarget.R * (1.0f - alphaTemp) + clrSource.R * alphaTemp)));
                            target.data[targetN].G = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrTarget.G * (1.0f - alphaTemp) + clrSource.G * alphaTemp)));
                            target.data[targetN].B = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrTarget.B * (1.0f - alphaTemp) + clrSource.B * alphaTemp)));
                            target.data[targetN].A = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrTarget.A * (1.0f - alphaTemp) + clrSource.A)));
                        }
                        else if (blend == BlendMode.Multiply)
                        {
                            clrTarget	= target.data[targetN];
                            float clrTempR = (float)clrTarget.R / 255.0f;
                            float clrTempG = (float)clrTarget.G / 255.0f;
                            float clrTempB = (float)clrTarget.B / 255.0f;
                            float clrTempA = (float)clrTarget.A / 255.0f;
                            target.data[targetN].R = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrSource.R * clrTempR)));
                            target.data[targetN].G = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrSource.G * clrTempG)));
                            target.data[targetN].B = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrSource.B * clrTempB)));
                            target.data[targetN].A = (byte)Math.Min(255, Math.Max(0, (int)clrTarget.A + (int)clrSource.A));
                        }
                        else if (blend == BlendMode.Light)
                        {
                            clrTarget	= target.data[targetN];
                            float clrTempR = (float)clrTarget.R / 255.0f;
                            float clrTempG = (float)clrTarget.G / 255.0f;
                            float clrTempB = (float)clrTarget.B / 255.0f;
                            float clrTempA = (float)clrTarget.A / 255.0f;
                            target.data[targetN].R = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrSource.R * clrTempR + clrTarget.R)));
                            target.data[targetN].G = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrSource.G * clrTempG + clrTarget.G)));
                            target.data[targetN].B = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrSource.B * clrTempB + clrTarget.B)));
                            target.data[targetN].A = (byte)Math.Min(255, Math.Max(0, (int)clrTarget.A + (int)clrSource.A));
                        }
                        else if (blend == BlendMode.Invert)
                        {
                            clrTarget	= target.data[targetN];
                            float clrTempR = (float)clrTarget.R / 255.0f;
                            float clrTempG = (float)clrTarget.G / 255.0f;
                            float clrTempB = (float)clrTarget.B / 255.0f;
                            float clrTempA = (float)clrTarget.A / 255.0f;
                            float clrTempR2 = (float)clrSource.R / 255.0f;
                            float clrTempG2 = (float)clrSource.G / 255.0f;
                            float clrTempB2 = (float)clrSource.B / 255.0f;
                            float clrTempA2 = (float)clrSource.A / 255.0f;
                            target.data[targetN].R = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrSource.R * (1.0f - clrTempR) + clrTarget.R * (1.0f - clrTempR2))));
                            target.data[targetN].G = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrSource.G * (1.0f - clrTempG) + clrTarget.G * (1.0f - clrTempG2))));
                            target.data[targetN].B = (byte)Math.Min(255, Math.Max(0, (int)Math.Round(clrSource.B * (1.0f - clrTempB) + clrTarget.B * (1.0f - clrTempB2))));
                            target.data[targetN].A = (byte)Math.Min(255, Math.Max(0, (int)(clrTarget.A + clrSource.A)));
                        }
                    }
                });
            }
 private void DrawShape(Canvas canvas, Transform transform, ChainShapeInfo shape, ColorRgba fillColor, ColorRgba outlineColor)
 {
     this.DrawPolygonOutline(canvas, transform, shape.Vertices, outlineColor, false);
 }
Example #51
0
 public ColorChangeElement(ColorRgba color)
 {
     this.color = color;
 }
        private void DrawShape(Canvas canvas, Transform transform, PolyShapeInfo shape, ColorRgba fillColor, ColorRgba outlineColor)
        {
            if (shape.ConvexPolygons != null)
            {
                // Fill each convex polygon individually
                foreach (Vector2[] polygon in shape.ConvexPolygons)
                {
                    this.FillPolygon(canvas, transform, polygon, fillColor);
                }

                // Draw all convex polygon edges that are not outlines
                canvas.State.ZOffset = this.depthOffset - 0.05f;
                this.DrawPolygonInternals(canvas, transform, shape.Vertices, shape.ConvexPolygons, outlineColor);
                canvas.State.ZOffset = this.depthOffset;
            }


            // Draw the polygon outline
            canvas.State.ZOffset = this.depthOffset - 0.1f;
            this.DrawPolygonOutline(canvas, transform, shape.Vertices, outlineColor, true);
            canvas.State.ZOffset = this.depthOffset;
        }
Example #53
0
            public RenderState(RenderState other)
            {
                this.parent = other.parent;
                this.vertTextIndex = other.vertTextIndex.Clone() as int[];
                this.vertIconIndex = other.vertIconIndex;
                this.offset = other.offset;
                this.elemIndex = other.elemIndex;
                this.lineIndex = other.lineIndex;

                this.fontIndex = other.fontIndex;
                this.font = other.font;
                this.color = other.color;

                this.lineBeginX = other.lineBeginX;
                this.lineWidth = other.lineWidth;
                this.lineAvailWidth = other.lineAvailWidth;
                this.lineHeight = other.lineHeight;
                this.lineBaseLine = other.lineBaseLine;
                this.lineAlign = other.lineAlign;

                this.curElemOffset = other.curElemOffset;
                this.curElemVertTextIndex = other.curElemVertTextIndex;
                this.curElemVertIconIndex = other.curElemVertIconIndex;
                this.curElemWrapIndex = other.curElemWrapIndex;
                this.curElemText = other.curElemText;
            }
        private void DrawShape(Canvas canvas, Transform transform, CircleShapeInfo shape, ColorRgba fillColor, ColorRgba outlineColor)
        {
            Vector3 objPos   = transform.Pos;
            float   objAngle = transform.Angle;
            float   objScale = transform.Scale;

            Vector2 circlePos = shape.Position * objScale;

            MathF.TransformCoord(ref circlePos.X, ref circlePos.Y, objAngle);

            if (fillColor.A > 0)
            {
                canvas.State.ColorTint = fillColor;
                canvas.FillCircle(
                    objPos.X + circlePos.X,
                    objPos.Y + circlePos.Y,
                    0.0f,
                    shape.Radius * objScale);
            }

            float outlineWidth = this.GetScreenConstantScale(canvas, this.shapeOutlineWidth);

            canvas.State.ColorTint = outlineColor;
            canvas.State.ZOffset   = this.depthOffset - 0.1f;
            canvas.FillCircleSegment(
                objPos.X + circlePos.X,
                objPos.Y + circlePos.Y,
                0.0f,
                shape.Radius * objScale,
                0.0f,
                MathF.RadAngle360,
                outlineWidth);
            canvas.State.ZOffset = this.depthOffset;
        }
Example #55
0
 /// <summary>
 /// Returns a format string for changing the current text color to the specified one.
 /// </summary>
 /// <returns></returns>
 public static string FormatColor(ColorRgba color)
 {
     int intClr = color.ToIntRgba();
     return string.Format("{1}{0:X8}", intClr, FormatColorTag);
 }
        private void FillPolygon(Canvas canvas, Transform transform, Vector2[] polygon, ColorRgba fillColor)
        {
            Vector3 objPos   = transform.Pos;
            float   objAngle = transform.Angle;
            float   objScale = transform.Scale;

            canvas.State.ColorTint      = fillColor;
            canvas.State.TransformAngle = objAngle;
            canvas.State.TransformScale = new Vector2(objScale, objScale);

            canvas.FillPolygon(polygon, objPos.X, objPos.Y, 0.0f);

            canvas.State.TransformAngle = 0.0f;
            canvas.State.TransformScale = Vector2.One;
        }
Example #57
0
        /// <summary>
        /// Emits sets of vertices for glyphs and icons based on this formatted text. To render it, use each set of vertices combined with
        /// the corresponding Fonts <see cref="Material"/>.
        /// </summary>
        /// <param name="vertText">One set of vertices for each Font that is available to this ForattedText.</param>
        /// <param name="vertIcons">A set of icon vertices.</param>
        /// <param name="x">An X-Offset applied to the position of each emitted vertex.</param>
        /// <param name="y">An Y-Offset applied to the position of each emitted vertex.</param>
        /// <param name="z">An Z-Offset applied to the position of each emitted vertex.</param>
        /// <param name="clr">The color value that is applied to each emitted vertex.</param>
        /// <param name="xDot">Dot product base for the transformed vertices.</param>
        /// <param name="yDot">Dot product base for the transformed vertices.</param>
        /// <returns>
        /// Returns an array of vertex counts for each emitted vertex array. 
        /// Index 0 represents the number of emitted icon vertices, Index n represents the number of vertices emitted using Font n - 1.
        /// </returns>
        public int[] EmitVertices(ref VertexC1P3T2[][] vertText, ref VertexC1P3T2[] vertIcons, float x, float y, float z, ColorRgba clr, Vector2 xDot, Vector2 yDot)
        {
            int[] vertLen = this.EmitVertices(ref vertText, ref vertIcons);

            Vector3 offset = new Vector3(x, y, z);

            if (clr == ColorRgba.White)
            {
                for (int i = 0; i < vertText.Length; i++)
                {
                    for (int j = 0; j < vertLen[i + 1]; j++)
                    {
                        MathF.TransformDotVec(ref vertText[i][j].Pos, ref xDot, ref yDot);
                        Vector3.Add(ref vertText[i][j].Pos, ref offset, out vertText[i][j].Pos);
                    }
                }
                for (int i = 0; i < vertLen[0]; i++)
                {
                    MathF.TransformDotVec(ref vertIcons[i].Pos, ref xDot, ref yDot);
                    Vector3.Add(ref vertIcons[i].Pos, ref offset, out vertIcons[i].Pos);
                }
            }
            else
            {
                for (int i = 0; i < vertText.Length; i++)
                {
                    for (int j = 0; j < vertLen[i + 1]; j++)
                    {
                        MathF.TransformDotVec(ref vertText[i][j].Pos, ref xDot, ref yDot);
                        Vector3.Add(ref vertText[i][j].Pos, ref offset, out vertText[i][j].Pos);
                        ColorRgba.Multiply(ref vertText[i][j].Color, ref clr, out vertText[i][j].Color);
                    }
                }
                for (int i = 0; i < vertLen[0]; i++)
                {
                    MathF.TransformDotVec(ref vertIcons[i].Pos, ref xDot, ref yDot);
                    Vector3.Add(ref vertIcons[i].Pos, ref offset, out vertIcons[i].Pos);
                    ColorRgba.Multiply(ref vertIcons[i].Color, ref clr, out vertIcons[i].Color);
                }
            }

            return vertLen;
        }
        private void DrawPolygonOutline(Canvas canvas, Transform transform, Vector2[] polygon, ColorRgba outlineColor, bool closedLoop)
        {
            Vector3 objPos   = transform.Pos;
            float   objAngle = transform.Angle;
            float   objScale = transform.Scale;

            canvas.State.TransformAngle = objAngle;
            canvas.State.TransformScale = new Vector2(objScale, objScale);
            canvas.State.ColorTint      = outlineColor;

            float outlineWidth = this.GetScreenConstantScale(canvas, this.shapeOutlineWidth);

            outlineWidth /= objScale;
            if (closedLoop)
            {
                canvas.FillPolygonOutline(polygon, outlineWidth, objPos.X, objPos.Y, 0.0f);
            }
            else
            {
                canvas.FillThickLineStrip(polygon, outlineWidth, objPos.X, objPos.Y, 0.0f);
            }

            canvas.State.TransformAngle = 0.0f;
            canvas.State.TransformScale = Vector2.One;
        }
Example #59
0
			public Pass(Pass copyFrom, BatchInfo inputOverride)
			{
				this.input = inputOverride;
				this.output = copyFrom.output;
				this.clearColor = copyFrom.clearColor;
				this.clearDepth = copyFrom.clearDepth;
				this.clearFlags = copyFrom.clearFlags;
				this.matrixMode = copyFrom.matrixMode;
				this.visibilityMask = copyFrom.visibilityMask;

				this.MakeAvailable();
			}
        private void DrawPolygonInternals(Canvas canvas, Transform transform, Vector2[] hullVertices, IReadOnlyList <Vector2[]> convexPolygons, ColorRgba outlineColor)
        {
            if (convexPolygons.Count <= 1)
            {
                return;
            }

            Vector3 objPos   = transform.Pos;
            float   objAngle = transform.Angle;
            float   objScale = transform.Scale;

            Vector2 xDot;
            Vector2 yDot;

            MathF.GetTransformDotVec(objAngle, objScale, out xDot, out yDot);

            float dashPatternLength = this.GetScreenConstantScale(canvas, this.shapeOutlineWidth * 0.5f);

            // Generate a lookup of drawn vertex indices, so we can
            // avoid drawing the same edge twice. Every item is a combination
            // of two indices.
            HashSet <uint> drawnEdges = new HashSet <uint>();

            for (int i = 0; i < hullVertices.Length; i++)
            {
                int  currentHullIndex = i;
                int  nextHullIndex    = (i + 1) % hullVertices.Length;
                uint edgeId           = (currentHullIndex > nextHullIndex) ?
                                        ((uint)currentHullIndex << 16) | (uint)nextHullIndex :
                                        ((uint)nextHullIndex << 16) | (uint)currentHullIndex;
                drawnEdges.Add(edgeId);
            }

            canvas.State.ColorTint = outlineColor;

            foreach (Vector2[] polygon in convexPolygons)
            {
                if (polygon.Length < 2)
                {
                    continue;
                }

                int currentHullIndex;
                int nextHullIndex = VertexListIndex(hullVertices, polygon[0]);
                for (int i = 0; i < polygon.Length; i++)
                {
                    int nextIndex = (i + 1) % polygon.Length;
                    currentHullIndex = nextHullIndex;
                    nextHullIndex    = VertexListIndex(hullVertices, polygon[nextIndex]);

                    // Filter out edges that have already been drawn
                    if (currentHullIndex >= 0 && nextHullIndex >= 0)
                    {
                        uint edgeId = (currentHullIndex > nextHullIndex) ?
                                      ((uint)currentHullIndex << 16) | (uint)nextHullIndex :
                                      ((uint)nextHullIndex << 16) | (uint)currentHullIndex;
                        if (!drawnEdges.Add(edgeId))
                        {
                            continue;
                        }
                    }

                    Vector2 lineStart = new Vector2(
                        polygon[i].X,
                        polygon[i].Y);
                    Vector2 lineEnd = new Vector2(
                        polygon[nextIndex].X,
                        polygon[nextIndex].Y);
                    MathF.TransformDotVec(ref lineStart, ref xDot, ref yDot);
                    MathF.TransformDotVec(ref lineEnd, ref xDot, ref yDot);

                    canvas.DrawDashLine(
                        objPos.X + lineStart.X,
                        objPos.Y + lineStart.Y,
                        0.0f,
                        objPos.X + lineEnd.X,
                        objPos.Y + lineEnd.Y,
                        0.0f,
                        DashPattern.Dash,
                        1.0f / dashPatternLength);
                }
            }
        }