From 3a423201584c23cad71267b927e44e84602edd8f Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Thu, 7 Apr 2022 15:52:28 +0100 Subject: [PATCH] Add support for cylinders and capsules in editor vis --- .../Private/StevesDebugRenderSceneProxy.cpp | 27 ++++++++++ .../Private/StevesEditorVisComponent.cpp | 46 +++++++++++++++++ .../Public/StevesDebugRenderSceneProxy.h | 27 ++++++++++ .../Public/StevesEditorVisComponent.h | 50 +++++++++++++++++++ 4 files changed, 150 insertions(+) diff --git a/Source/StevesUEHelpers/Private/StevesDebugRenderSceneProxy.cpp b/Source/StevesUEHelpers/Private/StevesDebugRenderSceneProxy.cpp index e50a319..9818092 100644 --- a/Source/StevesUEHelpers/Private/StevesDebugRenderSceneProxy.cpp +++ b/Source/StevesUEHelpers/Private/StevesDebugRenderSceneProxy.cpp @@ -33,6 +33,33 @@ void FStevesDebugRenderSceneProxy::GetDynamicMeshElements(const TArrayBoxes.Add(FStevesDebugRenderSceneProxy::FDebugBox( DBox, Box.Colour, CombinedXForm)); } + for (auto& Cylinder : Cylinders) + { + // Apply local rotation first then parent transform + const FTransform CombinedXForm = FTransform(Cylinder.Rotation, Cylinder.Location) * XForm; + const float HalfH = Cylinder.Height * 0.5f * CombinedXForm.GetScale3D().Z; + const float R = Cylinder.Radius * CombinedXForm.GetScale3D().Z; + const FVector Centre = CombinedXForm.TransformPosition(FVector::ZeroVector); + const FVector LocalX = CombinedXForm.TransformVectorNoScale(FVector::ForwardVector); + const FVector LocalY = CombinedXForm.TransformVectorNoScale(FVector::RightVector); + const FVector LocalZ = CombinedXForm.TransformVectorNoScale(FVector::UpVector); + Ret->CylindersImproved.Add(FStevesDebugRenderSceneProxy::FDebugCylinder( + Centre, LocalX, LocalY, LocalZ, R, HalfH, 16, Cylinder.Colour)); + } + for (auto& Capsule : Capsules) + { + // Apply local rotation first then parent transform + const FTransform CombinedXForm = FTransform(Capsule.Rotation, Capsule.Location) * XForm; + const float HalfH = Capsule.Height * 0.5f * CombinedXForm.GetScale3D().Z; + const float R = Capsule.Radius * CombinedXForm.GetScale3D().Z; + const FVector Position = CombinedXForm.TransformPosition(FVector::ZeroVector); + const FVector LocalX = CombinedXForm.TransformVectorNoScale(FVector::ForwardVector); + const FVector LocalY = CombinedXForm.TransformVectorNoScale(FVector::RightVector); + const FVector LocalZ = CombinedXForm.TransformVectorNoScale(FVector::UpVector); + Ret->CapsulesImproved.Add(FStevesDebugRenderSceneProxy::FCapsule( + Position, R, + LocalX, LocalY, LocalZ, + HalfH, Capsule.Colour)); + } return Ret; @@ -120,6 +148,24 @@ FBoxSphereBounds UStevesEditorVisComponent::CalcBounds(const FTransform& LocalTo DBox = DBox.TransformBy(BoxXForm); B = B + FBoxSphereBounds(DBox); } + for (auto& Cylinder : Cylinders) + { + FVector HalfSize = FVector(Cylinder.Radius, Cylinder.Radius, Cylinder.Height * 0.5f); + FBox DBox(-HalfSize, HalfSize); + // Apply local rotation only, world is done later + FTransform XForm = FTransform(Cylinder.Rotation, Cylinder.Location); + DBox = DBox.TransformBy(XForm); + B = B + FBoxSphereBounds(DBox); + } + for (auto& Capsule : Capsules) + { + FVector HalfSize = FVector(Capsule.Radius, Capsule.Radius, Capsule.Height * 0.5f + Capsule.Radius * 2.f); + FBox DBox(-HalfSize, HalfSize); + // Apply local rotation only, world is done later + FTransform XForm = FTransform(Capsule.Rotation, Capsule.Location); + DBox = DBox.TransformBy(XForm); + B = B + FBoxSphereBounds(DBox); + } return B.TransformBy(LocalToWorld); } diff --git a/Source/StevesUEHelpers/Public/StevesDebugRenderSceneProxy.h b/Source/StevesUEHelpers/Public/StevesDebugRenderSceneProxy.h index c802841..9a78871 100644 --- a/Source/StevesUEHelpers/Public/StevesDebugRenderSceneProxy.h +++ b/Source/StevesUEHelpers/Public/StevesDebugRenderSceneProxy.h @@ -70,6 +70,33 @@ public: FColor Color; }; + /// Replacement for FWireCylinder because that's garbage and doesn't reflect the component transform + struct FDebugCylinder + { + FDebugCylinder(const FVector &InCentre, const FVector& InX, const FVector& InY, const FVector& InZ, const float InRadius, const float InHalfHeight, int InNumSegments, const FColor &InColor) : + Centre(InCentre), + X(InX), Y(InY), Z(InZ), + Radius(InRadius), + HalfHeight(InHalfHeight), + NumSegments(InNumSegments), + Color(InColor) + { + } + + FVector Centre; + FVector X; + FVector Y; + FVector Z; + float Radius; + float HalfHeight; + int NumSegments; + FColor Color; + }; + + TArray Circles; TArray Arcs; + TArray CylindersImproved; // Because we need our own + TArray CapsulesImproved; // Because we need our own + }; diff --git a/Source/StevesUEHelpers/Public/StevesEditorVisComponent.h b/Source/StevesUEHelpers/Public/StevesEditorVisComponent.h index e0ba5f9..851a997 100644 --- a/Source/StevesUEHelpers/Public/StevesEditorVisComponent.h +++ b/Source/StevesUEHelpers/Public/StevesEditorVisComponent.h @@ -195,7 +195,53 @@ struct STEVESUEHELPERS_API FStevesEditorVisBox } }; +USTRUCT(BlueprintType) +struct STEVESUEHELPERS_API FStevesEditorVisCylinder +{ + GENERATED_BODY() + /// Location relative to component + UPROPERTY(EditAnywhere) + FVector Location; + /// Height of cylinder + UPROPERTY(EditAnywhere) + float Height; + /// Radius of cylinder + UPROPERTY(EditAnywhere) + float Radius; + /// Rotation relative to component + UPROPERTY(EditAnywhere) + FRotator Rotation; + /// The colour of the line render + UPROPERTY(EditAnywhere) + FColor Colour; + + FStevesEditorVisCylinder(const FVector& InLocation, float InHeight, float InRadius, const FRotator& InRot, + const FColor& InColour) : + Location(InLocation), + Height(InHeight), + Radius(InRadius), + Rotation(InRot), + Colour(InColour) + { + } + + FStevesEditorVisCylinder(): + Location(FVector::ZeroVector), + Height(50), + Radius(10), + Rotation(FRotator::ZeroRotator), + Colour(FColor::White) + { + } +}; + +USTRUCT(BlueprintType) +struct STEVESUEHELPERS_API FStevesEditorVisCapsule : public FStevesEditorVisCylinder +{ + GENERATED_BODY() + +}; /** * * A component that solely exists to provide arbitrary editor visualisation when not selected. @@ -227,6 +273,10 @@ public: TArray Spheres; UPROPERTY(EditAnywhere, BlueprintReadWrite) TArray Boxes; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + TArray Cylinders; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + TArray Capsules; UStevesEditorVisComponent(const FObjectInitializer& ObjectInitializer);