protected Vector2d CalculateOffset(int frame) { var box = CameraBoundingBox.Create(Vector2d.Zero, _zoom); if (_prevframe != -1 && _prevframe <= frame && (frame - _prevframe) <= 1) { if (frame == _prevframe) { return(_prevcamera); } if (frame % cacherate != 0) { return(box.Clamp(StepCamera(box, ref _prevcamera, frame))); } } int cachepos = Math.Min(frame / cacherate, _framecache.Count - 1); int framestart = cachepos * cacherate; Vector2d start = _framecache[cachepos]; for (int i = framestart; i <= frame; i++) { if (i % cacherate == 0 && i / cacherate == _framecache.Count) { _framecache.Add(start); } start = StepCamera(box, ref start, i); } // Debug.WriteLine("Calculating " + framestart + "-" + (frame) + " for legacy camera"); return(box.Clamp(start)); }
/// <summary> /// reduces the amount of movement the camera has to do to capture the /// rider. It does so predictively /// </summary> /// <returns>The reduced position in game coords</returns> private Vector2d CameraMotionReducer(int frame) { const int forwardcount = 40; EnsureFrame(frame + forwardcount); Vector2d offset = CalculateOffset(frame); var box = CameraBoundingBox.Create(Vector2d.Zero, _zoom); var framebox = CameraBoundingBox.Create( _frames[frame].RiderCenter, _zoom); Vector2d center = Vector2d.Zero; int math = 0; for (int i = 0; i < forwardcount; i++) { var f = _frames[frame + i]; offset = box.Clamp(offset + f.CameraOffset); center += framebox.Clamp(f.RiderCenter + offset); math++; } // force the rider to center at the beginning // it looks awkward to predict heavily at the start. if (frame < forwardcount) { return(Vector2d.Lerp( _frames[frame].RiderCenter, center / math, frame / (float)forwardcount)); } return(center / math); }
protected override Vector2d StepCamera(CameraBoundingBox box, ref Vector2d prev, int frame) { const double push = 0.8; const double pull = 0.01; CameraEntry entry = _frames[frame]; var ret = box.Clamp(prev + entry.CameraOffset); Angle a = Angle.FromVector(ret); double length = ret.Length; double prevlength = prev.Length; var edge = a.MovePoint( Vector2d.Zero, Math.Max(box.Bounds.Width, box.Bounds.Height)); double maxlength = box.Clamp(edge).Length; double lengthratio = length / maxlength; double prevratio = prevlength / maxlength; double diffratio = Math.Abs(lengthratio - prevratio); if (length > prevlength) { var dr = lengthratio - prevratio; var damper = lengthratio - (dr / 2); var delta = length - prevlength; delta *= Math.Max(0.05, push * (1 - Math.Max(0, damper))); length = prevlength + delta; } length -= length * pull; return(box.Clamp(a.MovePoint(Vector2d.Zero, length))); }
public override Vector2d GetFrameCamera(int frame) { base.GetFrameCamera(frame); var box = CameraBoundingBox.Create(_frames[frame].RiderCenter, _zoom); return(box.Clamp(CameraMotionReducer(frame))); }
private Vector2d Calculate(int frame) { if (_cacheframe != -1 && _cacheframe <= frame && (frame - _cacheframe) < 80) { return(ClampFrames( _cacheframe, (frame - _cacheframe), _cachepos)); } Vector2d framecenter = _frames[frame].RiderCenter; var box = new CameraBoundingBox(framecenter); if (Settings.RoundLegacyCamera) { box.SetupSmooth(_frames[frame].ppf, _zoom); } else { box.SetupLegacy(_zoom); } var framebounds = box.Bounds; int calcstart = 0; var ret = framecenter; var xfound = false; var yfound = false; for (int i = frame; i >= 0; i--) { var current = _frames[i].RiderCenter; var cmp = framecenter - current; // todo, i have no idea why this works. // seriously, ive tried so much stuff, but for the ellipse // camera i can't seem to make it work any better than with // width or height * 2 if (Math.Abs(cmp.X) >= framebounds.Width * 2) { xfound = true; } if (Math.Abs(cmp.Y) >= framebounds.Height * 2) { yfound = true; } if (xfound && yfound) { calcstart = i; break; } } var calccount = (frame - calcstart); return(ClampFrames(calcstart, calccount, _frames[calcstart].RiderCenter)); }
public static CameraBoundingBox Create(Vector2d center, float zoom) { CameraBoundingBox box = new CameraBoundingBox(new Vector2d(center.X, center.Y)); if (Settings.RoundLegacyCamera || Settings.SmoothCamera) { box.SetupSmooth(0, zoom); } else { box.SetupLegacy(zoom); } return(box); }
private Vector2d Clamp(Vector2d pos, Vector2d center, double ppf) { CameraBoundingBox box = new CameraBoundingBox(center); if (Settings.SmoothCamera) { box.SetupSmooth(ppf, _zoom); } else { box.SetupLegacy(_zoom); } return(box.Clamp(pos)); }
private Vector2d Clamp(Vector2d pos, int frame) { var entry = _frames[frame]; CameraBoundingBox box = new CameraBoundingBox(entry.RiderCenter); if (Settings.RoundLegacyCamera) { box.SetupSmooth(entry.ppf, _zoom); } else { box.SetupLegacy(_zoom); } return(box.Clamp(pos)); }
public DoubleRect getclamp(float zoom, int width, int height) { var ret = GetViewport(zoom, width, height); var pos = ret.Vector + (ret.Size / 2); var b = new CameraBoundingBox(pos); if (Settings.SmoothCamera || Settings.RoundLegacyCamera) { b.SetupSmooth(GetPPF(_currentframe), _zoom); return(b.Bounds); } else { b.SetupLegacy(_zoom); return(b.Bounds); } }
public DoubleRect getclamp(float zoom, int width, int height, Vector2d offset) { offset.Y = -offset.Y; //Flip Y value so it's up, not down var ret = GetViewport(zoom, width, height, offset); var pos = ret.Vector + (ret.Size / 2); var b = new CameraBoundingBox(pos); if (Settings.SmoothCamera || Settings.RoundLegacyCamera) { b.SetupSmooth(GetPPF(_currentframe), _zoom); return(b.Bounds); } else { b.SetupLegacy(_zoom); return(b.Bounds); } }
protected abstract Vector2d StepCamera(CameraBoundingBox box, ref Vector2d prev, int frame);
protected override Vector2d StepCamera(CameraBoundingBox box, ref Vector2d prev, int frame) { var entry = _frames[frame]; return(box.Clamp(prev + entry.CameraOffset)); }