/// <summary> /// Performs an object lookup in the picking map that was rendered last /// time <see cref="RenderSetup.RenderPointOfView"/> was called. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="w"></param> /// <param name="h"></param> public IEnumerable <ICmpRenderer> LookupPickingMap(int x, int y, int w, int h) { if (this.pickingBuffer == null) { return(Enumerable.Empty <ICmpRenderer>()); } if ((x + w) + (y + h) * this.pickingTex.ContentWidth >= this.pickingBuffer.Length) { return(Enumerable.Empty <ICmpRenderer>()); } Rect dstRect = new Rect(x, y, w, h); Rect availRect = new Rect(this.pickingTex.ContentSize); if (!dstRect.Intersects(availRect)) { return(Enumerable.Empty <ICmpRenderer>()); } dstRect = dstRect.Intersection(availRect); x = Math.Max((int)dstRect.X, 0); y = Math.Max((int)dstRect.Y, 0); w = Math.Min((int)dstRect.W, this.pickingTex.ContentWidth - x); h = Math.Min((int)dstRect.H, this.pickingTex.ContentHeight - y); HashSet <ICmpRenderer> result = new HashSet <ICmpRenderer>(); int rendererIdLast = 0; for (int j = 0; j < h; ++j) { int offset = 4 * (x + (y + j) * this.pickingTex.ContentWidth); for (int i = 0; i < w; ++i) { int rendererId = (this.pickingBuffer[offset] << 16) | (this.pickingBuffer[offset + 1] << 8) | (this.pickingBuffer[offset + 2] << 0); if (rendererId != rendererIdLast) { if (rendererId - 1 > this.pickingMap.Count) { Logs.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; } offset += 4; } } return(result); }
/// <summary> /// Picks the <see cref="Duality.ICmpRenderer"/> that owns the pixel at the specified position. /// The resulting information is only accurate if <see cref="RenderPickingMap"/> has been called this frame. /// </summary> /// <param name="x">x-Coordinate of the pixel to check.</param> /// <param name="y">y-Coordinate of the pixel to check.</param> /// <returns>The <see cref="Duality.ICmpRenderer"/> that owns the pixel.</returns> public ICmpRenderer PickRendererAt(int x, int y) { if (this.pickingBuffer == null) { return(null); } if (x < 0 || x >= this.pickingTex.PixelWidth) { return(null); } if (y < 0 || y >= this.pickingTex.PixelHeight) { return(null); } x = MathF.Clamp(x, 0, this.pickingTex.PixelWidth - 1); y = MathF.Clamp(y, 0, this.pickingTex.PixelHeight - 1); int baseIndex = 4 * (x + y * this.pickingTex.PixelWidth); if (baseIndex + 4 >= this.pickingBuffer.Length) { return(null); } int rendererId = (this.pickingBuffer[baseIndex + 0] << 16) | (this.pickingBuffer[baseIndex + 1] << 8) | (this.pickingBuffer[baseIndex + 2] << 0); if (rendererId > this.pickingMap.Count) { Log.Core.WriteWarning("Unexpected picking result: {0}", ColorRgba.FromIntArgb(rendererId)); return(null); } else if (rendererId != 0) { if ((this.pickingMap[rendererId - 1] as Component).Disposed) { return(null); } else { return(this.pickingMap[rendererId - 1]); } } else { return(null); } }
/// <summary> /// Performs an object lookup in the picking map that was rendered last /// time <see cref="RenderSetup.RenderPointOfView"/> was called. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public ICmpRenderer LookupPickingMap(int x, int y) { if (this.pickingBuffer == null) { return(null); } if (x < 0 || x >= this.pickingTex.ContentWidth) { return(null); } if (y < 0 || y >= this.pickingTex.ContentHeight) { return(null); } int baseIndex = 4 * (x + y * this.pickingTex.ContentWidth); if (baseIndex + 4 >= this.pickingBuffer.Length) { return(null); } int rendererId = (this.pickingBuffer[baseIndex + 0] << 16) | (this.pickingBuffer[baseIndex + 1] << 8) | (this.pickingBuffer[baseIndex + 2] << 0); if (rendererId > this.pickingMap.Count) { App.Log("Unexpected picking result: {0}", ColorRgba.FromIntArgb(rendererId)); return(null); } else if (rendererId != 0) { if ((this.pickingMap[rendererId - 1] as Component).Disposed) { return(null); } else { return(this.pickingMap[rendererId - 1]); } } else { return(null); } }
/// <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> /// <param name="viewportRect">The viewport area to which will be rendered.</param> /// <returns>A set of all <see cref="Duality.ICmpRenderer">ICmpRenderers</see> that have been picked.</returns> public HashSet <ICmpRenderer> PickRenderersIn(Rect viewportRect, int x, int y, int w, int h) { Rect dstRect = new Rect(x, y, w, h); if (!dstRect.Intersects(viewportRect)) { return(new HashSet <ICmpRenderer>()); } dstRect = dstRect.Intersection(viewportRect); dstRect.X -= viewportRect.X; dstRect.Y -= viewportRect.Y; this.RenderPickingMap(viewportRect.Size); 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; for (int j = 0; j < h; ++j) { int offset = 4 * (x + (y + j) * this.pickingTex.PixelWidth); for (int i = 0; i < w; ++i) { int rendererId = (this.pickingBuffer[offset] << 16) | (this.pickingBuffer[offset + 1] << 8) | (this.pickingBuffer[offset + 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; } offset += 4; } } return(result); }
/// <summary> /// Picks the <see cref="Duality.ICmpRenderer"/> that owns the pixel at the specified position. /// </summary> /// <param name="x">x-Coordinate of the pixel to check.</param> /// <param name="y">y-Coordinate of the pixel to check.</param> /// <param name="viewportRect">The viewport area to which will be rendered.</param> /// <returns>The <see cref="Duality.ICmpRenderer"/> that owns the pixel.</returns> public ICmpRenderer PickRendererAt(Rect viewportRect, int x, int y) { if (x < viewportRect.LeftX || x >= viewportRect.RightX) { return(null); } if (y < viewportRect.TopY || y >= viewportRect.BottomY) { return(null); } this.RenderPickingMap(viewportRect.Size); x = MathF.Clamp(x - (int)viewportRect.X, 0, this.pickingTex.PixelWidth - 1); y = MathF.Clamp(y - (int)viewportRect.Y, 0, this.pickingTex.PixelHeight - 1); int rendererId = (this.pickingBuffer[4 * (x + y * this.pickingTex.PixelWidth) + 0] << 16) | (this.pickingBuffer[4 * (x + y * this.pickingTex.PixelWidth) + 1] << 8) | (this.pickingBuffer[4 * (x + y * this.pickingTex.PixelWidth) + 2] << 0); if (rendererId > this.pickingMap.Count) { Log.Core.WriteWarning("Unexpected picking result: {0}", ColorRgba.FromIntArgb(rendererId)); return(null); } else if (rendererId != 0) { if ((this.pickingMap[rendererId - 1] as Component).Disposed) { return(null); } else { return(this.pickingMap[rendererId - 1]); } } else { return(null); } }
/// <summary> /// Picks the <see cref="Duality.ICmpRenderer"/> that owns the pixel at the specified position. /// </summary> /// <param name="x">x-Coordinate of the pixel to check.</param> /// <param name="y">y-Coordinate of the pixel to check.</param> /// <returns>The <see cref="Duality.ICmpRenderer"/> that owns the pixel.</returns> public ICmpRenderer PickRendererAt(int x, int y) { if (x < 0 || x >= DualityApp.TargetResolution.X) { return(null); } if (y < 0 || y >= DualityApp.TargetResolution.Y) { return(null); } this.RenderPickingMap(); x = MathF.Clamp(x, 0, this.pickingTex.PixelWidth - 1); y = MathF.Clamp(y, 0, this.pickingTex.PixelHeight - 1); int rendererId = (this.pickingBuffer[4 * (x + y * this.pickingTex.PixelWidth) + 0] << 16) | (this.pickingBuffer[4 * (x + y * this.pickingTex.PixelWidth) + 1] << 8) | (this.pickingBuffer[4 * (x + y * this.pickingTex.PixelWidth) + 2] << 0); if (rendererId > this.pickingMap.Count) { Log.Core.WriteWarning("Unexpected picking result: {0}", ColorRgba.FromIntArgb(rendererId)); return(null); } else if (rendererId != 0) { if ((this.pickingMap[rendererId - 1] as Component).Disposed) { return(null); } else { return(this.pickingMap[rendererId - 1]); } } else { return(null); } }
/// <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); }