void UVREditorMode::PreTick( const float DeltaTime ) { if( !bIsFullyInitialized || !bIsActive || bWantsToExitMode ) { return; } //Setting the initial position and rotation based on the editor viewport when going into VR mode if( bFirstTick && bActuallyUsingVR ) { const FTransform RoomToWorld = GetRoomTransform(); const FTransform WorldToRoom = RoomToWorld.Inverse(); FTransform ViewportToWorld = FTransform( SavedEditorState.ViewRotation, SavedEditorState.ViewLocation ); FTransform ViewportToRoom = ( ViewportToWorld * WorldToRoom ); FTransform ViewportToRoomYaw = ViewportToRoom; ViewportToRoomYaw.SetRotation( FQuat( FRotator( 0.0f, ViewportToRoomYaw.GetRotation().Rotator().Yaw, 0.0f ) ) ); FTransform HeadToRoomYaw = GetRoomSpaceHeadTransform(); HeadToRoomYaw.SetRotation( FQuat( FRotator( 0.0f, HeadToRoomYaw.GetRotation().Rotator().Yaw, 0.0f ) ) ); FTransform RoomToWorldYaw = RoomToWorld; RoomToWorldYaw.SetRotation( FQuat( FRotator( 0.0f, RoomToWorldYaw.GetRotation().Rotator().Yaw, 0.0f ) ) ); FTransform ResultToWorld = ( HeadToRoomYaw.Inverse() * ViewportToRoomYaw ) * RoomToWorldYaw; SetRoomTransform( ResultToWorld ); } }
FQuat UAnimGraphNode_SkeletalControlBase::ConvertCSRotationToBoneSpace(const USkeletalMeshComponent* SkelComp, FRotator& InCSRotator, FA2CSPose& MeshBases, const FName& BoneName, const EBoneControlSpace Space) { FQuat OutQuat = FQuat::Identity; if (MeshBases.IsValid()) { int32 MeshBoneIndex = SkelComp->GetBoneIndex(BoneName); FVector RotAxis; float RotAngle; InCSRotator.Quaternion().ToAxisAndAngle(RotAxis, RotAngle); switch (Space) { // World Space, no change in preview window case BCS_WorldSpace: case BCS_ComponentSpace: // Component Space, no change. OutQuat = InCSRotator.Quaternion(); break; case BCS_ParentBoneSpace: { const int32 ParentIndex = MeshBases.GetParentBoneIndex(MeshBoneIndex); if (ParentIndex != INDEX_NONE) { FTransform ParentTM = MeshBases.GetComponentSpaceTransform(ParentIndex); ParentTM = ParentTM.Inverse(); //Calculate the new delta rotation FVector4 BoneSpaceAxis = ParentTM.TransformVector(RotAxis); FQuat DeltaQuat(BoneSpaceAxis, RotAngle); DeltaQuat.Normalize(); OutQuat = DeltaQuat; } } break; case BCS_BoneSpace: { FTransform BoneTM = MeshBases.GetComponentSpaceTransform(MeshBoneIndex); BoneTM = BoneTM.Inverse(); FVector4 BoneSpaceAxis = BoneTM.TransformVector(RotAxis); //Calculate the new delta rotation FQuat DeltaQuat(BoneSpaceAxis, RotAngle); DeltaQuat.Normalize(); OutQuat = DeltaQuat; } break; } } return OutQuat; }
void FComponentEditorUtils::AdjustComponentDelta(USceneComponent* Component, FVector& Drag, FRotator& Rotation) { USceneComponent* ParentSceneComp = Component->GetAttachParent(); if (ParentSceneComp) { const FTransform ParentToWorldSpace = ParentSceneComp->GetSocketTransform(Component->AttachSocketName); if (!Component->bAbsoluteLocation) { Drag = ParentToWorldSpace.Inverse().TransformVector(Drag); } if (!Component->bAbsoluteRotation) { Rotation = ( ParentToWorldSpace.Inverse().GetRotation() * Rotation.Quaternion() * ParentToWorldSpace.GetRotation() ).Rotator(); } } }
void FComponentEditorUtils::AdjustComponentDelta(USceneComponent* Component, FVector& Drag, FRotator& Rotation) { USceneComponent* ParentSceneComp = Component->GetAttachParent(); if (ParentSceneComp) { const FTransform ParentToWorldSpace = ParentSceneComp->GetSocketTransform(Component->AttachSocketName); if (!Component->bAbsoluteLocation) { //transform the drag vector in relative to the parent transform Drag = ParentToWorldSpace.InverseTransformVectorNoScale(Drag); //Now that we have a global drag we can apply the parent scale Drag = Drag * ParentToWorldSpace.Inverse().GetScale3D(); } if (!Component->bAbsoluteRotation) { Rotation = ( ParentToWorldSpace.Inverse().GetRotation() * Rotation.Quaternion() * ParentToWorldSpace.GetRotation() ).Rotator(); } } }
//============================================================================= void UGripMotionControllerComponent::FViewExtension::PreRenderViewFamily_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneViewFamily& InViewFamily) { if (!MotionControllerComponent) { return; } FScopeLock ScopeLock(&CritSect); if (MotionControllerComponent->bDisableLowLatencyUpdate || !CVarEnableMotionControllerLateUpdate->GetValueOnRenderThread()) { return; } // Poll state for the most recent controller transform FVector Position; FRotator Orientation; //bool bRenderTracked = bRenderTracked = MotionControllerComponent->PollControllerState(Position, Orientation); if (!MotionControllerComponent->PollControllerState(Position, Orientation)) { return; } if (LateUpdatePrimitives.Num()) { // Calculate the late update transform that will rebase all children proxies within the frame of reference FTransform OldLocalToWorldTransform = MotionControllerComponent->CalcNewComponentToWorld(MotionControllerComponent->GetRelativeTransform()); FTransform NewLocalToWorldTransform = MotionControllerComponent->CalcNewComponentToWorld(FTransform(Orientation, Position)); FMatrix LateUpdateTransform = (OldLocalToWorldTransform.Inverse() * NewLocalToWorldTransform).ToMatrixWithScale(); FPrimitiveSceneInfo* RetrievedSceneInfo; FPrimitiveSceneInfo* CachedSceneInfo; // Apply delta to the affected scene proxies for (auto PrimitiveInfo : LateUpdatePrimitives) { RetrievedSceneInfo = InViewFamily.Scene->GetPrimitiveSceneInfo(*PrimitiveInfo.IndexAddress); CachedSceneInfo = PrimitiveInfo.SceneInfo; // If the retrieved scene info is different than our cached scene info then the primitive was removed from the scene if (CachedSceneInfo == RetrievedSceneInfo && CachedSceneInfo->Proxy) { CachedSceneInfo->Proxy->ApplyLateUpdateTransform(LateUpdateTransform); } } LateUpdatePrimitives.Reset(); } }
void IHeadMountedDisplay::ApplyLateUpdate(FSceneInterface* Scene, const FTransform& OldRelativeTransform, const FTransform& NewRelativeTransform) { if (!LateUpdatePrimitives.Num()) { return; } const FTransform OldCameraTransform = OldRelativeTransform * LateUpdateParentToWorld; const FTransform NewCameraTransform = NewRelativeTransform * LateUpdateParentToWorld; const FMatrix LateUpdateTransform = (OldCameraTransform.Inverse() * NewCameraTransform).ToMatrixWithScale(); // Apply delta to the affected scene proxies for (auto PrimitiveInfo : LateUpdatePrimitives) { FPrimitiveSceneInfo* RetrievedSceneInfo = Scene->GetPrimitiveSceneInfo(*PrimitiveInfo.IndexAddress); FPrimitiveSceneInfo* CachedSceneInfo = PrimitiveInfo.SceneInfo; // If the retrieved scene info is different than our cached scene info then the primitive was removed from the scene if (CachedSceneInfo == RetrievedSceneInfo && CachedSceneInfo->Proxy) { CachedSceneInfo->Proxy->ApplyLateUpdateTransform(LateUpdateTransform); } } LateUpdatePrimitives.Reset(); }
void FPhATEdPreviewViewportClient::StartManipulating(EAxisList::Type Axis, const FViewportClick& Click, const FMatrix& WorldToCamera) { check(!SharedData->bManipulating); if (SharedData->EditingMode == FPhATSharedData::PEM_BodyEdit && SharedData->SelectedBodies.Num()) { GEditor->BeginTransaction( NSLOCTEXT("UnrealEd", "MoveElement", "Move Element") ); for(int32 i=0; i<SharedData->SelectedBodies.Num(); ++i) { SharedData->PhysicsAsset->SkeletalBodySetups[SharedData->SelectedBodies[i].Index]->Modify(); SharedData->SelectedBodies[i].ManipulateTM = FTransform::Identity; } SharedData->bManipulating = true; } else if( SharedData->GetSelectedConstraint()) { GEditor->BeginTransaction( NSLOCTEXT("UnrealEd", "MoveConstraint", "Move Constraint") ); for(int32 i=0; i<SharedData->SelectedConstraints.Num(); ++i) { SharedData->PhysicsAsset->ConstraintSetup[SharedData->SelectedConstraints[i].Index]->Modify(); SharedData->SelectedConstraints[i].ManipulateTM = FTransform::Identity; } const FTransform WParentFrame = SharedData->GetConstraintWorldTM(SharedData->GetSelectedConstraint(), EConstraintFrame::Frame2); const FTransform WChildFrame = SharedData->GetConstraintWorldTM(SharedData->GetSelectedConstraint(), EConstraintFrame::Frame1); StartManRelConTM = WChildFrame * WParentFrame.Inverse(); UPhysicsConstraintTemplate* Setup = SharedData->PhysicsAsset->ConstraintSetup[SharedData->GetSelectedConstraint()->Index]; StartManParentConTM = Setup->DefaultInstance.GetRefFrame(EConstraintFrame::Frame2); StartManChildConTM = Setup->DefaultInstance.GetRefFrame(EConstraintFrame::Frame1); SharedData->bManipulating = true; } }
bool UGripMotionControllerComponent::GripComponent( UPrimitiveComponent* ComponentToGrip, const FTransform &WorldOffset, bool bWorldOffsetIsRelative, FName OptionalSnapToSocketName, TEnumAsByte<EGripCollisionType> GripCollisionType, bool bAllowSetMobility, float GripStiffness, float GripDamping, bool bTurnOffLateUpdateWhenColliding ) { if (!bIsServer || !ComponentToGrip) { UE_LOG(LogTemp, Warning, TEXT("VRGripMotionController grab function was passed an invalid or already gripped component")); return false; } // Has to be movable to work if (ComponentToGrip->Mobility != EComponentMobility::Movable) { if (bAllowSetMobility) ComponentToGrip->SetMobility(EComponentMobility::Movable); else { UE_LOG(LogTemp, Warning, TEXT("VRGripMotionController tried to grip a component set to static mobility and bAllowSetMobility is false")); return false; // It is not movable, can't grip it } } ComponentToGrip->IgnoreActorWhenMoving(this->GetOwner(), true); // So that events caused by sweep and the like will trigger correctly ComponentToGrip->AddTickPrerequisiteComponent(this); FBPActorGripInformation newActorGrip; newActorGrip.GripCollisionType = GripCollisionType; newActorGrip.Component = ComponentToGrip; if(ComponentToGrip->GetOwner()) newActorGrip.bOriginalReplicatesMovement = ComponentToGrip->GetOwner()->bReplicateMovement; newActorGrip.Stiffness = GripStiffness; newActorGrip.Damping = GripDamping; newActorGrip.bTurnOffLateUpdateWhenColliding = bTurnOffLateUpdateWhenColliding; if (OptionalSnapToSocketName.IsValid() && ComponentToGrip->DoesSocketExist(OptionalSnapToSocketName)) { // I inverse it so that laying out the sockets makes sense FTransform sockTrans = ComponentToGrip->GetSocketTransform(OptionalSnapToSocketName, ERelativeTransformSpace::RTS_Component); newActorGrip.RelativeTransform = sockTrans.Inverse(); newActorGrip.RelativeTransform.SetScale3D(ComponentToGrip->GetComponentScale()); } else if (bWorldOffsetIsRelative) newActorGrip.RelativeTransform = WorldOffset; else newActorGrip.RelativeTransform = WorldOffset.GetRelativeTransform(this->GetComponentTransform()); NotifyGrip(newActorGrip); GrippedActors.Add(newActorGrip); return true; }
bool FSCSEditorViewportClient::InputWidgetDelta( FViewport* Viewport, EAxisList::Type CurrentAxis, FVector& Drag, FRotator& Rot, FVector& Scale ) { bool bHandled = false; if(bIsManipulating && CurrentAxis != EAxisList::None) { bHandled = true; AActor* PreviewActor = GetPreviewActor(); if(PreviewActor) { TArray<FSCSEditorTreeNodePtrType> SelectedNodes = BlueprintEditorPtr.Pin()->GetSelectedSCSEditorTreeNodes(); if(SelectedNodes.Num() > 0) { FVector ModifiedScale = Scale; if( GEditor->UsePercentageBasedScaling() ) { ModifiedScale = Scale * ((GEditor->GetScaleGridSize() / 100.0f) / GEditor->GetGridSize()); } TSet<USceneComponent*> UpdatedComponents; for(auto It(SelectedNodes.CreateIterator());It;++It) { FSCSEditorTreeNodePtrType SelectedNodePtr = *It; // Don't allow editing of a root node, inherited SCS node or child node that also has a movable (non-root) parent node selected const bool bCanEdit = !SelectedNodePtr->IsRoot() && !SelectedNodePtr->IsInherited() && !IsMovableParentNodeSelected(SelectedNodePtr, SelectedNodes); if(bCanEdit) { USceneComponent* SceneComp = Cast<USceneComponent>(SelectedNodePtr->FindComponentInstanceInActor(PreviewActor, true)); USceneComponent* SelectedTemplate = Cast<USceneComponent>(SelectedNodePtr->GetComponentTemplate()); if(SceneComp != NULL && SelectedTemplate != NULL) { // Cache the current default values for propagation FVector OldRelativeLocation = SelectedTemplate->RelativeLocation; FRotator OldRelativeRotation = SelectedTemplate->RelativeRotation; FVector OldRelativeScale3D = SelectedTemplate->RelativeScale3D; USceneComponent* ParentSceneComp = SceneComp->GetAttachParent(); if( ParentSceneComp ) { const FTransform ParentToWorldSpace = ParentSceneComp->GetSocketTransform(SceneComp->AttachSocketName); if(!SceneComp->bAbsoluteLocation) { Drag = ParentToWorldSpace.Inverse().TransformVector(Drag); } if(!SceneComp->bAbsoluteRotation) { Rot = (ParentToWorldSpace.Inverse().GetRotation() * Rot.Quaternion() * ParentToWorldSpace.GetRotation()).Rotator(); } } FComponentEditorUtils::FTransformData OldDefaultTransform(*SelectedTemplate); TSharedPtr<ISCSEditorCustomization> Customization = BlueprintEditorPtr.Pin()->CustomizeSCSEditor(SceneComp); if(Customization.IsValid() && Customization->HandleViewportDrag(SceneComp, SelectedTemplate, Drag, Rot, ModifiedScale, GetWidgetLocation())) { UpdatedComponents.Add(SceneComp); UpdatedComponents.Add(SelectedTemplate); } else { // Apply delta to the preview actor's scene component GEditor->ApplyDeltaToComponent( SceneComp, true, &Drag, &Rot, &ModifiedScale, SceneComp->RelativeLocation ); UpdatedComponents.Add(SceneComp); // Apply delta to the template component object GEditor->ApplyDeltaToComponent( SelectedTemplate, true, &Drag, &Rot, &ModifiedScale, SelectedTemplate->RelativeLocation ); UpdatedComponents.Add(SelectedTemplate); } FComponentEditorUtils::FTransformData NewDefaultTransform(*SelectedTemplate); if (SelectedNodePtr->IsNative()) { if (ensure(SelectedTemplate->HasAnyFlags(RF_DefaultSubObject))) { FComponentEditorUtils::PropagateTransformPropertyChange(SelectedTemplate, OldDefaultTransform, NewDefaultTransform, UpdatedComponents); } } if(PreviewBlueprint != NULL) { // Like PostEditMove(), but we only need to re-run construction scripts if(PreviewBlueprint && PreviewBlueprint->bRunConstructionScriptOnDrag) { PreviewActor->RerunConstructionScripts(); } SceneComp->PostEditComponentMove(true); // @TODO HACK passing 'finished' every frame... // If a constraint, copy back updated constraint frames to template UPhysicsConstraintComponent* ConstraintComp = Cast<UPhysicsConstraintComponent>(SceneComp); UPhysicsConstraintComponent* TemplateComp = Cast<UPhysicsConstraintComponent>(SelectedTemplate); if(ConstraintComp && TemplateComp) { TemplateComp->ConstraintInstance.CopyConstraintGeometryFrom(&ConstraintComp->ConstraintInstance); } // Get the Blueprint class default object AActor* CDO = NULL; if(PreviewBlueprint->GeneratedClass) { CDO = Cast<AActor>(PreviewBlueprint->GeneratedClass->ClassDefaultObject); } else if(PreviewBlueprint->ParentClass) { CDO = Cast<AActor>(PreviewBlueprint->ParentClass->ClassDefaultObject); } if(CDO != NULL) { // Iterate over all the active archetype instances and propagate the change(s) to the matching component instance TArray<UObject*> ArchetypeInstances; CDO->GetArchetypeInstances(ArchetypeInstances); for(int32 InstanceIndex = 0; InstanceIndex < ArchetypeInstances.Num(); ++InstanceIndex) { AActor* ArchetypeInstance = Cast<AActor>(ArchetypeInstances[InstanceIndex]); if(ArchetypeInstance != NULL) { const bool bIsProcessingPreviewActor = (ArchetypeInstance == PreviewActor); SceneComp = Cast<USceneComponent>(SelectedNodePtr->FindComponentInstanceInActor(ArchetypeInstance, bIsProcessingPreviewActor)); if(!bIsProcessingPreviewActor && SceneComp != nullptr && !UpdatedComponents.Contains(SceneComp)) { FComponentEditorUtils::PropagateTransformPropertyChange(SceneComp, SceneComp->RelativeLocation, OldRelativeLocation, SelectedTemplate->RelativeLocation, UpdatedComponents); FComponentEditorUtils::PropagateTransformPropertyChange(SceneComp, SceneComp->RelativeRotation, OldRelativeRotation, SelectedTemplate->RelativeRotation, UpdatedComponents); FComponentEditorUtils::PropagateTransformPropertyChange(SceneComp, SceneComp->RelativeScale3D, OldRelativeScale3D, SelectedTemplate->RelativeScale3D, UpdatedComponents); } } } } } } } } GUnrealEd->RedrawLevelEditingViewports(); } } Invalidate(); } return bHandled; }