SMeshWidget - Hardware Instanced Slate Meshes Thread

Okay so here’s an update (finally).

Got back to working on my radar stuff, but decided to work in the example project nick gave first. I finally have this circular mesh drawing as slate geometry!

Source code (though it’s very simple). You can see the shader setup and the mesh in the video. What I want to do next is have better control over the position of the mesh in UMG, using the bounding rectangle ideally to scale and place it.



// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.

#include "MeshWidgetExample.h"
#include "Slate/SMeshWidget.h"
#include "Slate/SlateVectorArtInstanceData.h"

#include "ParticleWidget.h"

#include "MeshWidgetExampleCharacter.h"

DECLARE_STATS_GROUP(TEXT("MeshWidget"), STATGROUP_MeshWidget, STATCAT_Advanced);
DECLARE_CYCLE_STAT(TEXT("Particle Update"), STAT_ParticleUpdate, STATGROUP_MeshWidget);

class SParticleMeshWidget : public SMeshWidget
{
public:
	SLATE_BEGIN_ARGS(SParticleMeshWidget) { }
	SLATE_END_ARGS()

public:
	void Construct(const FArguments& Args, UParticleWidget& InThis)
	{
		This = &InThis;
	}

	virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const override
	{
		SCOPE_CYCLE_COUNTER(STAT_ParticleUpdate);

		const float Scale = AllottedGeometry.Scale;

		// Trail
		if ( This->TrailMeshId != -1 )
		{
			FVector2D TrailOriginWindowSpace = AllottedGeometry.LocalToAbsolute(AllottedGeometry.GetLocalSize() * 0.5f);

			TSharedPtr<FSlateInstanceBufferUpdate> PerInstaceUpdate = BeginPerInstanceBufferUpdateConst(This->TrailMeshId);
			PerInstaceUpdate->GetData().Empty();

			// Draw Radar Mesh
			FSlateVectorArtInstanceData RadarData;
			RadarData.SetPosition(TrailOriginWindowSpace * Scale);
			RadarData.SetScale(Scale);
			RadarData.SetBaseAddress(AMeshWidgetExampleCharacter::RotationAngle); // Set to Pawn Rotation

			// Add Radar to Data
			PerInstaceUpdate->GetData().Add(RadarData.GetData());
			FSlateInstanceBufferUpdate::CommitUpdate(PerInstaceUpdate);
		}

		return SMeshWidget::OnPaint(Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
	}

public:
	UParticleWidget* This;
};

UParticleWidget::UParticleWidget()
	: TrailMeshId(-1)
{
}

void UParticleWidget::SynchronizeProperties()
{
	Super::SynchronizeProperties();

	if ( TrailMeshAsset )
	{
		TrailMeshId = MyMesh->AddMesh(*TrailMeshAsset);
		MyMesh->EnableInstancing(TrailMeshId, 1);
	}
}

void UParticleWidget::ReleaseSlateResources(bool bReleaseChildren)
{
	Super::ReleaseSlateResources(bReleaseChildren);

	MyMesh.Reset();
}

TSharedRef<SWidget> UParticleWidget::RebuildWidget()
{
	MyMesh = SNew(SParticleMeshWidget, *this);
	return MyMesh.ToSharedRef();
}



1 Like