Skip to content

Commit 907a701

Browse files
committed
Alpha 3.2 update - hotfix
The plug-in is linked with Houdini 18.0.532 / HAPI3.3.11. New features: - Attributes values used for splitting instancers into multiple components (via the "unreal_split_attr" attribute) are now read as strings instead of ints. This allow splitting instancers using either int, float or string attributes, and not just int attributes. - Added support for forcing the creation of Hierarchical Instanced Static Mesh Components when instancing. To do so, simply add the "unreal_hierarchical_instancer" (value 1) to the instancer. - Session sync: First pass at adding viewport sync (still a work in progress) This allows synchronizing the unreal and Houdini viewport when using Session Sync. Bug Fixes: - Added back missing sub asset selection dialog when instantiating multi/versioned HDAs. - Fixed regression that caused Houdini/HARS to crash upon updating a world input... - Fixed regression that caused crashes when using Brushes in a world input. (potentially, when using anything that used the default material in a world input) - Fixed crash when converting attribute values due to bad logging/string handling. - When importing landscape layers to Houdini, their values are now converted from [0 255] (uint8) top [0 1] (floats), instead of being normalized [min max] (uint8) to [0 1] floats. This also fixes Nan when importing flat layers. - Fixed "output templated geos" displaying all nested templated geos, including those in nested HDAs. We now only display templated geos that are children of the main HDA node, the output OBJ node or the output display SOP. - Curve Input: Fixed "Ghost/Broken" curve components appearing when spamming the add button. We now check if the HDA is being cooked when click Add button. - Fixed bad initialization warning (CachedSurfaceHash) when building the game
1 parent 3fb511b commit 907a701

17 files changed

+516
-190
lines changed

Source/HoudiniEngine/Private/HoudiniEngine.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -578,8 +578,8 @@ FHoudiniEngine::SessionSyncConnect(
578578

579579
// Update the default viewport sync settings
580580
bSyncViewport = HoudiniRuntimeSettings->bSyncViewport;
581-
//bSyncHoudiniViewport = HoudiniRuntimeSettings->bSyncHoudiniViewport;
582-
//bSyncUnrealViewport = HoudiniRuntimeSettings->bSyncUnrealViewport;
581+
bSyncHoudiniViewport = HoudiniRuntimeSettings->bSyncHoudiniViewport;
582+
bSyncUnrealViewport = HoudiniRuntimeSettings->bSyncUnrealViewport;
583583

584584
return true;
585585
}

Source/HoudiniEngine/Private/HoudiniEngineManager.cpp

+31-20
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,6 @@ FHoudiniEngineManager::Tick()
223223
{
224224
// See if the session sync settings have changed on the houdini side, update ours if they did
225225
FHoudiniEngine::Get().UpdateSessionSyncInfoFromHoudini();
226-
/*
227226
#if WITH_EDITOR
228227
// Update the Houdini viewport from unreal if needed
229228
if (FHoudiniEngine::Get().IsSyncViewportEnabled())
@@ -237,7 +236,6 @@ FHoudiniEngineManager::Tick()
237236
}
238237
}
239238
#endif
240-
*/
241239
}
242240
}
243241

@@ -1131,7 +1129,7 @@ FHoudiniEngineManager::BuildStaticMeshesForAllHoudiniStaticMeshes(UHoudiniAssetC
11311129
/* Unreal's viewport representation rules:
11321130
Viewport location is the actual camera location;
11331131
Lookat position is always 1024cm right in front of the camera, which means the camera is looking at;
1134-
The rotator rotates the base vector to a direction & orientation, and this dir and orientation is the camera's;
1132+
The rotator rotates the forward vector to a direction & orientation, and this dir and orientation is the camera's;
11351133
The identity direction and orientation of the camera is facing positive X-axis.
11361134
*/
11371135

@@ -1172,38 +1170,51 @@ FHoudiniEngineManager::SyncHoudiniViewportToUnreal()
11721170
return false;
11731171
}
11741172

1175-
// Orbit pivot is by default zero
1176-
FVector OrbitPivot = FVector::ZeroVector;
1173+
/* Calculate Hapi Quaternion */
1174+
// Initialize Hapi Quat with Unreal Quat.
1175+
// Note that rotations are in general non-commutative ***
1176+
FQuat HapiQuat = UnrealViewportRotation.Quaternion();
11771177

