Example #1
0
        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);
        }