AkAcousticPortalVisualizer.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*******************************************************************************
  2. The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
  3. Technology released in source code form as part of the game integration package.
  4. The content of this file may not be used without valid licenses to the
  5. AUDIOKINETIC Wwise Technology.
  6. Note that the use of the game engine is subject to the Unreal(R) Engine End User
  7. License Agreement at https://www.unrealengine.com/en-US/eula/unreal
  8. License Usage
  9. Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
  10. this file in accordance with the end user license agreement provided with the
  11. software or, alternatively, in accordance with the terms contained
  12. in a written agreement between you and Audiokinetic Inc.
  13. Copyright (c) 2023 Audiokinetic Inc.
  14. *******************************************************************************/
  15. /*=============================================================================
  16. AkAcousticPortalVisualizer.cpp:
  17. =============================================================================*/
  18. #include "AkAcousticPortalVisualizer.h"
  19. #include "WwiseUEFeatures.h"
  20. #include "AkSpatialAudioDrawUtils.h"
  21. #include "AkDrawPortalComponent.h"
  22. #include "AkRoomComponent.h"
  23. #include "SceneManagement.h"
  24. #include "DynamicMeshBuilder.h"
  25. #include "EditorModes.h"
  26. #include "Materials/Material.h"
  27. void UAkPortalComponentVisualizer::DrawVisualization(const UActorComponent* Component, const FSceneView* View, FPrimitiveDrawInterface* PDI)
  28. {
  29. const UAkPortalComponent* PortalComponent = Cast<UAkPortalComponent>(Component);
  30. if (IsValid(PortalComponent) && IsValid(PortalComponent->GetPrimitiveParent()))
  31. {
  32. const UPrimitiveComponent* PrimitiveParent = Cast<UPrimitiveComponent>(PortalComponent->GetPrimitiveParent());
  33. // Calculate the unscaled, unrotated box extent of the primitive parent component, at origin.
  34. FVector BoxExtent = PrimitiveParent->CalcLocalBounds().BoxExtent;
  35. FDynamicMeshBuilder MeshBuilderFront(ERHIFeatureLevel::Type::ES3_1);
  36. FDynamicMeshBuilder MeshBuilderBack(ERHIFeatureLevel::Type::ES3_1);
  37. MeshBuilderFront.AddVertices({
  38. FUnrealFloatVector(BoxExtent), // FRU
  39. FUnrealFloatVector(BoxExtent.X, BoxExtent.Y, -BoxExtent.Z), // FRD
  40. FUnrealFloatVector(0.0f, BoxExtent.Y, -BoxExtent.Z), // RD
  41. FUnrealFloatVector(0.0f, BoxExtent.Y, BoxExtent.Z), // RU
  42. FUnrealFloatVector(BoxExtent.X, -BoxExtent.Y, BoxExtent.Z), // FLU
  43. FUnrealFloatVector(BoxExtent.X, -BoxExtent.Y, -BoxExtent.Z), // FLD
  44. FUnrealFloatVector(0.0f, -BoxExtent.Y, -BoxExtent.Z), // LD
  45. FUnrealFloatVector(0.0f, -BoxExtent.Y, BoxExtent.Z) // LU
  46. });
  47. MeshBuilderBack.AddVertices({
  48. FUnrealFloatVector(-BoxExtent.X, -BoxExtent.Y, BoxExtent.Z), // BLU
  49. FUnrealFloatVector(-BoxExtent), // BLD
  50. FUnrealFloatVector(0.0f, -BoxExtent.Y, -BoxExtent.Z), // LD
  51. FUnrealFloatVector(0.0f, -BoxExtent.Y, BoxExtent.Z), // LU
  52. FUnrealFloatVector(-BoxExtent.X, BoxExtent.Y, BoxExtent.Z), // BRU
  53. FUnrealFloatVector(-BoxExtent.X, BoxExtent.Y, -BoxExtent.Z), // BRD
  54. FUnrealFloatVector(0.0f, BoxExtent.Y, -BoxExtent.Z), // RD
  55. FUnrealFloatVector(0.0f, BoxExtent.Y, BoxExtent.Z) // RU
  56. });
  57. // add vertices using front - back, right - left, up - down winding.
  58. MeshBuilderFront.AddTriangles
  59. ({
  60. /*front face*/0, 3, 2, 0, 2, 1,
  61. /*back face*/4, 7, 6, 4, 6, 5,
  62. /*top face*/0, 3, 7, 0, 7, 4,
  63. /*bottom face*/1, 2, 6, 1, 6, 5
  64. });
  65. MeshBuilderBack.AddTriangles
  66. ({
  67. /*front face*/0, 3, 2, 0, 2, 1,
  68. /*back face*/4, 7, 6, 4, 6, 5,
  69. /*top face*/0, 3, 7, 0, 7, 4,
  70. /*bottom face*/1, 2, 6, 1, 6, 5
  71. });
  72. // Allocate the material proxy and register it so it can be deleted properly once the rendering is done with it.
  73. auto* renderProxy = GEngine->GeomMaterial->GetRenderProxy();
  74. FLinearColor FrontDrawColor;
  75. FLinearColor BackDrawColor;
  76. AkSpatialAudioColors::GetPortalColors(PortalComponent, FrontDrawColor, BackDrawColor);
  77. FDynamicColoredMaterialRenderProxy* ColorInstanceFront = new FDynamicColoredMaterialRenderProxy(renderProxy, FrontDrawColor);
  78. PDI->RegisterDynamicResource(ColorInstanceFront);
  79. MeshBuilderFront.Draw(PDI, PrimitiveParent->GetComponentToWorld().ToMatrixWithScale(), ColorInstanceFront, SDPG_World, true, false);
  80. FDynamicColoredMaterialRenderProxy* ColorInstanceBack = new FDynamicColoredMaterialRenderProxy(renderProxy, BackDrawColor);
  81. PDI->RegisterDynamicResource(ColorInstanceBack);
  82. MeshBuilderBack.Draw(PDI, PrimitiveParent->GetComponentToWorld().ToMatrixWithScale(), ColorInstanceBack, SDPG_World, true, false);
  83. // Draw an outline around the centre of the portal, to distinguish front and back
  84. const FTransform& T = PrimitiveParent->GetComponentTransform();
  85. AkDrawBounds DrawBounds(T, BoxExtent);
  86. const float Thickness = AkDrawConstants::PortalRoomConnectionThickness;
  87. const FLinearColor OutlineColor = AkSpatialAudioColors::GetPortalOutlineColor(PortalComponent);
  88. PDI->DrawLine(DrawBounds.RU(), DrawBounds.LU(), OutlineColor, SDPG_Foreground, Thickness);
  89. PDI->DrawLine(DrawBounds.LU(), DrawBounds.LD(), OutlineColor, SDPG_Foreground, Thickness);
  90. PDI->DrawLine(DrawBounds.LD(), DrawBounds.RD(), OutlineColor, SDPG_Foreground, Thickness);
  91. PDI->DrawLine(DrawBounds.RD(), DrawBounds.RU(), OutlineColor, SDPG_Foreground, Thickness);
  92. // Draw a line from back room to front room.
  93. FVector Front = FVector(BoxExtent.X, 0.0f, 0.0f);
  94. FVector Back = FVector(-BoxExtent.X, 0.0f, 0.0f);
  95. PDI->DrawLine(T.TransformPosition(Back), T.TransformPosition(Front), OutlineColor, SDPG_Foreground, Thickness);
  96. // draw a diagonal on left and right faces if the portal is closed
  97. if (PortalComponent->InitialState == AkAcousticPortalState::Closed)
  98. {
  99. PDI->DrawLine(DrawBounds.FRU(), DrawBounds.BRD(), FrontDrawColor, SDPG_Foreground, Thickness);
  100. PDI->DrawLine(DrawBounds.FLD(), DrawBounds.BLU(), BackDrawColor, SDPG_Foreground, Thickness);
  101. }
  102. PortalComponent->UpdateTextRotations();
  103. }
  104. if (GEditor->GetSelectedActorCount() == 1 && IsValid(PortalComponent))
  105. {
  106. AAkAcousticPortal* pPortal = Cast<AAkAcousticPortal>(PortalComponent->GetOwner());
  107. if (pPortal && pPortal->GetFitToGeometry() && pPortal->GetIsDragging())
  108. {
  109. FVector Point0, End0, Point1, End1;
  110. if (pPortal->GetBestHits(Point0, End0, Point1, End1))
  111. {
  112. FVector Dir0 = End0 - Point0;
  113. float L0 = Dir0.SizeSquared();
  114. FVector Dir1 = End1 - Point1;
  115. float L1 = Dir1.SizeSquared();
  116. FVector V01 = Point1 - Point0;
  117. FVector TL0 = Point1 - FVector::DotProduct(V01, Dir0) * Dir0 / L0;
  118. FVector TL1 = Point0 - FVector::DotProduct(-V01, Dir1) * Dir1 / L1;
  119. FVector TL = (TL0 + TL1) / 2.f;
  120. FVector TR = TL + Dir0;
  121. FVector BL = TL + Dir1;
  122. FVector BR = BL + Dir0;
  123. const FLinearColor PreviewColor = FAkAppStyle::Get().GetSlateColor("SelectionColor").GetSpecifiedColor() * 1.3f;
  124. PDI->DrawLine(TL, TR, PreviewColor, 100, 5.f, 50.f);
  125. PDI->DrawLine(TR, BR, PreviewColor, 100, 5.f, 50.f);
  126. PDI->DrawLine(BR, BL, PreviewColor, 100, 5.f, 50.f);
  127. PDI->DrawLine(BL, TL, PreviewColor, 100, 5.f, 50.f);
  128. }
  129. }
  130. }
  131. }