Announcement

Collapse
No announcement yet.

Is this a Local Rotation Bug?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Is this a Local Rotation Bug?

    GOD of DREAMs: A Unique FTPS/RPG Sandbox MMO

    #2
    Can someone confirm the above is the result of Gimbal Lock?
    GOD of DREAMs: A Unique FTPS/RPG Sandbox MMO

    Comment


      #3
      Expand and check the rotation values?
      Gimbal lock would take the value to a certain number and stop increasing after.

      Assuming it is, implementing BP quaternions instead of rotation nodes would solve the problem.

      I can't find the original thing I found most of this from, but here is a copypaste of the C++ code itself. Create a custom blueprint class, paste in, use the new nodes:

      Flight_Quaternions.h

      Note the initial lines of UCLASS are generated for your project by unreal, so don't replace the whole thing, keep the generated ones where I have "
      CUSTOMNAMEHERE UFlight_Quaternions : public UBlueprintFunctionLibrary"

      Code:
      // Fill out your copyright notice in the Description page of Project Settings.
      
      #pragma once
      
      #include "CoreMinimal.h"
      #include "Kismet/BlueprintFunctionLibrary.h"
      #include "Flight_Quaternions.generated.h"
      
      /**
       *
       */
      UCLASS()
      class CUSTOMNAMEHERE UFlight_Quaternions : public UBlueprintFunctionLibrary
      {
          GENERATED_BODY()
      public:
      
          // Convert Euler Rotations To Quaternions
          UFUNCTION(BlueprintCallable, meta = (DisplayName = "Euler To Quaternion", Keywords = "rotation, quaterion"), Category = "Quaternion Rotation")
              static FQuat Euler_To_Quaternion(FRotator Current_Rotation);
      
          // Function to set world rotation of scene component to input quaternion rotation
          UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set World Rotation (Quaterion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
              static void SetWorldRotationQuat(USceneComponent* SceneComponent, const FQuat& Desired_Rotation);
      
          // Function to set relative rotation of scene component to input quaternion rotation
          UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set Relative Rotation (Quaterion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
              static void SetRelativeRotationQuat(USceneComponent* SceneComponent, const FQuat& Desired_Rotation);
      
          // Function to add delta rotation to current local rotation of scene component
          UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Local Rotation (Quaterion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
              static void AddLocalRotationQuat(USceneComponent* SceneComponent, const FQuat& Delta_Rotation);
      
          // Function to set world rotation of Actor to input quaternion rotation
          UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set Actor World Rotation (Quaternion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
              static void SetActorWorldRotationQuat(AActor* Actor, const FQuat& Desired_Rotation);
      
          // Function to set relative rotation of Actor to input quaternion rotation
          UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set Actor Relative Rotation (Quaternion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
              static void SetActorRelativeRotationQuat(AActor* Actor, const FQuat& Desired_Rotation);
      
          // Function to add delta rotation to current local rotation of Actor
          UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Actor Local Rotation (Quaternion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
              static void AddActorLocalRotationQuat(AActor* Actor, const FQuat& Delta_Rotation);
      };

      And
      Flight_Quaternions.cpp
      Code:
      // Fill out your copyright notice in the Description page of Project Settings.
      
      #include "Flight_Quaternions.h"
      
      
      // Formula to convert a Euler angle in degrees to a quaternion rotation
      FQuat UFlight_Quaternions::Euler_To_Quaternion(FRotator Current_Rotation)
      {
          FQuat q;                                            // Declare output quaternion
          float yaw = Current_Rotation.Yaw * PI / 180;        // Convert degrees to radians
          float roll = Current_Rotation.Roll * PI / 180;
          float pitch = Current_Rotation.Pitch * PI / 180;
      
          double cy = cos(yaw * 0.5);
          double sy = sin(yaw * 0.5);
          double cr = cos(roll * 0.5);
          double sr = sin(roll * 0.5);
          double cp = cos(pitch * 0.5);
          double sp = sin(pitch * 0.5);
      
          q.W = cy * cr * cp + sy * sr * sp;
          q.X = cy * sr * cp - sy * cr * sp;
          q.Y = cy * cr * sp + sy * sr * cp;
          q.Z = sy * cr * cp - cy * sr * sp;
      
          return q;                                            // Return the quaternion of the input Euler rotation
      }
      
      // Set the scene component's world rotation to the input quaternion
      void UFlight_Quaternions::SetWorldRotationQuat(USceneComponent* SceneComponent, const FQuat& Desired_Rotation)
      {
          if (SceneComponent)
          {
              SceneComponent->SetWorldRotation(Desired_Rotation);
          }
      }
      
      // Set the scene component's relative rotation to the input quaternion
      void UFlight_Quaternions::SetRelativeRotationQuat(USceneComponent* SceneComponent, const FQuat& Desired_Rotation)
      {
          if (SceneComponent)
          {
              SceneComponent->SetRelativeRotation(Desired_Rotation);
          }
      }
      
      // Add the input delta rotation to the scene component's current local rotation
      void UFlight_Quaternions::AddLocalRotationQuat(USceneComponent* SceneComponent, const FQuat& Delta_Rotation)
      {
          if (SceneComponent)
          {
              SceneComponent->AddLocalRotation(Delta_Rotation);
          }
      }
      
      // Set the Actor's world rotation to the input quaternion
      void UFlight_Quaternions::SetActorWorldRotationQuat(AActor* Actor, const FQuat& Desired_Rotation)
      {
          if (Actor)
          {
              Actor->SetActorRotation(Desired_Rotation);
          }
      }
      
      // Set the Actor's relative rotation to the input quaternion
      void UFlight_Quaternions::SetActorRelativeRotationQuat(AActor* Actor, const FQuat& Desired_Rotation)
      {
          if (Actor)
          {
              Actor->SetActorRelativeRotation(Desired_Rotation);
          }
      }
      
      // Add the input delta rotation to the Actor's current local rotation
      void UFlight_Quaternions::AddActorLocalRotationQuat(AActor* Actor, const FQuat& Delta_Rotation)
      {
          if (Actor)
          {
              Actor->AddActorLocalRotation(Delta_Rotation);
          }
      }
      Last edited by MostHost LA; 07-19-2019, 05:17 AM.

      Comment


        #4
        Awesome MostHost LA

        Thank you for taking time read, research and provide a solution. I use only Blueprints, ill attempt to translate the C++ in Blueprints. I truly appreciate your assistance in this matter.
        GOD of DREAMs: A Unique FTPS/RPG Sandbox MMO

        Comment


          #5
          Originally posted by TechLord View Post
          ill attempt to translate the C++ in Blueprints.
          The code above creates blueprint nodes for you. You just need to figure out how to hook it up properly as a blueprint interface.

          Comment


            #6
            Originally posted by MostHost LA View Post

            The code above creates blueprint nodes for you. You just need to figure out how to hook it up properly as a blueprint interface.
            Thanks again MostHost LA .This is to be used in a blueprints-based framework. No C++ involved.

            Originally posted by MostHost LA View Post
            Expand and check the rotation values?
            Gimbal lock would take the value to a certain number and stop increasing after.

            Assuming it is, implementing BP quaternions instead of rotation nodes would solve the problem.

            I can't find the original thing I found most of this from, but here is a copypaste of the C++ code itself. Create a custom blueprint class, paste in, use the new nodes:

            Flight_Quaternions.h

            Note the initial lines of UCLASS are generated for your project by unreal, so don't replace the whole thing, keep the generated ones where I have "
            CUSTOMNAMEHERE UFlight_Quaternions : public UBlueprintFunctionLibrary"

            Code:
            // Fill out your copyright notice in the Description page of Project Settings.
            
            #pragma once
            
            #include "CoreMinimal.h"
            #include "Kismet/BlueprintFunctionLibrary.h"
            #include "Flight_Quaternions.generated.h"
            
            /**
            *
            */
            UCLASS()
            class CUSTOMNAMEHERE UFlight_Quaternions : public UBlueprintFunctionLibrary
            {
            GENERATED_BODY()
            public:
            
            // Convert Euler Rotations To Quaternions
            UFUNCTION(BlueprintCallable, meta = (DisplayName = "Euler To Quaternion", Keywords = "rotation, quaterion"), Category = "Quaternion Rotation")
            static FQuat Euler_To_Quaternion(FRotator Current_Rotation);
            
            // Function to set world rotation of scene component to input quaternion rotation
            UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set World Rotation (Quaterion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
            static void SetWorldRotationQuat(USceneComponent* SceneComponent, const FQuat& Desired_Rotation);
            
            // Function to set relative rotation of scene component to input quaternion rotation
            UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set Relative Rotation (Quaterion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
            static void SetRelativeRotationQuat(USceneComponent* SceneComponent, const FQuat& Desired_Rotation);
            
            // Function to add delta rotation to current local rotation of scene component
            UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Local Rotation (Quaterion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
            static void AddLocalRotationQuat(USceneComponent* SceneComponent, const FQuat& Delta_Rotation);
            
            // Function to set world rotation of Actor to input quaternion rotation
            UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set Actor World Rotation (Quaternion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
            static void SetActorWorldRotationQuat(AActor* Actor, const FQuat& Desired_Rotation);
            
            // Function to set relative rotation of Actor to input quaternion rotation
            UFUNCTION(BlueprintCallable, meta = (DisplayName = "Set Actor Relative Rotation (Quaternion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
            static void SetActorRelativeRotationQuat(AActor* Actor, const FQuat& Desired_Rotation);
            
            // Function to add delta rotation to current local rotation of Actor
            UFUNCTION(BlueprintCallable, meta = (DisplayName = "Add Actor Local Rotation (Quaternion)", Keywords = "rotation, quaternion"), Category = "Quaternion Rotation")
            static void AddActorLocalRotationQuat(AActor* Actor, const FQuat& Delta_Rotation);
            };

            And
            Flight_Quaternions.cpp
            Code:
            // Fill out your copyright notice in the Description page of Project Settings.
            
            #include "Flight_Quaternions.h"
            
            
            // Formula to convert a Euler angle in degrees to a quaternion rotation
            FQuat UFlight_Quaternions::Euler_To_Quaternion(FRotator Current_Rotation)
            {
            FQuat q; // Declare output quaternion
            float yaw = Current_Rotation.Yaw * PI / 180; // Convert degrees to radians
            float roll = Current_Rotation.Roll * PI / 180;
            float pitch = Current_Rotation.Pitch * PI / 180;
            
            double cy = cos(yaw * 0.5);
            double sy = sin(yaw * 0.5);
            double cr = cos(roll * 0.5);
            double sr = sin(roll * 0.5);
            double cp = cos(pitch * 0.5);
            double sp = sin(pitch * 0.5);
            
            q.W = cy * cr * cp + sy * sr * sp;
            q.X = cy * sr * cp - sy * cr * sp;
            q.Y = cy * cr * sp + sy * sr * cp;
            q.Z = sy * cr * cp - cy * sr * sp;
            
            return q; // Return the quaternion of the input Euler rotation
            }
            
            // Set the scene component's world rotation to the input quaternion
            void UFlight_Quaternions::SetWorldRotationQuat(USceneComponent* SceneComponent, const FQuat& Desired_Rotation)
            {
            if (SceneComponent)
            {
            SceneComponent->SetWorldRotation(Desired_Rotation);
            }
            }
            
            // Set the scene component's relative rotation to the input quaternion
            void UFlight_Quaternions::SetRelativeRotationQuat(USceneComponent* SceneComponent, const FQuat& Desired_Rotation)
            {
            if (SceneComponent)
            {
            SceneComponent->SetRelativeRotation(Desired_Rotation);
            }
            }
            
            // Add the input delta rotation to the scene component's current local rotation
            void UFlight_Quaternions::AddLocalRotationQuat(USceneComponent* SceneComponent, const FQuat& Delta_Rotation)
            {
            if (SceneComponent)
            {
            SceneComponent->AddLocalRotation(Delta_Rotation);
            }
            }
            
            // Set the Actor's world rotation to the input quaternion
            void UFlight_Quaternions::SetActorWorldRotationQuat(AActor* Actor, const FQuat& Desired_Rotation)
            {
            if (Actor)
            {
            Actor->SetActorRotation(Desired_Rotation);
            }
            }
            
            // Set the Actor's relative rotation to the input quaternion
            void UFlight_Quaternions::SetActorRelativeRotationQuat(AActor* Actor, const FQuat& Desired_Rotation)
            {
            if (Actor)
            {
            Actor->SetActorRelativeRotation(Desired_Rotation);
            }
            }
            
            // Add the input delta rotation to the Actor's current local rotation
            void UFlight_Quaternions::AddActorLocalRotationQuat(AActor* Actor, const FQuat& Delta_Rotation)
            {
            if (Actor)
            {
            Actor->AddActorLocalRotation(Delta_Rotation);
            }
            }
            GOD of DREAMs: A Unique FTPS/RPG Sandbox MMO

            Comment


              #7
              I believe you can still incorporate the c++ code to get the blueprint nodes even if you didn't specifically start your project out as Cpp based.

              Either way, you have the math right there enough that you could create a full BP version of it as a function.
              the problem is that you cannot set the rotation without CPP because unreal will only accept the quaternion via CPP as they aren't natively exposed to BP.

              Another somewhat viable work around is to simply manually reset the rotation of the mirrored component, and the current component to 0 when it reaches 360 deg.
              You should not notice any snapping since 360 Is 0. But it's obviously not as fluid as utilizing a non gimbal locked value.
              Hard to say how much of a difference you would experience until you try it out though.

              As far as simplicity goes, implementing the cpp and calling in the set quaternion rotation nodes is probably 5 min of work, if even.

              Anyway good luck with it

              Comment

              Working...
              X