/// <summary>Sets the vertices of this box to that specified by the given block /// but clipped to fit within a boundary.</summary> /// <param name="boundary">The clipping boundary. The vertices will be clipped to within this.</param> /// <param name="block">The position of the vertices.</param> /// <param name="zIndex">The depth of the vertices.</param> public void SetClipped(BoxRegion boundary, BoxRegion block, Renderman renderer, float zIndex) { // Clipping with no image/ affect on UVs: block.ClipBy(boundary); // And just apply the result: ApplyVertices(block, renderer, zIndex); }
/// <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>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> private 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>Sets the vertices of this box to that specified by the given block /// but clipped to fit within a boundary. At the same time, an image is applied /// to the block and its UV coordinates are also clipped.</summary> /// <param name="boundary">The clipping boundary. The vertices will be clipped to within this.</param> /// <param name="block">The position of the vertices.</param> /// <param name="renderer">The renderer that will render this block.</param> /// <param name="zIndex">The depth of the vertices.</param> /// <param name="imgLocation">The location of the image on the meshes atlas.</param> public UVBlock SetClipped(BoxRegion boundary,BoxRegion block,Renderman renderer,float zIndex,AtlasLocation imgLocation,UVBlock uvBlock){ // Image defines how big we want the image to be in pixels on the screen. // So firstly we need to find the ratio of how scaled our image actually is: float originalHeight=block.Height; float scaleX=imgLocation.Width/block.Width; float scaleY=imgLocation.Height/originalHeight; // We'll need to clip block and make sure the image block is clipped too: float blockX=block.X; float blockY=block.Y; if(block.ClipByChecked(boundary)){ // It actually got clipped - time to do some UV clipping too. // Apply the verts: ApplyVertices(block,renderer,zIndex); block.X-=blockX; block.Y-=blockY; block.MaxX-=blockX; block.MaxY-=blockY; // Flip the gaps (the clipped and now 'missing' sections) - UV's are inverted relative to the vertices. // Bottom gap is just block.Y: float bottomGap=block.Y; // Top gap is the original height - the new maximum; write it to the bottom gap: block.Y=originalHeight-block.MaxY; // Update the top gap: block.MaxY=originalHeight-bottomGap; // Image was in terms of real screen pixels, so now we need to scale it to being in 'actual image' pixels. // From there, the region block.X*=scaleX; block.MaxX*=scaleX; block.Y*=scaleY; block.MaxY*=scaleY; if(uvBlock==null || uvBlock.Shared){ // Create the UV block: uvBlock=new UVBlock(); } // Get the new max/min values: uvBlock.MinX=imgLocation.GetU(block.X+0.2f); uvBlock.MaxX=imgLocation.GetU(block.MaxX-0.2f); uvBlock.MaxY=imgLocation.GetV(block.MaxY-0.2f); uvBlock.MinY=imgLocation.GetV(block.Y+0.2f); }else{ // Apply the verts: ApplyVertices(block,renderer,zIndex); // Globally share the UV! uvBlock=imgLocation; } return uvBlock; }
/// <summary>Sets the vertices of this box to that specified by the given block /// but clipped to fit within a boundary.</summary> /// <param name="boundary">The clipping boundary. The vertices will be clipped to within this.</param> /// <param name="block">The position of the vertices.</param> /// <param name="zIndex">The depth of the vertices.</param> public void SetClipped(BoxRegion boundary,BoxRegion block,Renderman renderer,float zIndex){ // Clipping with no image/ affect on UVs: block.ClipBy(boundary); // And just apply the result: ApplyVertices(block,renderer,zIndex); }
/// <summary>Sets the vertices of this box to that specified by the given block /// but clipped to fit within a boundary. At the same time, an image is applied /// to the block and its UV coordinates are also clipped.</summary> /// <param name="boundary">The clipping boundary. The vertices will be clipped to within this.</param> /// <param name="block">The position of the vertices.</param> /// <param name="renderer">The renderer that will render this block.</param> /// <param name="zIndex">The depth of the vertices.</param> /// <param name="imgLocation">The location of the image on the meshes atlas.</param> public UVBlock SetClipped(BoxRegion boundary, BoxRegion block, Renderman renderer, float zIndex, AtlasLocation imgLocation, UVBlock uvBlock) { // Image defines how big we want the image to be in pixels on the screen. // So firstly we need to find the ratio of how scaled our image actually is: float originalHeight = block.Height; float scaleX = imgLocation.Width / block.Width; float scaleY = imgLocation.Height / originalHeight; // We'll need to clip block and make sure the image block is clipped too: float blockX = block.X; float blockY = block.Y; if (block.ClipByChecked(boundary)) { // It actually got clipped - time to do some UV clipping too. // Apply the verts: ApplyVertices(block, renderer, zIndex); block.X -= blockX; block.Y -= blockY; block.MaxX -= blockX; block.MaxY -= blockY; // Flip the gaps (the clipped and now 'missing' sections) - UV's are inverted relative to the vertices. // Bottom gap is just block.Y: float bottomGap = block.Y; // Top gap is the original height - the new maximum; write it to the bottom gap: block.Y = originalHeight - block.MaxY; // Update the top gap: block.MaxY = originalHeight - bottomGap; // Image was in terms of real screen pixels, so now we need to scale it to being in 'actual image' pixels. // From there, the region block.X *= scaleX; block.MaxX *= scaleX; block.Y *= scaleY; block.MaxY *= scaleY; if (uvBlock == null || uvBlock.Shared) { // Create the UV block: uvBlock = new UVBlock(); } // Get the new max/min values: uvBlock.MinX = imgLocation.GetU(block.X + 0.2f); uvBlock.MaxX = imgLocation.GetU(block.MaxX - 0.2f); uvBlock.MaxY = imgLocation.GetV(block.MaxY - 0.2f); uvBlock.MinY = imgLocation.GetV(block.Y + 0.2f); } else { // Apply the verts: ApplyVertices(block, renderer, zIndex); // Globally share the UV! uvBlock = imgLocation; } return(uvBlock); }
/// <summary>This is the second pass of layout requests. /// It positions the element in global screen space and also fires the render events /// which in turn generate or reallocates mesh blocks. This call applies to all it's /// children elements too.</summary> /// <param name="relativeTo">The current style we are positioning relative to.</param> public void PositionGlobally(ComputedStyle relativeTo) { ComputedStyle computed = Style.Computed; if (computed.Display == DisplayType.None) { // Don't draw this element or it's kids. return; } // Position globally: if (computed.Position == PositionType.Fixed) { // Fixed elements are nice and simple to deal with - Their essentially absolutely positioned but relative to the html tag. ComputedStyle html = Document.html.style.Computed; if (computed.RightPositioned) { // The right hand edge of parent minus how far from the edge minus the width. computed.OffsetLeft = computed.MarginLeft + html.OffsetLeft + html.PixelWidth - computed.PositionRight - computed.PixelWidth; } else { computed.OffsetLeft = computed.MarginLeft + html.OffsetLeft + computed.PositionLeft; } if (computed.BottomPositioned) { computed.OffsetTop = computed.MarginTop + html.OffsetTop + html.PixelHeight - computed.PositionBottom - computed.PixelHeight; } else { computed.OffsetTop = computed.MarginTop + html.OffsetTop + computed.PositionTop; } // Change relativeTo here - we are now hopping to this fixed objects kids. relativeTo = computed; } else if (computed.Position == PositionType.Relative) { // Relative to where they should have been. PositionLeft/PositionRight etc. may be zero, but not always. // The width of border/padding/margin + the position of the parent + the offet from the parent. if (relativeTo == null) { computed.OffsetLeft = computed.MarginLeft + computed.ParentOffsetLeft; } else { computed.OffsetLeft = computed.MarginLeft + relativeTo.StyleOffsetLeft + relativeTo.OffsetLeft + computed.ParentOffsetLeft; } if (computed.RightPositioned) { computed.OffsetLeft -= computed.PositionRight; } else { computed.OffsetLeft += computed.PositionLeft; } if (relativeTo == null) { computed.OffsetTop = computed.MarginTop + computed.ParentOffsetTop; } else { computed.OffsetTop = computed.MarginTop + relativeTo.StyleOffsetTop + relativeTo.OffsetTop + computed.ParentOffsetTop; } if (computed.BottomPositioned) { computed.OffsetTop -= computed.PositionBottom; } else { computed.OffsetTop += computed.PositionTop; } // Vertical alignment: bool tableCell = (computed.Display == DisplayType.TableCell); if (relativeTo != null || computed.AutoMarginY || tableCell) { if (computed.AutoMarginY || relativeTo.VerticalAlign == VerticalAlignType.Middle || (tableCell && computed.VerticalAlign == VerticalAlignType.Middle)) { // Similar to below - we find the gap, then add *half* of that onto OffsetTop. if (tableCell) { // Move upwards - we're sitting on the line and want to be above it. computed.OffsetTop -= (relativeTo.InnerHeight - computed.PixelHeight) / 2; } else { computed.OffsetTop += (relativeTo.InnerHeight - relativeTo.ContentHeight) / 2; } } else if (relativeTo.VerticalAlign == VerticalAlignType.Bottom) { // Find the gap - parent height-contentHeight. // Then simply add that onto offsetTop. computed.OffsetTop += relativeTo.InnerHeight - relativeTo.ContentHeight; } else if (tableCell && computed.VerticalAlign == VerticalAlignType.Top) { // This time we find the gap and remove it - we're at the bottom by default as a td sits on the line. computed.OffsetTop -= relativeTo.InnerHeight - computed.PixelHeight; } } // Note: relativeTo does not change here if we're in an inline element: if (computed.Display != DisplayType.Inline) { relativeTo = computed; } } else { // Absolute - relative to parent. It's ParentOffsetLeft/Top are both zero. if (computed.RightPositioned) { // The right hand edge of parent minus how far from the edge minus the width. computed.OffsetLeft = computed.MarginLeft + relativeTo.OffsetLeft - relativeTo.StyleOffsetLeft - relativeTo.ScrollLeft + relativeTo.PixelWidth - computed.PositionRight - computed.PixelWidth; } else { computed.OffsetLeft = computed.MarginLeft + relativeTo.OffsetLeft + relativeTo.StyleOffsetLeft + relativeTo.ScrollLeft + computed.PositionLeft; } if (computed.BottomPositioned) { computed.OffsetTop = computed.MarginTop + relativeTo.OffsetTop - relativeTo.StyleOffsetTop - relativeTo.ScrollTop + relativeTo.PixelHeight - computed.PositionBottom - computed.PixelHeight; } else { computed.OffsetTop = computed.MarginTop + relativeTo.OffsetTop + relativeTo.StyleOffsetTop + relativeTo.ScrollTop + computed.PositionTop; } // Set relativeTo to this - this is because the kids of absolute objects are relative to the absolute object itself. relativeTo = computed; } // Push the transform to our stack, if we have one. if (computed.Transform != null) { // Add it to the stack: Document.Renderer.Transformations.Push(computed.Transform); // Update it: computed.Transform.RecalculateMatrix(computed); } // Great, it's good to go! computed.Render(); if (KidsToRender != null || HScrollbar || VScrollbar) { BoxRegion parentBoundary = null; if (relativeTo == computed) { // We changed who we're relative to. // Change the clipping boundary: Renderman renderer = Document.Renderer; parentBoundary = renderer.ClippingBoundary; renderer.SetBoundary(computed); } if (KidsToRender != null) { for (int i = 0; i < KidsToRender.Count; i++) { Element child = KidsToRender[i]; if (child != null) { child.PositionGlobally(relativeTo); } } } if (HScrollbar) { HorizontalScrollbar.Element.PositionGlobally(relativeTo); } if (VScrollbar) { VerticalScrollbar.Element.PositionGlobally(relativeTo); } if (relativeTo == computed) { // Restore the previous boundary before this one: [Note - can't use SetBoundary here as it would destroy the box.] Document.Renderer.ClippingBoundary = parentBoundary; } } if (computed.Transform != null) { // Pop it off again: Document.Renderer.Transformations.Pop(); } }
/// <summary>Sets the clipping boundary from the given computed style.</summary> /// <param name="style">The computed style to find the clipping boundary from.</param> public void SetBoundary(ComputedStyle style){ bool visibleX=(style.OverflowX==OverflowType.Visible); bool visibleY=(style.OverflowY==OverflowType.Visible); if(visibleX && visibleY){ return; } BoxRegion newBoundary=null; if(visibleX){ newBoundary=new BoxRegion(ClippingBoundary.X,style.OffsetTop+style.StyleOffsetTop+style.ScrollTop,ClippingBoundary.Width,style.InnerHeight); }else if(visibleY){ newBoundary=new BoxRegion(style.OffsetLeft+style.StyleOffsetLeft+style.ScrollLeft,ClippingBoundary.Y,style.InnerWidth,ClippingBoundary.Height); }else{ newBoundary=new BoxRegion(style.OffsetLeft+style.StyleOffsetLeft+style.ScrollLeft,style.OffsetTop+style.StyleOffsetTop+style.ScrollTop,style.InnerWidth,style.InnerHeight); } if(style.Clip){ newBoundary.ClipBy(ClippingBoundary); } ClippingBoundary=newBoundary; }
/// <summary>Creates a new renderer and a new document.</summary> public Renderman(){ ClippingBoundary=new BoxRegion(0,0,Screen.width,Screen.height); RootDocument=new Document(this); RootDocument.location=new FilePath("resources://","",false); }