示例#1
0
        public List<BlockIndex> BlocksBeneath(PhysicsObject obj)
        {
            List<BlockIndex> returnList = new List<BlockIndex>();

            for (int x = (int)Math.Floor(obj.BoundingBox.Min.X); x <= Math.Floor(obj.BoundingBox.Max.X); x++)
            {
                for (int z = (int)Math.Floor(obj.BoundingBox.Min.Z); z <= Math.Floor(obj.BoundingBox.Max.Z); z++)
                {
                    returnList.Add(new BlockIndex(x, (int)Math.Floor(obj.Position.Y - Constants.Player.MinDistanceToGround), z));
                }
            }

            return returnList;
        }
示例#2
0
 public bool IsOnGround(PhysicsObject obj)
 {
     return !PlaceFree(obj, obj.Position - Vector3d.UnitY * Constants.Player.MinDistanceToGround);
 }
示例#3
0
        private void UpdateVelocity(PhysicsObject currentObject)
        {
            // To avoid errors (specifically, NaN), remove velocity if too small.
            if (Player.Velocity.Length <= Constants.Physics.MinSpeed)
            {
                Player.Velocity = Vector3d.Zero;
            }

            // Gravity
            currentObject.Accelerate(-Vector3d.UnitY * Constants.Physics.Gravity);

            // Buoyancy
            currentObject.Accelerate(Vector3d.UnitY * currentObject.BuoyancyMagnitude);

            // Surface friction
            Vector3d horizontalVelocity = Vector3d.Multiply(currentObject.Velocity, new Vector3d(1, 0, 1));

            if (IsOnGround(currentObject) && horizontalVelocity != Vector3d.Zero)
            {
                currentObject.Accelerate((-Vector3d.Normalize(horizontalVelocity) * currentObject.KineticFrictionCoefficient * Constants.Physics.Gravity) * horizontalVelocity.Length * Constants.Physics.FrictionSignificance / Constants.Physics.GripSignificance);
            }

            // Update velocity
            currentObject.ApplyAcceleration();
        }
示例#4
0
        private void UpdatePositionOneDimension(PhysicsObject obj, ref double position, ref double velocity, Vector3d axis)
        {
            while (!PlaceFree(obj, velocity * Constants.Physics.TimeStep * axis + obj.Position))
            {
                if (Math.Round(velocity, 4) != 0.0)
                {
                    velocity = velocity / 1.5;
                }
                else
                {
                    velocity = 0.0;
                    return;
                }
            }

            position += velocity * Constants.Physics.TimeStep;
        }
示例#5
0
        private void UpdatePosition(PhysicsObject obj)
        {
            Vector3d newPos = obj.Position + obj.Velocity * Constants.Physics.TimeStep;

            if (PlaceFree(obj, newPos))
            {
                obj.Position = newPos;
            }
            else
            {
                UpdatePositionOneDimension(obj, ref obj.Position.Y, ref obj.Velocity.Y, Vector3d.UnitY);

                if (Math.Abs(obj.Velocity.X) > Math.Abs(obj.Velocity.Z))
                {
                    UpdatePositionOneDimension(obj, ref obj.Position.X, ref obj.Velocity.X, Vector3d.UnitX);
                    UpdatePositionOneDimension(obj, ref obj.Position.Z, ref obj.Velocity.Z, Vector3d.UnitZ);
                }
                else
                {
                    UpdatePositionOneDimension(obj, ref obj.Position.Z, ref obj.Velocity.Z, Vector3d.UnitZ);
                    UpdatePositionOneDimension(obj, ref obj.Position.X, ref obj.Velocity.X, Vector3d.UnitX);
                }
            }
        }
示例#6
0
        private bool PlaceFree(PhysicsObject obj, Vector3d position)
        {
            foreach (BlockIndex index in obj.BoundingBox.At(position).IntersectionIndices)
            {
                if (ChunkManager.GetBlock(index).Solidity)
                {
                    return false;
                }
            }

            return true;
        }