public void Update(RotateZoomEffectConfigToken token) { Transform(token, 0, 0, out startX, out startY, out startZ); Transform(token, 1, 0, out dsxdx, out dsydx, out dszdx); Transform(token, 0, 1, out dsxdy, out dsydy, out dszdy); dsxdx -= startX; dsydx -= startY; dszdx -= startZ; dsxdy -= startX; dsydy -= startY; dszdy -= startZ; }
protected RotateZoomEffectConfigToken(RotateZoomEffectConfigToken copyMe) { this.highQuality = copyMe.highQuality; this.preRotateZ = copyMe.preRotateZ; this.postRotateZ = copyMe.postRotateZ; this.tilt = copyMe.tilt; this.zoom = copyMe.zoom; this.offset = copyMe.offset; this.sourceAsBackground = copyMe.sourceAsBackground; this.tile = copyMe.tile; UpdateRzInfo(); }
protected override void InitDialogFromToken(EffectConfigToken effectToken) { RotateZoomEffectConfigToken token = (RotateZoomEffectConfigToken)effectToken; double r = Math.Sin(token.Tilt) * 90; double t = -token.PreRotateZ; panControl.Position = token.Offset; rollControl.Angle = (token.PostRotateZ - t) * 180 / Math.PI; rollControl.RollDirection = 180 * t / Math.PI; rollControl.RollAmount = r; keepBackgroundCheckBox.Checked = token.SourceAsBackground; tileSourceCheckBox.Checked = token.Tile; trackBarZoom.Value = (int)Math.Round(512 + 128 * Math.Log(token.Zoom, 2.0)); TrackBarZoom_ValueChanged(this, EventArgs.Empty); }
protected override void InitTokenFromDialog() { RotateZoomEffectConfigToken token = (RotateZoomEffectConfigToken)theEffectToken; double angle = rollControl.RollDirection * Math.PI / 180; double dist = rollControl.RollAmount; if (double.IsNaN(angle)) { angle = 0; dist = 0; } token.Offset = panControl.Position; token.PreRotateZ = (float)(angle); token.PostRotateZ = (float)(-angle - rollControl.Angle * Math.PI / 180); token.Tilt = (float)Math.Asin(dist / 90); token.SourceAsBackground = keepBackgroundCheckBox.Checked; token.Tile = tileSourceCheckBox.Checked; token.Zoom = (float)Math.Pow(2.0, (trackBarZoom.Value - 512) / 128.0); }
private void Transform(RotateZoomEffectConfigToken token, int x, int y, out float sx, out float sy, out float sz) { float rb = token.preRotateZ; float ra = token.postRotateZ; float r = -token.tilt; float crb = (float)Math.Cos(rb); float cr = (float)Math.Cos(r); float cra = (float)Math.Cos(ra); float srb = (float)Math.Sin(rb); float sr = (float)Math.Sin(r); float sra = (float)Math.Sin(ra); float ox = x, oy = y, oz = 0; sx = (ox * crb + oy * srb) / cr; sy = -ox * srb + oy * crb; sz = sx * sr; sx = sx / cr; ox = sx; oy = sy; oz = sz; sx = ox * cra + oy * sra; sy = -ox * sra + oy * cra; }
protected override void InitialInitToken() { theEffectToken = new RotateZoomEffectConfigToken(true, 0, 0, 0, 1.0f, PointF.Empty, false, false); }
public unsafe override void Render(EffectConfigToken parameters, RenderArgs dstArgs, RenderArgs srcArgs, Rectangle[] rois, int startIndex, int length) { RotateZoomEffectConfigToken token = (RotateZoomEffectConfigToken)parameters; RotateZoomEffectConfigToken.RzInfo rzInfo = token.ComputedOnce; Rectangle bounds = this.EnvironmentParameters.GetSelection(dstArgs.Bounds).GetBoundsInt(); bounds.Intersect(dstArgs.Bounds); Surface src = srcArgs.Surface; Surface dst = dstArgs.Surface; PdnRegion selection = this.EnvironmentParameters.GetSelection(src.Bounds); Rectangle srcBounds = src.Bounds; int srcMaxX = srcBounds.Width - 1; int srcMaxY = srcBounds.Height - 1; float dsxdx = rzInfo.dsxdx; float dsydx = rzInfo.dsydx; float dszdx = rzInfo.dszdx; float dsxdy = rzInfo.dsxdy; float dsydy = rzInfo.dsydy; float dszdy = rzInfo.dszdy; float zoom = token.Zoom; uint srcMask = token.SourceAsBackground ? 0xffffffff : 0; bool tile = token.Tile; float divZ = 0.5f * (float)Math.Sqrt(dst.Width * dst.Width + dst.Height * dst.Height); float centerX = (float)dst.Width / 2.0f; float centerY = (float)dst.Height / 2.0f; float tx = (token.Offset.X) * dst.Width / 2.0f; float ty = (token.Offset.Y) * dst.Height / 2.0f; uint tilingMask = tile ? 0xffffffff : 0; for (int i = startIndex; i < startIndex + length; ++i) { Rectangle rect = rois[i]; float cx = rzInfo.startX; float cy = rzInfo.startY; float cz = rzInfo.startZ; float mcl = ((rect.Left - tx) - dst.Width / 2.0f); cx += dsxdx * mcl; cy += dsydx * mcl; cz += dszdx * mcl; float mct = ((rect.Top - ty) - dst.Height / 2.0f); cx += dsxdy * mct; cy += dsydy * mct; cz += dszdy * mct; for (int y = rect.Top; y < rect.Bottom; ++y) { ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y); ColorBgra *srcPtr = src.GetPointAddressUnchecked(rect.Left, y); float rx = cx; float ry = cy; float rz = cz; for (int x = rect.Left; x < rect.Right; ++x) { if (rz > -divZ) { float div = divZ / (zoom * (divZ + rz)); float u = (rx * div) + centerX; float v = (ry * div) + centerY; if (tile || (u >= -1 && v >= -1 && u <= srcBounds.Width && v <= srcBounds.Height)) { unchecked { int iu = (int)Math.Floor(u); uint sxfrac = (uint)(256 * (u - (float)iu)); uint sxfracinv = 256 - sxfrac; int iv = (int)Math.Floor(v); uint syfrac = (uint)(256 * (v - (float)iv)); uint syfracinv = 256 - syfrac; uint wul = (uint)(sxfracinv * syfracinv); uint wur = (uint)(sxfrac * syfracinv); uint wll = (uint)(sxfracinv * syfrac); uint wlr = (uint)(sxfrac * syfrac); uint inBoundsMaskLeft = tilingMask; uint inBoundsMaskTop = tilingMask; uint inBoundsMaskRight = tilingMask; uint inBoundsMaskBottom = tilingMask; int sx = iu; if (sx < 0) { sx = srcMaxX + ((sx + 1) % srcBounds.Width); } else if (sx > srcMaxX) { sx = sx % srcBounds.Width; } else { inBoundsMaskLeft = 0xffffffff; } int sy = iv; if (sy < 0) { sy = srcMaxY + ((sy + 1) % srcBounds.Height); } else if (sy > srcMaxY) { sy = sy % srcBounds.Height; } else { inBoundsMaskTop = 0xffffffff; } int sleft = sx; int sright; if (sleft == srcMaxX) { sright = 0; inBoundsMaskRight = (iu == -1) ? 0xffffffff : tilingMask; } else { sright = sleft + 1; inBoundsMaskRight = inBoundsMaskLeft & 0xffffffff; } int stop = sy; int sbottom; if (stop == srcMaxY) { sbottom = 0; inBoundsMaskBottom = (iv == -1) ? 0xffffffff : tilingMask; } else { sbottom = stop + 1; inBoundsMaskBottom = inBoundsMaskTop & 0xffffffff; } uint maskUL = inBoundsMaskLeft & inBoundsMaskTop; ColorBgra cul = ColorBgra.FromUInt32(src.GetPointUnchecked(sleft, stop).Bgra & maskUL); uint maskUR = inBoundsMaskRight & inBoundsMaskTop; ColorBgra cur = ColorBgra.FromUInt32(src.GetPointUnchecked(sright, stop).Bgra & maskUR); uint maskLL = inBoundsMaskLeft & inBoundsMaskBottom; ColorBgra cll = ColorBgra.FromUInt32(src.GetPointUnchecked(sleft, sbottom).Bgra & maskLL); uint maskLR = inBoundsMaskRight & inBoundsMaskBottom; ColorBgra clr = ColorBgra.FromUInt32(src.GetPointUnchecked(sright, sbottom).Bgra & maskLR); ColorBgra c = ColorBgra.BlendColors4W16IP(cul, wul, cur, wur, cll, wll, clr, wlr); if (c.A == 255 || !token.SourceAsBackground) { dstPtr->Bgra = c.Bgra; } else { *dstPtr = PaintDotNet.UserBlendOps.NormalBlendOp.ApplyStatic(*srcPtr, c); } } } else { if (srcMask != 0) { dstPtr->Bgra = srcPtr->Bgra; } else { dstPtr->Bgra = 0; } } } else { if (srcMask != 0) { dstPtr->Bgra = srcPtr->Bgra; } else { dstPtr->Bgra = 0; } } rx += dsxdx; ry += dsydx; rz += dszdx; ++dstPtr; ++srcPtr; } cx += dsxdy; cy += dsydy; cz += dszdy; } } }