SetRotation on instanced static mesh causing a crash

Hey I’m trying to generate a room using instanced static meshes. Currently I can generate a room of flat floor tiles but I wanted to now add walls to the outer edges. The maths is fine for this and I managed to get the walls to generate in the right places but now I need to rotate them to fit the room (As they are all rotated the same way at the moment)

My code for setting the location is here:

FTransform Transform;
	FQuat Rotation;

	Rotation.X = RotX;
	Rotation.Y = RotY;
	Rotation.Z = RotZ;

	Transform.SetLocation(FVector(LocX, LocY, LocZ));
	Transform.SetRotation(Rotation);

	switch (TileID)
	{
	case 0:
	ISMCompFloor->AddInstance(Transform);
		break;
	case 1:
	ISMCompWall->AddInstance(Transform);
		break;
	}

The game definitely crashes on the SetRotation function call and when I comment it out everything else works out fine. I have also set the instanced static mesh component to movable when it is created shown here:

ISMComp->RegisterComponent();
ISMComp->SetStaticMesh(SMesh);
ISMComp->SetFlags(RF_Transactional);
ISMComp->SetMobility(EComponentMobility::Movable);
this->AddInstanceComponent(ISMComp);

This is definitely working as shown in the editor here:

The error message I’m getting is:

Assertion failed: IsRotationNormalized() [File:d:\build\++ue4+release-4.12+compile\sync\engine\source\runtime\core\public\math\TransformVectorized.h] [Line: 1257] 

UE4Editor.exe has triggered a breakpoint.

The program '[2808] UE4Editor.exe' has exited with code 0 (0x0).

I feel like I’m probably being stupid but I can’t seem to find a way to make this rotation work and I need it to be able to generate the rooms properly.

I noticed that I was using Euler angles instead of Quaternions so I changed the code to:

FTransform Transform;
	FQuat NewRotation;
	FVector RotationEuler;

	RotationEuler.X = RotX;
	RotationEuler.Y = RotY;
	RotationEuler.Z = RotZ;

	NewRotation.MakeFromEuler(RotationEuler);

	Transform.SetLocation(FVector(LocX, LocY, LocZ));
	Transform.SetRotation(NewRotation);

	switch (TileID)
	{
	case 0:
		ISMCompFloor->AddInstance(Transform);
		break;
	case 1:
		ISMCompWall->AddInstance(Transform);
		break;
	}

Still crashing though.

Even setting the Quaternion to default values isn’t working so it must be something to do with the function call and not the values being passed in.

Hey Gama97-

The SetRotation function should work with an FRotator. Rather than using FQuat, could you try making your NewRotation variable an FRotator instead? Then, rather than .X, .Y, and .Z as the values, you would set .Pitch, .Roll, and .Yaw. This should also remove the need for MakeFromEuler() as well.

Cheers

Thanks I’ll try this when I get back!

It doesn’t seem like the SetRotation function works with an FRotator. It’s telling me to use FQuat instead.

Update: If I set the FQuat to completely default values like so:

    NewRotation.X = 0.0f;
	NewRotation.Y = 0.0f;
	NewRotation.Z = 0.0f;
	NewRotation.W = 1.0f;

	Transform.SetLocation(Location);
	Transform.SetRotation(NewRotation);

Then I don’t crash but the second I change any of the values to anything but these defaults I get the crash again (For example changing Z to 0.5f). So it must be something to do with the actual rotation of the Instanced meshes rather than the values I’m putting in.

I have also tried moving the GenerateRoom function to BeginPlay instead of OnConstruction and I get the exact same thing. Default values = no crash but changing any rotation value results in the same error as before:

Assertion failed: IsRotationNormalized() [File:d:\build\++ue4+release-4.12+compile\sync\engine\source\runtime\core\public\math\TransformVectorized.h] [Line: 1257]

Can you provide the callstack and logs from the crash that you’re receiving as well as the code class where the code provided is being used?

Hey Gama97-

As another piece of information, I found that adding a call to Rotation.Normalize(float); after setting the rotation values but before the call to Transform.SetRotation(Rotation); prevents the crash from occurring when AddInstance(Transform) is called. Can you let me know if adding this line prevents the crash for you as well?

Cheers

Of course I’ll do that when I get home (Assuming your other answer doesn’t work)

Okay so this method solved the crashing, thank you very much! I have another problem now though that is no matter what rotation I put in, the same Quaternion values come out as seen in my log:

