本文整理汇总了C++中FQuat::ToAxisAndAngle方法的典型用法代码示例。如果您正苦于以下问题:C++ FQuat::ToAxisAndAngle方法的具体用法?C++ FQuat::ToAxisAndAngle怎么用?C++ FQuat::ToAxisAndAngle使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类FQuat
的用法示例。
在下文中一共展示了FQuat::ToAxisAndAngle方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: MultiplyQuatBasedOnSourceIndex
FQuat FAnimNode_RotationMultiplier::MultiplyQuatBasedOnSourceIndex(const FTransform& RefPoseTransform, const FTransform& LocalBoneTransform, const EBoneAxis Axis, float InMultiplier, const FQuat& ReferenceQuat)
{
// Find delta angle for source bone.
FQuat DeltaQuat = ExtractAngle(RefPoseTransform, LocalBoneTransform, Axis);
// Turn to Axis and Angle
FVector RotationAxis;
float RotationAngle;
DeltaQuat.ToAxisAndAngle(RotationAxis, RotationAngle);
const FVector DefaultAxis = GetAxisVector(Axis);
// See if we need to invert angle - shortest path
if( (RotationAxis | DefaultAxis) < 0.f )
{
RotationAxis = -RotationAxis;
RotationAngle = -RotationAngle;
}
// Make sure it is the shortest angle.
RotationAngle = FMath::UnwindRadians(RotationAngle);
// New bone rotation
FQuat OutQuat = ReferenceQuat * FQuat(RotationAxis, RotationAngle* InMultiplier);
// Normalize resulting quaternion.
OutQuat.Normalize();
#if 0 //DEBUG_TWISTBONECONTROLLER
UE_LOG(LogSkeletalControl, Log, TEXT("\t RefQuat: %s, Rot: %s"), *ReferenceQuat.ToString(), *ReferenceQuat.Rotator().ToString() );
UE_LOG(LogSkeletalControl, Log, TEXT("\t NewQuat: %s, Rot: %s"), *OutQuat.ToString(), *OutQuat.Rotator().ToString() );
UE_LOG(LogSkeletalControl, Log, TEXT("\t RollAxis: %s, RollAngle: %f"), *RotationAxis.ToString(), RotationAngle );
#endif
return OutQuat;
}
示例2: ExtractAngle
FQuat FAnimNode_RotationMultiplier::ExtractAngle(const TArray<FTransform> & RefPoseTransforms, FA2CSPose & MeshBases, const EBoneAxis Axis, int32 SourceBoneIndex)
{
// local bone transform
const FTransform & LocalBoneTransform = MeshBases.GetLocalSpaceTransform(SourceBoneIndex);
// local bone transform with reference rotation
FTransform ReferenceBoneTransform = RefPoseTransforms[SourceBoneIndex];
ReferenceBoneTransform.SetTranslation(LocalBoneTransform.GetTranslation());
// find delta angle between the two quaternions X Axis.
const FVector RotationAxis = GetAxisVector(Axis);
const FVector LocalRotationVector = LocalBoneTransform.GetRotation().RotateVector(RotationAxis);
const FVector ReferenceRotationVector = ReferenceBoneTransform.GetRotation().RotateVector(RotationAxis);
const FQuat LocalToRefQuat = FQuat::FindBetween(LocalRotationVector, ReferenceRotationVector);
checkSlow( LocalToRefQuat.IsNormalized() );
// Rotate parent bone atom from position in local space to reference skeleton
// Since our rotation rotates both vectors with shortest arc
// we're essentially left with a quaternion that has angle difference with reference skeleton version
const FQuat BoneQuatAligned = LocalToRefQuat * LocalBoneTransform.GetRotation();
checkSlow( BoneQuatAligned.IsNormalized() );
// Find that delta angle
const FQuat DeltaQuat = (ReferenceBoneTransform.GetRotation().Inverse()) * BoneQuatAligned;
checkSlow( DeltaQuat.IsNormalized() );
#if 0 //DEBUG_TWISTBONECONTROLLER
UE_LOG(LogSkeletalControl, Log, TEXT("\t ExtractAngle, Bone: %s (%d)"),
*SourceBone.BoneName.ToString(), SourceBoneIndex);
UE_LOG(LogSkeletalControl, Log, TEXT("\t\t Bone Quat: %s, Rot: %s, AxisX: %s"), *LocalBoneTransform.GetRotation().ToString(), *LocalBoneTransform.GetRotation().Rotator().ToString(), *LocalRotationVector.ToString() );
UE_LOG(LogSkeletalControl, Log, TEXT("\t\t BoneRef Quat: %s, Rot: %s, AxisX: %s"), *ReferenceBoneTransform.GetRotation().ToString(), *ReferenceBoneTransform.GetRotation().Rotator().ToString(), *ReferenceRotationVector.ToString() );
UE_LOG(LogSkeletalControl, Log, TEXT("\t\t LocalToRefQuat Quat: %s, Rot: %s"), *LocalToRefQuat.ToString(), *LocalToRefQuat.Rotator().ToString() );
const FVector BoneQuatAlignedX = LocalBoneTransform.GetRotation().RotateVector(RotationAxis);
UE_LOG(LogSkeletalControl, Log, TEXT("\t\t BoneQuatAligned Quat: %s, Rot: %s, AxisX: %s"), *BoneQuatAligned.ToString(), *BoneQuatAligned.Rotator().ToString(), *BoneQuatAlignedX.ToString() );
UE_LOG(LogSkeletalControl, Log, TEXT("\t\t DeltaQuat Quat: %s, Rot: %s"), *DeltaQuat.ToString(), *DeltaQuat.Rotator().ToString() );
FTransform BoneAtomAligned(BoneQuatAligned, ReferenceBoneTransform.GetTranslation());
const FQuat DeltaQuatAligned = FQuat::FindBetween(BoneAtomAligned.GetScaledAxis( EAxis::X ), ReferenceBoneTransform.GetScaledAxis( EAxis::X ));
UE_LOG(LogSkeletalControl, Log, TEXT("\t\t DeltaQuatAligned Quat: %s, Rot: %s"), *DeltaQuatAligned.ToString(), *DeltaQuatAligned.Rotator().ToString() );
FVector DeltaAxis;
float DeltaAngle;
DeltaQuat.ToAxisAndAngle(DeltaAxis, DeltaAngle);
UE_LOG(LogSkeletalControl, Log, TEXT("\t\t DeltaAxis: %s, DeltaAngle: %f"), *DeltaAxis.ToString(), DeltaAngle );
#endif
return DeltaQuat;
}
示例3: ApplyRigidBodyState
bool UPrimitiveComponent::ApplyRigidBodyState(const FRigidBodyState& NewState, const FRigidBodyErrorCorrection& ErrorCorrection, FVector& OutDeltaPos, FName BoneName)
{
bool bRestoredState = true;
FBodyInstance* BI = GetBodyInstance(BoneName);
if (BI && BI->IsInstanceSimulatingPhysics())
{
// failure cases
const float QuatSizeSqr = NewState.Quaternion.SizeSquared();
if (QuatSizeSqr < KINDA_SMALL_NUMBER)
{
UE_LOG(LogPhysics, Warning, TEXT("Invalid zero quaternion set for body. (%s:%s)"), *GetName(), *BoneName.ToString());
return bRestoredState;
}
else if (FMath::Abs(QuatSizeSqr - 1.f) > KINDA_SMALL_NUMBER)
{
UE_LOG(LogPhysics, Warning, TEXT("Quaternion (%f %f %f %f) with non-unit magnitude detected. (%s:%s)"),
NewState.Quaternion.X, NewState.Quaternion.Y, NewState.Quaternion.Z, NewState.Quaternion.W, *GetName(), *BoneName.ToString() );
return bRestoredState;
}
FRigidBodyState CurrentState;
GetRigidBodyState(CurrentState, BoneName);
const bool bShouldSleep = (NewState.Flags & ERigidBodyFlags::Sleeping) != 0;
/////// POSITION CORRECTION ///////
// Find out how much of a correction we are making
const FVector DeltaPos = NewState.Position - CurrentState.Position;
const float DeltaMagSq = DeltaPos.SizeSquared();
const float BodyLinearSpeedSq = CurrentState.LinVel.SizeSquared();
// Snap position by default (big correction, or we are moving too slowly)
FVector UpdatedPos = NewState.Position;
FVector FixLinVel = FVector::ZeroVector;
// If its a small correction and velocity is above threshold, only make a partial correction,
// and calculate a velocity that would fix it over 'fixTime'.
if (DeltaMagSq < ErrorCorrection.LinearDeltaThresholdSq &&
BodyLinearSpeedSq >= ErrorCorrection.BodySpeedThresholdSq)
{
UpdatedPos = FMath::Lerp(CurrentState.Position, NewState.Position, ErrorCorrection.LinearInterpAlpha);
FixLinVel = (NewState.Position - UpdatedPos) * ErrorCorrection.LinearRecipFixTime;
}
// Get the linear correction
OutDeltaPos = UpdatedPos - CurrentState.Position;
/////// ORIENTATION CORRECTION ///////
// Get quaternion that takes us from old to new
const FQuat InvCurrentQuat = CurrentState.Quaternion.Inverse();
const FQuat DeltaQuat = NewState.Quaternion * InvCurrentQuat;
FVector DeltaAxis;
float DeltaAng; // radians
DeltaQuat.ToAxisAndAngle(DeltaAxis, DeltaAng);
DeltaAng = FMath::UnwindRadians(DeltaAng);
// Snap rotation by default (big correction, or we are moving too slowly)
FQuat UpdatedQuat = NewState.Quaternion;
FVector FixAngVel = FVector::ZeroVector; // degrees per second
// If the error is small, and we are moving, try to move smoothly to it
if (FMath::Abs(DeltaAng) < ErrorCorrection.AngularDeltaThreshold )
{
UpdatedQuat = FMath::Lerp(CurrentState.Quaternion, NewState.Quaternion, ErrorCorrection.AngularInterpAlpha);
FixAngVel = DeltaAxis.GetSafeNormal() * FMath::RadiansToDegrees(DeltaAng) * (1.f - ErrorCorrection.AngularInterpAlpha) * ErrorCorrection.AngularRecipFixTime;
}
/////// BODY UPDATE ///////
BI->SetBodyTransform(FTransform(UpdatedQuat, UpdatedPos), true);
BI->SetLinearVelocity(NewState.LinVel + FixLinVel, false);
BI->SetAngularVelocity(NewState.AngVel + FixAngVel, false);
// state is restored when no velocity corrections are required
bRestoredState = (FixLinVel.SizeSquared() < KINDA_SMALL_NUMBER) && (FixAngVel.SizeSquared() < KINDA_SMALL_NUMBER);
/////// SLEEP UPDATE ///////
const bool bIsAwake = BI->IsInstanceAwake();
if (bIsAwake && (bShouldSleep && bRestoredState))
{
BI->PutInstanceToSleep();
}
else if (!bIsAwake)
{
BI->WakeInstance();
}
}
return bRestoredState;
}
示例4: ConvertDeltaRotationsToAxisAngle
static bool ConvertDeltaRotationsToAxisAngle(const FRotator& StartOrientation, const FRotator& EndOrientation, FVector& OutAxis, float& OutAngle)
{
FQuat deltaRotation = EndOrientation.Quaternion() * StartOrientation.Quaternion().Inverse();
deltaRotation.ToAxisAndAngle(OutAxis, OutAngle);
return true;
}