/* * Copyright (c) <2021> Side Effects Software Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. The name of Side Effects Software may not be used to endorse or * promote products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include "CoreMinimal.h" #include "UObject/ObjectMacros.h" #include "HoudiniEngineRuntimeCommon.h" #include "HoudiniEngineRuntimeUtils.h" #include "HoudiniRuntimeSettings.h" #include "HoudiniOutput.h" #include "HoudiniInputTypes.h" #include "HoudiniPluginSerializationVersion.h" #include "HoudiniAssetStateTypes.h" #include "IHoudiniAssetStateEvents.h" #include "Engine/EngineTypes.h" #include "Components/PrimitiveComponent.h" #include "Components/SceneComponent.h" #include "HoudiniAssetComponent.generated.h" class UHoudiniAsset; class UHoudiniParameter; class UHoudiniInput; class UHoudiniOutput; class UHoudiniHandleComponent; class UHoudiniPDGAssetLink; class UHoudiniAssetComponent_V1; UENUM() enum class EHoudiniStaticMeshMethod : uint8 { // Static Meshes will be generated by using Raw Meshes. RawMesh, // Static Meshes will be generated by using Mesh Descriptions. FMeshDescription, // Always build Houdini Proxy Meshes (dev) UHoudiniStaticMesh, }; class UHoudiniAssetComponent; DECLARE_MULTICAST_DELEGATE_OneParam(FHoudiniAssetEvent, UHoudiniAsset*); DECLARE_MULTICAST_DELEGATE_OneParam(FHoudiniAssetComponentEvent, UHoudiniAssetComponent*) UCLASS(ClassGroup = (Rendering, Common), hidecategories = (Object, Activation, "Components|Activation"), ShowCategories = (Mobility), editinlinenew) class HOUDINIENGINERUNTIME_API UHoudiniAssetComponent : public UPrimitiveComponent, public IHoudiniAssetStateEvents { GENERATED_UCLASS_BODY() // Declare translators as friend so they can easily directly modify // Inputs, outputs and parameters friend class FHoudiniEngineManager; friend struct FHoudiniOutputTranslator; friend struct FHoudiniInputTranslator; friend struct FHoudiniSplineTranslator; friend struct FHoudiniParameterTranslator; friend struct FHoudiniPDGManager; friend struct FHoudiniHandleTranslator; #if WITH_EDITORONLY_DATA friend class FHoudiniAssetComponentDetails; #endif public: // Declare the delegate that is broadcast when RefineMeshesTimer fires DECLARE_MULTICAST_DELEGATE_OneParam(FOnRefineMeshesTimerDelegate, UHoudiniAssetComponent*); DECLARE_DELEGATE_RetVal_OneParam(bool, FOnPostCookBakeDelegate, UHoudiniAssetComponent*); // Delegate for when EHoudiniAssetState changes from InFromState to InToState on a Houdini Asset Component (InHAC). DECLARE_MULTICAST_DELEGATE_ThreeParams(FOnAssetStateChangeDelegate, UHoudiniAssetComponent*, const EHoudiniAssetState, const EHoudiniAssetState); DECLARE_MULTICAST_DELEGATE_TwoParams(FOnPostCookDelegate, UHoudiniAssetComponent*, bool); DECLARE_MULTICAST_DELEGATE_TwoParams(FOnPostBakeDelegate, UHoudiniAssetComponent*, bool); virtual ~UHoudiniAssetComponent(); virtual void Serialize(FArchive & Ar) override; virtual bool ConvertLegacyData(); // Called after the C++ constructor and after the properties have been initialized, including those loaded from config. // This is called before any serialization or other setup has happened. virtual void PostInitProperties() override; // Returns the Owner actor / HAC name FString GetDisplayName() const; // Indicates if the HAC needs to be updated bool NeedUpdate() const; // Indicates if the HAC's transform needs to be updated bool NeedTransformUpdate() const { return (bHasComponentTransformChanged && bUploadTransformsToHoudiniEngine); }; // Indicates if any of the HAC's output components needs to be updated (no recook needed) bool NeedOutputUpdate() const; // Check whether any inputs / outputs / parameters have made blueprint modifications. bool NeedBlueprintStructureUpdate() const; bool NeedBlueprintUpdate() const; // Prevents automatic triggering of updates on this HAC in its current state. // This is to prevent endless cook/instantiation loops when an issue happens void PreventAutoUpdates(); // Try to find one of our parameter that matches another (name, type, size and enabled) UHoudiniParameter* FindMatchingParameter(UHoudiniParameter* InOtherParam); // Try to find one of our input that matches another one (name, isobjpath, index / parmId) UHoudiniInput* FindMatchingInput(UHoudiniInput* InOtherInput); // Try to find one of our handle that matches another one (name and handle type) UHoudiniHandleComponent* FindMatchingHandle(UHoudiniHandleComponent* InOtherHandle); // Finds a parameter by name UHoudiniParameter* FindParameterByName(const FString& InParamName); // Returns True if the component has at least one mesh output of class U template bool HasMeshOutputObjectOfClass() const; // Returns True if the component has at least one mesh output with a current proxy bool HasAnyCurrentProxyOutput() const; // Returns True if the component has at least one proxy mesh output (not necessarily current/displayed) bool HasAnyProxyOutput() const; // Returns True if the component has at least one non-proxy output component amongst its outputs bool HasAnyOutputComponent() const; // Returns true if the component has InOutputObjectToFind in its output object bool HasOutputObject(UObject* InOutputObjectToFind) const; //------------------------------------------------------------------------------------------------ // Accessors //------------------------------------------------------------------------------------------------ UHoudiniAsset * GetHoudiniAsset() const; int32 GetAssetId() const { return AssetId; }; EHoudiniAssetState GetAssetState() const { return AssetState; }; FString GetAssetStateAsString() const { return FHoudiniEngineRuntimeUtils::EnumToString(TEXT("EHoudiniAssetState"), GetAssetState()); }; EHoudiniAssetStateResult GetAssetStateResult() const { return AssetStateResult; }; FGuid GetHapiGUID() const { return HapiGUID; }; FString GetHapiAssetName() const { return HapiAssetName; }; FGuid GetComponentGUID() const { return ComponentGUID; }; int32 GetNumInputs() const { return Inputs.Num(); }; int32 GetNumOutputs() const { return Outputs.Num(); }; int32 GetNumParameters() const { return Parameters.Num(); }; int32 GetNumHandles() const { return HandleComponents.Num(); }; UHoudiniInput* GetInputAt(const int32& Idx) { return Inputs.IsValidIndex(Idx) ? Inputs[Idx] : nullptr; }; UHoudiniOutput* GetOutputAt(const int32& Idx) { return Outputs.IsValidIndex(Idx) ? Outputs[Idx] : nullptr;}; UHoudiniParameter* GetParameterAt(const int32& Idx) { return Parameters.IsValidIndex(Idx) ? Parameters[Idx] : nullptr;}; UHoudiniHandleComponent* GetHandleComponentAt(const int32& Idx) { return HandleComponents.IsValidIndex(Idx) ? HandleComponents[Idx] : nullptr; }; void GetOutputs(TArray& OutOutputs) const; TArray& GetBakedOutputs() { return BakedOutputs; } const TArray& GetBakedOutputs() const { return BakedOutputs; } /* TArray& GetParameters() { return Parameters; }; TArray& GetInputs() { return Inputs; }; TArray& GetOutputs() { return Outputs; }; */ bool IsCookingEnabled() const { return bEnableCooking; }; bool HasBeenLoaded() const { return bHasBeenLoaded; }; bool HasBeenDuplicated() const { return bHasBeenDuplicated; }; bool HasRecookBeenRequested() const { return bRecookRequested; }; bool HasRebuildBeenRequested() const { return bRebuildRequested; }; //bool GetEditorPropertiesNeedFullUpdate() const { return bEditorPropertiesNeedFullUpdate; }; int32 GetAssetCookCount() const { return AssetCookCount; }; bool IsFullyLoaded() const { return bFullyLoaded; }; UHoudiniPDGAssetLink * GetPDGAssetLink() const { return PDGAssetLink; }; virtual bool IsProxyStaticMeshEnabled() const; bool IsProxyStaticMeshRefinementByTimerEnabled() const; float GetProxyMeshAutoRefineTimeoutSeconds() const; bool IsProxyStaticMeshRefinementOnPreSaveWorldEnabled() const; bool IsProxyStaticMeshRefinementOnPreBeginPIEEnabled() const; // If true, then the next cook should not build proxy meshes, regardless of global or override settings, // but should instead directly build UStaticMesh bool HasNoProxyMeshNextCookBeenRequested() const { return bNoProxyMeshNextCookRequested; } // Returns true if the asset state indicates that it has been cooked in this session, false otherwise. bool IsHoudiniCookedDataAvailable(bool &bOutNeedsRebuildOrDelete, bool &bOutInvalidState) const; // Returns true if the asset should be bake after the next cook bool IsBakeAfterNextCookEnabled() const { return bBakeAfterNextCook; } FOnPostCookDelegate& GetOnPostCookDelegate() { return OnPostCookDelegate; } FOnPostCookBakeDelegate& GetOnPostCookBakeDelegate() { return OnPostCookBakeDelegate; } FOnPostBakeDelegate& GetOnPostBakeDelegate() { return OnPostBakeDelegate; } FOnAssetStateChangeDelegate& GetOnAssetStateChangeDelegate() { return OnAssetStateChangeDelegate; } // Derived blueprint based components will check whether the template // component contains updates that needs to processed. bool NeedUpdateParameters() const; bool NeedUpdateInputs() const; // Returns true if the component has any previous baked output recorded in its outputs bool HasPreviousBakeOutput() const; // Returns true if the last cook of the HDA was successful bool WasLastCookSuccessful() const { return bLastCookSuccess; } // Returns true if a parameter definition update (excluding values) is needed. bool IsParameterDefinitionUpdateNeeded() const { return bParameterDefinitionUpdateNeeded; } //------------------------------------------------------------------------------------------------ // Mutators //------------------------------------------------------------------------------------------------ //void SetAssetId(const int& InAssetId); //void SetAssetState(const EHoudiniAssetState& InAssetState) { AssetState = InAssetState; }; //void SetAssetStateResult(const EHoudiniAssetStateResult& InAssetStateResult) { AssetStateResult = InAssetStateResult; }; //void SetHapiGUID(const FGuid& InGUID) { HapiGUID = InGUID; }; //void SetComponentGUID(const FGuid& InGUID) { ComponentGUID = InGUID; }; //UFUNCTION(BlueprintSetter) virtual void SetHoudiniAsset(UHoudiniAsset * NewHoudiniAsset); void SetCookingEnabled(const bool& bInCookingEnabled) { bEnableCooking = bInCookingEnabled; }; void SetHasBeenLoaded(const bool& InLoaded) { bHasBeenLoaded = InLoaded; }; void SetHasBeenDuplicated(const bool& InDuplicated) { bHasBeenDuplicated = InDuplicated; }; //void SetEditorPropertiesNeedFullUpdate(const bool& InUpdate) { bEditorPropertiesNeedFullUpdate = InUpdate; }; // Marks the assets as needing a recook void MarkAsNeedCook(); // Marks the assets as needing a full rebuild void MarkAsNeedRebuild(); // Marks the asset as needing to be instantiated void MarkAsNeedInstantiation(); // The blueprint has been structurally modified void MarkAsBlueprintStructureModified(); // The blueprint has been modified but not structurally changed. void MarkAsBlueprintModified(); // void SetAssetCookCount(const int32& InCount) { AssetCookCount = InCount; }; // void SetRecookRequested(const bool& InRecook) { bRecookRequested = InRecook; }; // void SetRebuildRequested(const bool& InRebuild) { bRebuildRequested = InRebuild; }; // void SetHasComponentTransformChanged(const bool& InHasChanged); // Set to True to force the next cook to not build a proxy mesh (regardless of global or override settings) and // instead build a UStaticMesh directly (if applicable for the output type). void SetNoProxyMeshNextCookRequested(bool bInNoProxyMeshNextCookRequested) { bNoProxyMeshNextCookRequested = bInNoProxyMeshNextCookRequested; } // Set to True to force the next cook to bake the asset after the cook completes. void SetBakeAfterNextCookEnabled(bool bInEnabled) { bBakeAfterNextCook = bInEnabled; } // void SetPDGAssetLink(UHoudiniPDGAssetLink* InPDGAssetLink); // virtual void OnHoudiniAssetChanged(); // void AddDownstreamHoudiniAsset(UHoudiniAssetComponent* InDownstreamAsset) { DownstreamHoudiniAssets.Add(InDownstreamAsset); }; // void RemoveDownstreamHoudiniAsset(UHoudiniAssetComponent* InRemoveDownstreamAsset) { DownstreamHoudiniAssets.Remove(InRemoveDownstreamAsset); }; // void ClearDownstreamHoudiniAsset() { DownstreamHoudiniAssets.Empty(); }; // bool NotifyCookedToDownstreamAssets(); // bool NeedsToWaitForInputHoudiniAssets(); // Clear/disable the RefineMeshesTimer. void ClearRefineMeshesTimer(); // Re-set the RefineMeshesTimer to its default value. void SetRefineMeshesTimer(); virtual void OnRefineMeshesTimerFired(); // Called by RefineMeshesTimer when the timer is triggered. // Checks for any UHoudiniStaticMesh in Outputs and bakes UStaticMesh for them via FHoudiniMeshTranslator. FOnRefineMeshesTimerDelegate& GetOnRefineMeshesTimerDelegate() { return OnRefineMeshesTimerDelegate; } // Returns true if the asset is valid for cook/bake virtual bool IsComponentValid() const; // Return false if this component has no cooking or instantiation in progress. bool IsInstantiatingOrCooking() const; // HoudiniEngineTick will be called by HoudiniEngineManager::Tick() virtual void HoudiniEngineTick(); #if WITH_EDITOR // This alternate version of PostEditChange is called when properties inside structs are modified. The property that was actually modified // is located at the tail of the list. The head of the list of the FStructProperty member variable that contains the property that was modified. virtual void PostEditChangeProperty(FPropertyChangedEvent & PropertyChangedEvent) override; //Called after applying a transaction to the object. Default implementation simply calls PostEditChange. virtual void PostEditUndo() override; // Whether this component is currently open in a Blueprint editor. This // method is overridden by HoudiniAssetBlueprintComponent. virtual bool HasOpenEditor() const { return false; }; #endif void SetStaticMeshGenerationProperties(UStaticMesh* InStaticMesh) const; virtual void RegisterHoudiniComponent(UHoudiniAssetComponent* InComponent); virtual void OnRegister() override; // USceneComponent methods. virtual FBoxSphereBounds CalcBounds(const FTransform & LocalToWorld) const override; virtual void OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport) override; FBox GetAssetBounds(UHoudiniInput* IgnoreInput, const bool& bIgnoreGeneratedLandscape) const; // Set this component's input presets void SetInputPresets(const TMap& InPresets); // Apply the preset input for HoudiniTools void ApplyInputPresets(); // return the cached component template, if available. virtual UHoudiniAssetComponent* GetCachedTemplate() const { return nullptr; } virtual FPrimitiveSceneProxy* CreateSceneProxy() override; //------------------------------------------------------------------------------------------------ // Supported Features //------------------------------------------------------------------------------------------------ // Whether or not this component should be able to delete the Houdini nodes // that correspond to the HoudiniAsset when being deregistered. virtual bool CanDeleteHoudiniNodes() const { return true; } virtual bool IsInputTypeSupported(EHoudiniInputType InType) const; virtual bool IsOutputTypeSupported(EHoudiniOutputType InType) const; //------------------------------------------------------------------------------------------------5 // Characteristics //------------------------------------------------------------------------------------------------ // Try to determine whether this component belongs to a preview actor. // Preview / Template components need to sync their data for HDA cooks and output translations. bool IsPreview() const; virtual bool IsValidComponent() const; //------------------------------------------------------------------------------------------------ // Notifications //------------------------------------------------------------------------------------------------ // TODO: After the cook worfklow rework, most of these won't be needed anymore, so clean up! //FHoudiniAssetComponentEvent OnTemplateParametersChanged; //FHoudiniAssetComponentEvent OnPreAssetCook; //FHoudiniAssetComponentEvent OnCookCompleted; //FHoudiniAssetComponentEvent OnOutputProcessingCompleted; /*virtual void BroadcastParametersChanged(); virtual void BroadcastPreAssetCook(); virtual void BroadcastCookCompleted();*/ virtual void OnPrePreCook() {}; virtual void OnPostPreCook() {}; virtual void OnPreOutputProcessing() {}; virtual void OnPostOutputProcessing() {}; virtual void OnPrePreInstantiation() {}; virtual void NotifyHoudiniRegisterCompleted() {}; virtual void NotifyHoudiniPreUnregister() {}; virtual void NotifyHoudiniPostUnregister() {}; virtual void OnFullyLoaded(); // Component template parameters have been updated. // Broadcast delegate, and let preview components take care of the rest. virtual void OnTemplateParametersChanged() { }; virtual void OnBlueprintStructureModified() { }; virtual void OnBlueprintModified() { }; // // Begin: IHoudiniAssetStateEvents // virtual void HandleOnHoudiniAssetStateChange(UObject* InHoudiniAssetContext, const EHoudiniAssetState InFromState, const EHoudiniAssetState InToState) override; FORCEINLINE virtual FOnHoudiniAssetStateChange& GetOnHoudiniAssetStateChangeDelegate() override { return OnHoudiniAssetStateChangeDelegate; } // // End: IHoudiniAssetStateEvents // // Called by HandleOnHoudiniAssetStateChange when entering the PostCook state. Broadcasts OnPostCookDelegate. void HandleOnPostCook(); // Called by baking code after baking all outputs of this HAC (HoudiniEngineBakeOption) void HandleOnPostBake(const bool bInSuccess); protected: // UActorComponents Method virtual void OnComponentCreated() override; virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; virtual void OnChildAttached(USceneComponent* ChildComponent) override; virtual void BeginDestroy() override; // virtual void CreateRenderState_Concurrent(FRegisterComponentContext* Context) override; // Do any object - specific cleanup required immediately after loading an object. // This is not called for newly - created objects, and by default will always execute on the game thread. virtual void PostLoad() override; // Called after importing property values for this object (paste, duplicate or .t3d import) // Allow the object to perform any cleanup for properties which shouldn't be duplicated or // Are unsupported by the script serialization virtual void PostEditImport() override; // void OnActorMoved(AActor* Actor); // void UpdatePostDuplicate(); // //static void AddReferencedObjects(UObject * InThis, FReferenceCollector & Collector); // Updates physics state, bounds, and mark render state dirty // Should be call PostLoad and PostProcessing void UpdateRenderingInformation(); // Mutators // Set asset state void SetAssetState(EHoudiniAssetState InNewState); public: // Houdini Asset associated with this component. /*Category = HoudiniAsset, EditAnywhere, meta = (DisplayPriority=0)*/ UPROPERTY(Category = HoudiniAsset, EditAnywhere)// BlueprintSetter = SetHoudiniAsset, BlueprintReadWrite, ) UHoudiniAsset* HoudiniAsset; // Automatically cook when a parameter or input is changed UPROPERTY() bool bCookOnParameterChange; // Enables uploading of transformation changes back to Houdini Engine. UPROPERTY() bool bUploadTransformsToHoudiniEngine; // Transform changes automatically trigger cooks. UPROPERTY() bool bCookOnTransformChange; // Houdini materials will be converted to Unreal Materials. //UPROPERTY() //bool bUseNativeHoudiniMaterials; // This asset will cook when its asset input cook UPROPERTY() bool bCookOnAssetInputCook; // Enabling this will prevent the HDA from producing any output after cooking. UPROPERTY() bool bOutputless; // Enabling this will allow outputing the asset's templated geos UPROPERTY() bool bOutputTemplateGeos; // Enabling this will allow outputing the asset's output nodes UPROPERTY() bool bUseOutputNodes; // Temporary cook folder UPROPERTY() FDirectoryPath TemporaryCookFolder; // Folder used for baking this asset's outputs (unless set by prim/detail attribute on the output). Falls back to // the default from the plugin settings if not set. UPROPERTY() FDirectoryPath BakeFolder; // The method used to create Static Meshes UPROPERTY(Category = "HoudiniMeshGeneration", EditAnywhere, meta = (DisplayPriority = 0)) EHoudiniStaticMeshMethod StaticMeshMethod; // Generation properties for the Static Meshes generated by this Houdini Asset UPROPERTY(Category = "HoudiniMeshGeneration", EditAnywhere, meta = (DisplayPriority = 1)/*, meta = (ShowOnlyInnerProperties)*/) FHoudiniStaticMeshGenerationProperties StaticMeshGenerationProperties; // Build Settings to be used when generating the Static Meshes for this Houdini Asset UPROPERTY(Category = "HoudiniMeshGeneration", EditAnywhere, meta = (DisplayPriority = 2)) FMeshBuildSettings StaticMeshBuildSettings; // Override the global fast proxy mesh settings on this component? UPROPERTY(Category = "HoudiniProxyMeshGeneration", EditAnywhere/*, meta = (DisplayAfter = "StaticMeshGenerationProperties")*/) bool bOverrideGlobalProxyStaticMeshSettings; // For StaticMesh outputs: should a fast proxy be created first? UPROPERTY(Category = "HoudiniProxyMeshGeneration", EditAnywhere, meta = (DisplayName="Enable Proxy Static Mesh", EditCondition="bOverrideGlobalProxyStaticMeshSettings")) bool bEnableProxyStaticMeshOverride; // If fast proxy meshes are being created, must it be baked as a StaticMesh after a period of no updates? UPROPERTY(Category = "HoudiniProxyMeshGeneration", EditAnywhere, meta = (DisplayName="Refine Proxy Static Meshes After a Timeout", EditCondition = "bOverrideGlobalProxyStaticMeshSettings && bEnableProxyStaticMeshOverride")) bool bEnableProxyStaticMeshRefinementByTimerOverride; // If the option to automatically refine the proxy mesh via a timer has been selected, this controls the timeout in seconds. UPROPERTY(Category = "HoudiniProxyMeshGeneration", EditAnywhere, meta = (DisplayName="Proxy Mesh Auto Refine Timeout Seconds", EditCondition = "bOverrideGlobalProxyStaticMeshSettings && bEnableProxyStaticMeshOverride && bEnableProxyStaticMeshRefinementByTimerOverride")) float ProxyMeshAutoRefineTimeoutSecondsOverride; // Automatically refine proxy meshes to UStaticMesh before the map is saved UPROPERTY(Category = "HoudiniProxyMeshGeneration", EditAnywhere, meta = (DisplayName="Refine Proxy Static Meshes When Saving a Map", EditCondition = "bOverrideGlobalProxyStaticMeshSettings && bEnableProxyStaticMeshOverride")) bool bEnableProxyStaticMeshRefinementOnPreSaveWorldOverride; // Automatically refine proxy meshes to UStaticMesh before starting a play in editor session UPROPERTY(Category = "HoudiniProxyMeshGeneration", EditAnywhere, meta = (DisplayName="Refine Proxy Static Meshes On PIE", EditCondition = "bOverrideGlobalProxyStaticMeshSettings && bEnableProxyStaticMeshOverride")) bool bEnableProxyStaticMeshRefinementOnPreBeginPIEOverride; #if WITH_EDITORONLY_DATA UPROPERTY() bool bGenerateMenuExpanded; UPROPERTY() bool bBakeMenuExpanded; UPROPERTY() bool bAssetOptionMenuExpanded; UPROPERTY() bool bHelpAndDebugMenuExpanded; UPROPERTY() EHoudiniEngineBakeOption HoudiniEngineBakeOption; // If true, then after a successful bake, the HACs outputs will be cleared and removed. UPROPERTY() bool bRemoveOutputAfterBake; // If true, recenter baked actors to their bounding box center after bake UPROPERTY() bool bRecenterBakedActors; // If true, replace the previously baked output (if any) instead of creating new objects UPROPERTY() bool bReplacePreviousBake; #endif protected: // Id of corresponding Houdini asset. UPROPERTY(DuplicateTransient) int32 AssetId; // Ids of the nodes that should be cook for this HAC // This is for additional output and templated nodes if they are used. UPROPERTY(Transient, DuplicateTransient) TArray NodeIdsToCook; // List of dependent downstream HACs that have us as an asset input UPROPERTY(DuplicateTransient) TSet DownstreamHoudiniAssets; // Unique GUID created by component. UPROPERTY(DuplicateTransient) FGuid ComponentGUID; // GUID used to track asynchronous cooking requests. UPROPERTY(DuplicateTransient) FGuid HapiGUID; // The asset name of the selected asset inside the asset library UPROPERTY(DuplicateTransient) FString HapiAssetName; // Current state of the asset UPROPERTY(DuplicateTransient) EHoudiniAssetState AssetState; // Last asset state logged. UPROPERTY(DuplicateTransient) mutable EHoudiniAssetState DebugLastAssetState; // Result of the current asset's state UPROPERTY(DuplicateTransient) EHoudiniAssetStateResult AssetStateResult; //// Contains the context for keeping track of shared //// Houdini data. //UPROPERTY(DuplicateTransient) //UHoudiniAssetContext* AssetContext; // Subasset index UPROPERTY() uint32 SubAssetIndex; // Number of times this asset has been cooked. UPROPERTY(DuplicateTransient) int32 AssetCookCount; // UPROPERTY(DuplicateTransient) bool bHasBeenLoaded; UPROPERTY(DuplicateTransient) bool bHasBeenDuplicated; UPROPERTY(DuplicateTransient) bool bPendingDelete; UPROPERTY(DuplicateTransient) bool bRecookRequested; UPROPERTY(DuplicateTransient) bool bRebuildRequested; UPROPERTY(DuplicateTransient) bool bEnableCooking; UPROPERTY(DuplicateTransient) bool bForceNeedUpdate; UPROPERTY(DuplicateTransient) bool bLastCookSuccess; // Indicates that the parameter state (excluding values) on the HAC and the instantiated node needs to be synced. // The most common use for this would be a newly instantiated HDA that has only a default parameter interface // from its asset definition, and needs to sync pre-cook. UPROPERTY(DuplicateTransient) bool bParameterDefinitionUpdateNeeded; UPROPERTY(DuplicateTransient) bool bBlueprintStructureModified; UPROPERTY(DuplicateTransient) bool bBlueprintModified; //UPROPERTY(DuplicateTransient) //bool bEditorPropertiesNeedFullUpdate; UPROPERTY(Instanced) TArray Parameters; UPROPERTY(Instanced) TArray Inputs; UPROPERTY(Instanced) TArray Outputs; // The baked outputs from the last bake. UPROPERTY() TArray BakedOutputs; // Any actors that aren't explicitly // tracked by output objects should be registered // here so that they can be cleaned up. UPROPERTY() TArray> UntrackedOutputs; UPROPERTY() TArray HandleComponents; UPROPERTY(Transient, DuplicateTransient) bool bHasComponentTransformChanged; UPROPERTY(Transient, DuplicateTransient) bool bFullyLoaded; UPROPERTY() UHoudiniPDGAssetLink* PDGAssetLink; // Timer that is used to trigger creation of UStaticMesh for all mesh outputs // that still have UHoudiniStaticMeshes. The timer is cleared on PreCook and reset // at the end of the PostCook. UPROPERTY() FTimerHandle RefineMeshesTimer; // Delegate that is used to broadcast when RefineMeshesTimer fires FOnRefineMeshesTimerDelegate OnRefineMeshesTimerDelegate; // If true, don't build a proxy mesh next cook (regardless of global or override settings), // instead build the UStaticMesh directly (if applicable for the output types). UPROPERTY(DuplicateTransient) bool bNoProxyMeshNextCookRequested; // Maps a UObject to an Input number, used to preset the asset's inputs UPROPERTY(Transient, DuplicateTransient) TMap InputPresets; // If true, bake the asset after its next cook. UPROPERTY(DuplicateTransient) bool bBakeAfterNextCook; // Delegate to broadcast after a post cook event // Arguments are (HoudiniAssetComponent* HAC, bool IsSuccessful) FOnPostCookDelegate OnPostCookDelegate; // Delegate to broadcast when baking after a cook. // Currently we cannot call the bake functions from here (Runtime module) // or from the HoudiniEngineManager (HoudiniEngine) module, so we use // a delegate. FOnPostCookBakeDelegate OnPostCookBakeDelegate; // Delegate to broadcast after baking the HAC. Not called when just baking individual outputs directly. // Arguments are (HoudiniAssetComponent* HAC, bool bIsSuccessful) FOnPostBakeDelegate OnPostBakeDelegate; // Delegate that is broadcast when the asset state changes (HAC version). FOnAssetStateChangeDelegate OnAssetStateChangeDelegate; // Cached flag of whether this object is considered to be a 'preview' component or not. // This is typically useful in destructors when references to the World, for example, // is no longer available. UPROPERTY(Transient, DuplicateTransient) bool bCachedIsPreview; USimpleConstructionScript* GetSCS() const; // Object used to convert V1 HAC to V2 HAC UHoudiniAssetComponent_V1* Version1CompatibilityHAC; // The last timestamp this component was ticked // used to prioritize/limit the number of HAC processed per tick UPROPERTY(Transient) double LastTickTime; // // Begin: IHoudiniAssetStateEvents // // Delegate that is broadcast when AssetState changes FOnHoudiniAssetStateChange OnHoudiniAssetStateChangeDelegate; // // End: IHoudiniAssetStateEvents // };