Skip to content

Commit

Permalink
All type of assets create/modify, instance and landscape output perfo…
Browse files Browse the repository at this point in the history
…rmance optimize
  • Loading branch information
ChildAdrian committed Jan 31, 2025
1 parent 5d07988 commit de3b749
Show file tree
Hide file tree
Showing 15 changed files with 45 additions and 31 deletions.
Binary file modified Binaries/Win64/UnrealEditor-HoudiniEngine.dll
Binary file not shown.
Binary file modified Binaries/Win64/UnrealEditor-HoudiniEngineEditor.dll
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ void EmptyLinkFunctionForGeneratedCodeHoudiniEngine_init() {}
SingletonFuncArray,
UE_ARRAY_COUNT(SingletonFuncArray),
PKG_CompiledIn | 0x00000040,
0xD7E265C0,
0xB058F6B5,
0x85A24F5C,
0xFCD70E75,
METADATA_PARAMS(0, nullptr)
};
UECodeGen_Private::ConstructUPackage(Z_Registration_Info_UPackage__Script_HoudiniEngine.OuterSingleton, PackageParams);
}
return Z_Registration_Info_UPackage__Script_HoudiniEngine.OuterSingleton;
}
static FRegisterCompiledInInfo Z_CompiledInDeferPackage_UPackage__Script_HoudiniEngine(Z_Construct_UPackage__Script_HoudiniEngine, TEXT("/Script/HoudiniEngine"), Z_Registration_Info_UPackage__Script_HoudiniEngine, CONSTRUCT_RELOAD_VERSION_INFO(FPackageReloadVersionInfo, 0xD7E265C0, 0xB058F6B5));
static FRegisterCompiledInInfo Z_CompiledInDeferPackage_UPackage__Script_HoudiniEngine(Z_Construct_UPackage__Script_HoudiniEngine, TEXT("/Script/HoudiniEngine"), Z_Registration_Info_UPackage__Script_HoudiniEngine, CONSTRUCT_RELOAD_VERSION_INFO(FPackageReloadVersionInfo, 0x85A24F5C, 0xFCD70E75));
PRAGMA_ENABLE_DEPRECATION_WARNINGS
Binary file not shown.
33 changes: 20 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Welcome to the [repository](https://github.com/AdrianPanGithub/HoudiniEngineForUnreal) for the Houdini Engine For Unreal Plugin.

This plug-in is the completely remaster of the official Houdini Engine For Unreal from zero, with similar usages but up to 2x - 15x faster data I/O performance compare to the lastest official plug-in, native World-Partition support and much more functionalities optimized for making procedural landscape and city toolset. Moreover, this plug-in provides a set of C++ API to define your own unreal classes and assets I/O translators
This plug-in is the completely remaster of the official Houdini Engine For Unreal from zero, with similar usages but up to 2x - 15x faster data I/O performance compare to the lastest official plug-in, native World-Partition support and much more functionalities optimized for making procedural landscape and city toolset. Moreover, this plug-in provides a set of C++ API to define your own unreal classes and assets I/O translators (See [HoudiniPCGTranslator](https://github.com/AdrianPanGithub/HoudiniPCGTranslator) and [HoudiniMassTranslator](https://github.com/AdrianPanGithub/HoudiniMassTranslator))

As the usage is similar, [Official Documentation](https://www.sidefx.com/docs/houdini/unreal/) is also available for this plug-in . But there are still a lot of things are different. For the concrete usage of this plug-in, please see **Usage Brief** below, also see `Resources/houdini/otls/examples` and `Source/HoudiniEngine/Public/HoudiniEngineCommon.h`

Expand All @@ -15,25 +15,29 @@ Support all builds of Houdini 20.5, and Unreal Engine >= 5.3.
NOT compatible with official plug-in, and can NOT work together with official one.

# Installation
01. In this GitHub [repository](https://github.com/AdrianPanGithub/HoudiniEngineForUnreal), click **Releases** on the right side.
01. In this GitHub [repository](https://github.com/AdrianPanGithub/HoudiniEngineForUnreal), click [Releases](https://github.com/AdrianPanGithub/HoudiniEngineForUnreal) on the right side.
02. Download the Houdini Engine zip file that matches your Unreal Engine Version.
03. Extract the **HoudiniEngine** folder to the **Plugins** of your Unreal Project Directory.

e.g. `C:/Unreal Projects/MyGameProject/Plugins/HoudiniEngine`

This Plugin will automatically find the correct houdini version on your computer, or you can specify a custom Houdini installation in the plug-in settings.
This plug-in will automatically find the correct houdini version on your computer, or you can specify a custom Houdini installation in the plug-in settings(Houdini Engine menu/Settings).

N.B. But for Steam Houdini Indie, You MUST specify your steam houdini location manually, by plug-in setting: CustomHoudiniLocation, or use "HAPI_PATH" environment variable to specify your Houdini location.

# Usage Brief

Here's a list of extra functionalities than official plug-in:
All official functionalities are supported by this plug-in!

And here's a list of Extra functionalities than official plug-in:

N.B. This list is NOT completed, for details please see `Source/HoudiniEngine/Public/HoudiniEngineCommon.h` and `Resources/houdini/otls/examples`

**Common**:
01. Provides a set of C++ API, allow writing custom I/O translator for your own unreal classes or assets

See `Source/HoudiniEngine/Public/HoudiniInput.h` and `Source/HoudiniEngine/Public/HoudiniOutput.h`
Also see [HoudiniMassTranslator](https://github.com/AdrianPanGithub/HoudiniMassTranslator) and [HoudiniPCGTranslator](https://github.com/AdrianPanGithub/HoudiniPCGTranslator) of how to use these API.
Also see [HoudiniPCGTranslator](https://github.com/AdrianPanGithub/HoudiniPCGTranslator) and [HoudiniMassTranslator](https://github.com/AdrianPanGithub/HoudiniMassTranslator) of how to use these API.
02. Finite state machine for achieving rich user interactions by only using HDA (See `Resources/houdini/otls/examples/he_example_quick_shape.hda`)
03. Streamlined Blueprint API.
04. Light weight, compact usage and panel widgets.
Expand All @@ -59,12 +63,13 @@ N.B. This list is NOT completed, for details please see `Source/HoudiniEngine/Pu
07. Unreal spline input support import custom properties on your Blueprint.
08. Texture input support.
09. DynamicMeshComponent input support.
10. All component type input support.
11. All settings in the operator-path input panel could be set by parameter tags (e.g. { "check_changed", "0" }, { "unreal_ref", "1" }, See `Source/HoudiniEngine/Public/HoudiniEngineCommon.h`)
12. Mesh inputs are packed before transform.
13. All Input types support shared memory data transport, up to 15x faster than official shared memory session.
10. DataAsset input support
11. All component type input support.
12. All settings in the operator-path input panel could be set by parameter tags (e.g. { "check_changed", "0" }, { "unreal_ref", "1" }, See `Source/HoudiniEngine/Public/HoudiniEngineCommon.h`)
13. Mesh inputs are packed before transform.
14. All Input types support shared memory data transport, up to 15x faster than official shared memory session.

14. ... (And Much More)
15. ... (And Much More)

**Output**:
01. Allow output special mesh and curves that could edit directly in unreal editor (See `Resources/houdini/otls/examples/he_example_quick_shape.hda`)
Expand All @@ -78,7 +83,9 @@ N.B. This list is NOT completed, for details please see `Source/HoudiniEngine/Pu
09. Landscape output support shared memory output (6x faster than official shared-memory session, need to add my sharedmemory_volumeoutput Sop to your HDA)
10. Support instantiate USceneComponent derived Classes(e.g. SplineMeshComponent, PointLightComponent etc. See `Resources/houdini/otls/examples/he_example_spline_mesh_output.hda`).
11. Geometry Collection (Chaos) output as instancers (s@unreal_output_instance_type = "GC"), all of the settings on UGeometryCollection could be set by unreal_uproperty_*, also support split and partial output (See `Resources/houdini/otls/examples/he_example_chaos_geometry_collection_output.hda`).
12. Support Static/AnimatedSparseVolumeTexture (VDBs) output
13. Support Dynamic Mesh (Geometry Script, s@unreal_output_mesh_type = "dynamic") Output
12. Standalone MaterialInstance asset output (s@unreal_material_instance and @unreal_material_parameter_*, but on points, See `Resources/houdini/otls/examples/he_example_vdb_output.hda`)
13. All assets (including DataAsset) support create or modify by HDA output (See `Resources/houdini/otls/examples/he_example_split_actors.hda`, using s@unreal_object_path ("having class prefix" means create, otherwise, means modify), d@unreal_object_metadata, @unreal_uproperty_*).
14. Support Dynamic Mesh (Geometry Script, s@unreal_output_mesh_type = "dynamic") output.
15. Static/AnimatedSparseVolumeTexture (VDBs) output support.

14. ... (And Much More)
16. ... (And Much More)
Binary file modified Resources/houdini/dso/SOP_SharedMemory_VolumeInput.dll
Binary file not shown.
Binary file modified Resources/houdini/otls/examples/he_example_split_actors.hda
Binary file not shown.
Binary file not shown.
17 changes: 10 additions & 7 deletions Source/HoudiniEngine/Public/HoudiniAttribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,18 @@ class HOUDINIENGINE_API FHoudiniAttribute
static bool FindPropertyRecursive(const UStruct* Struct, const FString& PropertyName,
const TSharedPtr<FEditPropertyChain>& PropertyChain, size_t& OutOffset);

void SetPropertyValues(void* TargetPtr, const UStruct* TargetStruct,
const TSharedPtr<FEditPropertyChain>& PropertyChain, void* ContainerPtr, const int32& Index) const;

FORCEINLINE bool IsRestrictString() const { return Storage == HAPI_STORAGETYPE_STRING || Storage == HAPI_STORAGETYPE_STRING_ARRAY; }
FORCEINLINE bool IsRestrictString() const { return ((Storage == HAPI_STORAGETYPE_STRING) || (Storage == HAPI_STORAGETYPE_STRING_ARRAY)); }

public:
static const TArray<FName> SupportStructNames;

static const uint8 SupportStructTupleSize[];

static const EHoudiniDataType SupportStructElemType[];
static const EHoudiniDataType SupportStructDataType[];

static const FName SoftObjectPathName;
static const FName SoftClassPathName;

public:
static void ResetPropertiesMaps(); // Call after hot-reload

static void ClearBlueprintProperties(); // Will be called after output process finished
Expand All @@ -60,7 +60,10 @@ class HOUDINIENGINE_API FHoudiniAttribute
const int AttribCounts[HAPI_ATTROWNER_MAX], const char* AttributePrefix, TArray<TSharedPtr<FHoudiniAttribute>>& OutAttribs);

static bool FindProperty(const UStruct* Struct, const FString& PropertyName,
TSharedPtr<FEditPropertyChain>& OutFoundPropertyChain, size_t& OutOffset, const bool& bVerbose);
TSharedPtr<FEditPropertyChain>& OutFoundPropertyChain, size_t& OutOffset, const bool& bVerbose); // Low level API, should only be used when batch set structs

void SetPropertyValues(void* TargetPtr, const UStruct* TargetStruct,
const TSharedPtr<FEditPropertyChain>& PropertyChain, void* ContainerPtr, const int32& Index) const; // Low level API, should only be used when batch set structs

bool SetStructPropertyValues(void* StructPtr, const UStruct* Struct, const int32& Index, const bool& bVerbose = false) const;

Expand Down
4 changes: 2 additions & 2 deletions Source/HoudiniEngine/Public/HoudiniEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class HOUDINIENGINE_API FHoudiniEngine : public IModuleInterface
FORCEINLINE void FinishHoudiniMainTaskMessage() const { HoudiniMainTaskMessageEvent.Broadcast(-1.0f, FText::GetEmpty()); }

// -------- Input/Output Builder --------
// The register order of houdini engine itself: SkeletalMesh < Texture2D < FoliageType_InstancedStaticMesh < Blueprint < DataTable < StaticMesh
// The register order of houdini engine itself: SkeletalMesh < DataAsset < Texture2D < FoliageType_InstancedStaticMesh < Blueprint < DataTable < StaticMesh
FORCEINLINE void RegisterInputBuilder(const TSharedPtr<IHoudiniContentInputBuilder>& Builder) { ContentInputBuilders.AddUnique(Builder); }

FORCEINLINE void UnregisterInputBuilder(const TSharedPtr<IHoudiniContentInputBuilder>& Builder) { ContentInputBuilders.Remove(Builder); }
Expand All @@ -135,7 +135,7 @@ class HOUDINIENGINE_API FHoudiniEngine : public IModuleInterface

FORCEINLINE const TArray<TSharedPtr<IHoudiniComponentInputBuilder>>& GetComponentInputBuilders() const { return ComponentInputBuilders; }

// The register order of houdini engine itself: Landscape < Instancer < Curve < Mesh < SkeletalMesh(KineFX) < Texture(Image and VDB) < DataTable
// The register order of houdini engine itself: Landscape < Instancer < Asset < Curve < Mesh < SkeletalMesh(KineFX) < MaterialInstance < Texture(Image and VDB) < DataTable
FORCEINLINE void RegisterOutputBuilder(const TSharedPtr<IHoudiniOutputBuilder>& Builder) { OutputBuilders.AddUnique(Builder); }

FORCEINLINE void UnregisterOutputBuilder(const TSharedPtr<IHoudiniOutputBuilder>& Builder) { OutputBuilders.Remove(Builder); }
Expand Down
2 changes: 2 additions & 0 deletions Source/HoudiniEngine/Public/HoudiniEngineCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,9 @@ TEXT("");
#define HAPI_PARM_TAG_UNREAL_REF_FILTER "unreal_ref_filter"

#define HAPI_PARM_TAG_NUM_INPUT_OBJECTS "num_input_objects" // For content input, <= 0 means dynamic num objects
#define HAPI_PARM_TAG_IMPORT_RENDER_DATA "import_render_data" // Will import nanite fallback mesh
#define HAPI_PARM_TAG_LOD_IMPORT_METHOD "lod_import_method"
#define HAPI_PARM_TAG_COLLISION_IMPORT_METHOD "collision_import_method"
#define HAPI_PARM_TAG_CURVE_COLOR "curve_color"
#define HAPI_PARM_TAG_IMPORT_ROT_AND_SCALE "import_rot_and_scale"
#define HAPI_PARM_TAG_IMPORT_COLLOSION_INFO "import_collision_info"
Expand Down
4 changes: 1 addition & 3 deletions Source/HoudiniEngine/Public/HoudiniEngineUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,10 @@ struct HOUDINIENGINE_API FHoudiniEngineUtils

static FString GetPackagePath(const FString& AssetPath); // like "/Game/HoudiniEngine/SM_Test"

protected:
static UObject* FindOrCreateAsset(const UClass* AssetClass, const FString& AssetPath, bool* bOutFound = nullptr);

static UObject* CreateAsset(const UClass* AssetClass, const FString& AssetPath);

public:
template<typename TAssetClass>
FORCEINLINE static TAssetClass* FindOrCreateAsset(const FString& AssetPath, bool* bOutFound = nullptr) // Will try to reuse exist asset if found
{
Expand All @@ -118,7 +116,7 @@ struct HOUDINIENGINE_API FHoudiniEngineUtils

static void NotifyAssetChanged(const UObject* Asset);

static bool FilterClass(const UObject* Asset, const TArray<const UClass*>& AllowClasses, const TArray<const UClass*>& DisallowClasses);
static bool FilterClass(const TArray<const UClass*>& AllowClasses, const TArray<const UClass*>& DisallowClasses, const UClass* ObjectClass);


// -------- Misc ---------
Expand Down
4 changes: 2 additions & 2 deletions Source/HoudiniEngine/Public/HoudiniInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ struct HOUDINIENGINE_API FHoudiniInputSettings // All of the settings could set

bool HapiParseFromParameterTags(UHoudiniInput* Input, const int32& NodeId, const int32 ParmId);

void GetFilterClasses(TArray<const UClass*>& OutAllowClasses, TArray<const UClass*>& OutDisallowClasses, const bool& bIsActorClass) const;
void GetFilterClasses(TArray<const UClass*>& OutAllowClasses, TArray<const UClass*>& OutDisallowClasses, const UClass* ParentClass = nullptr) const;

bool FilterActorTags(const AActor* Actor) const;
};
Expand Down Expand Up @@ -337,7 +337,7 @@ class HOUDINIENGINE_API UHoudiniInputHolder : public UObject
};

// Inherit from builder and register using FHoudiniEngine::RegisterInputBuilder
// The register order of houdini engine itself: SkeletalMesh < Texture2D < FoliageType_InstancedStaticMesh < Blueprint < DataTable < StaticMesh
// The register order of houdini engine itself: SkeletalMesh < DataAsset < Texture2D < FoliageType_InstancedStaticMesh < Blueprint < DataTable < StaticMesh
class HOUDINIENGINE_API IHoudiniContentInputBuilder
{
public:
Expand Down
2 changes: 1 addition & 1 deletion Source/HoudiniEngine/Public/HoudiniOutput.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class HOUDINIENGINE_API UHoudiniOutput : public UObject // Outer must be AHoudi
};

// Inherit from builder and register using FHoudiniEngine::RegisterOutputBuilder
// The register order of houdini engine itself: Landscape < Instancer < Curve < Mesh < SkeletalMesh(KineFX) < Texture(Image and VDB) < DataTable
// The register order of houdini engine itself: Landscape < Instancer < Asset < Curve < Mesh < SkeletalMesh(KineFX) < MaterialInstance < Texture(Image and VDB) < DataTable
class HOUDINIENGINE_API IHoudiniOutputBuilder
{
public:
Expand Down
4 changes: 4 additions & 0 deletions Source/HoudiniEngine/Public/HoudiniOutputUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class AHoudiniNode;
class ALandscape;
class FHoudiniAttribute;

#define POINT_ATTRIB_ENTRY_IDX(OWNER, POINT_INDEX) ((OWNER == HAPI_ATTROWNER_DETAIL) ? 0 : POINT_INDEX)

#define GET_SPLIT_VALUE_STR SplitValueMap.IsEmpty() ? FString::FromInt(SplitKey) : SplitValueMap[SplitKey]

#define SET_OBJECT_UPROPERTIES(OBJECT, ATTRIB_INDEX) for (const TSharedPtr<FHoudiniAttribute>& PropAttrib : PropAttribs)\
Expand Down Expand Up @@ -87,6 +89,8 @@ struct HOUDINIENGINE_API FHoudiniOutputUtils
static void CloseData(const float* Data, const size_t& SHMHandle); // If SHMHandle is 0, means Data was from malloc

// -------- Geoemetry --------
static int32 CurveAttributeEntryIdx(const HAPI_AttributeOwner& AttribOwner, const int32& VtxIdx, const int32& CurveIdx);

// Find SplitAttrib based on "unreal_split_attr"
static bool HapiGetSplitValues(const int32& NodeId, const int32& PartId, const TArray<std::string>& AttribNames, const int AttribCounts[HAPI_ATTROWNER_MAX],
TArray<int32>& OutSplitKeys, TMap<int32, FString>& OutSplitValueMap, HAPI_AttributeOwner& InOutOwner); // SplitValueMap will be empty is split values is int
Expand Down

0 comments on commit de3b749

Please sign in to comment.