Files
UnrealEngineUWP/Engine/Plugins/Experimental/SampleToolsEditorMode/Source/Private/SampleTools/MeasureDistanceSampleTool.cpp

167 lines
4.2 KiB
C++
Raw Normal View History

// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#include "MeasureDistanceSampleTool.h"
#include "InteractiveToolManager.h"
#include "ToolBuilderUtil.h"
#include "BaseBehaviors/ClickDragBehavior.h"
// for raycast into World
#include "CollisionQueryParams.h"
#include "Engine/World.h"
#include "SceneManagement.h"
// localization namespace
#define LOCTEXT_NAMESPACE "UMeasureDistanceSampleTool"
/*
* ToolBuilder
*/
bool UMeasureDistanceSampleToolBuilder::CanBuildTool(const FToolBuilderState & SceneState) const
{
return true;
}
UInteractiveTool* UMeasureDistanceSampleToolBuilder::BuildTool(const FToolBuilderState & SceneState) const
{
UMeasureDistanceSampleTool* NewTool = NewObject<UMeasureDistanceSampleTool>(SceneState.ToolManager);
NewTool->SetWorld(SceneState.World);
return NewTool;
}
/*
* Tool
*/
UMeasureDistanceProperties::UMeasureDistanceProperties()
{
// initialize the points and distance to reasonable values
StartPoint = FVector(0,0,0);
EndPoint = FVector(0,0,100);
Distance = 100;
}
UMeasureDistanceSampleTool::UMeasureDistanceSampleTool()
{
}
void UMeasureDistanceSampleTool::SetWorld(UWorld* World)
{
check(World);
this->TargetWorld = World;
}
void UMeasureDistanceSampleTool::Setup()
{
UInteractiveTool::Setup();
// Add default mouse input behavior
UClickDragInputBehavior* MouseBehavior = NewObject<UClickDragInputBehavior>();
// We will use the shift key to indicate that we should move the second point.
// This call tells the Behavior to call our OnUpdateModifierState() function on mouse-down and mouse-move
MouseBehavior->Modifiers.RegisterModifier(MoveSecondPointModifierID, FInputDeviceState::IsShiftKeyDown);
MouseBehavior->Initialize(this);
AddInputBehavior(MouseBehavior);
// Create the property set and register it with the Tool
Properties = NewObject<UMeasureDistanceProperties>(this, "Measurement");
AddToolPropertySource(Properties);
bSecondPointModifierDown = false;
bMoveSecondPoint = false;
}
void UMeasureDistanceSampleTool::OnUpdateModifierState(int ModifierID, bool bIsOn)
{
// keep track of the "second point" modifier (shift key for mouse input)
if (ModifierID == MoveSecondPointModifierID)
{
bSecondPointModifierDown = bIsOn;
}
}
bool UMeasureDistanceSampleTool::CanBeginClickDragSequence(const FInputDeviceRay& PressPos)
{
// we only start drag if press-down is on top of something we can raycast
FVector Temp;
return FindRayHit(PressPos.WorldRay, Temp);
}
void UMeasureDistanceSampleTool::OnClickPress(const FInputDeviceRay& PressPos)
{
// determine whether we are moving first or second point for the drag sequence
bMoveSecondPoint = bSecondPointModifierDown;
UpdatePosition(PressPos.WorldRay);
}
void UMeasureDistanceSampleTool::OnClickDrag(const FInputDeviceRay& DragPos)
{
UpdatePosition(DragPos.WorldRay);
}
bool UMeasureDistanceSampleTool::FindRayHit(const FRay& WorldRay, FVector& HitPos)
{
// trace a ray into the World
FCollisionObjectQueryParams QueryParams(FCollisionObjectQueryParams::AllObjects);
FHitResult Result;
bool bHitWorld = TargetWorld->LineTraceSingleByObjectType(Result, WorldRay.Origin, WorldRay.PointAt(999999), QueryParams);
if (bHitWorld)
{
HitPos = Result.ImpactPoint;
return true;
}
return false;
}
void UMeasureDistanceSampleTool::UpdatePosition(const FRay& WorldRay)
{
if (FindRayHit(WorldRay, (bMoveSecondPoint) ? Properties->EndPoint : Properties->StartPoint))
{
UpdateDistance();
}
}
void UMeasureDistanceSampleTool::UpdateDistance()
{
Properties->Distance = FVector::Distance(Properties->StartPoint, Properties->EndPoint);
}
void UMeasureDistanceSampleTool::OnPropertyModified(UObject* PropertySet, UProperty* Property)
{
// if the user updated any of the property fields, update the distance
UpdateDistance();
}
void UMeasureDistanceSampleTool::Render(IToolsContextRenderAPI* RenderAPI)
{
FPrimitiveDrawInterface* PDI = RenderAPI->GetPrimitiveDrawInterface();
// draw a thin line that shows through objects
PDI->DrawLine(Properties->StartPoint, Properties->EndPoint,
FColor(240, 16, 16), SDPG_Foreground, 2.0f, 0.0f, true);
// draw a thicker line that is depth-tested
PDI->DrawLine(Properties->StartPoint, Properties->EndPoint,
FColor(240, 16, 16), SDPG_World, 4.0f, 0.0f, true);
}
#undef LOCTEXT_NAMESPACE