1178-
// // We're in orbit mode, override the default pivot position
1178+
// We're in orbit mode, forward vector is Y-axis
11791179
if (ViewportClient->bUsingOrbitCamera)
1180-
ViewportClient->GetPivotForOrbit(OrbitPivot);
1180+
{
1181+
// The forward vector is Y-negative direction when on orbiting mode
1182+
HapiQuat = HapiQuat * FQuat::MakeFromEuler(FVector(0.f, 0.f, 180.f));
11811183

1184+
// rotations around X and Y axis are reversed
1185+
float TempX = HapiQuat.X;
1186+
HapiQuat.X = HapiQuat.Y;
1187+
HapiQuat.Y = TempX;
1188+
HapiQuat.W = -HapiQuat.W;
11821189

1183-
/* Calculate Hapi Quaternion */
1184-
// Rotate the Quat arount Z-axis by 90 degree.
1185-
// Note that rotations are in general non-commutative ***
1186-
FQuat HapiQuat = UnrealViewportRotation.Quaternion() * FQuat::MakeFromEuler(FVector(0.f, 0.f, 90.f));
1190+
}
1191+
// We're not in orbiting mode, forward vector is X-axis
1192+
else
1193+
{
1194+
// Rotate the Quat arount Z-axis by 90 degree.
1195+
HapiQuat = HapiQuat * FQuat::MakeFromEuler(FVector(0.f, 0.f, 90.f));
1196+
}
11871197

1188-
// Get Hapi offset
1189-
float HapiOffset = (UnrealViewportPosition - OrbitPivot).Size() / HAPI_UNREAL_SCALE_FACTOR_TRANSLATION;
11901198

11911199
/* Update Hapi H_View */
11921200
// Note: There are infinte number of H_View representation for current viewport
11931201
// Each choice of pivot point determines an equivalent representation.
1194-
// If it is not in orbit mode in UE, we set the pivot point to be the origin
1202+
// We just find an equivalent when the pivot position is the UnrealViewportLookat position
11951203

11961204
HAPI_Viewport H_View;
1197-
H_View.position[0] = OrbitPivot.X;
1198-
H_View.position[1] = OrbitPivot.Z;
1199-
H_View.position[2] = OrbitPivot.Y;
1205+
H_View.position[0] = UnrealViewportLookatPosition.X / HAPI_UNREAL_SCALE_FACTOR_TRANSLATION;
1206+
H_View.position[1] = UnrealViewportLookatPosition.Z / HAPI_UNREAL_SCALE_FACTOR_TRANSLATION;
1207+
H_View.position[2] = UnrealViewportLookatPosition.Y / HAPI_UNREAL_SCALE_FACTOR_TRANSLATION;
12001208

1201-
H_View.offset = HapiOffset;
1209+
// Get HAPI_Offset
1210+
// In Unreal, Lookat position is always 1024 cm right in front of the view position.
1211+
// Since we choose the pivot point to be the view position, the Offset is always 1024 cm
1212+
H_View.offset = 1024.f / HAPI_UNREAL_SCALE_FACTOR_TRANSLATION;
12021213

12031214
H_View.rotationQuaternion[0] = -HapiQuat.X;
12041215
H_View.rotationQuaternion[1] = -HapiQuat.Z;
12051216
H_View.rotationQuaternion[2] = -HapiQuat.Y;
1206-
H_View.rotationQuaternion[3] = HapiQuat.W;
1217+
H_View.rotationQuaternion[3] = HapiQuat.W;
12071218

12081219
FHoudiniApi::SetViewport(FHoudiniEngine::Get().GetSession(), &H_View);
12091220

@@ -1284,7 +1295,7 @@ FHoudiniEngineManager::SyncUnrealViewportToHoudini()
12841295
FQuat UnrealQuat = FQuat(H_View.rotationQuaternion[0], H_View.rotationQuaternion[2], H_View.rotationQuaternion[1], -H_View.rotationQuaternion[3]);
12851296
UnrealQuat = UnrealQuat * FQuat::MakeFromEuler(FVector(0.f, 0.f, -90.f));
12861297

