How to get Blocks corresponding to the actual eye yaw / pitch

Discussion in 'Plugin Development' started by Unknown123, Sep 25, 2018.

Thread Status:
Not open for further replies.
  1. Offline

    Unknown123

    This is a simple Question but really hard to program.
    I am trying to add a vector to a Location BUT I don't want to add like X, Y ,Z, but the side (left, right from the actual player) "axis", forward (forwards and backwards from the actual player) "axis" and height axis (Important: Not the Y axis but in combination with the pitch, so if i look a bit down then the axis is diagonal, more "flat").
    I've uploaded a picture with visualizes this a bit.
     

    Attached Files:

  2. Offline

    Zombie_Striker

    @Unknown123
    1. Get the direction the player is looking by using Player#getLocation().getDirection()
    2. To get the forward or backwards direction, either keep it the way it is or multiply the vector by -1 respectively.
    3. To the get the left or right direction, swap the X with the Z, and either keep it the way it is for right, or multiply it by -1 to get the left direction.
    4. The up and down axis is harder to determine. For this, you will need to get the pitch, and then use some trig to find the sin and cos of the player's head relative to how far down they are looking. Then, using those values, convert those values for the X and Y to the distance away from the player and how far up the offset needs to be, respectively. Then, finally, get the yaw, and use some more trig to convert the yaw angle into x and z offsets.
     
  3. Offline

    Unknown123

  4. Offline

    Zombie_Striker

    @Unknown123
    The previous posts explains what you would need to do. Have you tried any of it?
     
    timtower likes this.
  5. Offline

    Unknown123

    I understand it for only one direction but with two I have no idea. How is this trig called, It properly isnt just Minecraft related
     
  6. I think the following approach will work if the player is not looking straight up or down:

    Determine the forward vector with player.getLocation().getDirection()

    The side vector is the cross product of the forward vector and (0, 1, 0).
    The up vector (height) is the cross product of the forward vector and side vector.

    You might have to normalize the forward vector (divide x, y and z by its own length).
    It's also possible that my formula will give the left or down vector instead of up or right vector. In that case, you should negate one of the vectors (multiply x, y and z by -1).

    The cross product of left and right = (left.y * right.z - left.z * right.y, left.z * right.x - left.x * right.z, left.x * right.y - left.y * right.x).

    I hope this helps

    I edited because I found out my first approach was incorrect...
     
    Last edited: Sep 30, 2018
    Zombie_Striker likes this.
  7. Offline

    Unknown123

    @knokko @Zombie_Striker Thank you, this helps a lot! But as you already said, it doesn't work if I look straight up or down. It would be perfect if it would work anyways. Sorry, that I could not respond earlier, I didn't get a notification. This is my Code:
    Code:
    package pluginpackage.commands;
    
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.util.Vector;
    
    public class TestCmd implements CommandExecutor {
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
            if (!(sender instanceof Player))
                return true;
            Player p = (Player) sender;
            Vector dir = p.getLocation().getDirection();
            Vector side = crossProduct(dir, new Vector(0D, 1D, 0D));
            Vector up = crossProduct(side, dir);
            p.setVelocity(side); // This knocks me right if I don't look straight up or down
            return true;
        }
    
        private static Vector crossProduct(Vector left, Vector right) {
            return new Vector(
                    left.getY() * right.getZ() - left.getZ() * right.getY(),
                    left.getZ() * right.getX() - left.getX() * right.getZ(),
                    left.getX() * right.getY() - left.getY() * right.getX()
            );
        }
    }
    
     
  8. @Unknown123

    I thought the cross product thing might have scared you off, but never mind.

    Ok, there are only 2 cases where this method doesn't work.
    So, you can solve it with dry if statements.

    If I remember will, a pitch of 90 degrees means you are looking straight down and a pitch of -90 degrees means you are looking straight up.

    Also, if my memories are correct:
    yaw = 0 means you are looking to the north / negative Z
    yaw = 90 means you are looking to the east / positive X
    yaw = 180 means you are looking to the south / positive Z
    yaw = 270 means you are looking to the west / negative X

    I think the following approach will work if you look straight up:

    forward vector = (0, 1, 0) because you are looking straight up
    up vector = (sin(yaw + 180), 0, -cos(yaw + 180))
    side vector = cross product of foward vector and up vector

    When you look straight down:
    forward vector = (0,-1,0)
    up vector = (sin(yaw), 0, -cos(yaw))
    side vector = cross product of forward vector and up vector

    Notice that I gave everything in degrees and minecraft uses degrees, but that Math.sin and Math.cos use radians, so Math.toRadians(value in degrees) may help you.
    Also, you might have to swap the left and right in the cross product formula because I never know whether to pick left or right (50% chance for me to be correct).
    There is also the case where my memory betrayed me, so you might have to swap the trigonometrics a bit.
     
Thread Status:
Not open for further replies.

Share This Page