Exemplo n.º 1
0
        public void Update(GameTime elapsed)
        {
            float dt = ((float)elapsed.ElapsedGameTime.TotalSeconds);

            //if (sw.ElapsedMilliseconds)
            //	dt = (float) sw.ElapsedMilliseconds / 1000f;

            Hit.Clear();
            foreach (var entity in PhysicsEntities.ToArray())
            {
                try
                {
                    if (entity is Entity e)
                    {
                        if (e.NoAi)
                        {
                            continue;
                        }
                        bool wasColliding = e.IsCollidingWithWorld;

                        //TruncateVelocity(e, dt);

                        var velocity = e.Velocity;

                        if (e.IsInWater && velocity.Y < 0f)
                        {
                            velocity.Y *= 0.8f;
                        }
                        else if (e.IsInLava)
                        {
                            //	velocity.Y *= 0.5f;
                        }

                        if (!e.IsFlying && !e.KnownPosition.OnGround && e.IsAffectedByGravity)
                        {
                            velocity -= new Vector3(0f, (float)(e.Gravity * dt), 0f);

                            //var modifier = new Vector3(1f, (float) (1f - (e.Gravity * dt)), 1f);
                            //velocity *= modifier;
                        }

                        var rawDrag = (float)(1f - ((e.Drag * 0.91f) * dt));

                        velocity *= new Vector3(rawDrag, 1f, rawDrag);

                        var position = e.KnownPosition;

                        var preview = position.PreviewMove(velocity * dt);

                        if (e.IsSneaking && e.KnownPosition.OnGround)
                        {
                            var newFeetBlock = e.Level?.GetBlock(preview + Vector3.Down);

                            if (!newFeetBlock.Solid)
                            {
                                velocity = new Vector3(-velocity.X, velocity.Y, -velocity.Z);
                            }
                        }

                        bool onGround = e.KnownPosition.OnGround;

                        //	if (velocity != Vector3.Zero)
                        {
                            var boundingBox = e.GetBoundingBox(preview);

                            Bound bound = new Bound(World, boundingBox, preview);

                            if (bound.GetIntersecting(boundingBox, out var blocks))
                            {
                                velocity = AdjustForY(
                                    e.GetBoundingBox(new Vector3(position.X, preview.Y, position.Z)), blocks, velocity,
                                    position, out float?yCollisionPoint);

                                if (yCollisionPoint.HasValue)
                                {
                                    if (yCollisionPoint > position.Y)
                                    {
                                        //We hit our head.
                                        onGround = false;
                                    }
                                    else
                                    {
                                        if (!onGround)
                                        {
                                            onGround = true;
                                        }
                                    }
                                }

                                Hit.AddRange(blocks.Select(x => x.box));

                                //var solid = blocks.Where(b => b.block.Solid && b.box.Max.Y > position.Y).ToArray();
                                var solid = blocks.Where(
                                    b => b.block.Solid && b.box.Max.Y > position.Y && b.block.CanCollide()).ToArray();

                                if (solid.Length > 0)
                                {
                                    var heighest = solid.OrderByDescending(x => x.box.Max.Y).FirstOrDefault();

                                    if (MathF.Abs(heighest.box.Max.Y - boundingBox.Min.Y) <= 0.65f &&
                                        e.KnownPosition.OnGround && !e.IsFlying)
                                    {
                                        //if (!heighest.block.BlockState.Model
                                        //	.GetIntersecting(heighest.coordinates, boundingBox)
                                        //	.Any(x => x.Max.Y > heighest.box.Max.Y))
                                        //if (!blocks.Any(x => x.))
                                        {
                                            e.KnownPosition.Y = (float)heighest.box.Max.Y;
                                        }
                                    }

                                    if (!wasColliding)
                                    {
                                        //var min = Vector3.Transform(boundingBox.Min,
                                        //	Matrix.CreateRotationY(-MathHelper.ToRadians(position.HeadYaw)));

                                        //var max = Vector3.Transform(boundingBox.Max,
                                        //	Matrix.CreateRotationY(-MathHelper.ToRadians(position.HeadYaw)));

                                        var min = boundingBox.Min;
                                        var max = boundingBox.Max;

                                        var minX = min.X;
                                        var maxX = max.X;

                                        var previewMinX = new Vector3(minX, preview.Y, preview.Z);

                                        bool checkX = false;

                                        if (!solid.Any(
                                                x =>
                                        {
                                            var contains = x.box.Contains(previewMinX);

                                            return(contains != ContainmentType.Contains &&
                                                   contains != ContainmentType.Intersects);
                                        }))
                                        {
                                            previewMinX = new Vector3(maxX, preview.Y, preview.Z);

                                            if (solid.Any(
                                                    x =>
                                            {
                                                var contains = x.box.Contains(previewMinX);

                                                return(contains != ContainmentType.Contains &&
                                                       contains != ContainmentType.Intersects);
                                            }))
                                            {
                                                checkX = true;
                                            }
                                        }
                                        else
                                        {
                                            checkX = true;
                                        }

                                        if (checkX)
                                        {
                                            for (float x = 1f; x > 0f; x -= 0.1f)
                                            {
                                                Vector3 c = (position - preview) * new Vector3(x, 1f, 1f) + position;

                                                if (solid.All(
                                                        s =>
                                                {
                                                    var contains = s.box.Contains(c);

                                                    return(contains != ContainmentType.Contains &&
                                                           contains != ContainmentType.Intersects);
                                                }))
                                                {
                                                    velocity = new Vector3(c.X - position.X, velocity.Y, velocity.Z);

                                                    break;
                                                }
                                            }
                                        }

                                        var minZ = min.Z;
                                        var maxZ = max.Z;

                                        var previewMinZ = new Vector3(preview.X, preview.Y, minZ);

                                        bool checkZ = false;

                                        if (!solid.Any(
                                                x =>
                                        {
                                            var contains = x.box.Contains(previewMinZ);

                                            return(contains != ContainmentType.Contains &&
                                                   contains != ContainmentType.Intersects);
                                        }))
                                        {
                                            previewMinZ = new Vector3(preview.X, preview.Y, maxZ);

                                            if (solid.Any(
                                                    x =>
                                            {
                                                var contains = x.box.Contains(previewMinZ);

                                                return(contains != ContainmentType.Contains &&
                                                       contains != ContainmentType.Intersects);
                                            }))
                                            {
                                                checkZ = true;
                                            }
                                        }
                                        else
                                        {
                                            checkZ = true;
                                        }

                                        if (checkZ)
                                        {
                                            for (float x = 1f; x > 0f; x -= 0.1f)
                                            {
                                                Vector3 c = (position - preview) * new Vector3(1f, 1f, x) + position;

                                                if (solid.All(
                                                        s =>
                                                {
                                                    var contains = s.box.Contains(c);

                                                    return(contains != ContainmentType.Contains &&
                                                           contains != ContainmentType.Intersects);
                                                }))
                                                {
                                                    velocity = new Vector3(velocity.X, velocity.Y, c.Z - position.Z);

                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        e.Velocity = velocity;

                        var beforeMove = e.KnownPosition.ToVector3();
                        e.KnownPosition.Move(velocity * dt);

                        //	if (e is PlayerMob p)
                        {
                            e.DistanceMoved += MathF.Abs(Vector3.Distance(beforeMove, e.KnownPosition.ToVector3()));
                        }
                        //var rawDrag = (float) (1f - (e.Drag * dt));

                        //e.Velocity = velocity;// * new Vector3(1f, 0.98f, 1f);

                        //e.KnownPosition.Move(e.Velocity * dt);

                        TruncateVelocity(e, dt);

                        /*var feetBlock = e.Level.GetBlockState(e.KnownPosition.GetCoordinates3D());
                         *
                         * if (!feetBlock.Block.Solid)
                         * {
                         *      e.KnownPosition.OnGround = false;
                         * }
                         * else
                         * {
                         *
                         * }*/

                        //if (MathF.Abs(e.Velocity.Y) < 0.000001f)
                        {
                            e.KnownPosition.OnGround = MathF.Abs(e.Velocity.Y) < 0.000001f || onGround;
                        }

                        {
                            //e.KnownPosition.OnGround = true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Warn(ex, $"Entity tick threw exception: {ex.ToString()}");
                }
            }

            if (Hit.Count > 0)
            {
                LastKnownHit = Hit.ToArray();
            }

            sw.Restart();
        }
Exemplo n.º 2
0
        public void Update(GameTime elapsed)
        {
            float dt = (float)elapsed.ElapsedGameTime.TotalSeconds;

            //if (sw.ElapsedMilliseconds)
            //	dt = (float) sw.ElapsedMilliseconds / 1000f;

            Hit.Clear();
            foreach (var entity in PhysicsEntities.ToArray())
            {
                try
                {
                    if (entity is Entity e)
                    {
                        if (e.NoAi)
                        {
                            continue;
                        }
                        //TruncateVelocity(e, dt);

                        var velocity = e.Velocity;

                        if (!e.IsFlying && !e.KnownPosition.OnGround)
                        {
                            velocity -= new Vector3(0, (float)(e.Gravity * dt), 0);
                        }
                        velocity *= (float)(1f - e.Drag * dt);

                        var position = e.KnownPosition;

                        var preview = position.PreviewMove(velocity * dt);

                        var boundingBox = e.GetBoundingBox(preview);

                        Bound bound = new Bound(World, boundingBox);

                        velocity = AdjustForY(e.GetBoundingBox(new Vector3(position.X, preview.Y, position.Z)), bound,
                                              velocity, position);

                        if (bound.GetIntersecting(boundingBox, out var blocks))
                        {
                            var solid = blocks.Where(b => b.block.Solid && b.box.Max.Y > position.Y).ToArray();
                            Hit.AddRange(solid.Select(x => x.box));

                            if (solid.Length > 0)
                            {
                                for (float x = 1f; x > 0f; x -= 0.1f)
                                {
                                    Vector3 c = (position - preview) * x + position;
                                    if (solid.All(s => s.box.Contains(c) != ContainmentType.Contains))
                                    {
                                        velocity = new Vector3(c.X - position.X, velocity.Y, c.Z - position.Z);
                                        break;
                                    }
                                }
                            }
                        }

                        e.Velocity = velocity;

                        e.KnownPosition.Move(e.Velocity * dt);

                        TruncateVelocity(e, dt);

                        if (velocity.Y == 0)
                        {
                            e.KnownPosition.OnGround = true;
                        }
                    }
                }
                catch (Exception ex)
                {
                    Log.Warn(ex, $"Entity tick threw exception: {ex.ToString()}");
                }
            }

            if (Hit.Count > 0)
            {
                LastKnownHit = Hit.ToArray();
            }

            sw.Restart();
        }
Exemplo n.º 3
0
        private void UpdateEntity(Entity e, float deltaTime)
        {
            var originalPosition = e.KnownPosition;

            Hit.Clear();

            var position = e.KnownPosition;

            var originalEntityBoundingBox = e.GetBoundingBox(position);

            var before      = e.Velocity;
            var velocity    = e.Velocity;
            var preview     = position.PreviewMove(velocity * deltaTime);
            var boundingBox = e.GetBoundingBox(preview);

            Bound bound = new Bound(World, boundingBox, preview);

            if (bound.GetIntersecting(boundingBox, out var blocks))
            {
                if (AdjustForY(
                        originalEntityBoundingBox, e.GetBoundingBox(new Vector3(position.X, preview.Y, position.Z)), blocks,
                        ref velocity, out var yCollisionPoint))
                {
                    e.CollidedWithWorld(before.Y < 0 ? Vector3.Down : Vector3.Up, yCollisionPoint);
                    //onGround = e.KnownPosition.OnGround;
                }

                var solidBlocks = blocks.Where(x => x.block.Solid).ToArray();

                if (solidBlocks.Length > 0)
                {
                    if (!e.IsFlying && velocity.Y >= 0f)
                    {
                        var matchingBlocks = solidBlocks
                                             .Where(x => x.block.Solid && x.box.Max.Y > preview.Y && x.block.CanCollide()).ToArray();

                        if (matchingBlocks.Length > 0)
                        {
                            var closest = matchingBlocks.Min(x => x.box.Max.Y);

                            if (MathF.Abs(preview.Y - closest) <= 0.55f)
                            {
                                e.KnownPosition.Y = closest + 0.005f;
                                position.Y        = closest + 0.005f;
                            }
                        }
                    }

                    if (AdjustForX(
                            originalEntityBoundingBox, e.GetBoundingBox(new Vector3(preview.X, position.Y, position.Z)),
                            blocks, ref velocity, out var xCollisionPoint))
                    {
                        e.CollidedWithWorld(before.X < 0 ? Vector3.Left : Vector3.Right, xCollisionPoint);
                    }

                    if (AdjustForZ(
                            originalEntityBoundingBox, e.GetBoundingBox(new Vector3(position.X, position.Y, preview.Z)),
                            blocks, ref velocity, out var zCollisionPoint))
                    {
                        e.CollidedWithWorld(before.Z < 0 ? Vector3.Backward : Vector3.Forward, zCollisionPoint);
                    }

                    Hit.AddRange(blocks.Select(x => x.box));
                }
            }

            if (Hit.Count > 0)
            {
                LastKnownHit = Hit.ToArray();
            }

            e.Velocity = velocity;

            e.KnownPosition.Move(e.Velocity * deltaTime);
            //e.KnownPosition.OnGround = onGround;

            e.DistanceMoved += MathF.Abs(Vector3.Distance(originalPosition, e.KnownPosition.ToVector3()));
        }
Exemplo n.º 4
0
        private void UpdateEntity(Entity e, float deltaTime)
        {
            var originalPosition = e.KnownPosition;

            Hit.Clear();

            var position = e.KnownPosition;
            //var originalPosition = position;

            var originalEntityBoundingBox = e.GetBoundingBox(position);

            var before      = e.Velocity;
            var velocity    = e.Velocity;
            var preview     = position.PreviewMove(velocity * deltaTime);
            var boundingBox = e.GetBoundingBox(preview);

            var bounding = new BoundingBox(
                new Vector3(
                    MathF.Min(originalEntityBoundingBox.Min.X, boundingBox.Min.X),
                    MathF.Min(originalEntityBoundingBox.Min.Y, boundingBox.Min.Y),
                    MathF.Min(originalEntityBoundingBox.Min.Z, boundingBox.Min.Z)),
                new Vector3(
                    MathF.Max(originalEntityBoundingBox.Max.X, boundingBox.Max.X),
                    MathF.Max(originalEntityBoundingBox.Max.Y, boundingBox.Max.Y),
                    MathF.Max(originalEntityBoundingBox.Max.Z, boundingBox.Max.Z)));

            var modifiedPreview = preview;

            Bound bound = new Bound(World, bounding, preview);

            if (bound.GetIntersecting(bounding, false, out var blocks))
            {
                var solidBlocks = blocks.Where(x => x.block.Solid).ToArray();

                if (solidBlocks.Length > 0)
                {
                    if (AdjustForY(e,
                                   originalEntityBoundingBox, e.GetBoundingBox(new Vector3(position.X, preview.Y, position.Z)),
                                   solidBlocks, ref velocity, out var yCollisionPoint, ref position))
                    {
                        e.CollidedWithWorld(before.Y < 0 ? Vector3.Down : Vector3.Up, yCollisionPoint);
                    }

                    if (AdjustForX(e,
                                   originalEntityBoundingBox, e.GetBoundingBox(new Vector3(preview.X, position.Y, position.Z)),
                                   solidBlocks, ref velocity, out var xCollisionPoint, ref position))
                    {
                        e.CollidedWithWorld(before.X < 0 ? Vector3.Left : Vector3.Right, xCollisionPoint);
                    }

                    if (AdjustForZ(e,
                                   originalEntityBoundingBox, e.GetBoundingBox(new Vector3(position.X, position.Y, preview.Z)),
                                   solidBlocks, ref velocity, out var zCollisionPoint, ref position))
                    {
                        e.CollidedWithWorld(before.Z < 0 ? Vector3.Backward : Vector3.Forward, zCollisionPoint);
                    }

                    Hit.AddRange(solidBlocks.Select(x => x.box));
                }
            }

            if (Hit.Count > 0)
            {
                LastKnownHit = Hit.ToArray();
            }

            if (before.Y >= 0f && position.Y > originalPosition.Y)
            {
                e.KnownPosition.Y = position.Y;
            }

            e.Velocity = velocity;

            e.KnownPosition.Move(e.Velocity * deltaTime);
            //e.KnownPosition.OnGround = onGround;

            e.DistanceMoved += MathF.Abs(Vector3.Distance(originalPosition, e.KnownPosition.ToVector3()));
        }