Files
UnrealEngineUWP/Engine/Source/Runtime/InteractiveToolsFramework/Private/BaseGizmos/GizmoElementCone.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

140 lines
3.4 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "BaseGizmos/GizmoElementCone.h"
#include "BaseGizmos/GizmoRenderingUtil.h"
#include "BaseGizmos/GizmoMath.h"
#include "InputState.h"
#include "Materials/MaterialInterface.h"
#include "SceneManagement.h"
void UGizmoElementCone::Render(IToolsContextRenderAPI* RenderAPI, const FRenderTraversalState& RenderState)
{
if (!IsVisible())
{
return;
}
check(RenderAPI);
const FSceneView* View = RenderAPI->GetSceneView();
FTransform LocalToWorldTransform = RenderState.LocalToWorldTransform;
bool bVisibleViewDependent = GetViewDependentVisibility(View, LocalToWorldTransform, Origin);
if (bVisibleViewDependent)
{
const UMaterialInterface* UseMaterial = GetCurrentMaterial(RenderState);
if (UseMaterial)
{
FQuat AlignRot;
const bool bHasAlignRot = GetViewAlignRot(View, LocalToWorldTransform, Origin, AlignRot);
const FVector AdjustedDir = bHasAlignRot ? AlignRot.RotateVector(Direction) : Direction;
FQuat Rotation = FRotationMatrix::MakeFromX(AdjustedDir).ToQuat();
const FVector Scale(Height);
FTransform RenderLocalToWorldTransform = FTransform(Rotation, Origin, Scale) * LocalToWorldTransform;
const float ConeSide = FMath::Sqrt(Height * Height + Radius * Radius);
const float Angle = FMath::Acos(Height / ConeSide);
FPrimitiveDrawInterface* PDI = RenderAPI->GetPrimitiveDrawInterface();
DrawCone(PDI, RenderLocalToWorldTransform.ToMatrixWithScale(), Angle, Angle, NumSides, false, FColor::White, UseMaterial->GetRenderProxy(), SDPG_Foreground);
}
}
CacheRenderState(LocalToWorldTransform, bVisibleViewDependent);
}
FInputRayHit UGizmoElementCone::LineTrace(const FVector RayOrigin, const FVector RayDirection)
{
if (IsHittableInView())
{
bool bIntersects = false;
double RayParam = 0.0;
const double ConeSide = FMath::Sqrt(Height * Height + Radius * Radius);
const double CosAngle = Height / ConeSide;
const double ConeHeight = Height * CachedLocalToWorldTransform.GetScale3D().X;
const FVector ConeOrigin = CachedLocalToWorldTransform.TransformPosition(Origin);
const FVector ConeDirection = CachedLocalToWorldTransform.TransformVectorNoScale(Direction);
GizmoMath::RayConeIntersection(
ConeOrigin,
ConeDirection,
CosAngle,
ConeHeight,
RayOrigin, RayDirection,
bIntersects, RayParam);
if (bIntersects)
{
FInputRayHit RayHit(RayParam);
RayHit.SetHitObject(this);
RayHit.HitIdentifier = PartIdentifier;
return RayHit;
}
}
return FInputRayHit();
}
FBoxSphereBounds UGizmoElementCone::CalcBounds(const FTransform& LocalToWorld) const
{
// @todo - implement box-sphere bounds calculation
return FBoxSphereBounds();
}
void UGizmoElementCone::SetOrigin(const FVector& InOrigin)
{
Origin = InOrigin;
}
FVector UGizmoElementCone::GetOrigin() const
{
return Origin;
}
void UGizmoElementCone::SetDirection(const FVector& InDirection)
{
Direction = InDirection;
Direction.Normalize();
}
FVector UGizmoElementCone::GetDirection() const
{
return Direction;
}
void UGizmoElementCone::SetHeight(float InHeight)
{
Height = InHeight;
}
float UGizmoElementCone::GetHeight() const
{
return Height;
}
void UGizmoElementCone::SetRadius(float InRadius)
{
Radius = InRadius;
}
float UGizmoElementCone::GetRadius() const
{
return Radius;
}
void UGizmoElementCone::SetNumSides(int32 InNumSides)
{
NumSides = InNumSides;
}
int32 UGizmoElementCone::GetNumSides() const
{
return NumSides;
}