1287-
FVector UnrealBaseVector(1.f, 0.f, 0.f); // Base vector in Unreal viewport
1298+
FVector UnrealBaseVector(1.f, 0.f, 0.f); // Forward vector in Unreal viewport
12881299

12891300
/* Get UE viewport location*/
12901301
FVector UnrealViewPosition = - UnrealQuat.RotateVector(UnrealBaseVector) * UnrealOffset + UnrealViewportPivotPosition;

Source/HoudiniEngine/Private/HoudiniEnginePrivatePCH.h

+1
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@
179179
#define HAPI_UNREAL_ATTRIB_INSTANCE_POSITION HAPI_ATTRIB_POSITION
180180
#define HAPI_UNREAL_ATTRIB_INSTANCE_COLOR "unreal_instance_color"
181181
#define HAPI_UNREAL_ATTRIB_SPLIT_ATTR "unreal_split_attr"
182+
#define HAPI_UNREAL_ATTRIB_HIERARCHICAL_INSTANCED_SM "unreal_hierarchical_instancer"
182183

183184

184185
#define HAPI_UNREAL_ATTRIB_LANDSCAPE_TILE_NAME HAPI_ATTRIB_NAME

Source/HoudiniEngine/Private/HoudiniEngineUtils.cpp

+23-12
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
#include "HoudiniParameter.h"
5353
#include "HoudiniEngineRuntimeUtils.h"
5454

55+
#if WITH_EDITOR
56+
#include "SAssetSelectionWidget.h"
57+
#endif
58+
5559
#include "HAPI/HAPI_Version.h"
5660

5761
#include "Misc/Paths.h"
@@ -73,13 +77,19 @@
7377
//#include "Kismet/BlueprintEditor.h"
7478
#include "Engine/WorldComposition.h"
7579

80+
#if WITH_EDITOR
81+
#include "Interfaces/IMainFrameModule.h"
82+
#endif
83+
7684
#include <vector>
7785

7886
#include "AssetRegistryModule.h"
7987
#include "FileHelpers.h"
8088
#include "Factories/WorldFactory.h"
8189
#include "HAL/FileManager.h"
8290

91+
#define LOCTEXT_NAMESPACE HOUDINI_LOCTEXT_NAMESPACE
92+
8393
// HAPI_Result strings
8494
const FString kResultStringSuccess(TEXT("Success"));
8595
const FString kResultStringFailure(TEXT("Generic Failure"));
@@ -1128,7 +1138,7 @@ FHoudiniEngineUtils::OpenSubassetSelectionWindow(TArray<HAPI_StringHandle>& Asse
11281138

11291139
// Default to the first asset
11301140
OutPickedAssetName = AssetNames[0];
1131-
/*
1141+
11321142
#if WITH_EDITOR
11331143
// Present the user with a dialog for choosing which asset to instantiate.
11341144
TSharedPtr<SWindow> ParentWindow;
@@ -1174,7 +1184,6 @@ FHoudiniEngineUtils::OpenSubassetSelectionWindow(TArray<HAPI_StringHandle>& Asse
11741184
return false;
11751185
}
11761186
#endif
1177-
*/
11781187

11791188
return true;
11801189
}
@@ -2401,7 +2410,7 @@ FHoudiniEngineUtils::HapiGetAttributeDataAsFloat(
24012410
OutData[Idx] = (float)IntData[Idx];
24022411
}
24032412

2404-
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be a float attribute, its value had to be converted from integer."), *InAttribName);
2413+
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be a float attribute, its value had to be converted from integer."), *FString(InAttribName));
24052414
return true;
24062415
}
24072416
}
@@ -2424,13 +2433,13 @@ FHoudiniEngineUtils::HapiGetAttributeDataAsFloat(
24242433

24252434
if (!bConversionError)
24262435
{
2427-
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be a float attribute, its value had to be converted from string."), *InAttribName);
2436+
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be a float attribute, its value had to be converted from string."), *FString(InAttribName));
24282437
return true;
24292438
}
24302439
}
24312440
}
24322441

