Download

Converting vector between local and world space

Hello! I’m trying to figure out how to convert local FVector from actor/local to world space. I worked in UDK previously, where I could just:


CameraWorldLocation = SomeActorLocation + (CameraOffset >> SomeActorRotation);

And back to local space:


CameraOffset = (CameraWorldLocation - SomeActorLocation) << SomeActorRotation;

How do I reproduce this code in UE4?

To convert a vector from world to local space



//LocalObjectWorldLocation is the location of the object you want to make your vector relative to
FVector LocalVector = WorldVector - LocalObjectWorldLocation;


To convert a vector from local to world



//LocalObjectWorldLocation is the location of the object that your LocalVector is relative to
FVector WorldVector = LocalVector + LocalObjectWorldLocation;


But what’s about actor’s rotation? In UDK >> operator adds rotation to a vector, thus converting it to world space. << does the opposite, removes this rotation.

Converting rotations from local to world and back is pretty much the same principle.



void ExampleFunction(){
     // RelativeObjectWorldRotation is the world rotation of the object that the local rotation is relative to
     FRotator WorldRotation = CombineRotators(LocalRotationToConvert, RelativeObjectWorldRotation);

     //We use a negative version of RelativeObjectWorldRotation because we are removing that from our WorldRotationToConvert to get a local rotation
     FRotator LocalRotation = CombineRotators(WorldRotationToConvert, -RelativeObjectWorldRotation);
}

FRotator CombineRotators(FRotator RotA, FRotator RotB) {
     FQuat AQuat = FQuat(RotA);
     FQuat BQuat = FQuat(RotB);

     return FRotator(BQuat*AQuat);
}


Explaining the local to world conversion just to make sure we’re on the same page:

FRotator WorldRotation is going to be the world rotation we are trying to get from LocalRotationToConvert.
LocalRotationToConvert is the local rotation we want to convert to a world rotation. Let’s say this is the local rotation of an actor (ChildActor) that is parented to a world rotation of an actor (ParentActor)
RelativeObjectWorldRotation is the world rotation of the parent object.

Essentially, all we have to do here is add our local rotation (LocalRotationToConvert) to our parent’s world rotation (RelativeObjectWorldRotation) to get the conversion of the local rotation to the world rotation; however FRotator doesn’t like it when you just add and subtract. So instead, we use the function CombineRotators.

Lastly, the reason why we use a negative RelativeObjectWorldRotation when converting from world to local is because we are subtracting the parent rotation from the world rotation we are converting.

I might be wrong. It’s been a while since I’ve dealt with rotations and quaternions, but I’m 90% sure this is how it was done.

I never used quaternions before, so I’ll need to make some testing.
But as I can see, I’ll need to get the length of my local vector, convert it to rotator, then convert it to quaternion, calculate the result, convert back to rotator, then to vector and multiply by it’s original length. It’s a bit complicated.

This is my solution for rotators in UDK, just in case:


static function rotator RotToWorld(rotator A, rotator B)
{
    local vector X, Y, Z;

    GetAxes(A, X, Y, Z);
    X = X >> B;
    Y = Y >> B;
    Z = Z >> B;
    return OrthoRotation(X, Y, Z);
}

static function rotator RotToLocal(rotator A, rotator B)
{
    local vector X, Y, Z;

    GetAxes(A, X, Y, Z);
    X = X << B;
    Y = Y << B;
    Z = Z << B;
    return OrthoRotation(X, Y, Z);
}

A is the rotator to convert, B is the relative rotation.
GetAxes() takes rotator and returns 3 vectors, representing it’s local axes. OrthoRotation() converts 3 vectors back to rotator.

I found exactly what I needed. It’s RotateVector() and UnrotateVector().


CameraWorldLocation = SomeActorLocation + SomeActorRotation.RotateVector(CameraLocalOffset);

CameraLocalOffset = SomeActorRotation.UnRotateVector(CameraWorldLocation - SomeActorLocation);

1 Like