Skip to content

Commit

Permalink
using new houdini engine api
Browse files Browse the repository at this point in the history
  • Loading branch information
ChildAdrian committed Jan 31, 2025
1 parent b37e3b0 commit 3ca93de
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 33 deletions.
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@ Also see [Tutorial](https://youtu.be/HAM8_OP_Fyc?si=K_1HXkTBwF1rLYVB)

# Compatibility

This plug-in is reply on **my custom** [HoudiniEngineForUnreal](https://github.com/AdrianPanGithub/HoudiniEngineForUnreal), so same compatibility as the Houdini Engine.
This plug-in is reply on **my custom** [HoudiniEngineForUnreal](https://github.com/AdrianPanGithub/HoudiniEngineForUnreal), so same [compatibility](https://github.com/AdrianPanGithub/HoudiniEngineForUnreal#compatibility) as the Houdini Engine. (Examples only run with >= 5.4)

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

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

# Tutorial/Example
[Tutorial](https://youtu.be/HAM8_OP_Fyc?si=K_1HXkTBwF1rLYVB) of how to use this plugin
01. Download the **CitySample** demo for Unreal Engine 5.4 or later from Epic Store.
[Tutorial](https://youtu.be/HAM8_OP_Fyc?si=K_1HXkTBwF1rLYVB) Require Unreal Engine >= 5.4 to run the example:
01. Download the [CitySample](https://www.fab.com/listings/4898e707-7855-404b-af0e-a505ee690e68) project (Unreal Engine >= 5.4) from Fab Store.
02. Put these two plug-ins into **CitySample/Plugins folder**.

03. Open `/HoudiniMassTranslator/Example/HoudiniTrafficDemo` in the content of this plug-in, and simulate.

Also see what can be achieved by Only using your HDAs and these two unreal plugins: [City toolchains](https://youtu.be/5Vp5nAFq1X8?si=IGSDG4cUdsefwn5x)
Also see what can be achieved by Only using your HDAs and these two unreal plugins: [City Toolchains](https://youtu.be/5Vp5nAFq1X8?si=IGSDG4cUdsefwn5x)

# Usage Brief

Expand All @@ -45,4 +45,7 @@ d[]@**unreal_zone_lane_profile**
Represent Lanes. Will find or create lane profiles based on this attribute when output. could be both on point and prim. Please click menu "Build/Clean Up Houdini Lane Profiles" at last.
s@**unreal_zone_lane_profile_name**

Will find lane profiles based on this attribute, could be both on point and prim.
Will find lane profiles based on this attribute, could be both on point and prim.
p@**rot**

Specify polygon zone shape point directions.
39 changes: 12 additions & 27 deletions Source/HoudiniMassTranslator/Private/HoudiniOutputZoneShape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ void FHoudiniZoneShapeOutput::Destroy(const AHoudiniNode* Node) const

namespace HoudiniZoneShapeOutputUtils
{
static int32 GetCurveAttributeElemIdx(const HAPI_AttributeOwner& AttribOwner, const int32& VtxIdx, const int32& CurveIdx);

static FZoneGraphTagMask FindOrCreateZoneGraphTag(UZoneGraphSettings* ZoneGraphSettings, const FName& TagName, bool& bZoneGraphSettingsModified);

static bool HapiGetOrCreateTags(const int32& NodeId, const int32& PartId, UZoneGraphSettings* ZoneGraphSettings,
Expand All @@ -84,19 +82,6 @@ namespace HoudiniZoneShapeOutputUtils
HAPI_AttributeOwner& OutLaneProfileOwner, TMap<uint32, int32>& InOutHashProfileIdxMap, TArray<int32>& OutLaneProfileIndices, bool& bZoneGraphSettingsModified);
}

int32 HoudiniZoneShapeOutputUtils::GetCurveAttributeElemIdx(const HAPI_AttributeOwner& AttribOwner, const int32& VtxIdx, const int32& CurveIdx)
{
switch (AttribOwner)
{
case HAPI_ATTROWNER_VERTEX:
case HAPI_ATTROWNER_POINT: return VtxIdx;
case HAPI_ATTROWNER_PRIM: return CurveIdx;
case HAPI_ATTROWNER_DETAIL: return 0;
}

return -1;
}

FZoneGraphTagMask HoudiniZoneShapeOutputUtils::FindOrCreateZoneGraphTag(UZoneGraphSettings* ZoneGraphSettings, const FName& TagName, bool& bZoneGraphSettingsModified)
{
TConstArrayView<FZoneGraphTagInfo> ConstTagInfos = ZoneGraphSettings->GetTagInfos();
Expand Down Expand Up @@ -489,11 +474,11 @@ bool UHoudiniOutputZoneShape::HapiUpdate(const HAPI_GeoInfo& GeoInfo, const TArr
// Same as HoudiniOutputMesh
// Judge PartialOutputMode, if remove && previous NOT set, then we will NOT parse the GroupIdx
const int32 SplitKey = bHasSplitValues ?
SplitKeys[GetCurveAttributeElemIdx(SplitAttribOwner, VertexIdx, CurveIdx)] : 0;
SplitKeys[FHoudiniOutputUtils::CurveAttributeEntryIdx(SplitAttribOwner, VertexIdx, CurveIdx)] : 0;
FHoudiniCurveIndicesHolder* FoundHolderPtr = bHasSplitValues ? SplitMap.Find(SplitKey) : nullptr;

const int8 PartialOutputMode = FMath::Clamp(PartialOutputModes.IsEmpty() ? HAPI_PARTIAL_OUTPUT_MODE_REPLACE :
PartialOutputModes[GetCurveAttributeElemIdx(PartialOutputModeOwner, VertexIdx, CurveIdx)],
PartialOutputModes[FHoudiniOutputUtils::CurveAttributeEntryIdx(PartialOutputModeOwner, VertexIdx, CurveIdx)],
HAPI_PARTIAL_OUTPUT_MODE_REPLACE, HAPI_PARTIAL_OUTPUT_MODE_REMOVE);

if (PartialOutputMode == HAPI_PARTIAL_OUTPUT_MODE_MODIFY)
Expand Down Expand Up @@ -675,7 +660,7 @@ bool UHoudiniOutputZoneShape::HapiUpdate(const HAPI_GeoInfo& GeoInfo, const TArr

bool bSplitActor = false;
if (!bSplitActors.IsEmpty())
bSplitActor = bSplitActors[GetCurveAttributeElemIdx(SplitActorsOwner, MainVertexIdx, CurveIdx)] >= 1;
bSplitActor = bSplitActors[FHoudiniOutputUtils::CurveAttributeEntryIdx(SplitActorsOwner, MainVertexIdx, CurveIdx)] >= 1;

FHoudiniZoneShapeOutput NewZSOutput;
if (FHoudiniZoneShapeOutput* FoundZSOutput = FHoudiniOutputUtils::FindOutputHolder(OldZoneShapeOutputs,
Expand All @@ -686,14 +671,14 @@ bool UHoudiniOutputZoneShape::HapiUpdate(const HAPI_GeoInfo& GeoInfo, const TArr

// We should judge ZoneShapeType first, if is Polygon, then points should have LaneProfile
if (!ZoneShapeTypes.IsEmpty())
ZSC->SetShapeType((FZoneShapeType)ZoneShapeTypes[GetCurveAttributeElemIdx(ZoneShapeTypeOwner, MainVertexIdx, CurveIdx)]);
ZSC->SetShapeType((FZoneShapeType)ZoneShapeTypes[FHoudiniOutputUtils::CurveAttributeEntryIdx(ZoneShapeTypeOwner, MainVertexIdx, CurveIdx)]);

if (!ZoneGraphTags.IsEmpty())
ZSC->SetTags(ZoneGraphTags[GetCurveAttributeElemIdx(ZoneShapeTypeOwner, MainVertexIdx, CurveIdx)]);
ZSC->SetTags(ZoneGraphTags[FHoudiniOutputUtils::CurveAttributeEntryIdx(ZoneShapeTypeOwner, MainVertexIdx, CurveIdx)]);

if (!LaneProfileIndices.IsEmpty())
{
const int32 LaneProfileIdx = LaneProfileIndices[GetCurveAttributeElemIdx(LaneProfileOwner, MainVertexIdx, CurveIdx)];
const int32 LaneProfileIdx = LaneProfileIndices[FHoudiniOutputUtils::CurveAttributeEntryIdx(LaneProfileOwner, MainVertexIdx, CurveIdx)];
if (ZoneGraphSettings->GetLaneProfiles().IsValidIndex(LaneProfileIdx))
ZSC->SetCommonLaneProfile(ZoneGraphSettings->GetLaneProfiles()[LaneProfileIdx]);
}
Expand All @@ -713,7 +698,7 @@ bool UHoudiniOutputZoneShape::HapiUpdate(const HAPI_GeoInfo& GeoInfo, const TArr
const int32 GlobalPointIdx = PointIdx + StartVertexIdx;
Point.Position = FVector(PositionData[GlobalPointIdx * 3], PositionData[GlobalPointIdx * 3 + 2], PositionData[GlobalPointIdx * 3 + 1]) * POSITION_SCALE_TO_UNREAL;
if (!Rots.IsEmpty())
Point.Rotation = Rots[GetCurveAttributeElemIdx(RotOwner, GlobalPointIdx, CurveIdx)];
Point.Rotation = Rots[FHoudiniOutputUtils::CurveAttributeEntryIdx(RotOwner, GlobalPointIdx, CurveIdx)];

Point.LaneProfile = FZoneShapePoint::InheritLaneProfile;
if (!PointLaneProfileIndices.IsEmpty() && ZSC->GetShapeType() == FZoneShapeType::Polygon)
Expand All @@ -727,20 +712,20 @@ bool UHoudiniOutputZoneShape::HapiUpdate(const HAPI_GeoInfo& GeoInfo, const TArr
for (const TSharedPtr<FHoudiniAttribute>& PropAttrib : PropAttribs)
{
const HAPI_AttributeOwner& PropAttribOwner = PropAttrib->GetOwner();
if (PropAttribOwner == HAPI_ATTROWNER_VERTEX || PropAttribOwner == HAPI_ATTROWNER_POINT)
if ((PropAttribOwner == HAPI_ATTROWNER_VERTEX) || (PropAttribOwner == HAPI_ATTROWNER_POINT))
PropAttrib->SetStructPropertyValues(&Point, FZoneShapePoint::StaticStruct(),
GetCurveAttributeElemIdx(PropAttribOwner, GlobalPointIdx, CurveIdx));
FHoudiniOutputUtils::CurveAttributeEntryIdx(PropAttribOwner, GlobalPointIdx, CurveIdx));
}
}

// Set UProperties
for (const TSharedPtr<FHoudiniAttribute>& PropAttrib : PropAttribs)
{
const HAPI_AttributeOwner& PropAttribOwner = PropAttrib->GetOwner();
if (PropAttribOwner == HAPI_ATTROWNER_PRIM || PropAttribOwner == HAPI_ATTROWNER_DETAIL)
PropAttrib->SetObjectPropertyValues(ZSC, GetCurveAttributeElemIdx(PropAttribOwner, MainVertexIdx, CurveIdx));
if ((PropAttribOwner == HAPI_ATTROWNER_PRIM) || (PropAttribOwner == HAPI_ATTROWNER_DETAIL))
PropAttrib->SetObjectPropertyValues(ZSC, FHoudiniOutputUtils::CurveAttributeEntryIdx(PropAttribOwner, MainVertexIdx, CurveIdx));
}
SET_SPLIT_ACTOR_UPROPERTIES(NewZSOutput, GetCurveAttributeElemIdx(PropAttribOwner, MainVertexIdx, CurveIdx), false);
SET_SPLIT_ACTOR_UPROPERTIES(NewZSOutput, FHoudiniOutputUtils::CurveAttributeEntryIdx(PropAttribOwner, MainVertexIdx, CurveIdx), false);

// Avoid Crash when ZSC create scene proxy
if (ShapeConnectorsProp && ConnectedShapesProp)
Expand Down

0 comments on commit 3ca93de

Please sign in to comment.