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 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 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; } } }
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; }