diff --git a/Source/DasherVR/Private/SDasherWidget.cpp b/Source/DasherVR/Private/SDasherWidget.cpp index 12cc35696b2fee1695b8accfb4d2ab9687a288df..6d993fc67e49d6c65ce0e2ac73101d7c74e213dc 100644 --- a/Source/DasherVR/Private/SDasherWidget.cpp +++ b/Source/DasherVR/Private/SDasherWidget.cpp @@ -4,16 +4,14 @@ #include "Brushes/SlateColorBrush.h" #include "Rendering/DrawElements.h" #include "DasherInterface.h" - #include "IDisplayCluster.h" #include "Cluster/DisplayClusterClusterEvent.h" #include "Cluster/IDisplayClusterClusterManager.h" +#include "Utility/RWTHVRUtilities.h" + #include "Components/SlateWrapperTypes.h" #include "Framework/Application/SlateApplication.h" -#include "Serialization/BufferArchive.h" -#include "Serialization/BufferWriter.h" -#include "Utility/RWTHVRUtilities.h" BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION @@ -48,6 +46,18 @@ FReply SDasherWidget::HandleMouseMoveEvent(const FGeometry& Geometry, const FPoi if (CurrentlyUsingVectorInput) return FReply::Unhandled(); //The mouse event only contains the Screen Space Position CursorPosition = Geometry.AbsoluteToLocal(MouseEvent.GetScreenSpacePosition()); + + if(URWTHVRUtilities::IsRoomMountedMode()) + { + FDisplayClusterClusterEventJson ClusterEvent; + ClusterEvent.Category = "Dasher"; + ClusterEvent.Type = "Input"; + ClusterEvent.Name = "MouseMove"; + ClusterEvent.Parameters.Add("X", FString::SanitizeFloat(CursorPosition.X)); + ClusterEvent.Parameters.Add("Y", FString::SanitizeFloat(CursorPosition.Y)); + IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventJson(ClusterEvent, false); + return FReply::Handled().ReleaseMouseLock(); + } } return FReply::Handled(); } @@ -56,6 +66,16 @@ FReply SDasherWidget::HandleMouseDownEvent(const FGeometry& Geometry, const FPoi { if (!InputPaused) { + if(URWTHVRUtilities::IsRoomMountedMode()) + { + FDisplayClusterClusterEventJson ClusterEvent; + ClusterEvent.Category = "Dasher"; + ClusterEvent.Type = "Input"; + ClusterEvent.Name = "MouseDown"; + IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventJson(ClusterEvent, false); + return FReply::Handled().ReleaseMouseLock(); + } + if (CurrentlyUsingVectorInput) { CurrentlyUsingVectorInput = false; @@ -69,6 +89,16 @@ FReply SDasherWidget::HandleMouseDownEvent(const FGeometry& Geometry, const FPoi FReply SDasherWidget::HandleMouseUpEvent(const FGeometry& Geometry, const FPointerEvent& MouseEvent) { + if(URWTHVRUtilities::IsRoomMountedMode()) + { + FDisplayClusterClusterEventJson ClusterEvent; + ClusterEvent.Category = "Dasher"; + ClusterEvent.Type = "Input"; + ClusterEvent.Name = "MouseUp"; + IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventJson(ClusterEvent, false); + return FReply::Handled().ReleaseMouseLock(); + } + if (CurrentlyUsingVectorInput) { CurrentlyUsingVectorInput = false; @@ -82,8 +112,19 @@ FReply SDasherWidget::HandleMouseUpEvent(const FGeometry& Geometry, const FPoint FReply SDasherWidget::HandleMouseDoubleClickEvent(const FGeometry& Geometry, const FPointerEvent& MouseEvent) { + if (!InputPaused) { + if(URWTHVRUtilities::IsRoomMountedMode()) + { + FDisplayClusterClusterEventJson ClusterEvent; + ClusterEvent.Category = "Dasher"; + ClusterEvent.Type = "Input"; + ClusterEvent.Name = "MouseDown"; + IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventJson(ClusterEvent, false); + return FReply::Handled().ReleaseMouseLock(); + } + if (CurrentlyUsingVectorInput) { CurrentlyUsingVectorInput = false; @@ -111,9 +152,36 @@ bool SDasherWidget::GetScreenCoords(screenint& iX, screenint& iY, Dasher::CDashe return true; } +void SDasherWidget::HandleClusterEvent(const FDisplayClusterClusterEventJson& Event) +{ + if(Event.Category != "Dasher") return; + if(Event.Type == "Input") + { + if(Event.Name == "MouseUp") + { + DasherMainInterface->KeyUp(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), Dasher::Keys::Primary_Input); + MouseUpListeners.ExecuteIfBound(); + } else + if(Event.Name == "MouseDown") + { + DasherMainInterface->KeyDown(FDateTime::Now().GetSecond() + FDateTime::Now().GetMillisecond(), Dasher::Keys::Primary_Input); + MouseDownListeners.ExecuteIfBound(); + } else + if(Event.Name == "MouseMove") + { + CursorPosition.X = FCString::Atod(*Event.Parameters["X"]); + CursorPosition.Y = FCString::Atod(*Event.Parameters["Y"]); + } + } else + if(Event.Type == "Tick") + { + double currentTime = FCString::Atod(*Event.Parameters["Time"]); + DasherMainInterface->Tick(static_cast<unsigned long>(currentTime * 1000.0)); + } +} + void SDasherWidget::InputVector(const FVector2D InputVector) { - if (!URWTHVRUtilities::IsPrimaryNode()) return; if (!InputPaused) { if (!CurrentlyUsingVectorInput) return; CursorPosition = DasherMainInterface->ConvertDasher2Screen(Dasher::CDasherModel::ORIGIN_X, Dasher::CDasherModel::ORIGIN_Y) @@ -123,7 +191,6 @@ void SDasherWidget::InputVector(const FVector2D InputVector) void SDasherWidget::InputButton(bool Pressed) { - if (!URWTHVRUtilities::IsPrimaryNode()) return; if (!InputPaused) { CurrentlyUsingVectorInput = true; if (Pressed) @@ -136,42 +203,6 @@ void SDasherWidget::InputButton(bool Pressed) } } -void SDasherWidget::HandleClusterEvent(const FDisplayClusterClusterEventBinary& Event) -{ - if(!URWTHVRUtilities::IsPrimaryNode()) UE_LOG(LogTemp, Log, TEXT("Non Primary Receive")); - - FMemoryReader r(Event.EventData); - - BackBuffer->Empty(); - - r << NDisplayBuffer; - - GeometryType t; - bool readError = false; - while(!r.AtEnd() && !readError) - { - r << t; - switch (t) - { - case GeometryType::Rectangle: - BackBuffer->Add(FFilledRect::Deserialize(r)); - break; - case GeometryType::Writing: - BackBuffer->Add(FWriting::Deserialize(r)); - break; - case GeometryType::PolyLine: - BackBuffer->Add(FPolyLine::Deserialize(r)); - break; - default: - readError = true; - break; - } - } - - std::swap(FrontBuffer, BackBuffer); - BackBuffer->Empty(); -} - //The construction of the Dasher Widget, Dasher parameters are set here, a function to set them outside is not provided, but can be easily implemented void SDasherWidget::Construct(const FArguments& InArgs) { @@ -202,17 +233,17 @@ void SDasherWidget::Construct(const FArguments& InArgs) if (ClusterManager && !ClusterEvent.IsBound()) { ClusterEvent = - FOnClusterEventBinaryListener::CreateSP(this, &SDasherWidget::HandleClusterEvent); - ClusterManager->AddClusterEventBinaryListener(ClusterEvent); + FOnClusterEventJsonListener::CreateSP(this, &SDasherWidget::HandleClusterEvent); + ClusterManager->AddClusterEventJsonListener(ClusterEvent); } - //Set up the Event Handlers for Mouse Movement etc. if (URWTHVRUtilities::IsPrimaryNode()) { - SetOnMouseMove(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseMoveEvent(Geometry, MouseEvent); })); - SetOnMouseButtonDown(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseDownEvent(Geometry, MouseEvent); })); - SetOnMouseButtonUp(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseUpEvent(Geometry, MouseEvent); })); - SetOnMouseDoubleClick(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseDoubleClickEvent(Geometry, MouseEvent); })); //We treat a double click of the mouse as a lift of the mouse button. + //Set up the Event Handlers for Mouse Movement etc. + SetOnMouseMove(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseMoveEvent(Geometry, MouseEvent); })); + SetOnMouseButtonDown(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseDownEvent(Geometry, MouseEvent); })); + SetOnMouseButtonUp(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseUpEvent(Geometry, MouseEvent); })); + SetOnMouseDoubleClick(FPointerEventHandler::CreateLambda([this](const FGeometry& Geometry, const FPointerEvent& MouseEvent) {return HandleMouseDoubleClickEvent(Geometry, MouseEvent); })); //We treat a double click of the mouse as a lift of the mouse button. } } @@ -269,23 +300,32 @@ int32 SDasherWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe //The tick function, we tick dasher in it and update the screen size for dasher void SDasherWidget::Tick(const FGeometry& AllotedGeometry, const double InCurrentTime, const float InDeltaTime) { + SCompoundWidget::Tick(AllotedGeometry, InCurrentTime, InDeltaTime); + //don't tick in the editor - if (!IsEditor && !InputPaused && URWTHVRUtilities::IsPrimaryNode()) { - SCompoundWidget::Tick(AllotedGeometry, InCurrentTime, InDeltaTime); + if (!IsEditor && !InputPaused && !URWTHVRUtilities::IsPrimaryNode()) return; + if(!URWTHVRUtilities::IsRoomMountedMode()){ DasherMainInterface->Tick(static_cast<unsigned long>(InCurrentTime * 1000.0)); //we need to provide ticks in milliseconds + } + else + { + FDisplayClusterClusterEventJson ClusterEvent; + ClusterEvent.Category = "Dasher"; + ClusterEvent.Type = "Tick"; + ClusterEvent.Parameters.Add("Time", FString::SanitizeFloat(InCurrentTime)); + IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventJson(ClusterEvent, false); + } - - //This probably doesn't have to be done every tick, but it does not seem to have a huge hit on performance - const FGeometry Geometry = GetTickSpaceGeometry(); - const FIntPoint AbsoluteSize = Geometry.Size.IntPoint(); - if (Width != AbsoluteSize.X || Height != AbsoluteSize.Y) { - Width = AbsoluteSize.X; - Height = AbsoluteSize.Y; - resize(Width, Height); - //tell dasher we resized the screen, but only if there's actually a screen - if (Width && Height) DasherMainInterface->ScreenResized(this); - } + //This probably doesn't have to be done every tick, but it does not seem to have a huge hit on performance + const FGeometry Geometry = GetTickSpaceGeometry(); + const FIntPoint AbsoluteSize = Geometry.Size.IntPoint(); + if (Width != AbsoluteSize.X || Height != AbsoluteSize.Y) { + Width = AbsoluteSize.X; + Height = AbsoluteSize.Y; + resize(Width, Height); + //tell dasher we resized the screen, but only if there's actually a screen + if (Width && Height) DasherMainInterface->ScreenResized(this); } } @@ -298,41 +338,21 @@ std::pair<SDasherWidget::screenint, SDasherWidget::screenint> SDasherWidget::Tex //Double Buffers are rotated here. void SDasherWidget::Display() { + std::swap(FrontBuffer, BackBuffer); + BackBuffer->Empty(); - // if (URWTHVRUtilities::IsRoomMountedMode()) - // { - // auto start = std::chrono::high_resolution_clock::now(); - // FDisplayClusterClusterEventBinary BinaryClusterEvent; - // BinaryClusterEvent.EventData.Reserve(100000); // 100kb of data - // FMemoryWriter m(BinaryClusterEvent.EventData); - - // m << NDisplayBuffer; - - // for(auto& e : *BackBuffer) - // { - // e->Serialize(m); - // } - - // IDisplayCluster::Get().GetClusterMgr()->EmitClusterEventBinary(BinaryClusterEvent, false); - // } - // else - // { - std::swap(FrontBuffer, BackBuffer); - BackBuffer->Empty(); - - if (CharacterEnteredFlag && CharacterDeletedFlag) { - CharacterSwitched.ExecuteIfBound(AlteredChar, GetBuffer()); - } - else if (CharacterEnteredFlag) { - CharacterEntered.ExecuteIfBound(AlteredChar, GetBuffer()); - } - else if (CharacterDeletedFlag) { - CharacterDeleted.ExecuteIfBound(AlteredChar, GetBuffer()); - } + if (CharacterEnteredFlag && CharacterDeletedFlag) { + CharacterSwitched.ExecuteIfBound(AlteredChar, GetBuffer()); + } + else if (CharacterEnteredFlag) { + CharacterEntered.ExecuteIfBound(AlteredChar, GetBuffer()); + } + else if (CharacterDeletedFlag) { + CharacterDeleted.ExecuteIfBound(AlteredChar, GetBuffer()); + } - CharacterEnteredFlag = false; - CharacterDeletedFlag = false; - // } + CharacterEnteredFlag = false; + CharacterDeletedFlag = false; } //Functions for Drawing @@ -388,13 +408,12 @@ void SDasherWidget::Polygon(CDasherScreen::point* points, int number, const Dash //We pass through the contents of the dasher buffer FString SDasherWidget::GetBuffer() const { - return (URWTHVRUtilities::IsPrimaryNode()) ? DasherMainInterface->GetBuffer() : NDisplayBuffer; + return DasherMainInterface->GetBuffer(); } void SDasherWidget::ResetBuffer() { DasherMainInterface->ResetBuffer(); - NDisplayBuffer = ""; } void SDasherWidget::StartTraining(FString PathToTextFile) diff --git a/Source/DasherVR/Public/SDasherWidget.h b/Source/DasherVR/Public/SDasherWidget.h index 765919e21de9c86df68f60ae8d861ae5d4a6ab46..b65371c2c0698f0bb48f8785919fb754b0b95440 100644 --- a/Source/DasherVR/Public/SDasherWidget.h +++ b/Source/DasherVR/Public/SDasherWidget.h @@ -5,11 +5,9 @@ #include <utility> #include "DasherInterface.h" -#include "Cluster/DisplayClusterClusterEvent.h" #include "Math/Vector2D.h" #include "Fonts/FontMeasure.h" #include "Widgets/DeclarativeSyntaxSupport.h" - #include "Cluster/IDisplayClusterClusterManager.h" //using namespace Dasher; @@ -36,24 +34,8 @@ struct FFilledRect : DasherDrawGeometry { FVector2D top; FVector2D bottom; FLinearColor color; - void Serialize(FMemoryWriter& ar) - { - ar << Type; - ar << top; - ar << bottom; - ar << color; - } - static TUniquePtr<DasherDrawGeometry> Deserialize(FMemoryReader& ar) - { - TUniquePtr<FFilledRect> g = MakeUnique<FFilledRect>(); - ar << g->top; - ar << g->bottom; - ar << g->color; - return g; - } FFilledRect(FVector2D Top, FVector2D Bottom, FLinearColor Color) : DasherDrawGeometry(GeometryType::Rectangle), top(Top), bottom(Bottom), color(Color) {} - FFilledRect() : DasherDrawGeometry(GeometryType::Rectangle) {} }; struct FWriting : DasherDrawGeometry{ @@ -62,26 +44,7 @@ struct FWriting : DasherDrawGeometry{ int size; FLinearColor color; - void Serialize(FMemoryWriter& ar) - { - ar << Type; - ar << pos; - ar << size; - ar << color; - ar << label; - } - static TUniquePtr<DasherDrawGeometry> Deserialize(FMemoryReader& ar) - { - TUniquePtr<FWriting> g = MakeUnique<FWriting>(); - ar << g->pos; - ar << g->size; - ar << g->color; - ar << g->label; - return g; - } - FWriting(FString Label, FVector2D Pos, int Size, FLinearColor Color) : DasherDrawGeometry(GeometryType::Writing), label(Label), pos(Pos), size(Size), color(Color) {} - FWriting() : DasherDrawGeometry(GeometryType::Writing) {} }; struct FPolyLine : DasherDrawGeometry{ @@ -90,26 +53,7 @@ struct FPolyLine : DasherDrawGeometry{ bool AntiAliasing; FLinearColor color; - void Serialize(FMemoryWriter& ar) - { - ar << Type; - ar << points; - ar << linewidth; - ar << AntiAliasing; - ar << color; - } - static TUniquePtr<DasherDrawGeometry> Deserialize(FMemoryReader& ar) - { - TUniquePtr<FPolyLine> g = MakeUnique<FPolyLine>(); - ar << g->points; - ar << g->linewidth; - ar << g->AntiAliasing; - ar << g->color; - return g; - } - FPolyLine(TArray<FVector2D> Points, float LineWidth, FLinearColor Color, bool AntiAliasing): DasherDrawGeometry(GeometryType::PolyLine), points(Points), linewidth(LineWidth), AntiAliasing(AntiAliasing), color(Color) {} - FPolyLine(): DasherDrawGeometry(GeometryType::PolyLine) {} }; DECLARE_DELEGATE(FDasherMouseUpDelegate); @@ -158,8 +102,6 @@ public: virtual void Display() override; - virtual void SendMarker(int imarker) override {} - virtual bool IsPointVisible(screenint x, screenint y) override { return true; } //Pass-me-down returning Buffer @@ -184,9 +126,10 @@ public: virtual bool GetScreenCoords(screenint& iX, screenint& iY, Dasher::CDasherView* pView) override; + void HandleClusterEvent(const FDisplayClusterClusterEventJson& Event); + void InputVector(FVector2D InputVector); void InputButton(bool Pressed); - void HandleClusterEvent(const FDisplayClusterClusterEventBinary& Event); FVector2D GetCursorPosition(); //Allows to Pause Input @@ -224,9 +167,8 @@ private: //set up the font measure service to ... measure fonts. TSharedPtr<FSlateFontMeasure> FontMeasureService; -private: - FString NDisplayBuffer = ""; - FOnClusterEventBinaryListener ClusterEvent; + //CAVE Sync + FOnClusterEventJsonListener ClusterEvent; protected: // stores color information diff --git a/Source/Thirdparty/Dasher/DasherCore b/Source/Thirdparty/Dasher/DasherCore index 015b8c82fab747de4ff98de27ac177fcac6ddbfc..f6211ff1ad2e6aaf3a0ecf7ecb58aec610893b52 160000 --- a/Source/Thirdparty/Dasher/DasherCore +++ b/Source/Thirdparty/Dasher/DasherCore @@ -1 +1 @@ -Subproject commit 015b8c82fab747de4ff98de27ac177fcac6ddbfc +Subproject commit f6211ff1ad2e6aaf3a0ecf7ecb58aec610893b52