Relative teleportation

Hi spongers!

I’m looking for a way to teleport a player in a short distance but relatively where he look at.
I mean if he look to the east he’ll be teleported to the east. I don’t know if I’m clear…
I know I can use player.setPosition(extend, x, y, x) btw I don’t exactly understand what extend is used for… is it the world in which the location is? And there is a player.getRotation but I don’t know if it represent the head rotation or just the body, and anyway I don’t know the math to do that, should I use trigonometry or there is a simpliest way?

I hope my english is understandable, and I would to thanks your team to create that api that better and better!

Thanks to read.

This is probably what you’re looking for:

2 Likes

Thanks you but it’s not exactly that…
I would like to do like a ‘blink’ I mean teleport the player 3 blocs forward he’s looking at.

There’s also a relative position overload parameter too.

The extent is typically either the world or the chunk.

I believe it’s the head rotation.

First, get the direction the player is looking at, then normalize it (so it’s length will become 1) and multiply it with the distance you want the player to move. You now have a vector you can add to the players old location.

Vector3d dir = player.getRotation().normalize().mul(3.0);
Location newLoc = player.getLocation().add(dir);
player.setLocation(newLoc);

This will move a player 3 blocks in the exact direction where he’s looking.

EDIT: getRotation() does not work as I assumed, see comment of @ryantheleach below

2 Likes

Thanks to reply

Vector3d dir = player.getDirection().normalize().mul(3.0);
Do you mean getRotation()? It doesn’t work…

Yeah, I’m sorry for mixing that up. Fixing my post.

Yes I guessed you meant getRotation() but it doesn’t work neither, it teleports on 3 blocks but at random location…
I think it’s because it’s a rotation not “direction”. I’m wondering how can I “transform” a rotation into a “direction”

Saw the subject line and thought someone came up with a way of getting rid of in-laws.

4 Likes

It should teleport in the exact direction someone is facing. If you want to somewhat normalize the behavior (if something is watching east, more or less, port him east), you can use the Direction Enum for that.

Direction dir = Direction.getClosest(player.getRotation());

This gives you a Direction to work with which can be converted back into a Vector3d using the Direction#toVector3d() method.

I’m a little rusty on my vector math, but wouldn’t you need to convert this from pitch yaw roll into something world relative?

Oh shoot, I totally overlooked that :confused: Thats what happens if you just check the returned type and not the rest of the docs.
Which means my above answer is useless since getRotation does not return a directional vector, it just uses a vector to store Euler angles. With my rusty understanding I just hacked together a helper function that will calculate the closest cardinal direction from the supplied pitch (assuming teleports only occur in North/East/South/West directions)

private void teleportForward(Player player, double distance) {
    Vector3d rotation = player.getRotation();
    Direction dir = cardinalDirectionFromPitch(rotation.getX());
    Vector3d diff = dir.toVector3d().normalize().mul(distance);
    Location newLoc = player.getLocation().add(diff);
    player.setLocationSafely(newLoc);
}

private Direction cardinalDirectionFromPitch(double pitch) {
     Direction[] cardinalDirections = {Direction.SOUTH, Direction.WEST, Direction.NORTH, Direction.EAST};
    
     int index = (int) ((pitch+45) / 90);
     return cardinalDirections[index % 4];    
 }

On how to calculate a directional vector form the Euler angles I cannot comment since I’d have to read it all up myself. I hope there is a helper function somewhere in Sponge but so far I have not found it.

If there isn’t a helper function it should be added IMO.

1 Like

I had a quick chat with @DDoS and he suggested having a look at flowpowered / flow.math and using Quaterniond to convert from Eulerangles to Quaternions and then to a vector representing the direction.

Javadocs here: flowpowered.com - flowpowered Resources and Information.
Take a look at Quaterniond.fromAxesAngleDeg(pitch, yaw, roll)

Hope this helps at least a bit. :smile:

1 Like

BTW, right now SpongeAPI returns the rotations in a Vector3i with the mapping X -> yaw, Y -> pitch, Z -> roll. I’m changing that tomorrow to X -> pitch, Y -> yaw, Z -> roll to match flow-math (and the standard).

Also here’s an example of a Euler angles -> direction conversion using Quaternions.

1 Like