void ACinemotusPlayerController::AbsoluteTick(float DeltaTime) { TotalYawAbs += addYaw; UPrimitiveComponent* prim = GetPawn()->GetMovementComponent()->UpdatedComponent; //USceneComponent* sComponent = GetPawn()->GetRootComponent(); //sComponent->SetRelativeLocation; bool SetPrimDirectly = true; FQuat finalQuat; if (((currentCaptureState&ECinemotusCaptureState::EAbsolute) == ECinemotusCaptureState::EAbsolute) && ((currentCaptureState&ECinemotusCaptureState::EAbsoluteOff) == 0)) { finalQuat = FRotator(0, TotalYawAbs, 0).Quaternion()*(HydraLatestData->controllers[CAM_HAND].quat); } else { finalQuat = FRotator(0, addYaw, 0).Quaternion()*prim->GetComponentQuat(); } SetControlRotation(finalQuat.Rotator()); if (SetPrimDirectly && prim) { prim->SetWorldLocationAndRotation(prim->GetComponentLocation(), finalQuat);// not sure need } HandleMovementAbs(DeltaTime, ((currentCaptureState&ECinemotusCaptureState::EAbsolute) == ECinemotusCaptureState::EAbsolute)); }
//Conversion - use find and replace to change behavior, no scaling version is typically used for orientations FVector ConvertLeapToUE(Leap::Vector LeapVector) { //Convert Axis FVector ConvertedVector = FVector(-LeapVector.z, LeapVector.x, LeapVector.y); //Hmd orientation adjustment if (LeapShouldAdjustForFacing) { FRotator Rotation = FRotator(90.f, 0.f, 180.f); ConvertedVector = FQuat(Rotation).RotateVector(ConvertedVector); if (LeapShouldAdjustRotationForHMD) { if (GEngine->HMDDevice.IsValid()) { FQuat orientationQuat; FVector position; GEngine->HMDDevice->GetCurrentOrientationAndPosition(orientationQuat, position); ConvertedVector = orientationQuat.RotateVector(ConvertedVector); } } } return ConvertedVector; }
void UOculusFunctionLibrary::GetPose(FRotator& DeviceRotation, FVector& DevicePosition, FVector& NeckPosition, bool bUseOrienationForPlayerCamera, bool bUsePositionForPlayerCamera, const FVector PositionScale) { #if OCULUS_SUPPORTED_PLATFORMS FHeadMountedDisplay* OculusHMD = GetOculusHMD(); if (OculusHMD && OculusHMD->IsHeadTrackingAllowed()) { FQuat OrientationAsQuat; OculusHMD->GetCurrentHMDPose(OrientationAsQuat, DevicePosition, bUseOrienationForPlayerCamera, bUsePositionForPlayerCamera, PositionScale); DeviceRotation = OrientationAsQuat.Rotator(); NeckPosition = OculusHMD->GetNeckPosition(OrientationAsQuat, DevicePosition, PositionScale); //UE_LOG(LogUHeadMountedDisplay, Log, TEXT("POS: %.3f %.3f %.3f"), DevicePosition.X, DevicePosition.Y, DevicePosition.Z); //UE_LOG(LogUHeadMountedDisplay, Log, TEXT("NECK: %.3f %.3f %.3f"), NeckPosition.X, NeckPosition.Y, NeckPosition.Z); //UE_LOG(LogUHeadMountedDisplay, Log, TEXT("ROT: sYaw %.3f Pitch %.3f Roll %.3f"), DeviceRotation.Yaw, DeviceRotation.Pitch, DeviceRotation.Roll); } else #endif // #if OCULUS_SUPPORTED_PLATFORMS { DeviceRotation = FRotator::ZeroRotator; DevicePosition = FVector::ZeroVector; } }
void URotatingMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) { // skip if we don't want component updated when not rendered or if updated component can't move if (ShouldSkipUpdate(DeltaTime)) { return; } Super::TickComponent(DeltaTime, TickType, ThisTickFunction); if (!IsValid(UpdatedComponent)) { return; } // Compute new rotation const FQuat OldRotation = UpdatedComponent->GetComponentQuat(); const FQuat DeltaRotation = (RotationRate * DeltaTime).Quaternion(); const FQuat NewRotation = bRotationInLocalSpace ? (OldRotation * DeltaRotation) : (DeltaRotation * OldRotation); // Compute new location FVector DeltaLocation = FVector::ZeroVector; if (!PivotTranslation.IsZero()) { const FVector OldPivot = OldRotation.RotateVector(PivotTranslation); const FVector NewPivot = NewRotation.RotateVector(PivotTranslation); DeltaLocation = (OldPivot - NewPivot); // ConstrainDirectionToPlane() not necessary because it's done by MoveUpdatedComponent() below. } const bool bEnableCollision = false; MoveUpdatedComponent(DeltaLocation, NewRotation, bEnableCollision); }
FMatrix USkeletalMeshComponent::GetTransformMatrix() const { FTransform RootTransform = GetBoneTransform(0); FVector Translation; FQuat Rotation; // if in editor, it should always use localToWorld // if root motion is ignored, use root transform if( GetWorld()->IsGameWorld() || !SkeletalMesh ) { // add root translation info Translation = RootTransform.GetLocation(); } else { Translation = ComponentToWorld.TransformPosition(SkeletalMesh->RefSkeleton.GetRefBonePose()[0].GetTranslation()); } // if root rotation is ignored, use root transform rotation Rotation = RootTransform.GetRotation(); // now I need to get scale // only LocalToWorld will have scale FVector ScaleVector = ComponentToWorld.GetScale3D(); Rotation.Normalize(); return FScaleMatrix(ScaleVector)*FQuatRotationTranslationMatrix(Rotation, Translation); }
/** custom instantiation of Interpolate for FQuats */ template <> FQuat Interpolate<FQuat>(const FQuat& A, const FQuat& B, float Alpha) { FQuat result = FQuat::FastLerp(A,B,Alpha); result.Normalize(); return result; }
bool UPerceptionNeuronBPLibrary::NeuronGetReferencePoseLocalBoneRotation(USkeletalMeshComponent *Mesh, FRotator& Rotation, int32 BoneIndex) { if (Mesh == nullptr && Mesh->SkeletalMesh == nullptr) { if (GEngine) { GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Mesh is invalid."))); } Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0; return false; } if (BoneIndex > Mesh->LocalAtoms.Num()) { if (GEngine) { GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("BoneIndex %d exceeds maximum available bones %d."), BoneIndex, Mesh->LocalAtoms.Num())); } Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0; return false; } const FReferenceSkeleton& refskel(Mesh->SkeletalMesh->RefSkeleton); FQuat Quat = refskel.GetRefBonePose()[BoneIndex].GetRotation(); Rotation = Quat.Rotator(); return true; }
/* * Spawns the hitbox and processes the actors within it */ void AHero::AttackTrace() { //Actors that overlap the box stored in this array TArray<struct FOverlapResult> OutOverlaps; //Orient the box in the direction of the character FQuat Rotation = Instigator->GetTransform().GetRotation(); FVector Start = Instigator->GetTransform().GetLocation() + Rotation.Rotator().Vector() * 100.0f; FCollisionShape CollisionHitShape; FCollisionQueryParams CollisionParams; //Have the hitbox ignore the player CollisionParams.AddIgnoredActor(Instigator); //Set what will respond to the collision FCollisionObjectQueryParams CollisionObjectTypes; CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_PhysicsBody); CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_Pawn); CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_WorldStatic); //Create the hitbox and get the actors within CollisionHitShape = FCollisionShape::MakeBox(FVector(100.0f, 60.0f, 0.5f)); GetWorld()->OverlapMulti(OutOverlaps, Start, Rotation, CollisionHitShape, CollisionParams, CollisionObjectTypes); //Process all hit actors for (int i = 0; i < OutOverlaps.Num(); i++) { if (OutOverlaps[i].GetActor() && !HitActors.Contains(OutOverlaps[i].GetActor())) { //Check if hit registered GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("hit")); //Now call the function that does something to our unfortunate actor... ProcessHitActor(OutOverlaps[i].GetActor()); } } }
//Conversion - use find and replace to change behavior, no scaling version is typically used for orientations FVector convertLeapToUE(Leap::Vector leapVector) { //Convert Axis FVector vect = FVector(-leapVector.z, leapVector.x, leapVector.y); //Hmd orientation adjustment if (LeapShouldAdjustForFacing) { FRotator rotation = FRotator(90.f, 0.f, 180.f); vect = FQuat(rotation).RotateVector(vect); if (LeapShouldAdjustRotationForHMD) { if (GEngine->HMDDevice.IsValid()) { FQuat orientationQuat; FVector position; GEngine->HMDDevice->GetCurrentOrientationAndPosition(orientationQuat, position); vect = orientationQuat.RotateVector(vect); } } } return vect; }
void UDestructibleComponent::SetChunksWorldTM(const TArray<FUpdateChunksInfo>& UpdateInfos) { const FQuat InvRotation = ComponentToWorld.GetRotation().Inverse(); for (const FUpdateChunksInfo& UpdateInfo : UpdateInfos) { // Bone 0 is a dummy root bone const int32 BoneIndex = ChunkIdxToBoneIdx(UpdateInfo.ChunkIndex); const FVector WorldTranslation = UpdateInfo.WorldTM.GetLocation(); const FQuat WorldRotation = UpdateInfo.WorldTM.GetRotation(); const FQuat BoneRotation = InvRotation*WorldRotation; const FVector BoneTranslation = InvRotation.RotateVector(WorldTranslation - ComponentToWorld.GetTranslation()) / ComponentToWorld.GetScale3D(); GetEditableSpaceBases()[BoneIndex] = FTransform(BoneRotation, BoneTranslation); } // Mark the transform as dirty, so the bounds are updated and sent to the render thread MarkRenderTransformDirty(); // New bone positions need to be sent to render thread MarkRenderDynamicDataDirty(); //Update bone visibilty and flip the editable space base buffer FlipEditableSpaceBases(); }
void LostCore::FBasicCamera::AddPositionLocal(const FFloat3& pos) { FQuat orientation; orientation.FromEuler(ViewEuler); FTransform world(orientation, ViewPosition); ViewPosition = world.TransformPosition(pos); }
void UCustomMovementComponent::UpdateCapsuleRotation(float DeltaTime, const FVector& TargetUpVector, bool bInstantRot, float RotationSpeed) { const FVector CapsuleUp = CapsuleComponent->GetUpVector(); const FQuat DeltaQuat = FQuat::FindBetween(CapsuleUp, TargetUpVector); const FQuat TargetQuat = DeltaQuat * CapsuleComponent->GetComponentRotation().Quaternion(); CurrentCapsuleRotation = bInstantRot ? TargetQuat.Rotator() : FMath::RInterpTo(CurrentCapsuleRotation, TargetQuat.Rotator(), DeltaTime, RotationSpeed); CapsuleComponent->SetWorldRotation(CurrentCapsuleRotation); }
FFloat4x4 LostCore::FBasicCamera::GetViewMatrix() const { FQuat orientation; orientation.FromEuler(ViewEuler); FFloat4x4 world; world.SetRotateAndOrigin(orientation, ViewPosition); world.Invert(); return world; }
bool UCapsuleComponent::AreSymmetricRotations(const FQuat& A, const FQuat& B, const FVector& Scale3D) const { if (Scale3D.X != Scale3D.Y) { return false; } const FVector AUp = A.GetAxisZ(); const FVector BUp = B.GetAxisZ(); return AUp.Equals(BUp); }
//--------------------------------------------------------------------------------------- // # Skookum: Vector3@unrotate_by(Rotation rot) Vector3 // # Author(s): Markus Breyer static void mthd_unrotate_by(SkInvokedMethod * scope_p, SkInstance ** result_pp) { // Do nothing if result not desired if (result_pp) { const FVector & vec = scope_p->this_as<SkVector3>(); const FQuat rot = scope_p->get_arg<SkRotation>(SkArg_1); *result_pp = SkVector3::new_instance(rot.Inverse().RotateVector(vec)); } }
//--------------------------------------------------------------------------------------- // # Skookum: Vector3@unrotate_by(Rotation rot) Vector3 // # Author(s): Markus Breyer static void mthd_unrotate_by(SSInvokedMethod * scope_p, SSInstance ** result_pp) { // Do nothing if result not desired if (result_pp) { const FVector & vec = *scope_p->this_as<FVector>(); const FQuat rot = *scope_p->get_arg<FQuat>(SSArg_1); *result_pp = as_instance(rot.Inverse().RotateVector(vec)); } }
FVector USplineComponent::GetRightVectorAtSplineInputKey(float InKey, ESplineCoordinateSpace::Type CoordinateSpace) const { const FQuat Quat = GetQuaternionAtSplineInputKey(InKey, ESplineCoordinateSpace::Local); FVector RightVector = Quat.RotateVector(FVector::RightVector); if (CoordinateSpace == ESplineCoordinateSpace::World) { RightVector = ComponentToWorld.TransformVectorNoScale(RightVector); } return RightVector; }
void UBerserkCameraComponent::UpdateCameraBounds(const APlayerController* playerController) { auto const* const localPlayer = Cast<ULocalPlayer>(playerController->Player); if (localPlayer == nullptr || localPlayer->ViewportClient == nullptr) return; FVector2D currentViewportSize; localPlayer->ViewportClient->GetViewportSize(currentViewportSize); // calc frustum edge direction, from bottom left corner if (CameraMovementBounds.GetSize() == FVector::ZeroVector || currentViewportSize != CameraMovementViewportSize) { // calc frustum edge direction, from bottom left corner const FVector frustumRay2dDir = FVector(1, 1, 0).GetSafeNormal(); const FVector frustumRay2dRight = FVector::CrossProduct(frustumRay2dDir, FVector::UpVector); const FQuat rotQuat(frustumRay2dRight, FMath::DegreesToRadians(90.0f - playerController->PlayerCameraManager->GetFOVAngle() * 0.5f)); const FVector frustumRayDir = rotQuat.RotateVector(frustumRay2dDir); // collect 3 world bounds' points and matching frustum rays (bottom left, top left, bottom right) auto const* const gameState = GetWorld()->GetGameState<ABerserkGameState>(); if (gameState) { const auto worldBounds = gameState->WorldBounds; if (worldBounds.GetSize() != FVector::ZeroVector) { const FVector worldBoundPoints[] = { FVector(worldBounds.Min.X, worldBounds.Min.Y, worldBounds.Max.Z), FVector(worldBounds.Min.X, worldBounds.Max.Y, worldBounds.Max.Z), FVector(worldBounds.Max.X, worldBounds.Min.Y, worldBounds.Max.Z) }; const FVector frustumRays[] = { FVector(frustumRayDir.X, frustumRayDir.Y, frustumRayDir.Z), FVector(frustumRayDir.X, -frustumRayDir.Y, frustumRayDir.Z), FVector(-frustumRayDir.X, frustumRayDir.Y, frustumRayDir.Z) }; // get camera plane for intersections const auto cameraPlane = FPlane(playerController->GetFocalLocation(), FVector::UpVector); // get matching points on camera plane const FVector cameraPlanePoints[3] = { FProjectionUtils::IntersectRayWithPlane(worldBoundPoints[0], frustumRays[0], cameraPlane) * MiniMapBoundsLimit, FProjectionUtils::IntersectRayWithPlane(worldBoundPoints[1], frustumRays[1], cameraPlane) * MiniMapBoundsLimit, FProjectionUtils::IntersectRayWithPlane(worldBoundPoints[2], frustumRays[2], cameraPlane) * MiniMapBoundsLimit }; // create new bounds CameraMovementBounds = FBox(cameraPlanePoints, 3); CameraMovementViewportSize = currentViewportSize; } } } }
//------------------------------------------------------------------------- // //------------------------------------------------------------------------- FVector FFbxDataConverter::ConvertRotationToFVect(FbxQuaternion Quaternion, bool bInvertOrient) { FQuat UnrealQuaternion = ConvertRotToQuat(Quaternion); FVector Euler; Euler = UnrealQuaternion.Euler(); if (bInvertOrient) { Euler.Y = -Euler.Y; Euler.Z = 180.f+Euler.Z; } return Euler; }
FVector adjustForHMDOrientation(FVector in) { if (GEngine->HMDDevice.IsValid()) { FQuat orientationQuat; FVector position; GEngine->HMDDevice->GetCurrentOrientationAndPosition(orientationQuat, position); FVector out = orientationQuat.RotateVector(in); return out; } else return in; }
void UAnimGraphNode_ModifyBone::DoRotation(const USkeletalMeshComponent* SkelComp, FRotator& Rotation, FAnimNode_Base* InOutAnimNode) { FAnimNode_ModifyBone* ModifyBone = static_cast<FAnimNode_ModifyBone*>(InOutAnimNode); if (Node.RotationMode != EBoneModificationMode::BMM_Ignore) { FQuat DeltaQuat = ConvertCSRotationToBoneSpace(SkelComp, Rotation, ModifyBone->ForwardedPose, Node.BoneToModify.BoneName, Node.RotationSpace); FQuat PrevQuat(ModifyBone->Rotation); FQuat NewQuat = DeltaQuat * PrevQuat; ModifyBone->Rotation = NewQuat.Rotator(); Node.Rotation = ModifyBone->Rotation; } }
FVector adjustForHMDOrientation(FVector In) { if (GEngine->HMDDevice.IsValid()) { FQuat OrientationQuat; FVector Position; GEngine->HMDDevice->GetCurrentOrientationAndPosition(OrientationQuat, Position); FVector Out = OrientationQuat.RotateVector(In); return Out; } else return In; }
void ABaseCharacter::CheckAttackOverlap(){ //Overlapping actors for each box spawned will be stored here TArray<struct FOverlapResult> OutActorOverlaps; //Hit other actors only once TArray<AActor*> ProcessedActors; //The initial rotation of our box is the same as our character rotation FQuat Rotation = GetTransform().GetRotation(); FVector Start = GetTransform().GetLocation() + Rotation.Rotator().Vector() * 100.0f; FCollisionShape CollisionHitShape; FCollisionQueryParams CollisionParams; //We do not want the character to hit itself, don't store this character in the array, to ignore it's collision CollisionParams.AddIgnoredActor(this); //Set the channels that will respond to the collision FCollisionObjectQueryParams CollisionObjectTypes; CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_PhysicsBody); CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_Pawn); //CollisionObjectTypes.AddObjectTypesToQuery(ECollisionChannel::ECC_WorldStatic); // uncomment to enable bashing objects //Create the box and get the overlapping actors CollisionHitShape = FCollisionShape::MakeBox(AttackBox); GetWorld()->OverlapMulti(OutActorOverlaps, Start, Rotation, CollisionHitShape, CollisionParams, CollisionObjectTypes); AActor* ActorToProcess; //Process all hit actors for (int i = 0; i < OutActorOverlaps.Num(); ++i) { ActorToProcess = OutActorOverlaps[i].GetActor(); //We process each actor only once per Attack execution if (ActorToProcess && !ProcessedActors.Contains(ActorToProcess)) { //Add this actor to the array because we are spawning one box per tick and we don't want to hit the same actor twice during the same attack animation ProcessedActors.AddUnique(ActorToProcess); if ( dynamic_cast<APatrollingEnemyCharacter*>(ActorToProcess) ){ APatrollingEnemyCharacter* ennemy = (APatrollingEnemyCharacter*)ActorToProcess; ennemy->OnHit(this); } } } }
void UOSVRInputComponent::InitializeComponent() { Super::InitializeComponent(); WorldToMetersScale = 100.f; UWorld* w = GetWorld(); if (w != nullptr) { AWorldSettings* ws = w->GetWorldSettings(); if (ws != nullptr) { WorldToMetersScale = ws->WorldToMeters; } } auto InterfaceCollection = IOSVR::Get().GetEntryPoint()->GetInterfaceCollection(); OSVRInterfaceCollection::RegistrationToken RegToken = InterfaceCollection->RegisterOnStateChangedCallback( [=](OSVRInterface* Interface, uint32 State) { /* FTransform Pose; if (((State & OSVRInterface::POSE_STATE_AVAILABLE) > 0) && Interface->GetPose(Pose, false)) { Pose.ScaleTranslation(WorldToMetersScale); OnPoseChanged.Broadcast(Interface->GetName(), Pose); } */ FVector Position; if (((State & OSVRInterface::POSITION_STATE_AVAILABLE) > 0) && Interface->GetPosition(Position, false)) OnPositionChanged.Broadcast(Interface->GetName(), Position * WorldToMetersScale); FQuat Orientation; if (((State & OSVRInterface::ORIENTATION_STATE_AVAILABLE) > 0) && Interface->GetOrientation(Orientation, false)) OnOrientationChanged.Broadcast(Interface->GetName(), Orientation.Rotator()); float Analog; if (((State & OSVRInterface::ANALOG_STATE_AVAILABLE) > 0) && Interface->GetAnalogState(Analog, false)) OnAnalogValueChanged.Broadcast(Interface->GetName(), Analog); uint8 Button; if (((State & OSVRInterface::BUTTON_STATE_AVAILABLE) > 0) && Interface->GetButtonState(Button, false)) OnButtonStateChanged.Broadcast(Interface->GetName(), EButtonState::Type(Button)); }); RegistrationToken = RegToken.Token; }
float UAblTargetingBox::CalculateRange() const { FVector RotatedBox; FQuat Rotation = FQuat(m_Location.GetRotation()); RotatedBox = Rotation.GetForwardVector() + m_HalfExtents.X; RotatedBox += Rotation.GetRightVector() + m_HalfExtents.Y; RotatedBox += Rotation.GetUpVector() + m_HalfExtents.Z; if (m_CalculateAs2DRange) { return m_Location.GetOffset().Size2D() + RotatedBox.Size2D(); } return m_Location.GetOffset().Size() + RotatedBox.Size(); }
FQuat USplineComponent::GetQuaternionAtSplineInputKey(float InKey, ESplineCoordinateSpace::Type CoordinateSpace) const { FQuat Quat = SplineRotInfo.Eval(InKey, FQuat::Identity); Quat.Normalize(); const FVector Direction = SplineInfo.EvalDerivative(InKey, FVector::ZeroVector).GetSafeNormal(); const FVector UpVector = Quat.RotateVector(DefaultUpVector); FQuat Rot = (FRotationMatrix::MakeFromXZ(Direction, UpVector)).ToQuat(); if (CoordinateSpace == ESplineCoordinateSpace::World) { Rot = ComponentToWorld.GetRotation() * Rot; } return Rot; }
void ASmrActor::PoseCharacterWorldSpace(UPoseableMeshComponent* mesh) { //Get skeleton and apply correct settings skeleton = m_motion.getSkeleton(m_frameIndex); skeleton.setRotationOrder(TRANSLATIONFIRST); skeleton.setMode(SMRModeType::ABSOLUTEMODE); //Apply rotation to each bone in the Unreal skeleton for (uint32 i = 0; i < skeleton.getNumJoints(); ++i) { FQuat orientation = USmrFunctions::RightCoordToLeft(USmrFunctions::MakeFQuat(skeleton.getJoint(i)->getOrientation())); FVector euler = orientation.Euler(); FRotator rotator = FRotator::MakeFromEuler(euler); //Rotations are applied to bones with identical names so the skeletons must match exactly mesh->SetBoneRotationByName(FName(skeleton.getJoint(i)->getName().c_str()), rotator, EBoneSpaces::WorldSpace); } }
FRotator UKismetMathLibrary::RLerp(FRotator A, FRotator B, float Alpha, bool bShortestPath) { FRotator DeltaAngle = B - A; // if shortest path, we use Quaternion to interpolate instead of using FRotator if( bShortestPath ) { FQuat AQuat(A); FQuat BQuat(B); FQuat Result = FQuat::Slerp(AQuat, BQuat, Alpha); Result.Normalize(); return Result.Rotator(); } return A + Alpha*DeltaAngle; }
void FAnimNode_RotationMultiplier::MultiplyQuatBasedOnSourceIndex(const TArray<FTransform> & RefPoseTransforms, FA2CSPose& MeshBases, const EBoneAxis Axis, int32 SourceBoneIndex, float Multiplier, const FQuat & ReferenceQuat, FQuat & OutQuat) { // Find delta angle for source bone. FQuat DeltaQuat = ExtractAngle(RefPoseTransforms, MeshBases, Axis, SourceBoneIndex); // 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 OutQuat = ReferenceQuat * FQuat(RotationAxis, RotationAngle* Multiplier); // 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 }
bool VRPNTrackerInputDevice::GetControllerOrientationAndPosition(const int32 ControllerIndex, const EControllerHand DeviceHand, FRotator& OutOrientation, FVector& OutPosition) const { for(auto &InputPair : TrackerMap) { const TrackerInput &Tracker = InputPair.Value; if(Tracker.PlayerIndex == ControllerIndex && Tracker.Hand == DeviceHand) { if(InputDevice) { FScopeLock ScopeLock(&CritSect); InputDevice->mainloop(); } FVector NewPosition; FQuat NewRotation; TransformCoordinates(Tracker, NewPosition, NewRotation); OutOrientation = NewRotation.Rotator(); OutPosition = NewPosition; return true; } } return false; }