2433-
HOUDINI_LOG_WARNING(TEXT("Found attribute %s, but it was expected to be a float attribute and is of an invalid type."), *InAttribName);
2442+
HOUDINI_LOG_WARNING(TEXT("Found attribute %s, but it was expected to be a float attribute and is of an invalid type."), *FString(InAttribName));
24342443
return false;
24352444
}
24362445

@@ -2516,7 +2525,7 @@ FHoudiniEngineUtils::HapiGetAttributeDataAsInteger(
25162525
OutData[Idx] = (int32)FloatData[Idx];
25172526
}
25182527

2519-
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be an integer attribute, its value had to be converted from float."), *InAttribName);
2528+
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be an integer attribute, its value had to be converted from float."), *FString(InAttribName));
25202529

25212530
return true;
25222531
}
@@ -2539,13 +2548,13 @@ FHoudiniEngineUtils::HapiGetAttributeDataAsInteger(
25392548

25402549
if (!bConversionError)
25412550
{
2542-
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be an integer attribute, its value had to be converted from string."), *InAttribName);
2551+
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be an integer attribute, its value had to be converted from string."), *FString(InAttribName));
25432552
return true;
25442553
}
25452554
}
25462555
}
25472556

2548-
HOUDINI_LOG_WARNING(TEXT("Found attribute %s, but it was expected to be an integer attribute and is of an invalid type."), *InAttribName);
2557+
HOUDINI_LOG_WARNING(TEXT("Found attribute %s, but it was expected to be an integer attribute and is of an invalid type."), *FString(InAttribName));
25492558
return false;
25502559
}
25512560

@@ -2623,7 +2632,7 @@ FHoudiniEngineUtils::HapiGetAttributeDataAsString(
26232632
OutData[Idx] = FString::SanitizeFloat(FloatData[Idx]);
26242633
}
26252634

2626-
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be a string attribute, its value had to be converted from float."), *InAttribName);
2635+
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be a string attribute, its value had to be converted from float."), *FString(InAttribName));
26272636
return true;
26282637
}
26292638
}
@@ -2647,12 +2656,12 @@ FHoudiniEngineUtils::HapiGetAttributeDataAsString(
26472656
OutData[Idx] = FString::FromInt(IntData[Idx]);
26482657
}
26492658

2650-
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be a string attribute, its value had to be converted from integer."), *InAttribName);
2659+
HOUDINI_LOG_MESSAGE(TEXT("Attribute %s was expected to be a string attribute, its value had to be converted from integer."), *FString(InAttribName));
26512660
return true;
26522661
}
26532662
}
26542663

2655-
HOUDINI_LOG_WARNING(TEXT("Found attribute %s, but it was expected to be a string attribute and is of an invalid type."), *InAttribName);
2664+
HOUDINI_LOG_WARNING(TEXT("Found attribute %s, but it was expected to be a string attribute and is of an invalid type."), *FString(InAttribName));
26562665
return false;
26572666
}
26582667

@@ -4374,4 +4383,6 @@ FHoudiniEngineUtils::HapiCookNode(const HAPI_NodeId& InNodeId, HAPI_CookOptions*
43744383
// We want to yield a bit.
43754384
FPlatformProcess::Sleep(0.1f);
43764385
}
4377-
}
4386+
}
4387+
4388+
#undef LOCTEXT_NAMESPACE

Source/HoudiniEngine/Private/HoudiniInputTranslator.cpp

+2-9
Original file line numberDiff line numberDiff line change
@@ -884,16 +884,9 @@ FHoudiniInputTranslator::UploadInputData(UHoudiniInput* InInput)
884884
}
885885
else
886886
{
887-
// Upload the current input object to Houdin
888-
if (UploadHoudiniInputObject(InInput, CurrentInputObject, CreatedNodeIds))
889-
{
890-
if (CreatedNodeIds.Num() > 0)
891-
CurrentInputObject->InputNodeId = CreatedNodeIds.Last();
892-
}
893-
else
894-
{
887+
// Upload the current input object to Houdini
888+
if (!UploadHoudiniInputObject(InInput, CurrentInputObject, CreatedNodeIds))
895889
bSuccess = false;
896-
}
897890
}
898891
}
899892

0 commit comments

Comments
 (0)