void FStaticMeshEditorViewportClient::SetPreviewMesh(UStaticMesh* InStaticMesh, UStaticMeshComponent* InStaticMeshComponent)
{
	StaticMesh = InStaticMesh;
	StaticMeshComponent = InStaticMeshComponent;

	// If we have a thumbnail transform, we will favor that over the camera position as the user may have customized this for a nice view
	// If we have neither a custom thumbnail nor a valid camera position, then we'll just use the default thumbnail transform 
	const USceneThumbnailInfo* const AssetThumbnailInfo = Cast<USceneThumbnailInfo>(StaticMesh->ThumbnailInfo);
	const USceneThumbnailInfo* const DefaultThumbnailInfo = USceneThumbnailInfo::StaticClass()->GetDefaultObject<USceneThumbnailInfo>();

	// Prefer the asset thumbnail if available
	const USceneThumbnailInfo* const ThumbnailInfo = (AssetThumbnailInfo) ? AssetThumbnailInfo : DefaultThumbnailInfo;
	check(ThumbnailInfo);

	FRotator ThumbnailAngle;
	ThumbnailAngle.Pitch = ThumbnailInfo->OrbitPitch;
	ThumbnailAngle.Yaw = ThumbnailInfo->OrbitYaw;
	ThumbnailAngle.Roll = 0;
	const float ThumbnailDistance = ThumbnailInfo->OrbitZoom;

	const float CameraY = StaticMesh->GetBounds().SphereRadius / (75.0f * PI / 360.0f);
	SetCameraSetup(
		FVector::ZeroVector, 
		ThumbnailAngle,
		FVector(0.0f, CameraY + ThumbnailDistance - AutoViewportOrbitCameraTranslate, 0.0f), 
		StaticMesh->GetBounds().Origin, 
		-FVector(0, CameraY, 0), 
		FRotator(0,90.f,0)
		);

	if(!AssetThumbnailInfo && StaticMesh->EditorCameraPosition.bIsSet)
	{
		// The static mesh editor saves the camera position in terms of an orbit camera, so ensure 
		// that orbit mode is enabled before we set the new transform information
		const bool bWasOrbit = bUsingOrbitCamera;
		ToggleOrbitCamera(true);

		SetViewRotation(StaticMesh->EditorCameraPosition.CamOrbitRotation);
		SetViewLocation(StaticMesh->EditorCameraPosition.CamOrbitPoint + StaticMesh->EditorCameraPosition.CamOrbitZoom);
		SetLookAtLocation(StaticMesh->EditorCameraPosition.CamOrbitPoint);

		ToggleOrbitCamera(bWasOrbit);
	}
}
void FStaticMeshEditorViewportClient::PerspectiveCameraMoved()
{
	FEditorViewportClient::PerspectiveCameraMoved();

	// The static mesh editor saves the camera position in terms of an orbit camera, so ensure 
	// that orbit mode is enabled before we store the current transform information
	const bool bWasOrbit = bUsingOrbitCamera;
	ToggleOrbitCamera(true);

	const FVector OrbitPoint = ViewTransform.GetLookAt();
	const FVector OrbitZoom = GetViewLocation() - OrbitPoint;
	StaticMesh->EditorCameraPosition = FAssetEditorOrbitCameraPosition(
		OrbitPoint,
		OrbitZoom,
		GetViewRotation()
		);

	ToggleOrbitCamera(bWasOrbit);
}
void FMaterialEditorViewportClient::FocusViewportOnBounds(const FBoxSphereBounds Bounds, bool bInstant /*= false*/)
{
	const FVector Position = Bounds.Origin;
	float Radius = Bounds.SphereRadius;

	float AspectToUse = AspectRatio;
	FIntPoint ViewportSize = Viewport->GetSizeXY();
	if (!bUseControllingActorViewInfo && ViewportSize.X > 0 && ViewportSize.Y > 0)
	{
		AspectToUse = Viewport->GetDesiredAspectRatio();
	}

	const bool bEnable = false;
	ToggleOrbitCamera(bEnable);

	/**
	* We need to make sure we are fitting the sphere into the viewport completely, so if the height of the viewport is less
	* than the width of the viewport, we scale the radius by the aspect ratio in order to compensate for the fact that we have
	* less visible vertically than horizontally.
	*/
	if (AspectToUse > 1.0f)
	{
		Radius *= AspectToUse;
	}

	/**
	* Now that we have a adjusted radius, we are taking half of the viewport's FOV,
	* converting it to radians, and then figuring out the camera's distance from the center
	* of the bounding sphere using some simple trig.  Once we have the distance, we back up
	* along the camera's forward vector from the center of the sphere, and set our new view location.
	*/
	const float HalfFOVRadians = FMath::DegreesToRadians(ViewFOV / 2.0f);
	const float DistanceFromSphere = Radius / FMath::Sin(HalfFOVRadians);
	FViewportCameraTransform& ViewTransform = GetViewTransform();
	FVector CameraOffsetVector = ViewTransform.GetRotation().Vector() * -DistanceFromSphere;

	ViewTransform.SetLookAt(Position);
	ViewTransform.TransitionToLocation(Position + CameraOffsetVector, EditorViewportWidget, bInstant);

	// Tell the viewport to redraw itself.
	Invalidate();
}
void FSCSEditorViewportClient::ResetCamera()
{
	UBlueprint* Blueprint = BlueprintEditorPtr.Pin()->GetBlueprintObj();

	// For now, loosely base default camera positioning on thumbnail preview settings
	USceneThumbnailInfo* ThumbnailInfo = Cast<USceneThumbnailInfo>(Blueprint->ThumbnailInfo);
	if(ThumbnailInfo)
	{
		if(PreviewActorBounds.SphereRadius + ThumbnailInfo->OrbitZoom < 0)
		{
			ThumbnailInfo->OrbitZoom = -PreviewActorBounds.SphereRadius;
		}
	}
	else
	{
		ThumbnailInfo = USceneThumbnailInfo::StaticClass()->GetDefaultObject<USceneThumbnailInfo>();
	}

	ToggleOrbitCamera(true);
	{
		float TargetDistance = PreviewActorBounds.SphereRadius;
		if(TargetDistance <= 0.0f)
		{
			TargetDistance = AutoViewportOrbitCameraTranslate;
		}

		FRotator ThumbnailAngle(ThumbnailInfo->OrbitPitch, ThumbnailInfo->OrbitYaw, 0.0f);

		SetViewLocationForOrbiting(PreviewActorBounds.Origin);
		SetViewLocation( GetViewLocation() + FVector(0.0f, TargetDistance * 1.5f + ThumbnailInfo->OrbitZoom - AutoViewportOrbitCameraTranslate, 0.0f) );
		SetViewRotation( ThumbnailAngle );
	
	}

	Invalidate();
}