예제 #1
0
        /**
         * Get a normalized copy of this quaternion.
         * If it is too small, returns an identity quaternion.
         *
         * @param Tolerance Minimum squared length of quaternion for normalization.
         */
        public FQuat GetNormalized(float Tolerance = Const.SMALL_NUMBER)
        {
            FQuat Result = this;

            Result.Normalize(Tolerance);
            return(Result);
        }
예제 #2
0
 public FQuat(FQuat Q)
 {
     X = Q.X;
     Y = Q.Y;
     Z = Q.Z;
     W = Q.W;
 }
예제 #3
0
        /**
         * @note Exp should really only be used after Log.
         * Assumes a quaternion with W=0 and V=theta*v (where |v| = 1).
         * Exp(q) = (sin(theta)*v, cos(theta))
         */
        public FQuat Exp()
        {
            float Angle    = (float)FMath.Sqrt(X * X + Y * Y + Z * Z);
            float SinAngle = (float)FMath.Sin(Angle);

            FQuat Result = new FQuat();

            Result.W = (float)FMath.Cos(Angle);

            if (FMath.Abs(SinAngle) >= Const.SMALL_NUMBER)
            {
                float Scale = SinAngle / Angle;
                Result.X = Scale * X;
                Result.Y = Scale * Y;
                Result.Z = Scale * Z;
            }
            else
            {
                Result.X = X;
                Result.Y = Y;
                Result.Z = Z;
            }

            return(Result);
        }
예제 #4
0
        /**
         * Checks whether another Quaternion is equal to this, within specified tolerance.
         *
         * @param Q The other Quaternion.
         * @param Tolerance Error Tolerance.
         * @return true if two Quaternion are equal, within specified tolerance, otherwise false.
         */
        public override bool Equals(object Obj)
        {
            FQuat Q         = (FQuat)Obj;
            float Tolerance = Const.KINDA_SMALL_NUMBER;

            return((FMath.Abs(X - Q.X) <= Tolerance && FMath.Abs(Y - Q.Y) <= Tolerance && FMath.Abs(Z - Q.Z) <= Tolerance && FMath.Abs(W - Q.W) <= Tolerance) ||
                   (FMath.Abs(X + Q.X) <= Tolerance && FMath.Abs(Y + Q.Y) <= Tolerance && FMath.Abs(Z + Q.Z) <= Tolerance && FMath.Abs(W + Q.W) <= Tolerance));
        }
예제 #5
0
        /**
         * Sets the components
         * @param InRotation The new value for the Rotation component
         * @param InTranslation The new value for the Translation component
         * @param InScale3D The new value for the Scale3D component
         */
        public void SetComponents(FQuat InRotation, FVector InTranslation, FVector InScale3D)
        {
            Rotation    = InRotation;
            Translation = InTranslation;
            Scale3D     = InScale3D;

            DiagnosticCheckNaN_All();
        }
예제 #6
0
        /**
         * Convert this Transform to inverse.
         */
        public FTransform Inverse()
        {
            FQuat   InvRotation    = Rotation.Inverse();
            FVector InvScale3D     = Scale3D.Reciprocal();
            FVector InvTranslation = InvRotation * (InvScale3D * -Translation);

            return(new FTransform(InvRotation, InvTranslation, InvScale3D));
        }
예제 #7
0
        /**
         * Enforce that the delta between this Quaternion and another one represents
         * the shortest possible rotation angle
         */
        public void EnforceShortestArcWith(FQuat OtherQuat)
        {
            float DotResult = (OtherQuat | this);
            float Bias      = DotResult > 0 ? 1.0f : -1.0f;

            X *= Bias;
            Y *= Bias;
            Z *= Bias;
            W *= Bias;
        }
예제 #8
0
        public void SetFromMatrix(FMatrix InMatrix)
        {
            FMatrix M = InMatrix;

            // Get the 3D scale from the matrix
            Scale3D = M.ExtractScaling();

            // If there is negative scaling going on, we handle that here
            if (InMatrix.Determinant() < 0.0f)
            {
                // Assume it is along X and modify transform accordingly.
                // It doesn't actually matter which axis we choose, the 'appearance' will be the same
                Scale3D.X *= -1.0f;
                M.SetAxis(0, -M.GetScaledAxis(EAxis.X));
            }

            Rotation    = new FQuat(M);
            Translation = InMatrix.GetOrigin();

            // Normalize rotation
            Rotation.Normalize();
        }
예제 #9
0
 /// <summary>
 /// <para>Inverse transform a rotation. </para>
 /// <para>For example if this is a LocalToWorld transform, InverseTransformRotation(Q) would transform Q from world to local space. </para>
 /// </summary>
 public FQuat InverseTransformRotation(FQuat q)
 => E_FTransform_InverseTransformRotation(this, q);
예제 #10
0
 /// <summary>
 /// <para>Sets the components </para>
 /// <param name="InRotation">The new value for the Rotation component </param>
 /// <param name="InTranslation">The new value for the Translation component </param>
 /// <param name="InScale3D">The new value for the Scale3D component </param>
 /// </summary>
 public void SetComponents(FQuat inRotation, FVector inTranslation, FVector inScale3D)
 => E_FTransform_SetComponents(this, inRotation, inTranslation, inScale3D);
예제 #11
0
 //[MethodImplAttribute(MethodImplOptions.InternalCall)]
 extern static FRotator Rotator(ref FQuat _this);
