protected override void DoDraw(IBatchRenderer sbatch, FRectangle bounds) { if (_needsTabRecalc) { RecalcTabData(); } sbatch.FillRectangle(bounds, Background); float rowHeight = FontSize + 2 * LineWidth; float py = 0; // Header { sbatch.FillRectangle(new FRectangle(bounds.X, bounds.Y, bounds.Width - ScrollWidth, rowHeight), HeaderBackground); float x = 0; for (int i = 0; i < _columns.Count; i++) { if (FloatMath.IsZero(_columns[i].RealWidth)) { continue; } FontRenderHelper.DrawTextCentered( sbatch, Font, FontSize, _columns[i].Text, HeaderForeground, new FPoint(bounds.Left + x + _columns[i].RealWidth / 2f, bounds.Top + rowHeight / 2f)); x += _columns[i].RealWidth; } sbatch.DrawLine(bounds.Left, bounds.Top + rowHeight, bounds.Right - ScrollWidth, bounds.Top + rowHeight, LineColor, LineWidth); py += rowHeight; } // rows for (int di = (int)ScrollPosition; di < _data.Count; di++) { if (py + rowHeight > Height) { break; } float x = 0; for (int ci = 0; ci < _columns.Count; ci++) { if (FloatMath.IsZero(_columns[ci].RealWidth)) { continue; } FontRenderHelper.DrawTextVerticallyCentered( sbatch, Font, FontSize, _data[di].Data[ci], _data[di].ForegroundOverride ?? Foreground, new FPoint(bounds.Left + x + LineWidth * 2, bounds.Top + py + rowHeight / 2f)); x += _columns[ci].RealWidth; } sbatch.DrawLine(bounds.Left, bounds.Top + py + rowHeight, bounds.Right - ScrollWidth, bounds.Top + py + rowHeight, LineColor, LineWidth); py += rowHeight; } // scroll { var colPerPage = (int)(Height / rowHeight) - 1; var perc = FloatMath.Clamp(((int)ScrollPosition) / (1f * _data.Count - colPerPage), 0, 1); var pos = perc * (Height - ScrollHeight); sbatch.FillRectangle(new FRectangle(bounds.Right - ScrollWidth, bounds.Top + pos, ScrollWidth, ScrollHeight), ScrollThumbColor); } // Vert Lines { float x = 0; for (int i = 0; i < _columns.Count; i++) { x += _columns[i].RealWidth; sbatch.DrawLine(bounds.Left + x, bounds.Top, bounds.Left + x, bounds.Bottom, LineColor, LineWidth); } } sbatch.DrawRectangle(bounds, LineColor, LineWidth); }
public static void SetByteFloorRange(out byte target, float min, float max, float v) { SetByteFloor(out target, FloatMath.Clamp((v - min) / (max - min), 0f, 1f) * 255); }
private Vector4 Limit(Vector4 color) { return(new Vector4(FloatMath.Clamp(color.X, 0f, 255f), FloatMath.Clamp(color.Y, 0f, 255f), FloatMath.Clamp(color.Z, 0f, 255f), FloatMath.Clamp(color.W, 0f, 255f))); }
// test of rays hit each other private bool RayParallality(FPoint v1s, FPoint v1e, float v1d, FPoint v2s, FPoint v2e, float v2d, bool reflTolerant, out FPoint intersect, out float u) { var a1 = (v1e - v1s).ToAngle(); var a2 = (v2e - v2s).ToAngle(); var maxAngle = reflTolerant ? FloatMath.RAD_POS_004 : FloatMath.RAD_POS_090; if (FloatMath.DiffRadiansAbs(a1, a2) < maxAngle) { // same direction var u1 = v2s.ProjectOntoLine(v1s, v1e); var u2 = v1s.ProjectOntoLine(v2s, v2e); if (u1 > 0 && u1 < 1) { intersect = Math2D.PointOnLine(u1, v1s, v1e); u = u1; return(true); } if (u2 > 0 && u2 < 1) { intersect = v1s; u = 0; return(true); } } else if (FloatMath.DiffRadiansAbs(a1 + FloatMath.RAD_POS_180, a2) < maxAngle) { var u1s = FloatMath.Clamp(v2e.ProjectOntoLine(v1s, v1e), 0f, 1f); var u1e = FloatMath.Clamp(v2s.ProjectOntoLine(v1s, v1e), 0f, 1f); var u2s = FloatMath.Clamp(v1e.ProjectOntoLine(v2s, v2e), 0f, 1f); var u2e = FloatMath.Clamp(v1s.ProjectOntoLine(v2s, v2e), 0f, 1f); var v1rs = (u1s == 0) ? v1s : Math2D.PointOnLine(u1s, v1s, v1e); var v1re = (u1e == 1) ? v1e : Math2D.PointOnLine(u1e, v1s, v1e); var v2rs = (u2s == 0) ? v2s : Math2D.PointOnLine(u2s, v2s, v2e); var v2re = (u1e == 1) ? v2e : Math2D.PointOnLine(u2e, v2s, v2e); var distStart = (v1rs - v2re).LengthSquared(); var distEnd = (v1re - v2rs).LengthSquared(); if (distStart < RAY_WIDTH * RAY_WIDTH && distEnd < RAY_WIDTH * RAY_WIDTH) { var pc = FPoint.MiddlePoint(v1s, v2s); pc = pc + (v1s - v2s).WithLength((v1d - v2d) / 2f); var pcu1 = pc.ProjectOntoLine(v1s, v1e); if (pcu1 < 0) { pc = v1s; } if (pcu1 > 1) { pc = v1e; } var pcu2 = pc.ProjectOntoLine(v2s, v2e); if (pcu2 < 0) { pc = v2s; } if (pcu2 > 1) { pc = v2e; } intersect = pc; u = pc.ProjectOntoLine(v1s, v1e); return(true); } else if (distStart < RAY_WIDTH * RAY_WIDTH) { var drStart = FloatMath.Sqrt(distStart); var drEnd = FloatMath.Sqrt(distEnd); var perc = (RAY_WIDTH - drStart) / (drEnd - drStart); u1e = u1s + (u1e - u1s) * perc; u2s = u2e + (u2s - u2e) * perc; v1re = Math2D.PointOnLine(u1e, v1s, v1e); v2rs = Math2D.PointOnLine(u2s, v2s, v2e); var v1rd = v1d + u1s * (v1e - v1s).Length(); var v2rd = v2d + u2s * (v2e - v2s).Length(); var pc = FPoint.MiddlePoint(v1rs, v2rs); pc = pc + (v1rs - v2rs).WithLength((v1rd - v2rd) / 2f); var pcu1 = pc.ProjectOntoLine(v1rs, v1re); if (pcu1 < u1s) { pc = v1rs; } if (pcu1 > u1e) { pc = v1re; } var pcu2 = pc.ProjectOntoLine(v2rs, v2re); if (pcu2 < u2s) { pc = v2rs; } if (pcu2 > u2e) { pc = v2re; } intersect = pc; u = pc.ProjectOntoLine(v1s, v1e); return(true); } else if (distEnd < RAY_WIDTH * RAY_WIDTH) { var drStart = FloatMath.Sqrt(distStart); var drEnd = FloatMath.Sqrt(distEnd); var perc = (RAY_WIDTH - drEnd) / (drStart - drEnd); u1s = u1e + (u1s - u1e) * perc; u2e = u2s + (u2e - u2s) * perc; v1rs = Math2D.PointOnLine(u1s, v1s, v1e); v2re = Math2D.PointOnLine(u2e, v2s, v2e); var v1rd = v1d + u1s * (v1e - v1s).Length(); var v2rd = v2d + u2s * (v2e - v2s).Length(); var pc = FPoint.MiddlePoint(v1rs, v2rs); pc = pc + (v1rs - v2rs).WithLength((v1rd - v2rd) / 2f); var pcu1 = pc.ProjectOntoLine(v1rs, v1re); if (pcu1 < u1s) { pc = v1rs; } if (pcu1 > u1e) { pc = v1re; } var pcu2 = pc.ProjectOntoLine(v2rs, v2re); if (pcu2 < u2s) { pc = v2rs; } if (pcu2 > u2e) { pc = v2re; } intersect = pc; u = pc.ProjectOntoLine(v1s, v1e); return(true); } } intersect = FPoint.Zero; u = float.NaN; return(false); }
protected void SimulateWorld(float deltaTime, List <ICollidableComponent> physicsComponents) { foreach (var body in physicsComponents) { if (!body.Awake) { continue; } body.SleepAccumulator++; // if the body cannot move, nothing to do here if (!body.CanMove()) { continue; } var linearVelocity = Vector2.Zero; foreach (var controller in body.Controllers.Values) { controller.UpdateBeforeProcessing(); linearVelocity += controller.LinearVelocity; } // i'm not sure if this is the proper way to solve this, but // these are not kinematic bodies, so we need to preserve the previous // velocity. //if (body.LinearVelocity.LengthSquared < linearVelocity.LengthSquared) body.LinearVelocity = linearVelocity; // Integrate forces const float damping = 0.98f; // space/air friction, so everything eventually stops moving body.LinearVelocity += body.Force * body.InvMass * deltaTime * damping; body.AngularVelocity += body.Torque * body.InvI * deltaTime * damping; // forces are instantaneous, so these properties are cleared // once integrated. If you want to apply a continuous force, // it has to be re-applied every tick. body.Force = Vector2.Zero; body.Torque = 0f; } // Calculate collisions and store them in the cache ProcessCollisions(physicsComponents); // Remove all entities that were deleted during collision handling physicsComponents.RemoveAll(p => p.Deleted); // Process frictional forces foreach (var physics in physicsComponents) { ProcessFriction(physics, deltaTime); } foreach (var physics in physicsComponents) { foreach (var controller in physics.Controllers.Values) { controller.UpdateAfterProcessing(); } } // Remove all entities that were deleted due to the controller physicsComponents.RemoveAll(p => p.Deleted); const int solveIterationsAt60 = 4; var multiplier = deltaTime / (1f / 60); var divisions = FloatMath.Clamp( MathF.Round(solveIterationsAt60 * multiplier, MidpointRounding.AwayFromZero), 1, 20 ); if (_timing.InSimulation) { divisions = 1; } for (var i = 0; i < divisions; i++) { foreach (var physics in physicsComponents) { if (physics.Awake && physics.CanMove()) { UpdatePosition(physics, deltaTime / divisions); } } for (var j = 0; j < divisions; ++j) { if (FixClipping(_collisionCache, divisions)) { break; } } } }
protected void SendForwardMiniguns(ref int idx) { var data = Screen.GetEntities <MinigunCannon>().ToList(); if (data.Count == 0) { return; } if (idx + 2 >= MAX_PACKAGE_SIZE_BYTES) { SendAndReset(ref idx); } MSG_FORWARD[idx] = AREA_MINIGUNS; idx++; byte arrsize = (byte)((MAX_PACKAGE_SIZE_BYTES - idx - 2) / PLEN_MINIGUN); int posSize = idx; MSG_FORWARD[posSize] = 0xFF; idx++; int i = 0; foreach (var cannon in data) { if (!ShouldSendData(cannon)) { continue; } // [8: ID] [3: Fraction] [5: Boost] [8: RotationActual] [8: RotationTarget] [8: Health] [8:Charge] [8:Shield] NetworkDataTools.SetByte(out MSG_FORWARD[idx + 0], cannon.BlueprintCannonID); NetworkDataTools.SetSplitByte(out MSG_FORWARD[idx + 1], Screen.GetFractionID(cannon.Fraction), cannon.IntegerBoost, 3, 5, 3, 5); NetworkDataTools.SetByte(out MSG_FORWARD[idx + 2], NetworkDataTools.ConvertFromRadians(cannon.Rotation.ActualValue, 8)); NetworkDataTools.SetByte(out MSG_FORWARD[idx + 3], NetworkDataTools.ConvertFromRadians(cannon.Rotation.TargetValue, 8)); NetworkDataTools.SetByteFloor(out MSG_FORWARD[idx + 4], FloatMath.Clamp(cannon.CannonHealth.TargetValue, 0f, 1f) * 255); NetworkDataTools.SetByteFloor(out MSG_FORWARD[idx + 5], FloatMath.Clamp(cannon.BarrelCharge, 0f, 1f) * 255); NetworkDataTools.SetByteFloorRange(out MSG_FORWARD[idx + 6], 0, Cannon.MAX_SHIELD_TIME, cannon.ShieldTime); idx += PLEN_MINIGUN; i++; if (i >= arrsize) { MSG_FORWARD[posSize] = (byte)i; SendAndReset(ref idx); MSG_FORWARD[idx] = AREA_MINIGUNS; idx++; i -= arrsize; arrsize = (byte)((MAX_PACKAGE_SIZE_BYTES - idx - 2) / PLEN_MINIGUN); posSize = idx; MSG_FORWARD[posSize] = 0xFF; idx++; } } MSG_FORWARD[posSize] = (byte)i; }
public FPoint ProjectPointOntoLineSegment(FPoint lineStart, FPoint lineEnd) { float u = FloatMath.Clamp(ProjectOntoLine(lineStart, lineEnd), 0f, 1f); return(lineStart + (lineEnd - lineStart) * u); }
private static float LogisticCurve(float x, float slope, float exponent, float yOffset, float xOffset) { return(FloatMath.Clamp( exponent * (1 / (1 + (float)Math.Pow(Math.Log(1000) * slope, -1 * x + xOffset))) + yOffset, 0.0f, 1.0f)); }
private static float QuadraticCurve(float x, float slope, float exponent, float yOffset, float xOffset) { return(FloatMath.Clamp(slope * (float)Math.Pow(x - xOffset, exponent) + yOffset, 0.0f, 1.0f)); }
private void ProcessInputs_(ProcessInputsEvent _) { this.motor_.ClearScheduled(); var primaryAnalogStick = this.gamepad_[AnalogStickType.PRIMARY]; var heldAxes = primaryAnalogStick.RawAxes; //var runButton = this.gamepad_[FaceButtonType.SECONDARY]; var isRunning = true; var heldX = FinMath.Abs(heldAxes.X) > GamepadConstants.DEADZONE ? heldAxes.X : 0; this.motor_.ScheduleMoveAttempt(heldX, isRunning); var heldY = heldAxes.Y; var minHeldDuckAmount = -.75f; if (this.stateMachine_.CanDuck) { var maxHeldDuckAmount = -.25f; this.toDuckFraction_ = 1 - (FloatMath.Clamp(minHeldDuckAmount, heldY, maxHeldDuckAmount) - minHeldDuckAmount) / (maxHeldDuckAmount - minHeldDuckAmount); } else if (this.stateMachine_.IsDucked) { this.toDuckFraction_ = 1; } else { this.toDuckFraction_ = 0; } this.duckFraction_ += (this.toDuckFraction_ - this.duckFraction_) / 2; if (heldY <= minHeldDuckAmount) { this.motor_.ScheduleDuckStartAttempt(); } else { this.motor_.ScheduleDuckStopAttempt(); } var jumpButton = this.gamepad_[FaceButtonType.PRIMARY]; if (jumpButton.IsPressed) { this.motor_.ScheduleJumpStartAttempt(); } else if (jumpButton.IsReleased) { this.motor_.ScheduleJumpStopAttempt(); } this.motor_.ProcessInputs(); }
public override FPoint Get(float len) { len = FloatMath.Clamp(len, 0, Length); return(startPoint + direction * len); }
//[MethodImpl(MethodImplOptions.AggressiveInlining)] public void HighPressureMovements() { // TODO ATMOS finish this if (PressureDifference > 15) { if (_soundCooldown == 0) { EntitySystem.Get <AudioSystem>().PlayAtCoords("/Audio/Effects/space_wind.ogg", GridIndices.ToGridCoordinates(_mapManager, GridIndex), AudioHelpers.WithVariation(0.125f).WithVolume(FloatMath.Clamp(PressureDifference / 10, 10, 100))); } } foreach (var entity in _entityManager.GetEntitiesIntersecting(_mapManager.GetGrid(GridIndex).ParentMapId, Box2.UnitCentered.Translated(GridIndices))) { if (!entity.TryGetComponent(out ICollidableComponent physics) || !entity.TryGetComponent(out MovedByPressureComponent pressure)) { continue; } var pressureMovements = physics.EnsureController <HighPressureMovementController>(); if (pressure.LastHighPressureMovementAirCycle < _gridAtmosphereComponent.UpdateCounter) { pressureMovements.ExperiencePressureDifference(_gridAtmosphereComponent.UpdateCounter, PressureDifference, _pressureDirection, 0, PressureSpecificTarget?.GridIndices.ToGridCoordinates(_mapManager, GridIndex) ?? GridCoordinates.InvalidGrid); } } if (PressureDifference > 100) { // Do space wind graphics here! } _soundCooldown++; if (_soundCooldown > 75) { _soundCooldown = 0; } }
protected override void LayoutUpdateOverride() { base.LayoutUpdateOverride(); if (ChildCount != 2) { return; } var first = GetChild(0); var second = GetChild(1); var firstExpand = Vertical ? (first.SizeFlagsVertical & SizeFlags.Expand) != 0 : (first.SizeFlagsHorizontal & SizeFlags.Expand) != 0; var secondExpand = Vertical ? (second.SizeFlagsVertical & SizeFlags.Expand) != 0 : (second.SizeFlagsHorizontal & SizeFlags.Expand) != 0; var firstMinSize = Vertical ? first.CombinedMinimumSize.Y : first.CombinedMinimumSize.X; var secondMinSize = Vertical ? second.CombinedMinimumSize.Y : second.CombinedMinimumSize.X; var size = Vertical ? Height : Width; var ratio = first.SizeFlagsStretchRatio / (first.SizeFlagsStretchRatio + second.SizeFlagsStretchRatio); switch (_splitState) { case SplitState.Manual: // min sizes of children may have changed, ensure the offset still respects the defined limits _splitCenter = ClampSplitCenter(_splitCenter, firstMinSize, secondMinSize); break; case SplitState.Auto: { if (firstExpand && secondExpand) { _splitCenter = size * ratio - SplitWidth / 2; } else if (firstExpand) { _splitCenter = size - secondMinSize - SplitWidth; } else { _splitCenter = firstMinSize; } _splitCenter += FloatMath.Clamp(0f, firstMinSize - _splitCenter, size - secondMinSize - SplitWidth - _splitCenter); break; } } if (Vertical) { FitChildInBox(first, new UIBox2(0, 0, Width, _splitCenter)); FitChildInBox(second, new UIBox2(0, _splitCenter + SplitWidth, Width, Height)); } else { FitChildInBox(first, new UIBox2(0, 0, _splitCenter, Height)); FitChildInBox(second, new UIBox2(_splitCenter + SplitWidth, 0, Width, Height)); } }
protected override void Set(float value) => this.impl_ = FloatMath.Clamp(this.Min, value, this.Max);