I need some help working on some transforms. I'm making a teleport mechanic where I have two transforms that are facing the direction the player will be moving when they hit the teleporter and where they should be facing when they leave the teleporter. I have this working with the below code using Euler's but, this doesn't scale to other axis of rotation... I'm looking for a way to correctly do the following but without `get_euler()`:

``````    var to_rot = tp["to_transform"].basis.get_euler()
var from_rot = tp["from_transform"].basis.get_euler()
var rot_diff = to_rot + from_rot

var new_t = Transform()
# The origin here is offset by the player's distance from the teleporter's origin so that
# when we rotate the transform that offset can be preserved
new_t.origin = state.get_transform().origin - tp["from_transform"].origin
# The player's basis as they pass through the teleporter
new_t.basis = state.get_transform().basis

# What I want to do is rotate new_t by the difference between tp["to_transform"].basis and tp["from_transform"].basis. I don't know how to do this without first converting to Euler's and doing it one axis at a time
if rot_diff.y != 0.0:
new_t = new_t.rotated(Vector3(0, 1, 0), -rot_diff.y)

state.set_linear_velocity(state.get_linear_velocity().rotated(Vector3(0, 1, 0), -rot_diff.y))

state.set_angular_velocity(state.get_angular_velocity().rotated(Vector3(0, 1, 0), -rot_diff.y))

new_t.origin += tp["from_transform"].origin
new_t.origin -= tp["from_transform"].origin - tp["to_transform"].origin
state.set_transform(new_t)
``````

I've read the docs on using transforms, but I just lack the fundamental understanding to apply it to my situation here. The problem with my code here is that `rot_diff` if in Eulers and can get all messed up, especially when adding another axis.I know there's some sort of math I can do on `new_t.basis` to get what I want, but I just don't know the proper functions to call.

in Engine

Hi,
if i understand correctly you want the player to face in the relative same direction he enters the portal 1 after leaving portal 2. Right?

``````# this is the global direction vector the player is facing, one unit forward minus the players global offset
var global_player_direction = player.to_global( Vector3.FORWARD ) - player.global_transform.origin

# now add this direction to the global position of the portal and transform this into local coordinate system of the portal. this is the relative (to the portal) viewing vector of the player.
var relative_player_direction = portal1.to_local( portal1.global_transform.origin + global_player_direction)

# transform this relative direction to global from the coordinate system of the other portal
var new_direction = portal2.to_global( relative_player_direction ) - portal2.global_tranform.origin
``````

this should do it.

by (4,088 points)

Thank you for answering, but this doesn't actually account for the player's `transform.basis` only the `origin` and translation. This would probably work fine for a physical teleporter where the exit should always be a direction, but I suppose I should have made it clearer that this is for an endless hallway type teleportation and should be seamless no matter what direction the player is facing as they walk through the hallway.

My above code works, I just know that there's a way to do it involving the matrix math functions that I don't have a grasp on.

Actually my code only deals with the "basis" (you propably mean the rotation) and does not deal with the translation.
Its just vector math. The endresult is the viewing direction transformed from one portal to another.

Hm okay, sorry for misunderstanding.. I'll have to give it another go. It's my understanding that the`transform.origin` is a vector representing the xyz cords of the transform and the `transform.basis` is a matrix composed of vectors representing the transforms rotation around the three axis. I don't see where the rotation happens in your example, I'll have to adapt it to my function to test it out properly.

The basis is the rotation matrix which is usualy created from a quaternion.
The rotation component in my code comes from the vector.forward which defines the orientation.
If you are not familar with vector math you should defintly dive into it. Its absolute supirior tot euler math.

I adapted your function to work with my variables, and am comparing it to the transform that my original code has constructed. The below screenshot of my debugger shows `new_t` with the correct transform, reached with Euler math, and `new_direction`, the vector calculated from your example. On the right you can see `transform`, which is the player's current transform when entering the teleport plane. It appears that `new_direction` is close to the `z` component of `new_t`, but `new_direction.y` is negative when it should be positive. I also still need the `x` and `y` components of the transform with your method.

Thank you for helping, I know it's my lack of understanding that's the problem here. If I knew more about the subject I know I could take your advice and apply it properly :(

``````var to_rot = tp["to_transform"].basis.get_euler()
var from_rot = tp["from_transform"].basis.get_euler()
var rot_diff = to_rot + from_rot

var new_t = Transform()
new_t.origin = state.get_transform().origin - tp["from_transform"].origin
new_t.basis = state.get_transform().basis

if rot_diff.y != 0.0:
new_t = new_t.rotated(Vector3(0, 1, 0), -rot_diff.y)
state.set_linear_velocity(state.get_linear_velocity().rotated(Vector3(0, 1, 0), -rot_diff.y))
state.set_angular_velocity(state.get_angular_velocity().rotated(Vector3(0, 1, 0), -rot_diff.y))

if rot_diff.z != 0.0:
new_t = new_t.rotated(Vector3(0, 0, 1), rot_diff.z)
state.set_linear_velocity(state.get_linear_velocity().rotated(Vector3(0, 0, 1), rot_diff.z))
state.set_angular_velocity(state.get_angular_velocity().rotated(Vector3(0, 0, 1), rot_diff.z))

if rot_diff.x != 0.0:
new_t = new_t.rotated(Vector3(1, 0, 0), -rot_diff.x)
state.set_linear_velocity(state.get_linear_velocity().rotated(Vector3(1, 0, 0), -rot_diff.x))
state.set_angular_velocity(state.get_angular_velocity().rotated(Vector3(0, 0, 0), -rot_diff.x))

new_t.origin += tp["from_transform"].origin
new_t.origin -= tp["from_transform"].origin - tp["to_transform"].origin

# this is the global direction vector the player is facing, one unit forward minus the players global offset
var global_player_direction = body.to_global( Vector3.FORWARD ) - body.global_transform.origin
# now add this direction to the global position of the portal and transform this into local coordinate system of the portal. this is the relative (to the portal) viewing vector of the player.
var relative_player_direction = tp["from_body"].to_local( tp["from_transform"].origin + global_player_direction)
# transform this relative direction to global from the coordinate system of the other portal
var new_direction = tp["to_body"].to_global( relative_player_direction ) - tp["to_transform"].origin

# debug screenshot point
state.set_transform(new_t)
``````

A bit late, but here's mine:

``````func teleport(body):
var transform_it = transform.xform_inv(body.transform.origin)
var transform_point = other_tele.to_global(transform_it)
body.transform.origin = transform_point

var rotation = Quat(global_transform.basis).inverse()
var player_rotation = Quat(body.global_transform.basis)
var other_rotation = Quat(other_tele.global_transform.basis)
body.global_transform.basis = Basis(rotation * player_rotation * other_rotation)
``````
by (42 points)