예제 #12
0
 /// <summary>
 /// <para>Transform a rotation. </para>
 /// <para>For example if this is a LocalToWorld transform, TransformRotation(Q) would transform Q from local to world space. </para>
 /// </summary>
 public FQuat TransformRotation(FQuat q)
 => E_FTransform_TransformRotation(this, q);
예제 #13
0
 /// <summary>
 /// <para>Sets the rotation component </para>
 /// <param name="NewRotation">The new value for the rotation component </param>
 /// </summary>
 public void SetRotation(FQuat newRotation)
 => E_FTransform_SetRotation(this, newRotation);
예제 #14
0
 public FTransform(FRotator InRotation)
 {
     Rotation    = new FQuat(InRotation);
     Translation = FVector.ZeroVector;
     Scale3D     = new FVector(1.0f);
 }
예제 #15
0
 public FTransform(FQuat InRotation)
 {
     Rotation    = InRotation;
     Translation = FVector.ZeroVector;
     Scale3D     = new FVector(1.0f);
 }
예제 #16
0
 /// <summary>
 /// <para>Constructor with all components initialized </para>
 /// <param name="InRotation">The value to use for rotation component </param>
 /// <param name="InTranslation">The value to use for the translation component </param>
 /// <param name="InScale3D">The value to use for the scale component </param>
 /// </summary>
 public FTransform(FQuat inRotation, FVector inTranslation, FVector inScale3D) :
     base(E_CreateStruct_FTransform_FQuat_FVector_FVector(inRotation, inTranslation, inScale3D), false)
 {
 }
예제 #17
0
 public FDualQuat(FQuat inR, FQuat inD) :
     base(E_CreateStruct_FDualQuat_FQuat_FQuat(inR, inD), false)
 {
 }
예제 #18
0
 /// <summary>
 /// <para>Copy constructor. </para>
 /// <param name="Q">A FQuat object to use to create new quaternion from. </param>
 /// </summary>
 public FQuat(FQuat Q) :
     base(E_CreateStruct_FQuat_FQuat(Q), false)
 {
 }
 /// <summary>
 /// <para>Convert a FQuat to FRotator. Uses the cached conversion if possible, and updates it if there was no match. </para>
 /// </summary>
 public FRotator QuatToRotator(FQuat InQuat)
 => E_FRotationConversionCache_QuatToRotator(this, InQuat);
예제 #20
0
 /**
  * Sets the rotation component
  * @param NewRotation The new value for the rotation component
  */
 public void SetRotation(FQuat NewRotation)
 {
     Rotation = NewRotation;
     DiagnosticCheckNaN_Rotate();
 }
예제 #21
0
 /**
  * Concatenates another rotation to this transformation
  * @param DeltaRotation The rotation to concatenate in the following fashion: Rotation = Rotation * DeltaRotation
  */
 public void ConcatenateRotation(FQuat DeltaRotation)
 {
     Rotation = Rotation * DeltaRotation;
     DiagnosticCheckNaN_Rotate();
 }
예제 #22
0
 public FTransform(FRotator InRotation, FVector InTranslation, FVector InScale3D)
 {
     Rotation    = new FQuat(InRotation);
     Translation = InTranslation;
     Scale3D     = InScale3D;
 }
예제 #23
0
        /**
         * Transform a rotation matrix into a quaternion.
         *
         * @warning rotation part will need to be unit length for this to be right!
         */
        public FQuat ToQuat()
        {
            FQuat Result = new FQuat(this);

            return(Result);
        }
예제 #24
0
 //[MethodImplAttribute(MethodImplOptions.InternalCall)]
 extern static FQuat Multiply(ref FQuat _this, ref FQuat Other);
예제 #25
0
 /// <summary>
 /// <para>Constructor. </para>
 /// <param name="Quat">Quaternion used to specify rotation. </param>
 /// </summary>
 public FRotator(FQuat quat) :
     base(E_CreateStruct_FRotator_FQuat(quat), false)
 {
 }
예제 #26
0
 public FTransform(FQuat InRotation, FVector InTranslation, FVector InScale3D)
 {
     Rotation    = InRotation;
     Translation = InTranslation;
     Scale3D     = InScale3D;
 }
 /// <summary>
 /// <para>Version of QuatToRotator when the Quat is known to already be normalized. Does *NOT* update the cache if there was no match. </para>
 /// </summary>
 public FRotator NormalizedQuatToRotator_ReadOnly(FQuat InNormalizedQuat)
 => E_FRotationConversionCache_NormalizedQuatToRotator_ReadOnly(this, InNormalizedQuat);
예제 #28
0
 /// <summary>
 /// Matrix factory. Return an FMatrix so we don't have type conversion issues in expressions.
 /// </summary>
 public FMatrix Make(FQuat rot)
 => E_FRotationMatrix_Make_o1(this, rot);
 /// <summary>
 /// <para>Convert a FQuat to FRotator. Uses the cached conversion if possible, but does *NOT* update the cache if there was no match. </para>
 /// </summary>
 public FRotator QuatToRotator_ReadOnly(FQuat InQuat)
 => E_FRotationConversionCache_QuatToRotator_ReadOnly(this, InQuat);
예제 #30
0
 /// <summary>
 /// <para>Concatenates another rotation to this transformation </para>
 /// <param name="DeltaRotation">The rotation to concatenate in the following fashion: Rotation = Rotation * DeltaRotation </param>
 /// </summary>
 public void ConcatenateRotation(FQuat deltaRotation)
 => E_FTransform_ConcatenateRotation(this, deltaRotation);