Download

How to rotate a vector in C++

Hi everybody,

I’m a Java developer getting into Unreal C++ and I’m having an hard time trying to figure out how to solve a simple (i guess) task: rotate a vector accordingly to mesh rotation.

I have a BP derived directly from a C++ class. The BP has a Scene component which contains 1 collision box and 4 UStaticMeshComponents.
The Scene has the pivot in lower right corner (see picture)

In the OnConstruction(FTransform& Transform) method, I “draw” 4 debug lines which frame the frontal mesh component (see picture)

So far so good :slight_smile: but when I try to rotate my BP by one or more axis then the frame is no more aligned with rotation.

I’m 100% sure that this is a rotation problem and i simply cannot find the correct way to do it.

I tried both using FRotationMatrix and FRotator.RotateVector(FVector) but none of them worked.
Here’s the relevant code:

// Getting the diagonal of my frontal mesh
FVector LowerDiagonalMeshPoint = FVector::ZeroVector;
FVector UpperDiagonalMeshPoint = FVector::ZeroVector;
FrontalMesh->GetLocalBounds(LowerDiagonalMeshPoint , UpperDiagonalMeshPoint );

// Getting the origin point in WorldSpace and relative Rotator
FVector OriginPointInWS = RootComponent->GetComponentLocation();
FRotator MeshRotator = RootComponent->GetComponentRotation();

// Calculate the correct position by taking into account the MeshLocation
FVector RelativeMin = MeshLocation + LowerDiagonalMeshPoint ;
FVector RelativeMax = MeshLocation + UpperDiagonalMeshPoint ;


// Calculate the front face corner points
FVector BottomLeft =FVector(RelativeMax.X, RelativeMax.Y, RelativeMin.Z);
FVector TopLeft = FVector(RelativeMax.X, RelativeMax.Y, RelativeMax.Z);
FVector BottomRight = FVector(RelativeMax.X, RelativeMin.Y, RelativeMin.Z);
FVector TopRight = FVector(RelativeMax.X, RelativeMin.Y, RelativeMax.Z);

//Draw debug lines
DrawDebugLine(GetWorld(), BottomLeft, TopLeft, FColor::Purple, false, 5.f, 0, 2.f);
DrawDebugLine(GetWorld(), TopLeft, TopRight, FColor::Purple, false, 5.f, 0, 2.f);	DrawDebugLine(GetWorld(), TopRight, BottomRight, FColor::Purple, false, 5.f, 0, 2.f);
DrawDebugLine(GetWorld(), BottomRight, BottomLeft, FColor::Purple, false, 5.f, 0, 2.f);

Thanks for your help
Luca

Can you try getting the transform from the root component then transforming the vector using that?
So something like:

RootComponent->GetComponentTransform().TransformVector( vector )

Hi herob4u,
Thanks for your answer! Your suggestion did the trick but it works only if my BP is placed exactly at WS origin point (0, 0, 0).

In any other point in space its behaviour is predictable but strange; further I move my BP at any XYZ-positive point in space, greater is the radius of the circumference it uses to draw the frame (see pictures)

O (0, 0, 0)

P (100, 0 ,0)

The behaviour is the same for every Axis.

Moreover, in any XYZ-negative position, the frame get drawn in the specular point of BP position. Same thing for any non 0degrees rotation

Location (-100,0 ,0) Rotation (0, 0, 90) Starting point

Location (-100,50 ,0) Rotation (0, 0, 90) Ending point (after +50 y units)

This kind of behaviour seems related to the math behind min/max coords I do to get the mesh position starting point.

Is there a simple way to get it works or should I improve the way I get coords (like getting abs value and invert algebric operation to avoid specular phenomenon)?

Thanks for your help

Luca

Couple of questions - where does MeshLocation come from, and is OriginPointInWS relevant in this case?

All in all, it feels like we just need to know what frame of reference we want to work in. I suggested transforming by the root component’s transform because that’s the one that changes when you move an object around.

But if your mesh is rotating relative to the root component, then you might want to try transforming your vector using the mesh component’s transform instead.

Now, it looks to me that all you are trying to do is get the world location of the bounding box - is that correct? If so, then you might as well just get the bounds in world coordinates directly and not worry about all the transformation nonsense.

if(FrontalMesh->GetStaticMesh())
{
    FBoxSphereBounds MeshBounds = FrontalMesh->GetStaticMesh()->GetBounds();

    // Can get the extremas of the shape this way
    FVector max = MeshBounds.GetBoxExtrema(1);  // 1 for positive extrema
    FVector min  = MeshBounds.GetBoxExtrema(0); // else for negative extrema

    // Or, if you want the box
    FBox box = MeshBounds.GetBox();
    // box.GetCenter();
    // box.GetExtent();
    // etc.
}

I’ve edited the code accordingly to your suggestion which is a better (and cleaner)way of getting mesh boundaries instead of what I did; and using those values in conjunction with RootComponent->GetComponentTransform().TransformVector( vector ) works as expected for all three Axis.

However, if I move the Mesh in any point in space the frame does not follow the mesh. It keeps get drawn in origin point.

MeshLocation is a copy/paste error, actually OriginPointInWS equals MeshLocation. I thought I need that vector to update the position where the frame should be drawn.

Maybe I’m getting the PositionVector in the wrong place?

Thanks for your help,
Luca