Files
UnrealEngineUWP/Engine/Plugins/Experimental/MeshModelingToolset/Source/ModelingComponents/Private/ToolSceneQueriesUtil.cpp
Chris Gagnon 8ab0638182 Copying //UE4/Dev-Editor to Dev-Main (//UE4/Dev-Main) for 4.24
#rb none

[CL 9325047 by Chris Gagnon in Main branch]
2019-10-01 20:41:42 -04:00

129 lines
4.5 KiB
C++

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "ToolSceneQueriesUtil.h"
#include "VectorUtil.h"
#include "Quaternion.h"
static double VISUAL_ANGLE_SNAP_THRESHOLD_DEG = 1.0;
double ToolSceneQueriesUtil::GetDefaultVisualAngleSnapThreshD()
{
return VISUAL_ANGLE_SNAP_THRESHOLD_DEG;
}
bool ToolSceneQueriesUtil::PointSnapQuery(const UInteractiveTool* Tool, const FVector3d& Point1, const FVector3d& Point2, double VisualAngleThreshold)
{
IToolsContextQueriesAPI* QueryAPI = Tool->GetToolManager()->GetContextQueriesAPI();
FViewCameraState CameraState;
QueryAPI->GetCurrentViewState(CameraState);
return PointSnapQuery(CameraState, Point1, Point2, VisualAngleThreshold);
}
bool ToolSceneQueriesUtil::PointSnapQuery(const FViewCameraState& CameraState, const FVector3d& Point1, const FVector3d& Point2, double VisualAngleThreshold)
{
double UseThreshold = (VisualAngleThreshold <= 0) ? GetDefaultVisualAngleSnapThreshD() : VisualAngleThreshold;
double VisualAngle = VectorUtil::OpeningAngleD(Point1, Point2, (FVector3d)CameraState.Position);
return FMathd::Abs(VisualAngle) < UseThreshold;
}
double ToolSceneQueriesUtil::CalculateViewVisualAngleD(const UInteractiveTool* Tool, const FVector3d& Point1, const FVector3d& Point2)
{
IToolsContextQueriesAPI* QueryAPI = Tool->GetToolManager()->GetContextQueriesAPI();
FViewCameraState CameraState;
QueryAPI->GetCurrentViewState(CameraState);
return CalculateViewVisualAngleD(CameraState, Point1, Point2);
}
double ToolSceneQueriesUtil::CalculateViewVisualAngleD(const FViewCameraState& CameraState, const FVector3d& Point1, const FVector3d& Point2)
{
double VisualAngle = VectorUtil::OpeningAngleD(Point1, Point2, (FVector3d)CameraState.Position);
return FMathd::Abs(VisualAngle);
}
double ToolSceneQueriesUtil::CalculateDimensionFromVisualAngleD(const UInteractiveTool* Tool, const FVector3d& Point, double TargetVisualAngleDeg)
{
IToolsContextQueriesAPI* QueryAPI = Tool->GetToolManager()->GetContextQueriesAPI();
FViewCameraState CameraState;
QueryAPI->GetCurrentViewState(CameraState);
return CalculateDimensionFromVisualAngleD(CameraState, Point, TargetVisualAngleDeg);
}
double ToolSceneQueriesUtil::CalculateDimensionFromVisualAngleD(const FViewCameraState& CameraState, const FVector3d& Point, double TargetVisualAngleDeg)
{
FVector3d EyePos = (FVector3d)CameraState.Position;
FVector3d PointVec = Point - EyePos;
FVector3d RotPointPos = EyePos + FQuaterniond(CameraState.Up(), TargetVisualAngleDeg, true)*PointVec;
double ActualAngleDeg = CalculateViewVisualAngleD(CameraState, Point, RotPointPos);
return Point.Distance(RotPointPos) * (TargetVisualAngleDeg/ActualAngleDeg);
}
bool ToolSceneQueriesUtil::IsPointVisible(const FViewCameraState& CameraState, const FVector3d& Point)
{
FVector3d PointDir = (Point - CameraState.Position);
//@todo should use view frustum here!
if (PointDir.Dot(CameraState.Forward()) < 0.25) // ballpark estimate
{
return false;
}
return true;
}
bool ToolSceneQueriesUtil::FindSceneSnapPoint(const UInteractiveTool* Tool, const FVector3d& Point, FVector3d& SnapPointOut,
bool bVertices, bool bEdges, double VisualAngleThreshold,
FSnapGeometry* SnapGeometry, FVector* DebugTriangleOut)
{
double UseThreshold = (VisualAngleThreshold <= 0) ? GetDefaultVisualAngleSnapThreshD() : VisualAngleThreshold;
IToolsContextQueriesAPI* QueryAPI = Tool->GetToolManager()->GetContextQueriesAPI();
FSceneSnapQueryRequest Request;
Request.RequestType = ESceneSnapQueryType::Position;
Request.TargetTypes = ESceneSnapQueryTargetType::None;
if (bVertices)
{
Request.TargetTypes |= ESceneSnapQueryTargetType::MeshVertex;
}
if (bEdges)
{
Request.TargetTypes |= ESceneSnapQueryTargetType::MeshEdge;
}
Request.Position = Point;
Request.VisualAngleThresholdDegrees = VISUAL_ANGLE_SNAP_THRESHOLD_DEG;
TArray<FSceneSnapQueryResult> Results;
if (QueryAPI->ExecuteSceneSnapQuery(Request, Results))
{
SnapPointOut = Results[0].Position;
if (SnapGeometry != nullptr)
{
int iSnap = Results[0].TriSnapIndex;
SnapGeometry->Points[0] = Results[0].TriVertices[iSnap];
SnapGeometry->PointCount = 1;
if (Results[0].TargetType == ESceneSnapQueryTargetType::MeshEdge)
{
SnapGeometry->Points[1] = Results[0].TriVertices[(iSnap+1)%3];
SnapGeometry->PointCount = 2;
}
}
if (DebugTriangleOut != nullptr)
{
DebugTriangleOut[0] = Results[0].TriVertices[0];
DebugTriangleOut[1] = Results[0].TriVertices[1];
DebugTriangleOut[2] = Results[0].TriVertices[2];
}
return true;
}
return false;
}