Files

268 lines
11 KiB
C++

/*
* Copyright (c) <2017> Side Effects Software Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
*/
#pragma once
#include "HoudiniGeoPartObject.h"
#include "HoudiniAssetParameter.h"
#include "Input/Reply.h"
#include "Input/Events.h"
#include "Layout/Geometry.h"
#include "HoudiniAssetInstanceInput.generated.h"
class AActor;
class UStaticMesh;
class UMaterialInterface;
class UInstancedStaticMeshComponent;
class UHoudiniAssetInstanceInputField;
UCLASS()
class HOUDINIENGINERUNTIME_API UHoudiniAssetInstanceInput : public UHoudiniAssetParameter
{
friend class UHoudiniAssetInstanceInputField;
GENERATED_UCLASS_BODY()
friend class FHoudiniParameterDetails;
public:
/** Create instance of this class. **/
static UHoudiniAssetInstanceInput * Create(
UHoudiniAssetComponent * InPrimaryObject,
const FHoudiniGeoPartObject & HoudiniGeoPartObject );
/** Create instance from another input. **/
static UHoudiniAssetInstanceInput * Create(
UHoudiniAssetComponent * InPrimaryObject,
const UHoudiniAssetInstanceInput * OtherInstanceInput );
public:
/** Create this instance input. **/
bool CreateInstanceInput();
/** Recreates render states for used instanced static mesh components. **/
void RecreateRenderStates();
/** Recreates physics states for used instanced static mesh components. **/
void RecreatePhysicsStates();
/** Retrieve all instanced mesh components used by this input. **/
bool CollectAllInstancedStaticMeshComponents(
TArray< UInstancedStaticMeshComponent * > & Components,
const UStaticMesh * StaticMesh );
/** Get material replacement meshes for a given input. **/
bool GetMaterialReplacementMeshes(
UMaterialInterface * Material,
TMap< UStaticMesh *, int32 > & MaterialReplacementsMap );
FORCEINLINE const TArray< UHoudiniAssetInstanceInputField * >& GetInstanceInputFields() const { return InstanceInputFields; }
FORCEINLINE const FHoudiniGeoPartObject& GetGeoPartObject() const { return HoudiniGeoPartObject; }
/** Refresh state based on the given geo part object */
void SetGeoPartObject( const FHoudiniGeoPartObject& InGeoPartObject );
/** UHoudiniAssetParameter methods. **/
public:
/** Create this parameter from HAPI information - this implementation does nothing as this is not **/
/** a true parameter. **/
virtual bool CreateParameter(
UObject * InPrimaryObject,
UHoudiniAssetParameter * InParentParameter,
HAPI_NodeId InNodeId, const HAPI_ParmInfo & ParmInfo );
/** Set component for this parameter. **/
virtual void SetHoudiniAssetComponent( UHoudiniAssetComponent * InComponent ) override;
/** UObject methods. **/
public:
virtual void BeginDestroy() override;
virtual void Serialize( FArchive & Ar ) override;
static void AddReferencedObjects( UObject * InThis, FReferenceCollector & Collector );
#if WITH_EDITOR
/** Clone all used instance static mesh components and and attach them to provided actor. **/
void CloneComponentsAndAttachToActor( AActor * Actor );
#endif
protected:
/** Retrieve all transforms for a given path. Used by attribute instancer. **/
void GetPathInstaceTransforms(
const FString & ObjectInstancePath, const TArray< FString > & PointInstanceValues,
const TArray< FTransform > & Transforms, TArray< FTransform > & OutTransforms );
protected:
/** Locate field which matches given criteria. Return null if not found. **/
UHoudiniAssetInstanceInputField * LocateInputField(
const FHoudiniGeoPartObject & GeoPartObject );
/** Locate or create (if it does not exist) an input field. **/
void CreateInstanceInputField(
const FHoudiniGeoPartObject & HoudiniGeoPartObject,
const TArray< FTransform > & ObjectTransforms,
const TArray< UHoudiniAssetInstanceInputField * > & OldInstanceInputFields,
TArray< UHoudiniAssetInstanceInputField * > & NewInstanceInputFields );
/** Locate or create (if it does not exist) an input field. This version is used with override attribute. **/
void CreateInstanceInputField(
UObject * InstancedObject, const TArray< FTransform > & ObjectTransforms,
const TArray< UHoudiniAssetInstanceInputField * > & OldInstanceInputFields,
TArray< UHoudiniAssetInstanceInputField * > & NewInstanceInputFields );
/** Clean unused input fields. **/
void CleanInstanceInputFields( TArray< UHoudiniAssetInstanceInputField * > & InInstanceInputFields );
/** Returns primary object cast to HoudiniAssetComponent */
class UHoudiniAssetComponent* GetHoudiniAssetComponent();
const class UHoudiniAssetComponent* GetHoudiniAssetComponent() const;
/** Get the node id of the asset we are associated with */
HAPI_NodeId GetAssetId() const;
protected:
#if WITH_EDITOR
/** Delegate used when static mesh has been drag and dropped. **/
void OnStaticMeshDropped(
UObject * InObject,
UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField,
int32 Idx, int32 VariationIdx );
/** Handler for when static mesh thumbnail is double clicked. We open editor in this case. **/
FReply OnThumbnailDoubleClick(
const FGeometry & InMyGeometry, const FPointerEvent & InMouseEvent, UObject * Object );
/** Closes the combo button. **/
void CloseStaticMeshComboButton(
UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField, int32 Idx,
int32 VariationIdx );
/** Triggered when combo button is opened or closed. **/
void ChangedStaticMeshComboButton(
bool bOpened, UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField,
int32 Idx, int32 VariationIdx );
/** Browse to static mesh. **/
void OnInstancedObjectBrowse( UObject* InstancedObject );
/** Handler for reset static mesh button. **/
FReply OnResetStaticMeshClicked(
UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField, int32 Idx,
int32 VariationIdx );
/** Handler for adding instance variation **/
void OnAddInstanceVariation( UHoudiniAssetInstanceInputField * InstanceInputField, int32 Index );
/** Handler for removing instance variation **/
void OnRemoveInstanceVariation( UHoudiniAssetInstanceInputField * InstanceInputField, int32 Index );
/** Helper for field label */
FString GetFieldLabel( int32 FieldIdx, int32 VariationIdx ) const;
/** Get rotation components for given index. **/
TOptional< float > GetRotationRoll(
UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField,
int32 VariationIdx ) const;
TOptional< float > GetRotationPitch(
UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField,
int32 VariationIdx ) const;
TOptional< float > GetRotationYaw(
UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField,
int32 VariationIdx ) const;
/** Set rotation components for given index. **/
void SetRotationRoll(
float Value, UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField, int32 VariationIdx );
void SetRotationPitch(
float Value, UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField, int32 VariationIdx );
void SetRotationYaw(
float Value, UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField, int32 VariationIdx );
/** Get scale components for a given index. **/
TOptional< float > GetScaleX(
UHoudiniAssetInstanceInputField* HoudiniAssetInstanceInputField, int32 VariationIdx ) const;
TOptional< float > GetScaleY(
UHoudiniAssetInstanceInputField* HoudiniAssetInstanceInputField, int32 VariationIdx ) const;
TOptional< float > GetScaleZ(
UHoudiniAssetInstanceInputField* HoudiniAssetInstanceInputField, int32 VariationIdx ) const;
/** Set scale components for a given index. **/
void SetScaleX( float Value, UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField, int32 VariationIdx );
void SetScaleY( float Value, UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField, int32 VariationIdx );
void SetScaleZ( float Value, UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField, int32 VariationIdx );
/** Set option for whether scale should be linear. **/
void CheckStateChanged(
bool IsChecked, UHoudiniAssetInstanceInputField * HoudiniAssetInstanceInputField,
int32 VariationIdx );
#endif
protected:
/** List of fields created by this instance input. **/
TArray< UHoudiniAssetInstanceInputField * > InstanceInputFields;
/** Corresponding geo part object. **/
FHoudiniGeoPartObject HoudiniGeoPartObject;
/** Id of an object to instance. **/
HAPI_NodeId ObjectToInstanceId;
public:
/** Flags used by this input. **/
union FHoudiniAssetInstanceInputFlags
{
struct
{
/** Set to true if this is an attribute instancer. **/
uint32 bIsAttributeInstancer : 1;
/** Set to true if this attribute instancer uses overrides. **/
uint32 bAttributeInstancerOverride : 1;
/** Set to true if this is a packed primitive instancer **/
uint32 bIsPackedPrimitiveInstancer : 1;
/** Set to true if this is a split mesh instancer */
uint32 bIsSplitMeshInstancer : 1;
};
uint32 HoudiniAssetInstanceInputFlagsPacked;
};
FHoudiniAssetInstanceInputFlags Flags;
static FHoudiniAssetInstanceInputFlags GetInstancerFlags(const FHoudiniGeoPartObject & InHoudiniGeoPartObject);
};