예제 #1
0
        /// <summary>This locates the vertices of this block in world space to the position defined by the given box.</summary>
        /// <param name="block">The position of the vertices in screen coordinates.</param>
        /// <param name="renderer">The renderer used when rendering this block.</param>
        /// <param name="zIndex">The depth of the vertices.</param>
        internal void ApplyVertices(BoxRegion block, Renderman renderer, float zIndex)
        {
            // Compute the min/max pixels:
            Vector3 min = renderer.PixelToWorldUnit(block.X, block.Y, zIndex);
            Vector3 max = renderer.PixelToWorldUnit(block.MaxX, block.MaxY, zIndex);

            // Get the 4 corners:
            VertexTopLeft     = min;
            VertexBottomRight = max;
            VertexTopRight    = new Vector3(max.x, min.y, min.z);
            VertexBottomLeft  = new Vector3(min.x, max.y, min.z);
        }
        /// <summary>Calculates where the transformation origin should go in screen space.</summary>
        /// <param name="relativeTo">The computed style of the element that the origin will be
        /// relative to if the origin position is 'Relative'</param>
        private void CalculateOrigin(ComputedStyle relativeTo)
        {
            // We need to figure out where the origin is and then apply the parent transformation to it.
            _Origin = _OriginOffset;

            if (_OriginOffsetPercX)
            {
                _Origin.x *= relativeTo.PixelWidth;
            }

            if (_OriginOffsetPercY)
            {
                _Origin.y *= relativeTo.PixelHeight;
            }

            if (_OriginPosition == PositionType.Relative)
            {
                _Origin.x += relativeTo.OffsetLeft;
                _Origin.y += relativeTo.OffsetTop;
            }

            // Map origin to world space:
            Renderman renderer = relativeTo.Element.Document.Renderer;

            _Origin = renderer.PixelToWorldUnit(_Origin.x, _Origin.y, relativeTo.ZIndex);

            if (Parent != null)
            {
                _Origin = Parent.Apply(_Origin);
            }
        }
