/// <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); } }
/// <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; } }