[2016.08.08-22.12.21:065][653]LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, 180.000000
[2016.08.08-22.12.21:065][653]LogTemp:Error: ID: 1 Rotation Quarternion: -0.500000, -0.500000, -0.500000
[2016.08.08-22.12.21:065][653]LogTemp:Error: Tile: 2 - 3
[2016.08.08-22.12.21:065][653]LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, 180.000000
[2016.08.08-22.12.21:065][653]LogTemp:Error: ID: 1 Rotation Quarternion: -0.500000, -0.500000, -0.500000
[2016.08.08-22.12.21:065][653]LogTemp:Error: Tile: 3 - 3
[2016.08.08-22.12.21:065][653]LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, 180.000000
[2016.08.08-22.12.21:066][653]LogTemp:Error: ID: 1 Rotation Quarternion: -0.500000, -0.500000, -0.500000
[2016.08.08-22.12.21:066][653]LogTemp:Error: Tile: 4 - 3
[2016.08.08-22.12.21:066][653]LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, 180.000000
[2016.08.08-22.12.21:066][653]LogTemp:Error: ID: 1 Rotation Quarternion: -0.500000, -0.500000, -0.500000
[2016.08.08-22.12.21:066][653]LogTemp:Error: Tile: 5 - 2
[2016.08.08-22.12.21:066][653]LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, 0.000000
[2016.08.08-22.12.21:066][653]LogTemp:Error: ID: 1 Rotation Quarternion: -0.500000, -0.500000, -0.500000

I was wondering whether this is to do with the normalize function or if maybe some of my code is wrong?

FTransform Transform;
FVector Location;
FQuat NewRotation;
FVector RotationEuler;
FTile NewTile;

    	Location.X = LocX;
    	Location.Y = LocY;
    	Location.Z = LocZ;
    
    	RotationEuler.X = RotX;
    	RotationEuler.Y = RotY;
    	RotationEuler.Z = RotZ;
    
    	NewRotation.MakeFromEuler(RotationEuler);
    
    	NewRotation.Normalize();
    
    	Transform.SetLocation(Location);
    	Transform.SetRotation(NewRotation);
    
    	NewTile.TileID = TileID;
    	NewTile.Transform = Transform;
    
    	UE_LOG(LogTemp, Error, TEXT("ID: %d Rotation Euler: %f, %f, %f"), TileID, RotX, RotY, RotZ);
    	UE_LOG(LogTemp, Error, TEXT("ID: %d Rotation Quarternion: %f, %f, %f"), TileID, NewRotation.X, NewRotation.Y, NewRotation.Z);

Here is most of the function as it stands.

Update: this seems to be a problem with .MakeFromEuler as it’s giving me weird values like:

[2016.08.08-23.52.15:919][992]LogTemp:Error: ID: 1 Rotation Quarternion: -107374176.000000, -107374176.000000, -107374176.000000
[2016.08.08-23.52.15:920][992]LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, 180.000000
[2016.08.08-23.52.15:920][992]LogTemp:Error: ID: 1 Rotation Quarternion: -0.500000, -0.500000, -0.500000

First is before .Normalize() and second is after.

I also tried inputting quarternions straight into the function instead and it also seems like .Normalize() is having troubles too.

LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, 1.000000
LogTemp:Error: ID: 1 Rotation Quarternion: 0.000000, 0.000000, 1.000000
LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, 1.000000
LogTemp:Error: ID: 1 Rotation Quarternion: 0.000000, 0.000000, 0.000000
LogTemp:Error: Tile: 13 - 4
LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, 1.000000
LogTemp:Error: ID: 1 Rotation Quarternion: 0.000000, 0.000000, 1.000000
LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, 1.000000
LogTemp:Error: ID: 1 Rotation Quarternion: 0.000000, 0.000000, 0.000000
LogTemp:Error: Tile: 14 - 4
LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, -0.500000
LogTemp:Error: ID: 1 Rotation Quarternion: 0.000000, 0.000000, -0.500000
LogTemp:Error: ID: 1 Rotation Euler: 0.000000, 0.000000, -0.500000
LogTemp:Error: ID: 1 Rotation Quarternion: 0.000000, 0.000000, -0.000000

Before and after normalize like before.

I’ve entered a report about the apparent crash when adding an instance through code. You can refer to this bug report here. As a work around I was able to create a blueprint from my actor class and set the rotation value of my transform variable in the construction script of the blueprint. After doing so the call to AddInstance(Transform) in code worked as expected.