Files
UnrealEngineUWP/Engine/Source/Runtime/InteractiveToolsFramework/Private/BaseGizmos/GizmoElementGroup.cpp
Christina TempelaarL 9ac82fb6dd Add IGizmoClickMultiTarget, IGizmoRenderTarget and IGizmoRenderMultiTarget interfaces to facilitate hitting parts within a gizmo element hierarchy. Add HitObject member to FInputRayHit struct to hold UObect-derived owners of hits.
#jira UETOOL-4781
#rb ryan.schmidt, brooke.hubert, jimmy.andrews
#preflight 6272b741e95a8b960ebfba9c

[CL 20050122 by Christina TempelaarL in ue5-main branch]
2022-05-04 17:25:53 -04:00

178 lines
4.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "BaseGizmos/GizmoElementGroup.h"
#include "BaseGizmos/GizmoRenderingUtil.h"
void UGizmoElementGroup::Render(IToolsContextRenderAPI* RenderAPI, const FRenderTraversalState& RenderState)
{
if (!IsVisible())
{
return;
}
const FSceneView* View = RenderAPI->GetSceneView();
bool bVisibleViewDependent = GetViewDependentVisibility(View, RenderState.LocalToWorldTransform, FVector::ZeroVector);
FRenderTraversalState RenderStateCopy = RenderState;
if (bVisibleViewDependent)
{
// Compute constant scale, if applicable
float Scale = RenderStateCopy.LocalToWorldTransform.GetScale3D().X;
if (bConstantScale)
{
const float ConstantScaleFactor = GizmoRenderingUtil::CalculateLocalPixelToWorldScale(RenderAPI->GetSceneView(), RenderStateCopy.LocalToWorldTransform.GetTranslation());
Scale *= ConstantScaleFactor;
}
RenderStateCopy.LocalToWorldTransform.SetScale3D(FVector(Scale, Scale, Scale));
// Compute view alignment, if applicable
FQuat AlignRot;
if (GetViewAlignRot(View, RenderStateCopy.LocalToWorldTransform, FVector::ZeroVector, AlignRot))
{
RenderStateCopy.LocalToWorldTransform = FTransform(AlignRot) * RenderState.LocalToWorldTransform;
}
UpdateRenderTraversalState(RenderStateCopy);
// Continue render even if not visible so all transforms will be cached
// for subsequent line tracing.
for (UGizmoElementBase* Element : Elements)
{
if (Element)
{
Element->Render(RenderAPI, RenderStateCopy);
}
}
}
CacheRenderState(RenderStateCopy.LocalToWorldTransform, bVisibleViewDependent);
}
FInputRayHit UGizmoElementGroup::LineTrace(const FVector Start, const FVector Direction)
{
FInputRayHit Hit;
if (IsHittable())
{
for (UGizmoElementBase* Element : Elements)
{
if (Element)
{
FInputRayHit NewHit = Element->LineTrace(Start, Direction);
if (!Hit.bHit || NewHit.HitDepth < Hit.HitDepth)
{
Hit = NewHit;
if (bHitOwner)
{
Hit.SetHitObject(this);
Hit.HitIdentifier = PartIdentifier;
}
}
}
}
}
return Hit;
}
FBoxSphereBounds UGizmoElementGroup::CalcBounds(const FTransform& LocalToWorld) const
{
/* @todo - accumulate box sphere bounds for all elements within the group
if (bEnabled)
{
for (UGizmoElementBase* Element : Elements)
{
if (Element)
{
CachedBoxSphereBounds = CachedBoxSphereBounds + Element->CalcBounds(LocalToWorld);
}
}
}
*/
return FBoxSphereBounds();
}
void UGizmoElementGroup::Add(UGizmoElementBase* InElement)
{
if (!Elements.Contains(InElement))
{
Elements.Add(InElement);
}
}
void UGizmoElementGroup::Remove(UGizmoElementBase* InElement)
{
if (InElement)
{
int32 Index;
if (Elements.Find(InElement, Index))
{
Elements.RemoveAtSwap(Index);
}
}
}
void UGizmoElementGroup::UpdatePartVisibleState(bool bVisible, uint32 InPartIdentifier)
{
Super::UpdatePartVisibleState(bVisible, InPartIdentifier);
for (UGizmoElementBase* Element : Elements)
{
if (Element)
{
Element->UpdatePartVisibleState(bVisible, InPartIdentifier);
}
}
}
void UGizmoElementGroup::UpdatePartHittableState(bool bHittable, uint32 InPartIdentifier)
{
Super::UpdatePartHittableState(bHittable, InPartIdentifier);
for (UGizmoElementBase* Element : Elements)
{
if (Element)
{
Element->UpdatePartHittableState(bHittable, InPartIdentifier);
}
}
}
void UGizmoElementGroup::UpdatePartInteractionState(EGizmoElementInteractionState InInteractionState, uint32 InPartIdentifier)
{
Super::UpdatePartInteractionState(InInteractionState, InPartIdentifier);
for (UGizmoElementBase* Element : Elements)
{
if (Element)
{
Element->UpdatePartInteractionState(InInteractionState, InPartIdentifier);
}
}
}
void UGizmoElementGroup::ResetCachedRenderState()
{
Super::ResetCachedRenderState();
for (UGizmoElementBase* Element : Elements)
{
if (Element)
{
Element->ResetCachedRenderState();
}
}
}
void UGizmoElementGroup::SetConstantScale(bool bInConstantScale)
{
bConstantScale = bInConstantScale;
}
bool UGizmoElementGroup::GetConstantScale() const
{
return bConstantScale;
}