private int CalculateFirstInteraction(RectLRTB changebounds) { int framecount = _frames.Count; for (int frame = 1; frame < framecount; frame++) { if (!changebounds.Intersects(_frames[frame].PhysicsBounds)) { continue; } foreach (var change in _changedcells) { if (_frames[frame].PhysicsBounds.ContainsPoint(change)) { if (CheckInteraction(frame)) { return(frame); } // we dont have to check this rider more than once! break; } } } return(-1); }
private Rider(SimulationPoint[] body, SimulationPoint[] scarf, RectLRTB physbounds, bool dead, bool sledbroken) { Body = new ImmutablePointCollection(body); Scarf = new ImmutablePointCollection(scarf); Crashed = dead; SledBroken = sledbroken; PhysicsBounds = physbounds; }
private Rider(SimulationPoint[] body, SimulationPoint[] scarf, RectLRTB physbounds, bool dead, bool sledbroken, bool useRemount, int rState = 0, int rTimer = 0) { Body = new ImmutablePointCollection(body); Scarf = new ImmutablePointCollection(scarf); Crashed = dead; SledBroken = sledbroken; PhysicsBounds = physbounds; UseRemount = useRemount; remountState = rState; remountTimer = rTimer; }
public List <int> Diagnose( ISimulationGrid grid, Bone[] bones, int maxiteration = 6) { var ret = new List <int>(); if (Crashed) { return(ret); } Debug.Assert(maxiteration != 0, "Momentum tick can't die but attempted diagnose"); SimulationPoint[] body = Body.Step(); int bodylen = Body.Length; bool dead = Crashed; int rState = remountState; RectLRTB phys = new RectLRTB(ref body[0]); List <int> breaks = new List <int>(); using (grid.Sync.AcquireRead()) { for (int i = 0; i < maxiteration; i++) { ProcessBones(bones, body, ref dead, ref rState, breaks); if (dead) { return(breaks); } ProcessLines(grid, body, ref phys); } } if (maxiteration == 6) { var nose = body[RiderConstants.SledTR].Location - body[RiderConstants.SledTL].Location; var tail = body[RiderConstants.SledBL].Location - body[RiderConstants.SledTL].Location; var head = body[RiderConstants.BodyShoulder].Location - body[RiderConstants.BodyButt].Location; if ((nose.X * tail.Y) - (nose.Y * tail.X) < 0) // tail fakie { dead = true; ret.Add(-1); } if ((nose.X * head.Y) - (nose.Y * head.X) > 0)// head fakie { dead = true; ret.Add(-2); } } return(ret); }
public static Rider Create(Vector2d start, Vector2d momentum, bool useRemount) { var joints = new SimulationPoint[RiderConstants.DefaultRider.Length]; var scarf = new SimulationPoint[RiderConstants.DefaultScarf.Length + 1]; RectLRTB pbounds = new RectLRTB(); for (int i = 0; i < joints.Length; i++) { var coord = (RiderConstants.DefaultRider[i] + start); var prev = coord - momentum; switch (i) { case RiderConstants.SledTL: case RiderConstants.BodyButt: case RiderConstants.BodyShoulder: joints[i] = new SimulationPoint(coord, prev, Vector2d.Zero, 0.8); break; case RiderConstants.BodyHandLeft: case RiderConstants.BodyHandRight: joints[i] = new SimulationPoint(coord, prev, Vector2d.Zero, 0.1); break; default: joints[i] = new SimulationPoint(coord, prev, Vector2d.Zero, 0.0); break; } if (i == 0) { pbounds = new RectLRTB(ref joints[0]); } else { var cellx = (int)Math.Floor(joints[i].Location.X / 14); var celly = (int)Math.Floor(joints[i].Location.Y / 14); pbounds.left = Math.Min(cellx - 1, pbounds.left); pbounds.top = Math.Min(celly - 1, pbounds.top); pbounds.right = Math.Max(cellx + 1, pbounds.right); pbounds.bottom = Math.Max(celly + 1, pbounds.bottom); } } scarf[0] = joints[RiderConstants.BodyShoulder]; for (int i = 0; i < RiderConstants.DefaultScarf.Length; i++) { var pos = scarf[0].Location + RiderConstants.DefaultScarf[i]; scarf[i + 1] = new SimulationPoint(pos, pos, Vector2d.Zero, 0.9); } return(new Rider(joints, scarf, pbounds, false, false, useRemount)); }
public Rider Simulate( ISimulationGrid grid, Bone[] bones, ref int activetriggers, LinkedList <int> collisions, int maxiteration = 6, bool stepscarf = true, int frameid = 0) { SimulationPoint[] body = Body.Step(); int bodylen = Body.Length; bool dead = Crashed; bool sledbroken = SledBroken; RectLRTB phys = new RectLRTB(ref body[0]); using (grid.Sync.AcquireRead()) { for (int i = 0; i < maxiteration; i++) { ProcessBones(bones, body, ref dead); ProcessLines(grid, body, ref phys, ref activetriggers, collisions); } } if (maxiteration == 6) { var nose = body[RiderConstants.SledTR].Location - body[RiderConstants.SledTL].Location; var tail = body[RiderConstants.SledBL].Location - body[RiderConstants.SledTL].Location; var head = body[RiderConstants.BodyShoulder].Location - body[RiderConstants.BodyButt].Location; if ((nose.X * tail.Y) - (nose.Y * tail.X) < 0 || // tail fakie (nose.X * head.Y) - (nose.Y * head.X) > 0) // head fakie { dead = true; sledbroken = true; } } SimulationPoint[] scarf; if (stepscarf) { scarf = Scarf.Step(friction: true); scarf[0] = body[RiderConstants.BodyShoulder]; FlutterScarf(scarf, frameid, Utility.LengthFast(scarf[0].Momentum)); ProcessScarfBones(RiderConstants.ScarfBones, scarf); } else { scarf = new SimulationPoint[Scarf.Length]; } return(new Rider(body, scarf, phys, dead, sledbroken)); }
private unsafe static void ProcessLines( ISimulationGrid grid, SimulationPoint[] body, ref RectLRTB physinfo, ref int activetriggers, LinkedList <int> collisions = null) { int bodylen = body.Length; for (int i = 0; i < bodylen; i++) { var startpos = body[i].Location; var cellx = (int)Math.Floor(startpos.X / 14); var celly = (int)Math.Floor(startpos.Y / 14); //every itreration is at least 3x3, so asjust the info for that physinfo.left = Math.Min(cellx - 1, physinfo.left); physinfo.top = Math.Min(celly - 1, physinfo.top); physinfo.right = Math.Max(cellx + 1, physinfo.right); physinfo.bottom = Math.Max(celly + 1, physinfo.bottom); for (var x = -1; x <= 1; x++) { for (var y = -1; y <= 1; y++) { var cell = grid.GetCell(cellx + x, celly + y); if (cell == null) { continue; } foreach (var line in cell) { if (line.Interact(ref body[i])) { collisions?.AddLast(line.ID); if (line.Trigger != null) { if (activetriggers != line.ID) { activetriggers = line.ID; } } } } } } } }
private int FindUpdateStart() { if (_changedcells.Count == 0) { return(-1); } RectLRTB changebounds = new RectLRTB(_changedcells.First()); foreach (var cell in _changedcells) { changebounds.left = Math.Min(cell.X, changebounds.left); changebounds.top = Math.Min(cell.Y, changebounds.top); changebounds.right = Math.Max(cell.X, changebounds.right); changebounds.bottom = Math.Max(cell.Y, changebounds.bottom); } return(CalculateFirstInteraction(changebounds)); }
public Rider Simulate( ISimulationGrid grid, Bone[] bones, LinkedList <int> collisions, int maxiteration = 6, bool stepscarf = true, int frameid = 0) { SimulationPoint[] body = Body.Step(); int bodylen = Body.Length; bool dead = Crashed; bool sledbroken = SledBroken; int rState = remountState; int rTimer = remountTimer; RectLRTB phys = new RectLRTB(ref body[0]); using (grid.Sync.AcquireRead()) { for (int i = 0; i < maxiteration; i++) { ProcessBones(bones, body, ref dead, ref rState); ProcessLines(grid, body, ref phys, collisions); } } if (maxiteration == 6) { var nose = body[RiderConstants.SledTR].Location - body[RiderConstants.SledTL].Location; var tail = body[RiderConstants.SledBL].Location - body[RiderConstants.SledTL].Location; var head = body[RiderConstants.BodyShoulder].Location - body[RiderConstants.BodyButt].Location; if (!dead && ((nose.X * tail.Y) - (nose.Y * tail.X) < 0 || // tail fakie (nose.X * head.Y) - (nose.Y * head.X) > 0)) // head fakie { dead = true; sledbroken = true; } } if (UseRemount) { ProcessRemount(bones, body, ref dead, ref sledbroken, ref rState, ref rTimer); } SimulationPoint[] scarf; if (stepscarf) { scarf = Scarf.Step(friction: true); if (Settings.multiScarfAmount * Settings.multiScarfSegments > RiderConstants.ScarfBones.Length) { Settings.multiScarfAmount = 1; } //if too big set to zero if (Settings.multiScarfAmount > 1) //If using dual scarf { List <SimulationPoint>[] scarves = new List <SimulationPoint> [Settings.multiScarfAmount]; List <SimulationPoint> finalScarf = new List <SimulationPoint>(); for (int i = 0; i < Settings.multiScarfAmount; i++) { scarf[i * Settings.multiScarfSegments] = body[RiderConstants.BodyShoulder]; scarves[i] = new List <SimulationPoint>(); if (i != Settings.multiScarfAmount - 1) { for (int k = 0; k < Settings.multiScarfSegments; k++) { scarves[i].Add(scarf[k + (i * Settings.multiScarfSegments)]); } } else { for (int k = 0; k < scarf.Length - (i * Settings.multiScarfSegments); k++) { scarves[i].Add(scarf[k + (i * Settings.multiScarfSegments)]); } } SimulationPoint[] scarfArr = scarves[i].ToArray(); FlutterScarf(scarfArr, frameid, Utility.LengthFast(scarf[i * Settings.multiScarfSegments].Momentum) + (i * 5)); ProcessScarfBones(RiderConstants.ScarfBones, scarfArr); for (int j = 0; j < scarfArr.Length; j++) { finalScarf.Add(scarfArr[j]); } } scarf = finalScarf.ToArray(); } else { scarf[0] = body[RiderConstants.BodyShoulder]; FlutterScarf(scarf, frameid, Utility.LengthFast(scarf[0].Momentum)); ProcessScarfBones(RiderConstants.ScarfBones, scarf); } } else { scarf = new SimulationPoint[Scarf.Length]; } return(new Rider(body, scarf, phys, dead, sledbroken, UseRemount, rState, rTimer)); }