예제 #3
0
        /// <summary>Called during the layout pass.</summary>
        public override void OnRender(Renderman renderer)
        {
            if (ParticleTransform == null)
            {
                return;
            }

            // Grab the computed style and the renderer:
            ComputedStyle computed = Style.Computed;
            LayoutBox     box      = computed.FirstBox;

            if (box == null)
            {
                // display:none.
                return;
            }

            // Get the top left inner corner (inside margin and border):
            float width  = box.PaddedWidth;
            float height = box.PaddedHeight;
            float top    = box.Y + box.Border.Top;
            float left   = box.X + box.Border.Left;

            // Figure out the middle of that:
            float middleX = left + (width / 2);
            float middleY = top + (height / 2);

            // Map it to our world location:
            ParticleTransform.localPosition = renderer.PixelToWorldUnit(middleX, middleY, computed.ZIndex);

            BatchProperty.GotBatchAlready = false;

            // Setup the batch (so we can get the queue number):
            renderer.SetupBatch(BatchProperty, null, null);

            // Set the particle material to the batch - this'll ensure it gets the right renderQueue:
            renderer.CurrentBatch.Mesh.SetMaterial(ParticleMaterial);
        }
        public void Render(float alpha, float cornerX, float cornerY)
        {
            // Grab the renderer:
            Renderman renderer = RoundCorners.Renderer;

            // Get the z-Index:
            float zIndex = renderer.Depth + 0.006f;

            // Figure out where half way is (divide by 2):
            int halfway = (BlocksRequired >> 1);

            Color colour;

            if (Border.Colour == null)
            {
                if (RoundCorners.Computed.Text != null)
                {
                    // Same as the font colour:
                    colour = RoundCorners.Computed.Text.FontColour;
                }
                else
                {
                    // Get the default colour:
                    colour = Color.black;

                    // Alpha is required:
                    colour.a = alpha;
                }
            }
            else if (Border.Colour.Length == 1)
            {
                // Get the only colour:
                colour = Border.Colour[0];
            }
            else
            {
                // Get the first colour:
                colour = Border.Colour[FromIndex];
            }

            // Grab the clipping boundary:
            BoxRegion clip = renderer.ClippingBoundary;

            // Make it relative to the corners location:
            float minClipX = clip.X - cornerX;
            float minClipY = clip.Y - cornerY;
            float maxClipX = clip.MaxX - cornerX;
            float maxClipY = clip.MaxY - cornerY;

            // For each block..
            for (int i = 0; i < BlocksRequired; i++)
            {
                // Get a block:
                MeshBlock block = Border.Add();

                // Read the outer arc:
                Vector2 outerPointA = OuterArc[i];

                // Figure out the bounding box (constant for a particular block).
                float minX = outerPointA.x;
                float maxX = minX;
                float minY = outerPointA.y;
                float maxY = minY;

                Vector2 outerPointB = OuterArc[i + 1];

                // Update the bounding box:
                if (outerPointB.x < minX)
                {
                    minX = outerPointB.x;
                }
                else if (outerPointB.x > maxX)
                {
                    maxX = outerPointB.x;
                }

                if (outerPointB.y < minY)
                {
                    minY = outerPointB.y;
                }
                else if (outerPointB.y > maxY)
                {
                    maxY = outerPointB.y;
                }

                // Line segment A->B on the "outer" arc.

                // Read the inner arc:
                Vector2 innerPointA = InnerArc[i];

                // Update the bounding box:
                if (innerPointA.x < minX)
                {
                    minX = innerPointA.x;
                }
                else if (innerPointA.x > maxX)
                {
                    maxX = innerPointA.x;
                }

                if (innerPointA.y < minY)
                {
                    minY = innerPointA.y;
                }
                else if (innerPointA.y > maxY)
                {
                    maxY = innerPointA.y;
                }

                Vector2 innerPointB = InnerArc[i + 1];

                // Update the bounding box:
                if (innerPointB.x < minX)
                {
                    minX = innerPointB.x;
                }
                else if (innerPointB.x > maxX)
                {
                    maxX = innerPointB.x;
                }

                if (innerPointB.y < minY)
                {
                    minY = innerPointB.y;
                }
                else if (innerPointB.y > maxY)
                {
                    maxY = innerPointB.y;
                }

                // How does our bounding box compare to the clipping region?
                if (maxX < minClipX)
                {
                    continue;
                }
                else if (minX > maxClipX)
                {
                    continue;
                }

                if (maxY < minClipY)
                {
                    continue;
                }
                else if (minY > maxClipY)
                {
                    continue;
                }

                // Line segment A->B on the "inner" arc.

                // Set the UV to that of the solid block colour pixel:
                block.SetSolidColourUV();

                // Get the border colour:
                if (i == halfway)
                {
                    // Get the next colour:

                    if (Border.Colour != null && Border.Colour.Length != 1)
                    {
                        colour = Border.Colour[ToIndex];
                    }
                }

                // Set the border colour:
                block.SetColour(colour);

                // Apply the block region:
                block.VertexTopLeft  = renderer.PixelToWorldUnit(cornerX + outerPointA.x, cornerY + outerPointA.y, zIndex);
                block.VertexTopRight = renderer.PixelToWorldUnit(cornerX + outerPointB.x, cornerY + outerPointB.y, zIndex);

                block.VertexBottomLeft  = renderer.PixelToWorldUnit(cornerX + innerPointA.x, cornerY + innerPointA.y, zIndex);
                block.VertexBottomRight = renderer.PixelToWorldUnit(cornerX + innerPointB.x, cornerY + innerPointB.y, zIndex);
            }
        }
        /// <summary>Renders the inverse of this corner for the border.</summary>
        public void RenderInverse(float cornerX, float cornerY)
        {
            // Grab the renderer:
            Renderman renderer = RoundCorners.Renderer;

            // Get the z-Index:
            float zIndex = renderer.Depth + 0.004f;

            // Grab the size of the outer arc array:
            int arcSize = OuterArc.Length;

            int currentIndex = 0;

            // Resolve the corner:
            Vector3 corner = renderer.PixelToWorldUnit(cornerX, cornerY, zIndex);

            // Ensure a batch is available:
            InverseBorder.SetupBatch(null, null);

            // For each inverse block:
            for (int i = 0; i < InverseBlocksRequired; i++)
            {
                // Get a block:
                MeshBlock block = InverseBorder.Add();

                // Set the clear colour:
                block.SetColour(Color.clear);

                // Always going to be space to sample two. Sample the first:
                Vector2 outerPoint = OuterArc[currentIndex];

                // Apply the triangle:
                block.VertexTopRight = corner;

                // Apply the first:
                block.VertexTopLeft = renderer.PixelToWorldUnit(cornerX + outerPoint.x, cornerY + outerPoint.y, zIndex);

                // Sample the second:
                outerPoint = OuterArc[currentIndex + 1];

                // Apply the second:
                block.VertexBottomLeft = renderer.PixelToWorldUnit(cornerX + outerPoint.x, cornerY + outerPoint.y, zIndex);

                if ((currentIndex + 2) >= arcSize)
                {
                    // Match the previous vertex:
                    block.VertexBottomRight = block.VertexBottomLeft;
                }
                else
                {
                    // Grab the next point along:
                    outerPoint = OuterArc[currentIndex + 2];

                    // Resolve and apply the third:
                    block.VertexBottomRight = renderer.PixelToWorldUnit(cornerX + outerPoint.x, cornerY + outerPoint.y, zIndex);
                }

                // Move index along:
                currentIndex += 2;
            }
        }