Ejemplo n.º 1
0
FWidget::EWidgetMode FSCSEditorViewportClient::GetWidgetMode() const
{
	// Default to not drawing the widget
	FWidget::EWidgetMode ReturnWidgetMode = FWidget::WM_None;

	AActor* PreviewActor = GetPreviewActor();
	if(!bIsSimulateEnabled && PreviewActor)
	{
		const TSharedPtr<FBlueprintEditor> BluePrintEditor = BlueprintEditorPtr.Pin();
		if ( BluePrintEditor.IsValid() )
		{
			TArray<FSCSEditorTreeNodePtrType> SelectedNodes = BluePrintEditor->GetSelectedSCSEditorTreeNodes();
			const TArray<FSCSEditorTreeNodePtrType>& RootNodes = BluePrintEditor->GetSCSEditor()->GetRootComponentNodes();

			// if the selected nodes array is empty, or only contains entries from the
			// root nodes array, or isn't visible in the preview actor, then don't display a transform widget
			for ( int32 CurrentNodeIndex=0; CurrentNodeIndex < SelectedNodes.Num(); CurrentNodeIndex++ )
			{
				FSCSEditorTreeNodePtrType CurrentNodePtr = SelectedNodes[CurrentNodeIndex];
				if (CurrentNodePtr.IsValid() && !RootNodes.Contains(CurrentNodePtr) && !CurrentNodePtr->IsRootComponent() && CurrentNodePtr->CanEditDefaults() && CurrentNodePtr->FindComponentInstanceInActor(PreviewActor))
				{
					// a non-NULL, non-root item is selected, draw the widget
					ReturnWidgetMode = WidgetMode;
					break;
				}
			}
		}
	}

	return ReturnWidgetMode;
}
void FSCSEditorViewportClient::DestroyPreview()
{
	AActor* PreviewActor = GetPreviewActor();
	if(PreviewActor != NULL)
	{
		check(PreviewScene);
		check(PreviewScene->GetWorld());
		PreviewScene->GetWorld()->EditorDestroyActor(PreviewActor, false);
	}

	if(PreviewBlueprint != NULL)
	{
		if(PreviewBlueprint->SimpleConstructionScript != NULL
			&& PreviewActor == PreviewBlueprint->SimpleConstructionScript->GetComponentEditorActorInstance())
		{
			// Ensure that all editable component references are cleared
			PreviewBlueprint->SimpleConstructionScript->ClearEditorComponentReferences();

			// Clear the reference to the preview actor instance
			PreviewBlueprint->SimpleConstructionScript->SetComponentEditorActorInstance(NULL);
		}

		PreviewBlueprint = NULL;
	}
}
Ejemplo n.º 3
0
FVector FSCSEditorViewportClient::GetWidgetLocation() const
{
	FVector Location = FVector::ZeroVector;

	AActor* PreviewActor = GetPreviewActor();
	if(PreviewActor)
	{
		TArray<FSCSEditorTreeNodePtrType> SelectedNodes = BlueprintEditorPtr.Pin()->GetSelectedSCSEditorTreeNodes();
		if(SelectedNodes.Num() > 0)
		{
			// Use the last selected item for the widget location
			USceneComponent* SceneComp = Cast<USceneComponent>(SelectedNodes.Last().Get()->FindComponentInstanceInActor(PreviewActor));
			if( SceneComp )
			{
				TSharedPtr<ISCSEditorCustomization> Customization = BlueprintEditorPtr.Pin()->CustomizeSCSEditor(SceneComp);
				FVector CustomLocation;
				if(Customization.IsValid() && Customization->HandleGetWidgetLocation(SceneComp, CustomLocation))
				{
					Location = CustomLocation;
				}
				else
				{
					Location = SceneComp->GetComponentLocation();
				}
			}
		}
	}

	return Location;
}
Ejemplo n.º 4
0
void FSCSEditorViewportClient::Draw(const FSceneView* View, FPrimitiveDrawInterface* PDI)
{
	FEditorViewportClient::Draw(View, PDI);

	bool bHitTesting = PDI->IsHitTesting();
	AActor* PreviewActor = GetPreviewActor();
	if(PreviewActor)
	{
		if(GUnrealEd != NULL)
		{
			TArray<FSCSEditorTreeNodePtrType> SelectedNodes = BlueprintEditorPtr.Pin()->GetSelectedSCSEditorTreeNodes();
			for (int32 SelectionIndex = 0; SelectionIndex < SelectedNodes.Num(); ++SelectionIndex)
			{
				FSCSEditorTreeNodePtrType SelectedNode = SelectedNodes[SelectionIndex];

				UActorComponent* Comp = SelectedNode->FindComponentInstanceInActor(PreviewActor);
				if(Comp != NULL && Comp->IsRegistered())
				{
					// Try and find a visualizer
					TSharedPtr<FComponentVisualizer> Visualizer = GUnrealEd->FindComponentVisualizer(Comp->GetClass());
					if (Visualizer.IsValid())
					{
						Visualizer->DrawVisualization(Comp, View, PDI);
					}
				}
			}
		}
	}
}
void FSCSEditorViewportClient::DrawCanvas( FViewport& InViewport, FSceneView& View, FCanvas& Canvas )
{
	AActor* PreviewActor = GetPreviewActor();
	if(PreviewActor)
	{
		TGuardValue<bool> AutoRestore(GAllowActorScriptExecutionInEditor, true);

		const int32 HalfX = 0.5f * Viewport->GetSizeXY().X;
		const int32 HalfY = 0.5f * Viewport->GetSizeXY().Y;

		auto SelectedNodes = BlueprintEditorPtr.Pin()->GetSelectedSCSEditorTreeNodes();
		if(bIsManipulating && SelectedNodes.Num() > 0)
		{
			USceneComponent* SceneComp = Cast<USceneComponent>(SelectedNodes[0]->FindComponentInstanceInActor(PreviewActor, true));
			if(SceneComp)
			{
				const FVector WidgetLocation = GetWidgetLocation();
				const FPlane Proj = View.Project(WidgetLocation);
				if(Proj.W > 0.0f)
				{
					const int32 XPos = HalfX + (HalfX * Proj.X);
					const int32 YPos = HalfY + (HalfY * (Proj.Y * -1));
					DrawAngles(&Canvas, XPos, YPos, GetCurrentWidgetAxis(), GetWidgetMode(), GetWidgetCoordSystem().Rotator(), WidgetLocation);
				}
			}
		}
	}
}
Ejemplo n.º 6
0
void FSCSEditorViewportClient::Tick(float DeltaSeconds)
{
	FEditorViewportClient::Tick(DeltaSeconds);

	// Register the selection override delegate for the preview actor's components
	TSharedPtr<SSCSEditor> SCSEditor = BlueprintEditorPtr.Pin()->GetSCSEditor();
	AActor* PreviewActor = GetPreviewActor();
	if (PreviewActor != nullptr)
	{
		TInlineComponentArray<UPrimitiveComponent*> PrimitiveComponents;
		PreviewActor->GetComponents(PrimitiveComponents);

		for (int32 CompIdx = 0; CompIdx < PrimitiveComponents.Num(); ++CompIdx)
		{
			UPrimitiveComponent* PrimComponent = PrimitiveComponents[CompIdx];
			if (!PrimComponent->SelectionOverrideDelegate.IsBound())
			{
				SCSEditor->SetSelectionOverride(PrimComponent);
			}
		}
	}
	else
	{
		InvalidatePreview(false);
	}

	if ( PreviewActor != LastPreviewActor.Get() || PreviewActor == nullptr || IsRealtime() )
	{
		LastPreviewActor = PreviewActor;

		Invalidate();
		RefreshPreviewBounds();
	}

	// Tick the preview scene world.
	if (!GIntraFrameDebuggingGameThread)
	{
		// Ensure that the preview actor instance is up-to-date for component editing (e.g. after compiling the Blueprint, the actor may be reinstanced outside of this class)
		if(PreviewActor != BlueprintEditorPtr.Pin()->GetBlueprintObj()->SimpleConstructionScript->GetComponentEditorActorInstance())
		{
			BlueprintEditorPtr.Pin()->GetBlueprintObj()->SimpleConstructionScript->SetComponentEditorActorInstance(PreviewActor);
		}

		// Allow full tick only if preview simulation is enabled and we're not currently in an active SIE or PIE session
		if(bIsSimulateEnabled && GEditor->PlayWorld == NULL && !GEditor->bIsSimulatingInEditor)
		{
			PreviewScene->GetWorld()->Tick(IsRealtime() ? LEVELTICK_All : LEVELTICK_TimeOnly, DeltaSeconds);
		}
		else
		{
			PreviewScene->GetWorld()->Tick(IsRealtime() ? LEVELTICK_ViewportsOnly : LEVELTICK_TimeOnly, DeltaSeconds);
		}
	}
}
Ejemplo n.º 7
0
void FSCSEditorViewportClient::BeginTransaction(const FText& Description)
{
	//UE_LOG(LogSCSEditorViewport, Log, TEXT("FSCSEditorViewportClient::BeginTransaction() pre: %s %08x"), SessionName, *((uint32*)&ScopedTransaction));

	if(!ScopedTransaction)
	{
		ScopedTransaction = new FScopedTransaction(Description);

		auto BlueprintEditor = BlueprintEditorPtr.Pin();
		if (BlueprintEditor.IsValid())
		{
			UBlueprint* PreviewBlueprint = BlueprintEditor->GetBlueprintObj();
			if (PreviewBlueprint != nullptr)
			{
				FBlueprintEditorUtils::MarkBlueprintAsModified(PreviewBlueprint);
			}

			TArray<FSCSEditorTreeNodePtrType> SelectedNodes = BlueprintEditor->GetSelectedSCSEditorTreeNodes();
			for(auto SelectedSCSNodeIter(SelectedNodes.CreateIterator()); SelectedSCSNodeIter; ++SelectedSCSNodeIter)
			{
				FSCSEditorTreeNodePtrType Node = *SelectedSCSNodeIter;
				if(Node.IsValid())
				{
					if(USCS_Node* SCS_Node = Node->GetSCSNode())
					{
						SCS_Node->Modify();
					}

					// Modify both the component template and the instance in the preview actor (provided there is one)
					UActorComponent* ComponentTemplate = Node->GetEditableComponentTemplate(PreviewBlueprint);
					if (ComponentTemplate != nullptr)
					{
						ComponentTemplate->SetFlags(RF_Transactional);
						ComponentTemplate->Modify();
					}

					AActor* PreviewActor = GetPreviewActor();
					if (PreviewActor)
					{
						UActorComponent* ComponentPreviewInstance = Node->FindComponentInstanceInActor(PreviewActor);
						if (ComponentPreviewInstance != nullptr)
						{
							ComponentPreviewInstance->SetFlags(RF_Transactional);
							ComponentPreviewInstance->Modify();
						}
					}
				}
			}
		}
	}

	//UE_LOG(LogSCSEditorViewport, Log, TEXT("FSCSEditorViewportClient::BeginTransaction() post: %s %08x"), SessionName, *((uint32*)&ScopedTransaction));
}
Ejemplo n.º 8
0
void FSCSEditorViewportClient::ProcessClick(class FSceneView& View, class HHitProxy* HitProxy, FKey Key, EInputEvent Event, uint32 HitX, uint32 HitY)
{
	if(HitProxy)
	{
		if(HitProxy->IsA(HInstancedStaticMeshInstance::StaticGetType()))
		{
			HInstancedStaticMeshInstance* InstancedStaticMeshInstanceProxy = ( ( HInstancedStaticMeshInstance* )HitProxy );

			TSharedPtr<ISCSEditorCustomization> Customization = BlueprintEditorPtr.Pin()->CustomizeSCSEditor(InstancedStaticMeshInstanceProxy->Component);
			if(Customization.IsValid() && Customization->HandleViewportClick(AsShared(), View, HitProxy, Key, Event, HitX, HitY))
			{
				Invalidate();
			}
		}
		else if(HitProxy->IsA(HActor::StaticGetType()))
		{
			HActor* ActorProxy = (HActor*)HitProxy;
			AActor* PreviewActor = GetPreviewActor();
			if(ActorProxy && ActorProxy->Actor && ActorProxy->Actor == PreviewActor && ActorProxy->PrimComponent != NULL)
			{
				TInlineComponentArray<USceneComponent*> SceneComponents;
				ActorProxy->Actor->GetComponents(SceneComponents);
	
				for(auto CompIt = SceneComponents.CreateConstIterator(); CompIt; ++CompIt)
				{
					USceneComponent* CompInstance = *CompIt;
					TSharedPtr<ISCSEditorCustomization> Customization = BlueprintEditorPtr.Pin()->CustomizeSCSEditor(CompInstance);
					if (Customization.IsValid() && Customization->HandleViewportClick(AsShared(), View, HitProxy, Key, Event, HitX, HitY))
					{
						break;
					}

					if (CompInstance == ActorProxy->PrimComponent)
					{
						const bool bIsCtrlKeyDown = Viewport->KeyState(EKeys::LeftControl) || Viewport->KeyState(EKeys::RightControl);
						if (BlueprintEditorPtr.IsValid())
						{
							// Note: This will find and select any node associated with the component instance that's attached to the proxy (including visualizers)
							BlueprintEditorPtr.Pin()->FindAndSelectSCSEditorTreeNode(CompInstance, bIsCtrlKeyDown);
						}
						break;
					}
				}
			}

			Invalidate();
		}

		// Pass to component vis manager
		//GUnrealEd->ComponentVisManager.HandleProxyForComponentVis(HitProxy);
	}
}
Ejemplo n.º 9
0
void FSCSEditorViewportClient::DrawCanvas( FViewport& InViewport, FSceneView& View, FCanvas& Canvas )
{
	AActor* PreviewActor = GetPreviewActor();
	if(PreviewActor)
	{
		if (GUnrealEd != NULL)
		{
			TArray<FSCSEditorTreeNodePtrType> SelectedNodes = BlueprintEditorPtr.Pin()->GetSelectedSCSEditorTreeNodes();
			for (int32 SelectionIndex = 0; SelectionIndex < SelectedNodes.Num(); ++SelectionIndex)
			{
				FSCSEditorTreeNodePtrType SelectedNode = SelectedNodes[SelectionIndex];

				UActorComponent* Comp = Cast<USceneComponent>(SelectedNode->FindComponentInstanceInActor(PreviewActor));
				if (Comp != NULL && Comp->IsRegistered())
				{
					// Try and find a visualizer
					TSharedPtr<FComponentVisualizer> Visualizer = GUnrealEd->FindComponentVisualizer(Comp->GetClass());
					if (Visualizer.IsValid())
					{
						Visualizer->DrawVisualizationHUD(Comp, &InViewport, &View, &Canvas);
					}
				}
			}
		}

		TGuardValue<bool> AutoRestore(GAllowActorScriptExecutionInEditor, true);

		const int32 HalfX = 0.5f * Viewport->GetSizeXY().X;
		const int32 HalfY = 0.5f * Viewport->GetSizeXY().Y;

		auto SelectedNodes = BlueprintEditorPtr.Pin()->GetSelectedSCSEditorTreeNodes();
		if(bIsManipulating && SelectedNodes.Num() > 0)
		{
			USceneComponent* SceneComp = Cast<USceneComponent>(SelectedNodes[0]->FindComponentInstanceInActor(PreviewActor));
			if(SceneComp)
			{
				const FVector WidgetLocation = GetWidgetLocation();
				const FPlane Proj = View.Project(WidgetLocation);
				if(Proj.W > 0.0f)
				{
					const int32 XPos = HalfX + (HalfX * Proj.X);
					const int32 YPos = HalfY + (HalfY * (Proj.Y * -1));
					DrawAngles(&Canvas, XPos, YPos, GetCurrentWidgetAxis(), GetWidgetMode(), GetWidgetCoordSystem().Rotator(), WidgetLocation);
				}
			}
		}
	}
}
void FSCSEditorViewportClient::TrackingStopped() 
{
	if( bIsManipulating )
	{
		// Re-run construction scripts if we haven't done so yet (so that the components in the preview actor can update their transforms)
		AActor* PreviewActor = GetPreviewActor();
		if(PreviewActor != NULL && PreviewBlueprint != NULL && !PreviewBlueprint->bRunConstructionScriptOnDrag)
		{
			PreviewActor->RerunConstructionScripts();
		}

		// End transaction
		bIsManipulating = false;
		EndTransaction();

		// Restore component delta modification
		GEditor->DisableDeltaModification(false);
	}
}
Ejemplo n.º 11
0
void FSCSEditorViewportClient::FocusViewportToSelection()
{
	AActor* PreviewActor = GetPreviewActor();
	if(PreviewActor)
	{
		TArray<FSCSEditorTreeNodePtrType> SelectedNodes = BlueprintEditorPtr.Pin()->GetSelectedSCSEditorTreeNodes();
		if(SelectedNodes.Num() > 0)
		{
			// Use the last selected item for the widget location
			USceneComponent* SceneComp = Cast<USceneComponent>(SelectedNodes.Last()->FindComponentInstanceInActor(PreviewActor));
			if( SceneComp )
			{
				FocusViewportOnBox( SceneComp->Bounds.GetBox() );
			}
		}
		else
		{
			FocusViewportOnBox( PreviewActor->GetComponentsBoundingBox( true ) );
		}
	}
}
Ejemplo n.º 12
0
void FSCSEditorViewportClient::RefreshPreviewBounds()
{
	AActor* PreviewActor = GetPreviewActor();

	if(PreviewActor)
	{
		// Compute actor bounds as the sum of its visible parts
		TInlineComponentArray<UPrimitiveComponent*> PrimitiveComponents;
		PreviewActor->GetComponents(PrimitiveComponents);

		PreviewActorBounds = FBoxSphereBounds(ForceInitToZero);
		for(auto CompIt = PrimitiveComponents.CreateConstIterator(); CompIt; ++CompIt)
		{
			// Aggregate primitive components that either have collision enabled or are otherwise visible components in-game
			UPrimitiveComponent* PrimComp = *CompIt;
			if(PrimComp->IsRegistered() && (!PrimComp->bHiddenInGame || PrimComp->IsCollisionEnabled()) && PrimComp->Bounds.SphereRadius < HALF_WORLD_MAX)
			{
				PreviewActorBounds = PreviewActorBounds + PrimComp->Bounds;
			}
		}
	}
}
Ejemplo n.º 13
0
FMatrix FSCSEditorViewportClient::GetWidgetCoordSystem() const
{
	FMatrix Matrix = FMatrix::Identity;
	if( GetWidgetCoordSystemSpace() == COORD_Local )
	{
		AActor* PreviewActor = GetPreviewActor();
		auto BlueprintEditor = BlueprintEditorPtr.Pin();
		if (PreviewActor && BlueprintEditor.IsValid())
		{
			TArray<FSCSEditorTreeNodePtrType> SelectedNodes = BlueprintEditor->GetSelectedSCSEditorTreeNodes();
			if(SelectedNodes.Num() > 0)
			{
				const auto SelectedNode = SelectedNodes.Last();
				USceneComponent* SceneComp = SelectedNode.IsValid() ? Cast<USceneComponent>(SelectedNode->FindComponentInstanceInActor(PreviewActor)) : NULL;
				if( SceneComp )
				{
					TSharedPtr<ISCSEditorCustomization> Customization = BlueprintEditor->CustomizeSCSEditor(SceneComp);
					FMatrix CustomTransform;
					if(Customization.IsValid() && Customization->HandleGetWidgetTransform(SceneComp, CustomTransform))
					{
						Matrix = CustomTransform;
					}					
					else
					{
						Matrix = FRotationMatrix( SceneComp->GetComponentRotation() );
					}
				}
			}
		}
	}

	if(!Matrix.Equals(FMatrix::Identity))
	{
		Matrix.RemoveScaling();
	}

	return Matrix;
}
void FSCSEditorViewportClient::ToggleIsSimulateEnabled() 
{
	// Must destroy existing actors before we toggle the world state
	DestroyPreview();

	bIsSimulateEnabled = !bIsSimulateEnabled;
	PreviewScene->GetWorld()->bBegunPlay = bIsSimulateEnabled;
	PreviewScene->GetWorld()->bShouldSimulatePhysics = bIsSimulateEnabled;

	AActor* PreviewActor = GetPreviewActor();
	TSharedRef<SWidget> SCSEditor = BlueprintEditorPtr.Pin()->GetSCSEditor();
	TSharedRef<SWidget> Inspector = BlueprintEditorPtr.Pin()->GetInspector();

	// When simulate is enabled, we don't want to allow the user to modify the components
	UpdatePreviewActorForBlueprint(PreviewBlueprint, true);
	SCSEditor->SetEnabled(!bIsSimulateEnabled);
	Inspector->SetEnabled(!bIsSimulateEnabled);

	if(!IsRealtime())
	{
		ToggleRealtimePreview();
	}
}
bool FSCSEditorViewportClient::IsPreviewSceneValid() const
{
	return GetPreviewActor() != NULL;
}
Ejemplo n.º 16
0
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();
		auto BlueprintEditor = BlueprintEditorPtr.Pin();
		if (PreviewActor && BlueprintEditor.IsValid())
		{
			TArray<FSCSEditorTreeNodePtrType> SelectedNodes = BlueprintEditor->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->IsRootComponent() && !SelectedNodePtr->IsInherited()
						&& !IsMovableParentNodeSelected(SelectedNodePtr, SelectedNodes);

					if(bCanEdit)
					{
						USceneComponent* SceneComp = Cast<USceneComponent>(SelectedNodePtr->FindComponentInstanceInActor(PreviewActor));
						USceneComponent* SelectedTemplate = Cast<USceneComponent>(SelectedNodePtr->GetEditableComponentTemplate(BlueprintEditor->GetBlueprintObj()));
						if(SceneComp != NULL && SelectedTemplate != NULL)
						{
							// Cache the current default values for propagation
							FVector OldRelativeLocation = SelectedTemplate->RelativeLocation;
							FRotator OldRelativeRotation = SelectedTemplate->RelativeRotation;
							FVector OldRelativeScale3D = SelectedTemplate->RelativeScale3D;

							// Adjust the deltas as necessary
							FComponentEditorUtils::AdjustComponentDelta(SceneComp, Drag, Rot);

							TSharedPtr<ISCSEditorCustomization> Customization = BlueprintEditor->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);
							}

							UBlueprint* PreviewBlueprint = UBlueprint::GetBlueprintFromClass(PreviewActor->GetClass());
							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);
								}

								// Iterate over all the active archetype instances and propagate the change(s) to the matching component instance
								TArray<UObject*> ArchetypeInstances;
								if(SelectedTemplate->HasAnyFlags(RF_ArchetypeObject))
								{
									SelectedTemplate->GetArchetypeInstances(ArchetypeInstances);
									for(int32 InstanceIndex = 0; InstanceIndex < ArchetypeInstances.Num(); ++InstanceIndex)
									{
										SceneComp = Cast<USceneComponent>(ArchetypeInstances[InstanceIndex]);
										if(SceneComp && SceneComp->GetOwner() != PreviewActor)
										{
											FComponentEditorUtils::ApplyDefaultValueChange(SceneComp, SceneComp->RelativeLocation, OldRelativeLocation, SelectedTemplate->RelativeLocation);
											FComponentEditorUtils::ApplyDefaultValueChange(SceneComp, SceneComp->RelativeRotation, OldRelativeRotation, SelectedTemplate->RelativeRotation);
											FComponentEditorUtils::ApplyDefaultValueChange(SceneComp, SceneComp->RelativeScale3D,  OldRelativeScale3D,  SelectedTemplate->RelativeScale3D);
										}
									}
								}
								else if(UObject* Outer = SelectedTemplate->GetOuter())
								{
									Outer->GetArchetypeInstances(ArchetypeInstances);
									for(int32 InstanceIndex = 0; InstanceIndex < ArchetypeInstances.Num(); ++InstanceIndex)
									{
										if(ArchetypeInstances[InstanceIndex] != PreviewActor)
										{
											SceneComp = static_cast<USceneComponent*>(FindObjectWithOuter(ArchetypeInstances[InstanceIndex], SelectedTemplate->GetClass(), SelectedTemplate->GetFName()));
											if(SceneComp)
											{
												FComponentEditorUtils::ApplyDefaultValueChange(SceneComp, SceneComp->RelativeLocation, OldRelativeLocation, SelectedTemplate->RelativeLocation);
												FComponentEditorUtils::ApplyDefaultValueChange(SceneComp, SceneComp->RelativeRotation, OldRelativeRotation, SelectedTemplate->RelativeRotation);
												FComponentEditorUtils::ApplyDefaultValueChange(SceneComp, SceneComp->RelativeScale3D,  OldRelativeScale3D,  SelectedTemplate->RelativeScale3D);
											}
										}
									}
								}
							}
						}
					}
				}
				GUnrealEd->RedrawLevelEditingViewports();
			}
		}

		Invalidate();
	}

	return bHandled;
}
void FSCSEditorViewportClient::UpdatePreviewActorForBlueprint(UBlueprint* InBlueprint, bool bInForceFullUpdate/* = false*/)
{
	AActor* PreviewActor = GetPreviewActor();

	// Signal that we're going to be constructing editor components
	if(InBlueprint != NULL && InBlueprint->SimpleConstructionScript != NULL)
	{
		InBlueprint->SimpleConstructionScript->BeginEditorComponentConstruction();
	}

	// If the Blueprint is changing
	if(InBlueprint != PreviewBlueprint || bInForceFullUpdate)
	{
		// Destroy the previous actor instance
		DestroyPreview();

		// Save the Blueprint we're creating a preview for
		PreviewBlueprint = InBlueprint;

		// Spawn a new preview actor based on the Blueprint's generated class if it's Actor-based
		if(PreviewBlueprint && PreviewBlueprint->GeneratedClass && PreviewBlueprint->GeneratedClass->IsChildOf(AActor::StaticClass()))
		{
			FVector SpawnLocation = FVector::ZeroVector;
			FRotator SpawnRotation = FRotator::ZeroRotator;

			// Spawn an Actor based on the Blueprint's generated class
			FActorSpawnParameters SpawnInfo;
			SpawnInfo.bNoCollisionFail = true;
			SpawnInfo.bNoFail = true;
			SpawnInfo.ObjectFlags = RF_Transient;

			// Temporarily remove the deprecated flag so we can respawn the Blueprint in the viewport
			bool bIsClassDeprecated = PreviewBlueprint->GeneratedClass->HasAnyClassFlags(CLASS_Deprecated);
			PreviewBlueprint->GeneratedClass->ClassFlags &= ~CLASS_Deprecated;

			PreviewActorPtr = PreviewActor = PreviewScene->GetWorld()->SpawnActor( PreviewBlueprint->GeneratedClass, &SpawnLocation, &SpawnRotation, SpawnInfo );

			// Reassign the deprecated flag if it was previously assigned
			if(bIsClassDeprecated)
			{
				PreviewBlueprint->GeneratedClass->ClassFlags |= CLASS_Deprecated;
			}

			check(PreviewActor);

			// Ensure that the actor is visible
			if(PreviewActor->bHidden)
			{
				PreviewActor->bHidden = false;
				PreviewActor->MarkComponentsRenderStateDirty();
				GetWorld()->SendAllEndOfFrameUpdates();
			}

			// Prevent any audio from playing as a result of spawning
			if(GEngine->AudioDevice)
			{
				GEngine->AudioDevice->Flush(GetWorld());
			}

			// Set the reference to the preview actor for component editing purposes
			if(PreviewBlueprint->SimpleConstructionScript != NULL)
			{
				PreviewBlueprint->SimpleConstructionScript->SetComponentEditorActorInstance(PreviewActor);
			}

			// Run the construction scripts again, otherwise the actor will appear as though it's had a script pass first, rather than the default properties as shown in the details panel
			PreviewActor->RerunConstructionScripts();
		}
	}
	else if(PreviewActor)
	{
		PreviewActor->RerunConstructionScripts();
	}

	// Signal that we're done constructing editor components
	if(InBlueprint != NULL && InBlueprint->SimpleConstructionScript != NULL)
	{
		InBlueprint->SimpleConstructionScript->EndEditorComponentConstruction();
	}

	Invalidate();
	RefreshPreviewBounds();
}
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;
}