diff --git a/Source/DasherVR/Private/Dasher3DWidget.cpp b/Source/DasherVR/Private/Dasher3DWidget.cpp deleted file mode 100644 index b1373ced25c1138e6670b0c3f8f94951c04940d5..0000000000000000000000000000000000000000 --- a/Source/DasherVR/Private/Dasher3DWidget.cpp +++ /dev/null @@ -1,328 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#include "Dasher3DWidget.h" -#include "Math/Rotator.h" -#include "Engine/Texture2DArray.h" -#include "Engine/World.h" -#include "GameFramework/WorldSettings.h" -#include "Materials/MaterialInstanceDynamic.h" -// Sets default values -ADasher3DWidget::ADasher3DWidget() : DasherParents() -{ - // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. - PrimaryActorTick.bCanEverTick = true; - - ActorRootComponent = CreateDefaultSubobject<UStaticMeshComponent>("Root"); - ActorRootComponent->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block); - SetRootComponent(ActorRootComponent); - - CubeInstances = CreateDefaultSubobject<UInstancedStaticMeshComponent>("Cubes"); - CubeInstances->SetupAttachment(GetRootComponent()); - CubeInstances->SetFlags(RF_Transactional); - CubeInstances->NumCustomDataFloats = 7; //Color(3), Scale(3), LineWidth(1) - CubeInstances->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block); - this->AddInstanceComponent(CubeInstances); - - LetterInstances = CreateDefaultSubobject<UInstancedStaticMeshComponent>("Letters"); - LetterInstances->SetupAttachment(GetRootComponent()); - LetterInstances->SetFlags(RF_Transactional); - LetterInstances->NumCustomDataFloats = 5; //UV(2), Size(2), TexturePage(1) - LetterInstances->SetCollisionResponseToAllChannels(ECR_Ignore); - this->AddInstanceComponent(LetterInstances); - -} - -void ADasher3DWidget::PostInitializeComponents() -{ - Super::PostInitializeComponents(); - - CubeMaterialInstanceDynamic = UMaterialInstanceDynamic::Create(CubeInstances->GetMaterial(0), CubeInstances); - CubeInstances->SetMaterial(0, CubeMaterialInstanceDynamic); - - LetterMaterialInstanceDynamic = UMaterialInstanceDynamic::Create(LetterInstances->GetMaterial(0), LetterInstances); - LetterInstances->SetMaterial(0, LetterMaterialInstanceDynamic); -} - -// Called when the game starts or when spawned -void ADasher3DWidget::BeginPlay() -{ - Super::BeginPlay(); - //Setting up Dasher - InitializeDasher(); - //Setting up the Texture array for the font - InitializeTextureArray(); - - WorldToMeters = GetWorld()->GetWorldSettings()->WorldToMeters; - - CubeMaterialInstanceDynamic->SetVectorParameterValue("DrawingSizeBorderWidth", FVector(DrawingSize, 0)); -} - -// Called every frame -void ADasher3DWidget::Tick(float DeltaTime) -{ - Super::Tick(DeltaTime); - - DasherMainInterface->Tick(static_cast<unsigned long>(GetGameTimeSinceCreation() * 1000.0)); //we need to provide ticks in milliseconds -} - -std::pair<Dasher::screenint, Dasher::screenint> ADasher3DWidget::TextSize(Label* label, unsigned iFontSize) -{ - FString labelText = UTF8_TO_TCHAR(label->m_strText.c_str()); - TCHAR CurrentChar = labelText[0]; - if (CurrentChar < 32) CurrentChar = 32; // replace non-printable characters with spaces. - CurrentChar = DisplayFont->RemapChar(CurrentChar); - - const float FontScale = iFontSize / DisplayFont->ImportOptions.Height; - const float CharacterSizeU = DisplayFont->Characters[CurrentChar].USize; // Pixel Sizes for actual character without blank space - const float CharacterSizeV = DisplayFont->Characters[CurrentChar].VSize; // Pixel Sizes for actual character without blank space - const float CharacterVerticalOffset = DisplayFont->Characters[CurrentChar].VerticalOffset; - const FVector2D CharScale = FVector2D( - (CharacterSizeU / CharacterSizeV) * CharacterSizeV, // (Width/Height * Height) - CharacterSizeV + CharacterVerticalOffset // Height + Vertical Offset, as the vertical offset also counts towards the height for line-height calculations - ) * FontScale; - - return {CharScale.X, CharScale.Y}; -} - -void ADasher3DWidget::DrawString(Label* label, Dasher::screenint x, Dasher::screenint y, unsigned iFontSize, const Dasher::ColorPalette::Color& color){} - -void ADasher3DWidget::DrawCube(Dasher::screenint posX, Dasher::screenint posY, Dasher::screenint sizeX, Dasher::screenint sizeY, Dasher::myint extrusionLevel, Dasher::myint groupRecursionDepth, const Dasher::ColorPalette::Color& color, const Dasher::ColorPalette::Color& outlineColor, int iThickness) { - - if (sizeX == 0 || sizeY == 0) return; - const FVector Scale = FVector(FVector2D(sizeX, sizeY) / DrawingSize, - FMath::Max(ExtrusionLevelToHeight(extrusionLevel), 0.001) + groupRecursionDepth*0.001) // Min Depth 1mm - + FVector(extrusionLevel,extrusionLevel,0)*FLT_EPSILON; - const FVector2D Translation = FVector2D(posX, posY) / DrawingSize - FVector2D(0.5f, 0.5f); - - const FLinearColor RectColor = FLinearColor(color.Red / 255.0, color.Green / 255.0, color.Blue / 255.0, color.Alpha / 255.0); - - BackBuffer->first.Add(FTransform(FQuat::Identity, FVector(Translation, 0) * WorldToMeters, Scale)); - BackBuffer->second.Add(RectColor.R); - BackBuffer->second.Add(RectColor.G); - BackBuffer->second.Add(RectColor.B); - BackBuffer->second.Add(Scale.X); - BackBuffer->second.Add(Scale.Y); - BackBuffer->second.Add(Scale.Z); - BackBuffer->second.Add(0.5f * iThickness * (outlineColor.isFullyTransparent() ? 0.0f : 1.0f)); //Allows for individual adjustment -} - -// x & y are given as upper left corner of the character -void ADasher3DWidget::Draw3DLabel(Label* label, Dasher::screenint x, Dasher::screenint y, Dasher::myint extrusionLevel, Dasher::myint groupRecursionDepth, unsigned int iFontSize, const Dasher::ColorPalette::Color& color) { - float CharacterOffset = 0; // in Meters - - if(LabelBackBuffer->first.Max() < LabelBackBuffer->first.Num() + label->m_strText.length()) LabelBackBuffer->first.Reserve(LabelBackBuffer->first.Num() + label->m_strText.length()); - if(LabelBackBuffer->second.Max() < LabelBackBuffer->second.Num() + label->m_strText.length()) LabelBackBuffer->second.Reserve(LabelBackBuffer->second.Num() + label->m_strText.length()); - - FString labelText = UTF8_TO_TCHAR(label->m_strText.c_str()); - for (int i = 0; i < labelText.Len(); i++) - { - TCHAR CurrentChar = labelText[i]; - if (CurrentChar < 32) CurrentChar = 32; // replace non-printable characters with spaces. - const TCHAR RemappedChar = DisplayFont->RemapChar(CurrentChar); - - const int TextureIndex = DisplayFont->Characters[RemappedChar].TextureIndex; - const float FontScale = iFontSize / DisplayFont->ImportOptions.Height; - const float TextureSizeU = DisplayFont->Textures[TextureIndex]->GetSizeX(); // Pixel Sizes - const float TextureSizeV = DisplayFont->Textures[TextureIndex]->GetSizeY(); // Pixel Sizes - const float CharacterOffsetU = DisplayFont->Characters[RemappedChar].StartU; //Upper left corner - const float CharacterOffsetV = DisplayFont->Characters[RemappedChar].StartV; //Upper left corner - const float CharacterSizeU = DisplayFont->Characters[RemappedChar].USize; // Pixel Sizes for actual character without blank space - const float CharacterSizeV = DisplayFont->Characters[RemappedChar].VSize; // Pixel Sizes for actual character without blank space - const float CharacterVerticalOffset = DisplayFont->Characters[RemappedChar].VerticalOffset * FontScale; //vertical offset in pixels - - TArray<float> FontData = { - CharacterOffsetU / TextureSizeU, // Upper Left Corner given in UV - CharacterOffsetV / TextureSizeV, // Upper Left Corner given in UV - CharacterSizeU / TextureSizeU, // Size given in UV - CharacterSizeV / TextureSizeV, // Size given in UV - static_cast<float>(TextureIndex) // Texture Page - }; - - const FVector2D CharScale = FVector2D( - (CharacterSizeU / CharacterSizeV) * CharacterSizeV, // (Width/Height * Height) - CharacterSizeV // Height - ) * FontScale / DrawingSize; // From Pixel to "Meter" (afterwards scaled by parent) - - - const FVector CharTranslation = FVector( - (x / DrawingSize.X + CharScale.X * 0.5f) * WorldToMeters + CharacterOffset, - ((y + CharacterVerticalOffset) / DrawingSize.Y) * WorldToMeters, - (FMath::Max(ExtrusionLevelToHeight(extrusionLevel), 0.001) + groupRecursionDepth*0.001) * WorldToMeters + 0.05f - ) - - FVector(0.5f, 0.5f, 0) * WorldToMeters; // Move to upper left corner of parent - - LabelBackBuffer->first.Add(FTransform(FQuat::Identity, CharTranslation, FVector(CharScale, 1.0f))); - LabelBackBuffer->second.Add(FontData); - - CharacterOffset += CharScale.X * WorldToMeters; // characterOffset is accumulated for multiple character strings - } -} - -void ADasher3DWidget::FinishRender3D(Dasher::myint originX, Dasher::myint originY, Dasher::myint originExtrusionLevel) -{ - Origin = FVector(originX / DrawingSize.X, originY / DrawingSize.Y, 0) * WorldToMeters; - - CubeInstances->SetRelativeLocation({0,0,-ExtrusionLevelToHeight(originExtrusionLevel) * WorldToMeters}); - LetterInstances->SetRelativeLocation({0,0,-ExtrusionLevelToHeight(originExtrusionLevel) * WorldToMeters}); -} - -void ADasher3DWidget::DrawRectangle(Dasher::screenint x1, Dasher::screenint y1, Dasher::screenint x2, Dasher::screenint y2, const Dasher::ColorPalette::Color& color, const Dasher::ColorPalette::Color& outlineColor, int iThickness) -{ - DrawCube((x2 - x1)/2 + x1, (y2-y1)/2 + y1, x2-x1, y2-y1, 1, 0, color, outlineColor, iThickness); -} - -void ADasher3DWidget::DrawCircle(Dasher::screenint iCX, Dasher::screenint iCY, Dasher::screenint iR, const Dasher::ColorPalette::Color& fillColor, const Dasher::ColorPalette::Color& lineColor, int iLineWidth) -{ - //Todo -} - -void ADasher3DWidget::Polyline(point* Points, int Number, int iWidth, const Dasher::ColorPalette::Color& color) -{ - for(int i = 1; i < Number; i++) - { - const point& p1 = Points[i-1]; - const point& p2 = Points[i]; - - const FVector Scale = FVector(FVector2D(sqrt(powf(p1.x - p2.x, 2)+powf(p1.y - p2.y, 2)), iWidth) / DrawingSize, ExtrusionLevelToHeight(2)); - const FVector2D Translation = FVector2D((p2.x - p1.x)/2.0f + p1.x, (p2.y - p1.y)/2.0f + p1.y) / DrawingSize - FVector2D(0.5f, 0.5f); - const FQuat Rotation = FQuat().MakeFromEuler({0,0,FMath::RadiansToDegrees(FMath::Atan2(static_cast<float>(p2.y - p1.y), static_cast<float>(p2.x - p1.x)))}); - - const FLinearColor RectColor = FLinearColor(color.Red / 255.0, color.Green / 255.0, color.Blue / 255.0, color.Alpha / 255.0); - - BackBuffer->first.Add(FTransform(Rotation, FVector(Translation, 0) * WorldToMeters, Scale)); - BackBuffer->second.Add(RectColor.R); - BackBuffer->second.Add(RectColor.G); - BackBuffer->second.Add(RectColor.B); - BackBuffer->second.Add(Scale.X); - BackBuffer->second.Add(Scale.Y); - BackBuffer->second.Add(Scale.Z); - BackBuffer->second.Add(0); - } -} - -void ADasher3DWidget::Polygon(point* Points, int Number, const Dasher::ColorPalette::Color& fillColor, const Dasher::ColorPalette::Color& outlineColor, int lineWidth) -{ - //Todo -} - -void ADasher3DWidget::Display() -{ - std::swap(FrontBuffer, BackBuffer); - BackBuffer->first.Empty(); - BackBuffer->second.Empty(); - CubeInstances->ClearInstances(); - CubeInstances->AddInstances(FrontBuffer->first, false); - - TArray<float> ColorScale = {0,0,0,0,0,0}; - for(int i = 0; i < FrontBuffer->first.Num(); i++) - { - ColorScale = { - FrontBuffer->second[i*CubeInstances->NumCustomDataFloats], - FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+1], - FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+2], - FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+3], - FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+4], - FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+5], - FrontBuffer->second[i*CubeInstances->NumCustomDataFloats+6] - }; - CubeInstances->SetCustomData(i, ColorScale); - } - - - std::swap(LabelFrontBuffer, LabelBackBuffer); - LabelBackBuffer->first.Empty(); - LabelBackBuffer->second.Empty(); - LetterInstances->ClearInstances(); - LetterInstances->AddInstances(LabelFrontBuffer->first, false); - - for (int i = 0; i < LabelFrontBuffer->first.Num(); i++) - { - TArray<float> data = LabelFrontBuffer->second[i]; - LetterInstances->SetCustomData(i, data); - } - - //Events: - const FString Buffer = DasherMainInterface->GetBuffer(); - if (CharacterEnteredFlag && CharacterDeletedFlag) { - CharacterSwitched(AlteredChar, Buffer); - BufferAltered(Buffer); - } - else if (CharacterEnteredFlag) { - CharacterEntered(AlteredChar, Buffer); - BufferAltered(Buffer); - } - else if (CharacterDeletedFlag) { - CharacterDeleted(AlteredChar, Buffer); - BufferAltered(Buffer); - } - - CharacterEnteredFlag = false; - CharacterDeletedFlag = false; -} - -bool ADasher3DWidget::IsPointVisible(Dasher::screenint x, Dasher::screenint y) -{ - return true; -} - -bool ADasher3DWidget::GetScreenCoords(Dasher::screenint& iX, Dasher::screenint& iY, Dasher::CDasherView* pView) -{ - const FVector2D Position = GetCursorPosition(); - - iX = Position.X; - iY = Position.Y; - - return true; -} - -void ADasher3DWidget::SetMouseLocation(FVector WorldLocation) -{ - MousePos = ActorRootComponent->GetComponentToWorld().InverseTransformPosition(WorldLocation) + FVector(0.5f,0.5f,0) * WorldToMeters; - CursorPosition = FVector2D(MousePos) / WorldToMeters * DrawingSize; //convert to pixels -} - -void ADasher3DWidget::SimulateClick(FKey Key, bool pressed) -{ - if(!(Key == EKeys::LeftMouseButton || Key == EKeys::RightMouseButton)) return; - if(pressed) - { - DasherMainInterface->KeyDown(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), (Key == EKeys::LeftMouseButton) ? Dasher::Keys::Primary_Input : Dasher::Keys::Secondary_Input); - } - else - { - DasherMainInterface->KeyUp(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), (Key == EKeys::LeftMouseButton) ? Dasher::Keys::Primary_Input : Dasher::Keys::Secondary_Input); - } -} - -void ADasher3DWidget::InitializeTextureArray() -{ - TextureArray = NewObject<UTexture2DArray>(); - for (int i = 0; i < DisplayFont->Textures.Num(); i++) - { - TextureArray->SourceTextures.Add(DisplayFont->Textures[i]); - } - TextureArray->UpdateSourceFromSourceTextures(true); - LetterMaterialInstanceDynamic->SetTextureParameterValue("TextureArray", TextureArray); -} - -float ADasher3DWidget::ExtrusionLevelToHeight(float level) -{ - return level*DepthScale; -} - -void ADasher3DWidget::InitializeDasher() { - resize(DrawingSize.X, DrawingSize.Y); - - static Dasher::XMLErrorDisplay display; - Dasher::XmlSettingsStore* Settings = new Dasher::XmlSettingsStore("Settings3D.xml"/*, &fileUtils*/, &display); //Gets deleted somewhere else - Settings->Load(); - Settings->Save(); - DasherMainInterface = MakeShared<Dasher::DasherInterface>(Settings); - DasherMainInterface->GetModuleManager()->RegisterInputDeviceModule(this, true); - - DasherMainInterface->SetCharEnteredCallback([this](FString Char, FString Buffer) {CharacterEnteredFlag = true; AlteredChar = Char; }); - DasherMainInterface->SetCharDeletedCallback([this](FString Char, FString Buffer) {CharacterDeletedFlag = true; AlteredChar = Char; }); - - DasherMainInterface->SetScreen(this); - DasherMainInterface->SetBuffer(0); -} diff --git a/Source/DasherVR/Public/Dasher3DWidget.h b/Source/DasherVR/Public/Dasher3DWidget.h deleted file mode 100644 index 84daed0d7bf85a3e5cb8b179602d9680151f4e66..0000000000000000000000000000000000000000 --- a/Source/DasherVR/Public/Dasher3DWidget.h +++ /dev/null @@ -1,103 +0,0 @@ -// Fill out your copyright notice in the Description page of Project Settings. - -#pragma once - -#include "CoreMinimal.h" -#include "Engine/Font.h" -#include "GameFramework/Actor.h" -#include "DasherCoreWrapper.h" -#include "DasherInterface.h" -#include "Components/InstancedStaticMeshComponent.h" -#include "Engine/Texture2DArray.h" -#include "Materials/Material.h" - -class DasherParents : public Dasher::CDasherScreen, public Dasher::CScreenCoordInput -{ -public: - DasherParents() : CDasherScreen(0,0), CScreenCoordInput("Mouse Input"){}; -}; - -#include "Dasher3DWidget.generated.h" - -UCLASS(BlueprintType) -class DASHERVR_API ADasher3DWidget : public AActor, public DasherParents -{ - GENERATED_BODY() - -public: - // Sets default values for this actor's properties - ADasher3DWidget(); - -protected: - // Called when the game starts or when spawned - virtual void BeginPlay() override; - void InitializeDasher(); - void InitializeTextureArray(); - virtual float ExtrusionLevelToHeight(float level); - -public: - // Called every frame - virtual void Tick(float DeltaTime) override; - - virtual std::pair<Dasher::screenint, Dasher::screenint> TextSize(Label* label, unsigned iFontSize) override; - virtual void DrawString(Label* label, Dasher::screenint x, Dasher::screenint y, unsigned iFontSize, const Dasher::ColorPalette::Color& color) override; - virtual void DrawRectangle(Dasher::screenint x1, Dasher::screenint y1, Dasher::screenint x2, Dasher::screenint y2, const Dasher::ColorPalette::Color& color, const Dasher::ColorPalette::Color& outlineColor, int iThickness) override; - virtual void DrawCube(Dasher::screenint posX, Dasher::screenint posY, Dasher::screenint sizeX, Dasher::screenint sizeY, Dasher::myint extrusionLevel, Dasher::myint groupRecursionDepth, const Dasher::ColorPalette::Color& color, const Dasher::ColorPalette::Color& outlineColor, int iThickness) override; - virtual void Draw3DLabel(Label* label, Dasher::screenint x, Dasher::screenint y, Dasher::myint extrusionLevel, Dasher::myint groupRecursionDepth, unsigned int iFontSize, const Dasher::ColorPalette::Color& color) override; - virtual void FinishRender3D(Dasher::myint originX, Dasher::myint originY, Dasher::myint originExtrusionLevel) override; - virtual void DrawCircle(Dasher::screenint iCX, Dasher::screenint iCY, Dasher::screenint iR, const Dasher::ColorPalette::Color& fillColor, const Dasher::ColorPalette::Color& lineColor, int iLineWidth) override; - virtual void Polyline(point* Points, int Number, int iWidth, const Dasher::ColorPalette::Color& color) override; - virtual void Polygon(point* Points, int Number, const Dasher::ColorPalette::Color& fillColor, const Dasher::ColorPalette::Color& outlineColor, int lineWidth) override; - virtual void Display() override; - virtual bool IsPointVisible(Dasher::screenint x, Dasher::screenint y) override; - virtual bool GetScreenCoords(Dasher::screenint& iX, Dasher::screenint& iY, Dasher::CDasherView* pView) override; - virtual void SendMarker(int Marker) override {}; - - FVector2D GetCursorPosition(){return CursorPosition;}; - - UPROPERTY(VisibleAnywhere, Category = "Components") UStaticMeshComponent* ActorRootComponent = nullptr; - UPROPERTY(VisibleAnywhere, Category = "Components") UInstancedStaticMeshComponent* CubeInstances = nullptr; - UPROPERTY(VisibleAnywhere, Category = "Components") UInstancedStaticMeshComponent* LetterInstances = nullptr; - UPROPERTY(EditAnywhere) UFont* DisplayFont; - UPROPERTY(EditAnywhere) UMaterial* FontMaterial; - UPROPERTY(EditAnywhere) float DepthScale = 0.1; - UPROPERTY(EditAnywhere, BlueprintReadOnly) FVector Origin = {0,0,0}; - UPROPERTY(EditAnywhere, BlueprintReadOnly) FVector MousePos = {0,0,0}; - - UFUNCTION(BlueprintCallable) void SetMouseLocation(FVector WorldLocation); - UFUNCTION(BlueprintCallable) void SimulateClick(FKey Key, bool pressed); - virtual void PostInitializeComponents() override; - -public: - UFUNCTION(BlueprintImplementableEvent) void CharacterEntered(const FString& Char, const FString& Buffer); - UFUNCTION(BlueprintImplementableEvent) void CharacterDeleted(const FString& Char, const FString& Buffer); - UFUNCTION(BlueprintImplementableEvent) void CharacterSwitched(const FString& Char, const FString& Buffer); - UFUNCTION(BlueprintImplementableEvent) void BufferAltered(const FString& Buffer); -private: - - bool CharacterEnteredFlag = false; - bool CharacterDeletedFlag = false; - FString AlteredChar = ""; - -private: - FVector2D CursorPosition; - float WorldToMeters; // normally 100 - FVector2D DrawingSize = {1000,1000}; // Rendering Resolution - TSharedPtr<Dasher::DasherInterface> DasherMainInterface; - UPROPERTY() UMaterialInstanceDynamic* CubeMaterialInstanceDynamic; - UPROPERTY() UMaterialInstanceDynamic* LetterMaterialInstanceDynamic; - UPROPERTY() UTexture2DArray* TextureArray; - - FVector DefaultTranslation; - std::pair<TArray<FTransform>, TArray<float>> GeometryBufferA; - std::pair<TArray<FTransform>, TArray<float>> GeometryBufferB; - std::pair<TArray<FTransform>, TArray<float>>* BackBuffer = &GeometryBufferA; - std::pair<TArray<FTransform>, TArray<float>>* FrontBuffer = &GeometryBufferB; - - - std::pair<TArray<FTransform>, TArray<TArray<float>>> LabelGeometryBufferA; - std::pair<TArray<FTransform>, TArray<TArray<float>>> LabelGeometryBufferB; - std::pair<TArray<FTransform>, TArray<TArray<float>>>* LabelBackBuffer = &LabelGeometryBufferA; - std::pair<TArray<FTransform>, TArray<TArray<float>>>* LabelFrontBuffer = &LabelGeometryBufferB; - -};