123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269 |
- /*******************************************************************************
- The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
- Technology released in source code form as part of the game integration package.
- The content of this file may not be used without valid licenses to the
- AUDIOKINETIC Wwise Technology.
- Note that the use of the game engine is subject to the Unreal(R) Engine End User
- License Agreement at https://www.unrealengine.com/en-US/eula/unreal
-
- License Usage
-
- Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
- this file in accordance with the end user license agreement provided with the
- software or, alternatively, in accordance with the terms contained
- in a written agreement between you and Audiokinetic Inc.
- Copyright (c) 2023 Audiokinetic Inc.
- *******************************************************************************/
- #pragma once
- #include "Components/TextRenderComponent.h"
- #include "GameFramework/Volume.h"
- #include "ObstructionAndOcclusionService/AkPortalObstructionAndOcclusionService.h"
- #include "AkGameplayTypes.h"
- #if WITH_EDITOR
- #include "AkSettings.h"
- #endif
- #include "AkAcousticPortal.generated.h"
- class UAkRoomComponent;
- class UAkLateReverbComponent;
- UCLASS(ClassGroup = Audiokinetic, hidecategories = (Advanced, Attachment, Volume), BlueprintType, meta = (BlueprintSpawnableComponent))
- class AKAUDIO_API UAkPortalComponent : public USceneComponent
- {
- GENERATED_BODY()
- public:
- UAkPortalComponent(const class FObjectInitializer& ObjectInitializer);
- UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkPortalComponent")
- void OpenPortal();
- UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkPortalComponent")
- void ClosePortal();
- UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkPortalComponent")
- AkAcousticPortalState GetCurrentState() const;
- UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkPortalComponent")
- UPrimitiveComponent* GetPrimitiveParent() const;
- UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkPortalComponent")
- bool PortalPlacementValid() const { return GetFrontRoom() != GetBackRoom(); }
- /** If true, the room connections for this portal can change during runtime when this portal moves. For worlds containing many rooms, this can be expensive. Note that this portal's room connections may still change, even when bDynamic = false, when dynamic rooms are moved (i.e. when rooms move who have bDynamic = true). */
- UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AkPortalComponent", meta = (DisplayName = "Is Dynamic"))
- bool bDynamic = false;
- UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "AkPortalComponent")
- AkAcousticPortalState InitialState = AkAcousticPortalState::Open;
- /** Time interval between obstruction checks (direct line of sight between listener and portal opening). Set to 0 to disable obstruction checks. We recommend disabling it if you want to use full Spatial Audio diffraction. */
- UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AkPortalComponent|Obstruction")
- float ObstructionRefreshInterval = .0f;
- /** Collision channel for obstruction checks (between listener and portal opening). */
- UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AkPortalComponent|Obstruction")
- TEnumAsByte<ECollisionChannel> ObstructionCollisionChannel = ECollisionChannel::ECC_Visibility;
- void ResetPortalState();
- FVector GetExtent() const;
- AkRoomID GetFrontRoom() const;
- AkRoomID GetBackRoom() const;
- AkPortalID GetPortalID() const { return AkPortalID(this); }
- /** Update the room connections for the portal, given the portals current transform.
- Return true if the room connections have changed.
- */
- bool UpdateConnectedRooms();
- const UAkRoomComponent* GetFrontRoomComponent() const { return FrontRoom; }
- const UAkRoomComponent* GetBackRoomComponent() const { return BackRoom; }
- virtual void BeginPlay() override;
- #if WITH_EDITOR
- virtual void BeginDestroy() override;
- virtual void InitializeComponent() override;
- virtual void OnComponentCreated() override;
- virtual void PostLoad() override;
- virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
- void UpdateTextRotations() const;
- #endif // WITH_EDITOR
- virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction) override;
- virtual void OnRegister() override;
- virtual void OnUnregister() override;
- virtual void OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport) override;
- virtual bool MoveComponentImpl(
- const FVector & Delta,
- const FQuat & NewRotation,
- bool bSweep,
- FHitResult * Hit,
- EMoveComponentFlags MoveFlags,
- ETeleportType Teleport) override;
- private:
- class UPrimitiveComponent* Parent;
- void InitializeParent();
- void SetSpatialAudioPortal();
- template <typename tComponent>
- void FindConnectedComponents(FAkEnvironmentIndex& RoomQuery, tComponent*& out_pFront, tComponent*& out_pBack);
- AkAcousticPortalState PortalState;
- #if WITH_EDITOR
- static const float RoomsRefreshIntervalEditor;
- #endif
- static const float RoomsRefreshIntervalGame;
- static const float RoomsRefreshDistanceThreshold;
- static const float RoomsRefreshMinRotationThreshold_Degrees;
- float RoomsRefreshIntervalSeconds = 0.5f;
- float LastRoomsUpdate = 0.0f;
- FVector PreviousLocation;
- FRotator PreviousRotation;
- bool PortalNeedUpdated = false;
- UAkRoomComponent* FrontRoom;
- UAkRoomComponent* BackRoom;
- AkPortalObstructionAndOcclusionService ObstructionService;
- #if WITH_EDITOR
- void HandleObjectsReplaced(const TMap<UObject*, UObject*>& ReplacementMap);
- class UDrawPortalComponent* DrawPortalComponent = nullptr;
- void RegisterVisEnabledCallback();
- void InitializeDrawComponent();
- void DestroyDrawComponent();
- FDelegateHandle ShowPortalsChangedHandle;
- bool AreTextVisualizersInitialized() const;
- void InitTextVisualizers();
- void DestroyTextVisualizers();
- void UpdateRoomNames();
- void UpdateTextVisibility();
- // Updates the location, rotation and visibility of the text visualizers
- void UpdateTextLocRotVis();
- bool bWasSelected = false;
- #endif
- #if WITH_EDITORONLY_DATA
- UPROPERTY(SkipSerialization, NonTransactional)
- mutable UTextRenderComponent* FrontRoomText = nullptr;
- UPROPERTY(SkipSerialization, NonTransactional)
- mutable UTextRenderComponent* BackRoomText = nullptr;
- #endif
- };
- UCLASS(ClassGroup = Audiokinetic, hidecategories = (Advanced, Attachment, Volume), BlueprintType)
- class AKAUDIO_API AAkAcousticPortal : public AVolume
- {
- GENERATED_BODY()
- public:
- AAkAcousticPortal(const class FObjectInitializer& ObjectInitializer);
- UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkAcousticPortal")
- void OpenPortal();
- UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkAcousticPortal")
- void ClosePortal();
- UFUNCTION(BlueprintCallable, Category = "Audiokinetic|AkAcousticPortal")
- AkAcousticPortalState GetCurrentState() const;
- AkRoomID GetFrontRoom() const;
- AkRoomID GetBackRoom() const;
- UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Portal", meta = (ShowOnlyInnerProperties))
- UAkPortalComponent* Portal = nullptr;
- virtual void PostRegisterAllComponents() override;
- virtual void PostLoad() override;
- virtual void Serialize(FArchive& Ar) override;
- #if WITH_EDITOR
- void FitRaycast();
- void FitPortal();
- virtual void PostEditMove(bool bFinished) override;
- virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
- bool GetBestHits(FVector& Start0, FVector& End0, FVector& Start1, FVector& End1)
- {
- if (BestFitValid)
- {
- Start0 = BestFit[0];
- End0 = BestFit[1];
- Start1 = BestFit[2];
- End1 = BestFit[3];
-
- return true;
- }
- return false;
- }
- float GetDetectionRadius() const { return DetectionRadius; }
- bool GetFitToGeometry() const { return FitToGeometry; }
- bool GetIsDragging() const { return IsDragging; }
- virtual FName GetCustomIconName() const override
- {
- static const FName IconName("ClassIcon.AkAcousticPortal");
- return IconName;
- }
- #endif
- protected:
- static const int kNumRaycasts = 128;
- #if WITH_EDITORONLY_DATA
- void ClearBestFit();
- /**
- Automatically fit the Ak Acoustic Portal to surrounding geometry. The fitting operation is performed after enabling this property, or after moving the actor to a new location.
- To find portals in surrounding geometry, rays emanating spherically outwards are cast from the origin of the actor in an attempt to detect sets of parallel surfaces.
- The "best" detected parallel surfaces are indicated with yellow outline when dragging the actor to a new location.
- */
- UPROPERTY(EditAnywhere, Category = "Fit to Geometry")
- bool FitToGeometry = false;
- /**
- Sets the collision channel for the ray traces performed to fit the portal to the surrounding geometry. When set to 'Use Integration Settings Default', the value will be taken from the DefaultFitToGeometryCollisionChannel in the Wwise Integration Settings.
- */
- UPROPERTY(EditAnywhere, Category = "Fit to Geometry")
- TEnumAsByte<EAkCollisionChannel> CollisionChannel = { EAkCollisionChannel::EAKCC_UseIntegrationSettingsDefault };
- #if WITH_EDITOR
- /**
- Converts between EAkCollisionChannel and ECollisionChannel. Returns Wwise Integration Settings default if CollisionChannel == UseIntegrationSettingsDefault. Otherwise, casts CollisionChannel to ECollisionChannel.
- */
- UFUNCTION(BlueprintCallable, Category = "Fit to Geometry")
- ECollisionChannel GetCollisionChannel();
- #endif
- /**
- Limits the effective portal opening size that can be detected when fitting the portal to surrounding geometry.
- Increase this value to find larger openings; decrease it if large portals are erroneously detected, for example ones that span whole rooms.
- The slider range can be expanded by entering a text value into this field.
- */
- UPROPERTY(EditAnywhere, Category = "Fit to Geometry", meta = (ClampMin = 1.0f, ClampMax = 100000.0f, UIMin = 100.0f, UIMax = 5000.0f))
- float DetectionRadius = 500.0f;
- FVector SavedRaycastOrigin;
- bool bUseSavedRaycastOrigin = false;
- FVector BestFit[4];
- bool BestFitValid = false;
- bool IsDragging = false;
- #endif
- private:
- /** As of Wwise 2020.1, the InitialState is contained in the AkPortalComponent */
- UPROPERTY()
- AkAcousticPortalState InitialState;
- UPROPERTY(Transient)
- bool bRequiresStateMigration = false;
- bool bRequiresTransformMigration = false;
- };
|