Example #1
0
        /// <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);
        }
Example #2
0
        /// <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);
            }
        }
Example #3
0
        /// <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);
            }
        }
Example #4
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>
        /// <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);
        }
Example #5
0
        /// <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);
            }
        }
Example #6
0
        /// <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);
            }
        }
Example #7
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);
        }