void GetNiceRotatorValue(FRotator& Rotator1, FRotator& Rotator2) { Rotator1.Normalize(); Rotator2.Normalize(); GetNiceAngleValue(Rotator1.Pitch, Rotator2.Pitch); GetNiceAngleValue(Rotator1.Yaw, Rotator2.Yaw); GetNiceAngleValue(Rotator1.Roll, Rotator2.Roll); }
void AARCharacter::MoveForward(float Value) { if ((Controller != NULL) && (Value != 0.0f)) { //if (Value < 0) //{ // float orignal = CharacterMovement->MaxWalkSpeed; // CharacterMovement->MaxWalkSpeed = CharacterMovement->MaxWalkSpeed / 2; // FRotator Rotation = GetBaseAimRotation(); // FVector Location; //not used, just need for below. // //Controller->GetPlayerViewPoint(Location, Rotation); // Rotation.Normalize(); // FRotator YawRotation(0, Rotation.Yaw, 0); // //const FVector Direction = FRotationMatrix(Rotation).GetScaledAxis( EAxis::X ); // const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); // AddMovementInput(Direction, Value); // CharacterMovement->MaxWalkSpeed = orignal; // return; //} FRotator Rotation = GetBaseAimRotation(); FVector Location; //not used, just need for below. //Controller->GetPlayerViewPoint(Location, Rotation); Rotation.Normalize(); FRotator YawRotation(0, Rotation.Yaw, 0); //const FVector Direction = FRotationMatrix(Rotation).GetScaledAxis( EAxis::X ); const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); AddMovementInput(Direction, Value); } }
void AActor::EditorApplyRotation(const FRotator& DeltaRotation, bool bAltDown, bool bShiftDown, bool bCtrlDown) { if( RootComponent != NULL ) { const FRotator Rot = RootComponent->GetAttachParent() != NULL ? GetActorRotation() : RootComponent->RelativeRotation; FRotator ActorRotWind, ActorRotRem; Rot.GetWindingAndRemainder(ActorRotWind, ActorRotRem); const FQuat ActorQ = ActorRotRem.Quaternion(); const FQuat DeltaQ = DeltaRotation.Quaternion(); const FQuat ResultQ = DeltaQ * ActorQ; const FRotator NewActorRotRem = FRotator( ResultQ ); FRotator DeltaRot = NewActorRotRem - ActorRotRem; DeltaRot.Normalize(); if( RootComponent->GetAttachParent() != NULL ) { RootComponent->SetWorldRotation( Rot + DeltaRot ); } else { // No attachment. Directly set relative rotation (to support winding) RootComponent->SetRelativeRotation( Rot + DeltaRot ); } } else { UE_LOG(LogActor, Warning, TEXT("WARNING: EditorApplyRotation %s has no root component"), *GetName() ); } }
void APlayerCameraManager::ProcessViewRotation(float DeltaTime, FRotator& OutViewRotation, FRotator& OutDeltaRot) { for( int32 ModifierIdx = 0; ModifierIdx < ModifierList.Num(); ModifierIdx++ ) { if( ModifierList[ModifierIdx] != NULL && !ModifierList[ModifierIdx]->IsDisabled() ) { if( ModifierList[ModifierIdx]->ProcessViewRotation(ViewTarget.Target, DeltaTime, OutViewRotation, OutDeltaRot) ) { break; } } } // Add Delta Rotation OutViewRotation += OutDeltaRot; OutDeltaRot = FRotator::ZeroRotator; if(GEngine->HMDDevice.IsValid() && GEngine->IsStereoscopic3D()) { // With the HMD devices, we can't limit the view pitch, because it's bound to the player's head. A simple normalization will suffice OutViewRotation.Normalize(); } else { // Limit Player View Axes LimitViewPitch( OutViewRotation, ViewPitchMin, ViewPitchMax ); LimitViewYaw( OutViewRotation, ViewYawMin, ViewYawMax ); LimitViewRoll( OutViewRotation, ViewRollMin, ViewRollMax ); } }
bool AKinectPlayerController::FindDeathCameraSpot(FVector& CameraLocation, FRotator& CameraRotation) { const FVector PawnLocation = GetPawn()->GetActorLocation(); FRotator ViewDir = GetControlRotation(); ViewDir.Pitch = -45.0f; const float YawOffsets[] = { 0.0f, -180.0f, 90.0f, -90.0f, 45.0f, -45.0f, 135.0f, -135.0f }; const float CameraOffset = 600.0f; FCollisionQueryParams TraceParams(TEXT("DeathCamera"), true, GetPawn()); for (int32 i = 0; i < ARRAY_COUNT(YawOffsets); i++) { FRotator CameraDir = ViewDir; CameraDir.Yaw += YawOffsets[i]; CameraDir.Normalize(); const FVector TestLocation = PawnLocation - CameraDir.Vector() * CameraOffset; const bool bBlocked = GetWorld()->LineTraceTest(PawnLocation, TestLocation, ECC_Camera, TraceParams); if (!bBlocked) { CameraLocation = TestLocation; CameraRotation = CameraDir; return true; } } return false; }
void FSpriteSelectedSocket::ApplyDelta(const FVector2D& Delta, const FRotator& Rotation, const FVector& Scale3D, FWidget::EWidgetMode MoveMode) { if (UPrimitiveComponent* PreviewComponent = PreviewComponentPtr.Get()) { UObject* AssociatedAsset = const_cast<UObject*>(PreviewComponent->AdditionalStatObject()); if (UPaperSprite* Sprite = Cast<UPaperSprite>(AssociatedAsset)) { if (FPaperSpriteSocket* Socket = Sprite->FindSocket(SocketName)) { const bool bDoRotation = (MoveMode == FWidget::WM_Rotate) || (MoveMode == FWidget::WM_TranslateRotateZ); const bool bDoTranslation = (MoveMode == FWidget::WM_Translate) || (MoveMode == FWidget::WM_TranslateRotateZ); const bool bDoScale = MoveMode == FWidget::WM_Scale; if (bDoTranslation) { //@TODO: Currently sockets are in unflipped pivot space, const FVector Delta3D_UU = (PaperAxisX * Delta.X) + (PaperAxisY * -Delta.Y); const FVector Delta3D = Delta3D_UU * Sprite->GetPixelsPerUnrealUnit(); Socket->LocalTransform.SetLocation(Socket->LocalTransform.GetLocation() + Delta3D); } if (bDoRotation) { const FRotator CurrentRot = Socket->LocalTransform.GetRotation().Rotator(); FRotator SocketWinding; FRotator SocketRotRemainder; CurrentRot.GetWindingAndRemainder(SocketWinding, SocketRotRemainder); const FQuat ActorQ = SocketRotRemainder.Quaternion(); const FQuat DeltaQ = Rotation.Quaternion(); const FQuat ResultQ = DeltaQ * ActorQ; const FRotator NewSocketRotRem = FRotator( ResultQ ); FRotator DeltaRot = NewSocketRotRem - SocketRotRemainder; DeltaRot.Normalize(); const FRotator NewRotation(CurrentRot + DeltaRot); Socket->LocalTransform.SetRotation(NewRotation.Quaternion()); } if (bDoScale) { const FVector4 LocalSpaceScaleOffset = Socket->LocalTransform.TransformVector(Scale3D); Socket->LocalTransform.SetScale3D(Socket->LocalTransform.GetScale3D() + LocalSpaceScaleOffset); } } } } }
void AARCharacter::MoveRight(float Value) { if ( (Controller != NULL) && (Value != 0.0f) ) { FRotator Rotation; FVector Location; //not used, just need for below. Controller->GetPlayerViewPoint(Location, Rotation); Rotation.Normalize(); FRotator YawRotation(0, Rotation.Yaw, 0); const FVector Direction = FRotationMatrix(YawRotation).GetScaledAxis(EAxis::Y); // add movement in that direction AddMovementInput(Direction, Value); } }
void FSteamVRHMD::ResetOrientation(float Yaw) { FRotator ViewRotation; ViewRotation = FRotator(TrackingFrame.DeviceOrientation[vr::k_unTrackedDeviceIndex_Hmd]); ViewRotation.Pitch = 0; ViewRotation.Roll = 0; if (Yaw != 0.f) { // apply optional yaw offset ViewRotation.Yaw -= Yaw; ViewRotation.Normalize(); } BaseOrientation = ViewRotation.Quaternion(); }
void FOSVRHMD::ResetOrientation(float yaw) { FRotator ViewRotation; ViewRotation = FRotator(CurHmdOrientation); ViewRotation.Pitch = 0; ViewRotation.Roll = 0; ViewRotation.Yaw += BaseOrientation.Rotator().Yaw; if (yaw != 0.f) { // apply optional yaw offset ViewRotation.Yaw -= yaw; ViewRotation.Normalize(); } BaseOrientation = ViewRotation.Quaternion(); }
void FSimpleHMD::ApplyHmdRotation(APlayerController* PC, FRotator& ViewRotation) { ViewRotation.Normalize(); GetCurrentPose(CurHmdOrientation); LastHmdOrientation = CurHmdOrientation; const FRotator DeltaRot = ViewRotation - PC->GetControlRotation(); DeltaControlRotation = (DeltaControlRotation + DeltaRot).GetNormalized(); // Pitch from other sources is never good, because there is an absolute up and down that must be respected to avoid motion sickness. // Same with roll. DeltaControlRotation.Pitch = 0; DeltaControlRotation.Roll = 0; DeltaControlOrientation = DeltaControlRotation.Quaternion(); ViewRotation = FRotator(DeltaControlOrientation * CurHmdOrientation); }
void FOSVRHMD::ApplyHmdRotation(APlayerController* PC, FRotator& ViewRotation) { ViewRotation.Normalize(); FQuat lastHmdOrientation, hmdOrientation; FVector lastHmdPosition, hmdPosition; UpdateHeadPose(lastHmdOrientation, lastHmdPosition, hmdOrientation, hmdPosition); const FRotator DeltaRot = ViewRotation - PC->GetControlRotation(); DeltaControlRotation = (DeltaControlRotation + DeltaRot).GetNormalized(); // Pitch from other sources is never good, because there is an absolute up and down that must be respected to avoid motion sickness. // Same with roll. Retain yaw by default - mouse/controller based yaw movement still isn't pleasant, but // it's necessary for sitting VR experiences. DeltaControlRotation.Pitch = 0; DeltaControlRotation.Roll = 0; DeltaControlOrientation = DeltaControlRotation.Quaternion(); ViewRotation = FRotator(DeltaControlOrientation * hmdOrientation); }
void FSpriteSelectedShape::ApplyDelta(const FVector2D& Delta, const FRotator& Rotation, const FVector& Scale3D, FWidget::EWidgetMode MoveMode) { if (Geometry.Shapes.IsValidIndex(ShapeIndex)) { FSpriteGeometryShape& Shape = Geometry.Shapes[ShapeIndex]; const bool bDoRotation = (MoveMode == FWidget::WM_Rotate) || (MoveMode == FWidget::WM_TranslateRotateZ); const bool bDoTranslation = (MoveMode == FWidget::WM_Translate) || (MoveMode == FWidget::WM_TranslateRotateZ); const bool bDoScale = MoveMode == FWidget::WM_Scale; if (bDoTranslation) { const FVector WorldSpaceDelta = (PaperAxisX * Delta.X) + (PaperAxisY * Delta.Y); const FVector2D TextureSpaceDelta = EditorContext->SelectedItemConvertWorldSpaceDeltaToLocalSpace(WorldSpaceDelta); Shape.BoxPosition += TextureSpaceDelta; Geometry.GeometryType = ESpritePolygonMode::FullyCustom; } if (bDoScale) { const float ScaleDeltaX = FVector::DotProduct(Scale3D, PaperAxisX); const float ScaleDeltaY = FVector::DotProduct(Scale3D, PaperAxisY); const FVector2D OldSize = Shape.BoxSize; const FVector2D NewSize(OldSize.X + ScaleDeltaX, OldSize.Y + ScaleDeltaY); if (!FMath::IsNearlyZero(NewSize.X, KINDA_SMALL_NUMBER) && !FMath::IsNearlyZero(NewSize.Y, KINDA_SMALL_NUMBER)) { const FVector2D ScaleFactor(NewSize.X / OldSize.X, NewSize.Y / OldSize.Y); Shape.BoxSize = NewSize; // Now apply it to the verts for (FVector2D& Vertex : Shape.Vertices) { Vertex.X *= ScaleFactor.X; Vertex.Y *= ScaleFactor.Y; } Geometry.GeometryType = ESpritePolygonMode::FullyCustom; } } if (bDoRotation) { //@TODO: This stuff should probably be wrapped up into a utility method (also used for socket editing) const FRotator CurrentRot(Shape.Rotation, 0.0f, 0.0f); FRotator SocketWinding; FRotator SocketRotRemainder; CurrentRot.GetWindingAndRemainder(SocketWinding, SocketRotRemainder); const FQuat ActorQ = SocketRotRemainder.Quaternion(); const FQuat DeltaQ = Rotation.Quaternion(); const FQuat ResultQ = DeltaQ * ActorQ; const FRotator NewSocketRotRem = FRotator(ResultQ); FRotator DeltaRot = NewSocketRotRem - SocketRotRemainder; DeltaRot.Normalize(); const FRotator NewRotation(CurrentRot + DeltaRot); Shape.Rotation = NewRotation.Pitch; Geometry.GeometryType = ESpritePolygonMode::FullyCustom; } } }
FRotator UKismetMathLibrary::NormalizedDeltaRotator(FRotator A, FRotator B) { FRotator Delta = A - B; Delta.Normalize(); return Delta; }
void AFollowRoadCamera::Tick(float Delta) { if (!Running) { return; } if (!Roadmap) { return; } float SpeedCMs = Speed / 0.036; float CurrentTime = GetWorld()->GetTimeSeconds(); float TimePassed = CurrentTime - StartTime; float DistancePassed = TimePassed * SpeedCMs; if (Rev) { DistancePassed = MaxDist - DistancePassed; } float TValue = SplineInfoDistance.Eval(DistancePassed, 0); FVector Location = Roadmap->SplineInfo.Eval(TValue, FVector(0, 0, 0)); FVector Tangent = Roadmap->SplineInfo.EvalDerivative(TValue, FVector(0, 0, 0)).GetSafeNormal2D(); FVector Side = FVector::CrossProduct(FVector::UpVector, Tangent); Location += Tangent * Offset.X; Location += Side * Offset.Y; Location += FVector::UpVector * Offset.Z; FVector LookAtLocation; if (ReplayPlayer && ReplayPlayer->LookAtActor) { LookAtLocation = ReplayPlayer->LookAtActor->GetActorLocation(); } else { float DistanceLookAt = 0; if (Rev) { DistanceLookAt = DistancePassed - LookAtDistance; } else { DistanceLookAt = DistancePassed + LookAtDistance; } float TValueLookAt = SplineInfoDistance.Eval(DistanceLookAt, 0); LookAtLocation = Roadmap->SplineInfo.Eval(TValueLookAt, FVector(0, 0, 0)); FVector LookAtTangent = Roadmap->SplineInfo.EvalDerivative(TValueLookAt, FVector(0, 0, 0)).GetSafeNormal2D(); FVector LookAtSide = FVector::CrossProduct(FVector::UpVector, LookAtTangent); LookAtLocation += LookAtTangent * LookAtOffset.X; LookAtLocation += LookAtSide * LookAtOffset.Y; LookAtLocation += FVector::UpVector * LookAtOffset.Z; } FRotator NewRotation = (LookAtLocation - Location).Rotation(); NewRotation.Pitch += DegreesAboveFollow; if (FirstTick) { SetActorLocation(Location); SetActorRotation(NewRotation); FirstTick = false; return; } FVector LastLocation = GetActorLocation(); FRotator LastRotation = GetActorRotation(); // Note: This will not work if LastRotation and NewRotation are too far from // each other (more than 20 degrees), however, in that case, nothing will // work... GetNiceRotatorValue(NewRotation, LastRotation); NewRotation = NewRotation * (1-FollowSmooth) + LastRotation * FollowSmooth; NewRotation.Normalize(); SetActorLocation(Location * 0.1 + LastLocation * 0.9); SetActorRotation(NewRotation); }
// Read motion data from Axis Neuron bool UPerceptionNeuronBPLibrary::NeuronRead(APerceptionNeuronController *Controller, USkeletalMeshComponent *Mesh, FVector& Translation, FRotator& Rotation, FVector AdditionalTranslation, FRotator AdditionalRotation, EPerceptionNeuronBonesEnum BVHBone, FName CustomBoneName, bool InverseForward) { if (Controller == nullptr) { if (GEngine) { GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Controller is invalid."))); } Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0; Translation.X = Translation.Y = Translation.Z = 0; return false; } else if ((Controller->bConnected == false) && (Controller->bPlay == false)) { Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0; Translation.X = Translation.Y = Translation.Z = 0; return false; } int32 BVHBoneIndex = (int32)BVHBone; if (BVHBoneIndex >= Controller->Skeleton.BoneNr) { if (GEngine) { GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Boneindex %d exceeds maximum available bones %d."), BVHBoneIndex, Controller->Skeleton.BoneNr)); } Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0; Translation.X = Translation.Y = Translation.Z = 0; return false; } int32 FloatsPerBone = 6; // 3 for x,y,z translation and 3 for x,y,z rotation if (Controller->bDisplacement == false) { FloatsPerBone = 3; // If there is no displacement (translation) info we have only 3 floats for rotation left } if ((BVHBoneIndex * FloatsPerBone) > Controller->FloatCount) { Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0; Translation.X = Translation.Y = Translation.Z = 0; return false; } // Get the rotation of the reference pose bone FQuat RefQuat(FQuat::Identity); if (Mesh != nullptr && Mesh->SkeletalMesh != nullptr) { const FReferenceSkeleton& RefSkeleton(Mesh->SkeletalMesh->RefSkeleton); int32 RefBoneIndex = Mesh->GetBoneIndex(CustomBoneName); while (RefBoneIndex != INDEX_NONE) { RefQuat = RefSkeleton.GetRefBonePose()[RefBoneIndex].GetRotation() * RefQuat; RefBoneIndex = RefSkeleton.GetParentIndex(RefBoneIndex); } } // // Translation // if (Controller->bDisplacement == true) { // Read translation values and remove BVH reference position float X = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].XPos] - Controller->Skeleton.Bones[BVHBoneIndex].Offset[0]; float Y = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].YPos] - Controller->Skeleton.Bones[BVHBoneIndex].Offset[1]; float Z = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].ZPos] - Controller->Skeleton.Bones[BVHBoneIndex].Offset[2]; // Map BVH translation to UE4 world coordinate system (Inverse if forward direction is -Y) if (InverseForward) { Translation = FVector(-X, -Z, Y); } else { Translation = FVector(X, Z, Y); } // Map UE4 world translation to bone space Translation = RefQuat.Inverse().RotateVector(Translation); } else { Translation.X = Translation.Y = Translation.Z = 0; } // Add additional translation Translation.X += AdditionalTranslation.X; Translation.Y += AdditionalTranslation.Y; Translation.Z += AdditionalTranslation.Z; // // Rotation // // Read rotation values and map to pitch, yaw, roll (y, z, x) float XR = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].XRot] * PI / 180.f; float YR = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].YRot] * PI / 180.f; float ZR = Controller->MotionLine[(BVHBoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BVHBoneIndex].ZRot] * PI / 180.f; // Calculate Rotation Matrix and map to Quaternion FQuat BVHQuat = CalculateQuat(XR, YR, ZR, Controller->Skeleton.Bones[BVHBoneIndex].RotOrder); // Map BVH rotation to UE4 world coordinate system (Inverse if forward direction is -Y) float Y = BVHQuat.Y; float Z = BVHQuat.Z; if (InverseForward) { BVHQuat.X *= -1.0; BVHQuat.Y = -Z; BVHQuat.Z = Y; } else { BVHQuat.Y = Z; BVHQuat.Z = Y; } // Map UE4 world rotation to bone space FQuat Quat(RefQuat.Inverse() * BVHQuat * RefQuat); // Add additional rotation FQuat AddRot(AdditionalRotation); Quat *= AddRot; // Convert to Rotator Rotation = Quat.Rotator(); Rotation.Normalize(); return true; }
// Read motion data from Axis Neuron // Deprecated bool UPerceptionNeuronBPLibrary::NeuronReadMotion(APerceptionNeuronController *Controller, FVector& Translation, FRotator& Rotation, FVector AdditionalTranslation, FRotator AdditionalRotation, int32 BoneIndex, ENeuronSkeletonEnum SkeletonType) { if (Controller == nullptr) { if (GEngine) { GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Controller is invalid."))); } Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0; Translation.X = Translation.Y = Translation.Z = 0; return false; } else if ((Controller->bConnected == false) && (Controller->bPlay == false)) { Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0; Translation.X = Translation.Y = Translation.Z = 0; return false; } else if (BoneIndex >= Controller->Skeleton.BoneNr) { if (GEngine) { GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Boneindex %d exceeds maximum available bones %d."), BoneIndex, Controller->Skeleton.BoneNr)); } Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0; Translation.X = Translation.Y = Translation.Z = 0; return false; } int32 FloatsPerBone = 6; // 3 for x,y,z translation and 3 for x,y,z rotation if (Controller->bDisplacement == false) { FloatsPerBone = 3; // If there is no displacement (translation) info we have only 3 floats for rotation left } if ((BoneIndex * FloatsPerBone) > Controller->FloatCount) { Rotation.Yaw = Rotation.Pitch = Rotation.Roll = 0; Translation.X = Translation.Y = Translation.Z = 0; return false; } // // Translation // if (Controller->bDisplacement == true) { // Read translation values and remove BVH reference position float X = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].XPos] - Controller->Skeleton.Bones[BoneIndex].Offset[0]; float Y = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].YPos] - Controller->Skeleton.Bones[BoneIndex].Offset[1]; float Z = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].ZPos] - Controller->Skeleton.Bones[BoneIndex].Offset[2]; // Map BVH right hand system to local bone coordinate system switch (SkeletonType) { case ENeuronSkeletonEnum::VE_Neuron: // Neuron BVH skeleton { if (BoneIndex == 0) { // Hips Translation = FVector(X, -Y, Z); } else if ((BoneIndex >= 1) && (BoneIndex <= 6)) { // Legs Translation = FVector(X, Y, -Z); } else if ((BoneIndex >= 7) && (BoneIndex <= 12)) { // Spine,... Translation = FVector(X, -Y, -Z); } else if ((BoneIndex >= 13) && (BoneIndex <= 35)) { // Right arm Translation = FVector(-Z, X, Y); } else if ((BoneIndex >= 36) && (BoneIndex <= 58)) { // Left arm Translation = FVector(Z, -X, Y); } break; } case ENeuronSkeletonEnum::VE_TPP_Hero: // Hero_TPP, Old blue Unreal default skeleton with T-Pose case ENeuronSkeletonEnum::VE_Mannequin: // Mannequin, New Unreal default skeleton with A-Pose { if (BoneIndex == 0) { // Hips Translation = FVector(Y, Z, -X); } // Ignore other bones break; } case ENeuronSkeletonEnum::VE_Map: // Map to configured bone map { // Map translation with configured Bonemap float Map[3] = { X, Y, Z }; Translation = FVector(Map[Controller->Bonemap[BoneIndex].XYZ[0]] * Controller->Bonemap[BoneIndex].Sign[0], Map[Controller->Bonemap[BoneIndex].XYZ[1]] * Controller->Bonemap[BoneIndex].Sign[1], Map[Controller->Bonemap[BoneIndex].XYZ[2]] * Controller->Bonemap[BoneIndex].Sign[2]); break; } case ENeuronSkeletonEnum::VE_UE4: // Map to UE4 world coordinate system { Translation = FVector(X, Z, Y); break; } case ENeuronSkeletonEnum::VE_None: // Map to nothing, use BVH translation as it is default: { Translation = FVector(X, Y, Z); break; } } } else { Translation.X = Translation.Y = Translation.Z = 0; } // Add additional translation Translation.X += AdditionalTranslation.X; Translation.Y += AdditionalTranslation.Y; Translation.Z += AdditionalTranslation.Z; // // Rotation // // Read rotation values and map to pitch, yaw, roll (y, z, x) float XR = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].XRot] * PI / 180.f; float YR = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].YRot] * PI / 180.f; float ZR = Controller->MotionLine[(BoneIndex * FloatsPerBone) + Controller->Skeleton.Bones[BoneIndex].ZRot] * PI / 180.f; // Calculate Rotation Matrix and map to Quaternion FQuat Quat = CalculateQuat(XR, YR, ZR, Controller->Skeleton.Bones[BoneIndex].RotOrder); // Map BVH coordinate system to each bone coordinate system dependend on skeleton type switch (SkeletonType) { case ENeuronSkeletonEnum::VE_Neuron: // Neuron BVH skeleton { if ((BoneIndex >= 1) && (BoneIndex <= 6)) { // Legs Quat.Z *= -1.f; } else if ((BoneIndex >= 13) && (BoneIndex <= 35)) { // Right Arm float X = Quat.X; float Y = Quat.Y; float Z = Quat.Z; Quat.X = -Z; Quat.Y = X; Quat.Z = Y; } else if ((BoneIndex >= 36) && (BoneIndex <= 58)) { // Left Arm float X = Quat.X; float Y = Quat.Y; float Z = Quat.Z; Quat.X = Z; Quat.Y = -X; Quat.Z = Y; } else { Quat.Y *= -1.f; } break; } case ENeuronSkeletonEnum::VE_TPP_Hero: // Hero_TPP, Old blue Unreal default skeleton with T-Pose case ENeuronSkeletonEnum::VE_Mannequin: // Mannequin, New Unreal default skeleton with A-Pose { if ((BoneIndex >= 1) && (BoneIndex <= 3)) { // Right Leg float X = Quat.X; float Y = Quat.Y; float Z = Quat.Z; Quat.X = -Y; Quat.Y = -Z; Quat.Z = -X; } else if (BoneIndex == 16) { // Right Hand Quat.Y *= -1.f; } else if ((BoneIndex >= 13) && (BoneIndex <= 19)) { // Right Arm and Thumb float Y = Quat.Y; float Z = Quat.Z; Quat.Y = -Z; Quat.Z = -Y; } else if ((BoneIndex >= 20) && (BoneIndex <= 35)) { // Right Finger Quat.Y *= -1.f; } else if (BoneIndex == 39) { // Left Hand Quat.Z *= -1.f; } else if ((BoneIndex >= 36) && (BoneIndex <= 42)) { // Left Arm and Thumb float Y = Quat.Y; float Z = Quat.Z; Quat.Y = Z; Quat.Z = Y; } else if ((BoneIndex >= 43) && (BoneIndex <= 58)) { // Left Finger Quat.Z *= -1.f; } else { // Left Leg, Hips, Spine, Neck, Head float X = Quat.X; float Y = Quat.Y; float Z = Quat.Z; Quat.X = Y; Quat.Y = Z; Quat.Z = -X; } break; } case ENeuronSkeletonEnum::VE_Map: // Map to configured bone map { // Map Quat.X/Y/Z with configured Bonemap float Map[3] = { Quat.X, Quat.Y, Quat.Z }; Quat.X = Map[Controller->Bonemap[BoneIndex].XYZ[0]] * Controller->Bonemap[BoneIndex].Sign[0]; Quat.Y = Map[Controller->Bonemap[BoneIndex].XYZ[1]] * Controller->Bonemap[BoneIndex].Sign[1]; Quat.Z = Map[Controller->Bonemap[BoneIndex].XYZ[2]] * Controller->Bonemap[BoneIndex].Sign[2]; break; } case ENeuronSkeletonEnum::VE_UE4: // Map to UE4 world coordinate system { float Y = Quat.Y; float Z = Quat.Z; Quat.Y = Z; Quat.Z = Y; break; } case ENeuronSkeletonEnum::VE_None: // Map to nothing, use BVH rotation as it is default: { // Nothing to do, Quaternion is already BVH break; } } // Convert to Rotator Rotation = Quat.Rotator(); // Add additional rotation Rotation.Yaw += AdditionalRotation.Yaw; Rotation.Pitch += AdditionalRotation.Pitch; Rotation.Roll += AdditionalRotation.Roll; Rotation.Normalize(); return true; }
bool FStaticMeshEditorViewportClient::InputWidgetDelta( FViewport* Viewport, EAxisList::Type CurrentAxis, FVector& Drag, FRotator& Rot, FVector& Scale ) { bool bHandled = false; if (bManipulating) { if (CurrentAxis != EAxisList::None) { UStaticMeshSocket* SelectedSocket = StaticMeshEditorPtr.Pin()->GetSelectedSocket(); if(SelectedSocket) { UProperty* ChangedProperty = NULL; const FWidget::EWidgetMode MoveMode = GetWidgetMode(); if(MoveMode == FWidget::WM_Rotate) { ChangedProperty = FindField<UProperty>( UStaticMeshSocket::StaticClass(), "RelativeRotation" ); SelectedSocket->PreEditChange(ChangedProperty); FRotator CurrentRot = SelectedSocket->RelativeRotation; FRotator SocketWinding, SocketRotRemainder; CurrentRot.GetWindingAndRemainder(SocketWinding, SocketRotRemainder); const FQuat ActorQ = SocketRotRemainder.Quaternion(); const FQuat DeltaQ = Rot.Quaternion(); const FQuat ResultQ = DeltaQ * ActorQ; const FRotator NewSocketRotRem = FRotator( ResultQ ); FRotator DeltaRot = NewSocketRotRem - SocketRotRemainder; DeltaRot.Normalize(); SelectedSocket->RelativeRotation += DeltaRot; SelectedSocket->RelativeRotation = SelectedSocket->RelativeRotation.Clamp(); } else if(MoveMode == FWidget::WM_Translate) { ChangedProperty = FindField<UProperty>( UStaticMeshSocket::StaticClass(), "RelativeLocation" ); SelectedSocket->PreEditChange(ChangedProperty); //FRotationMatrix SocketRotTM( SelectedSocket->RelativeRotation ); //FVector SocketMove = SocketRotTM.TransformVector( Drag ); SelectedSocket->RelativeLocation += Drag; } if ( ChangedProperty ) { FPropertyChangedEvent PropertyChangedEvent( ChangedProperty ); SelectedSocket->PostEditChangeProperty(PropertyChangedEvent); } StaticMeshEditorPtr.Pin()->GetStaticMesh()->MarkPackageDirty(); } else { const bool bSelectedPrim = StaticMeshEditorPtr.Pin()->HasSelectedPrims(); if (bSelectedPrim && CurrentAxis != EAxisList::None) { const FWidget::EWidgetMode MoveMode = GetWidgetMode(); if (MoveMode == FWidget::WM_Rotate) { StaticMeshEditorPtr.Pin()->RotateSelectedPrims(Rot); } else if (MoveMode == FWidget::WM_Scale) { StaticMeshEditorPtr.Pin()->ScaleSelectedPrims(Scale); } else if (MoveMode == FWidget::WM_Translate) { StaticMeshEditorPtr.Pin()->TranslateSelectedPrims(Drag); } StaticMeshEditorPtr.Pin()->GetStaticMesh()->MarkPackageDirty(); } } } Invalidate(); bHandled = true; } return bHandled; }
void AARCharacter::MoveForward(float Value) { if ((Controller != NULL) && (Value != 0.0f)) { // find out which way is forward FRotator Rotation = GetBaseAimRotation(); FVector Location; //not used, just need for below. //Controller->GetPlayerViewPoint(Location, Rotation); Rotation.Normalize(); FRotator YawRotation(0, Rotation.Yaw, 0); const FVector Direction = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X); AddMovementInput(Direction, Value); } }