public static BallStepResult Step( PhysicsProperties physicsProperties, Entity entity, ref float entityAngularVelocity, IBallContactListener listener) { Vector2 position = entity.position; Vector2 velocity1 = entity.velocity; Vector2 size = entity.Size; float num1 = entityAngularVelocity; float num2 = size.X * 0.5f; float num3 = num1 * physicsProperties.Drag; Vector2 vector2_1 = velocity1 * physicsProperties.Drag; float num4 = vector2_1.Length(); if ((double)num4 > 1000.0) { vector2_1 = 1000f * Vector2.Normalize(vector2_1); num4 = 1000f; } int num5 = Math.Max(1, (int)Math.Ceiling((double)num4 / 2.0)); float timeScale = 1f / (float)num5; Vector2 velocity2 = vector2_1 * timeScale; float angularVelocity = num3 * timeScale; float num6 = physicsProperties.Gravity / (float)(num5 * num5); bool flag = false; for (int index = 0; index < num5; ++index) { velocity2.Y += num6; BallPassThroughType type; Tile tile; if (BallCollision.CheckForPassThrough(position + size * 0.5f, out type, out tile)) { if (type == BallPassThroughType.Tile && Main.tileSolid[(int)tile.type] && !Main.tileSolidTop[(int)tile.type]) { velocity2 *= 0.0f; angularVelocity *= 0.0f; flag = true; } else { BallPassThroughEvent passThrough = new BallPassThroughEvent(timeScale, tile, entity, type); listener.OnPassThrough(physicsProperties, ref position, ref velocity2, ref angularVelocity, ref passThrough); } } position += velocity2; if (!BallCollision.IsBallInWorld(position, size)) { return(BallStepResult.OutOfBounds()); } Vector2 collisionPoint; if (BallCollision.GetClosestEdgeToCircle(position, size, velocity2, out collisionPoint, out tile)) { Vector2 normal = Vector2.Normalize(position + size * 0.5f - collisionPoint); position = collisionPoint + normal * (num2 + 0.0001f) - size * 0.5f; BallCollisionEvent collision = new BallCollisionEvent(timeScale, normal, collisionPoint, tile, entity); flag = true; velocity2 = Vector2.Reflect(velocity2, collision.Normal); listener.OnCollision(physicsProperties, ref position, ref velocity2, ref collision); angularVelocity = (float)((double)collision.Normal.X * (double)velocity2.Y - (double)collision.Normal.Y * (double)velocity2.X) / num2; } } Vector2 vector2_2 = velocity2 / timeScale; float num7 = angularVelocity / timeScale; BallStepResult ballStepResult = BallStepResult.Moving(); if (flag && (double)vector2_2.X > -0.00999999977648258 && ((double)vector2_2.X < 0.00999999977648258 && (double)vector2_2.Y <= 0.0) && (double)vector2_2.Y > -(double)physicsProperties.Gravity) { ballStepResult = BallStepResult.Resting(); } entity.position = position; entity.velocity = vector2_2; entityAngularVelocity = num7; return(ballStepResult); }
public static BallStepResult Step(PhysicsProperties physicsProperties, Entity entity, float entityAngularVelocity, IBallContactListener listener) { Vector2 position = entity.position; Vector2 velocity = entity.velocity; Vector2 size = entity.Size; float num = entityAngularVelocity; float num2 = size.X * 0.5f; num *= physicsProperties.Drag; velocity *= physicsProperties.Drag; float num3 = velocity.Length(); if (num3 > 1000f) { velocity = 1000f * Vector2.Normalize(velocity); num3 = 1000f; } int num4 = Math.Max(1, (int)Math.Ceiling(num3 / 2f)); float num5 = 1f / (float)num4; velocity *= num5; num *= num5; float num6 = physicsProperties.Gravity / (float)(num4 * num4); bool flag = false; for (int i = 0; i < num4; i++) { velocity.Y += num6; if (CheckForPassThrough(position + size * 0.5f, out var type, out var contactTile)) { if (type == BallPassThroughType.Tile && Main.tileSolid[contactTile.type] && !Main.tileSolidTop[contactTile.type]) { velocity *= 0f; num *= 0f; flag = true; } else { BallPassThroughEvent passThrough = new BallPassThroughEvent(num5, contactTile, entity, type); listener.OnPassThrough(physicsProperties, position, velocity, num, passThrough); } } position += velocity; if (!IsBallInWorld(position, size)) { return(BallStepResult.OutOfBounds()); } if (GetClosestEdgeToCircle(position, size, velocity, out var collisionPoint, out contactTile)) { Vector2 vector = Vector2.Normalize(position + size * 0.5f - collisionPoint); position = collisionPoint + vector * (num2 + 0.0001f) - size * 0.5f; BallCollisionEvent collision = new BallCollisionEvent(num5, vector, collisionPoint, contactTile, entity); flag = true; velocity = Vector2.Reflect(velocity, collision.Normal); listener.OnCollision(physicsProperties, position, velocity, collision); num = (collision.Normal.X * velocity.Y - collision.Normal.Y * velocity.X) / num2; } } velocity /= num5; num /= num5; BallStepResult result = BallStepResult.Moving(); if (flag && velocity.X > -0.01f && velocity.X < 0.01f && velocity.Y <= 0f && velocity.Y > 0f - physicsProperties.Gravity) { result = BallStepResult.Resting(); } entity.position = position; entity.velocity = velocity; entityAngularVelocity = num; return(result); }