Skip to content

Commit 8a254df

Browse files
committed
Unreal: Version 2
- Added missing new files.
1 parent fafa5db commit 8a254df

File tree

10 files changed

+937
-0
lines changed

10 files changed

+937
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include "../HoudiniEngine.h"
2+
#include "Misc/AutomationTest.h"
3+
4+
#if WITH_DEV_AUTOMATION_TESTS
5+
6+
IMPLEMENT_SIMPLE_AUTOMATION_TEST(HoudiniCoreTest, "Houdini.Core.TestAutomation", EAutomationTestFlags::EditorContext | EAutomationTestFlags::ProductFilter)
7+
8+
bool HoudiniCoreTest::RunTest(const FString & Parameters)
9+
{
10+
return true;
11+
}
12+
13+
#endif
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
#if WITH_DEV_AUTOMATION_TESTS
3+
4+
#include "CoreMinimal.h"
5+
6+
#endif
7+
Lines changed: 289 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,289 @@
1+
/*
2+
* Copyright (c) <2021> Side Effects Software Inc.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* 1. Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
*
11+
* 2. The name of Side Effects Software may not be used to endorse or
12+
* promote products derived from this software without specific prior
13+
* written permission.
14+
*
15+
* THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE "AS IS" AND ANY EXPRESS
16+
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
18+
* NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
19+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
21+
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24+
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
*/
26+
27+
#include "UnrealFoliageTypeTranslator.h"
28+
29+
#include "HoudiniEngine.h"
30+
#include "HoudiniEngineUtils.h"
31+
#include "FoliageType_InstancedStaticMesh.h"
32+
#include "HoudiniGenericAttribute.h"
33+
#include "HoudiniInputTranslator.h"
34+
35+
#include "Engine/StaticMesh.h"
36+
#include "Components/StaticMeshComponent.h"
37+
38+
39+
bool
40+
FUnrealFoliageTypeTranslator::HapiCreateInputNodeForFoliageType_InstancedStaticMesh(
41+
UFoliageType_InstancedStaticMesh* InFoliageType,
42+
HAPI_NodeId& InputObjectNodeId,
43+
const FString& InputNodeName,
44+
const bool& ExportAllLODs,
45+
const bool& ExportSockets,
46+
const bool& ExportColliders)
47+
{
48+
if (!IsValid(InFoliageType))
49+
return false;
50+
51+
UStaticMesh* const InputSM = InFoliageType->GetStaticMesh();
52+
if (!IsValid(InputSM))
53+
return false;
54+
55+
UStaticMeshComponent* const StaticMeshComponent = nullptr;
56+
bool bSuccess = HapiCreateInputNodeForStaticMesh(
57+
InputSM,
58+
InputObjectNodeId,
59+
InputNodeName,
60+
StaticMeshComponent,
61+
ExportAllLODs,
62+
ExportSockets,
63+
ExportColliders);
64+
65+
if (bSuccess)
66+
{
67+
const int32 PartId = 0;
68+
CreateHoudiniFoliageTypeAttributes(InFoliageType, InputObjectNodeId, PartId, HAPI_ATTROWNER_DETAIL);
69+
70+
HOUDINI_CHECK_ERROR_RETURN(FHoudiniApi::CommitGeo(
71+
FHoudiniEngine::Get().GetSession(), InputObjectNodeId), false);
72+
}
73+
74+
return bSuccess;
75+
}
76+
77+
bool FUnrealFoliageTypeTranslator::CreateInputNodeForReference(
78+
UFoliageType* InFoliageType,
79+
HAPI_NodeId& InInputNodeId,
80+
const FString& InRef,
81+
const FString& InInputNodeName,
82+
const FTransform& InTransform)
83+
{
84+
bool bSuccess = FHoudiniInputTranslator::CreateInputNodeForReference(InInputNodeId, InRef, InInputNodeName, InTransform);
85+
if (!bSuccess)
86+
return false;
87+
88+
const int32 PartId = 0;
89+
if (CreateHoudiniFoliageTypeAttributes(InFoliageType, InInputNodeId, PartId, HAPI_ATTROWNER_POINT))
90+
{
91+
HOUDINI_CHECK_ERROR_RETURN(FHoudiniApi::CommitGeo(
92+
FHoudiniEngine::Get().GetSession(), InInputNodeId), false);
93+
return true;
94+
}
95+
96+
return false;
97+
}
98+
99+
bool
100+
FUnrealFoliageTypeTranslator::CreateHoudiniFoliageTypeAttributes(UFoliageType* InFoliageType, const int32& InNodeId, const int32& InPartId, HAPI_AttributeOwner InAttributeOwner)
101+
{
102+
if (InNodeId < 0)
103+
return false;
104+
105+
bool bSuccess = true;
106+
107+
// Create attribute for unreal_foliage
108+
HAPI_AttributeInfo AttributeInfoUnrealFoliage;
109+
FHoudiniApi::AttributeInfo_Init(&AttributeInfoUnrealFoliage);
110+
AttributeInfoUnrealFoliage.tupleSize = 1;
111+
AttributeInfoUnrealFoliage.count = 1;
112+
AttributeInfoUnrealFoliage.exists = true;
113+
AttributeInfoUnrealFoliage.owner = InAttributeOwner;
114+
AttributeInfoUnrealFoliage.storage = HAPI_STORAGETYPE_INT;
115+
AttributeInfoUnrealFoliage.originalOwner = HAPI_ATTROWNER_INVALID;
116+
117+
// Create the new attribute
118+
if (HAPI_RESULT_SUCCESS == FHoudiniApi::AddAttribute(
119+
FHoudiniEngine::Get().GetSession(),
120+
InNodeId, InPartId, HAPI_UNREAL_ATTRIB_FOLIAGE_INSTANCER, &AttributeInfoUnrealFoliage))
121+
{
122+
// The New attribute has been successfully created, set its value
123+
int UnrealFoliage = 1;
124+
if (HAPI_RESULT_SUCCESS != FHoudiniApi::SetAttributeIntData(
125+
FHoudiniEngine::Get().GetSession(),
126+
InNodeId, InPartId, HAPI_UNREAL_ATTRIB_FOLIAGE_INSTANCER, &AttributeInfoUnrealFoliage,
127+
&UnrealFoliage, 0, 1))
128+
{
129+
bSuccess = false;
130+
}
131+
}
132+
133+
if (!bSuccess)
134+
return false;
135+
136+
// Foliage type properties that should be sent to Houdini as unreal_uproperty_ attributes.
137+
static TArray<FName> FoliageTypePropertyNames({
138+
// float
139+
// FName("Density"),
140+
// FName("DensityAdjustmentFactor"),
141+
// FName("Radius"),
142+
// FName("SingleInstanceModeRadius"),
143+
FName("AlignMaxAngle"),
144+
FName("RandomPitchAngle"),
145+
FName("MinimumLayerWeight"),
146+
FName("MinimumExclusionLayerWeight"),
147+
FName("CollisionRadius"),
148+
FName("ShadeRadius"),
149+
FName("InitialSeedDensity"),
150+
FName("AverageSpreadDistance"),
151+
FName("SpreadVariance"),
152+
FName("MaxInitialSeedOffset"),
153+
FName("MaxInitialAge"),
154+
FName("MaxAge"),
155+
FName("OverlapPriority"),
156+
157+
// bool
158+
// FName("bSingleInstanceModeOverrideRadius"),
159+
FName("bCanGrowInShade"),
160+
FName("bSpawnsInShade"),
161+
162+
// int32
163+
FName("OverriddenLightMapRes"),
164+
FName("CustomDepthStencilValue"),
165+
FName("TranslucencySortPriority"),
166+
FName("NumSteps"),
167+
FName("SeedsPerStep"),
168+
FName("DistributionSeed"),
169+
FName("ChangeCount"),
170+
FName("VirtualTextureCullMips"),
171+
172+
// uint32
173+
FName("AlignToNormal"),
174+
FName("RandomYaw"),
175+
FName("CollisionWithWorld"),
176+
FName("CastShadow"),
177+
FName("bAffectDynamicIndirectLighting"),
178+
FName("bAffectDistanceFieldLighting"),
179+
FName("bCastDynamicShadow"),
180+
FName("bCastStaticShadow"),
181+
FName("bCastShadowAsTwoSided"),
182+
FName("bReceivesDecals"),
183+
FName("bOverrideLightMapRes"),
184+
FName("bUseAsOccluder"),
185+
FName("bRenderCustomDepth"),
186+
FName("ReapplyDensity"),
187+
FName("ReapplyRadius"),
188+
FName("ReapplyAlignToNormal"),
189+
FName("ReapplyRandomYaw"),
190+
FName("ReapplyScaling"),
191+
FName("ReapplyScaleX"),
192+
FName("ReapplyScaleY"),
193+
FName("ReapplyScaleZ"),
194+
FName("ReapplyRandomPitchAngle"),
195+
FName("ReapplyGroundSlope"),
196+
FName("ReapplyHeight"),
197+
FName("ReapplyLandscapeLayers"),
198+
FName("ReapplyZOffset"),
199+
FName("ReapplyCollisionWithWorld"),
200+
FName("ReapplyVertexColorMask"),
201+
FName("bEnableDensityScaling"),
202+
FName("bEnableDiscardOnLoad"),
203+
204+
// enums
205+
// FName("Scaling"),
206+
FName("LightmapType"),
207+
208+
// FFloatInterval
209+
// FName("ScaleX"),
210+
// FName("ScaleY"),
211+
// FName("ScaleZ"),
212+
FName("ZOffset"),
213+
FName("GroundSlopeAngle"),
214+
FName("Height"),
215+
FName("ProceduralScale"),
216+
217+
// FVector
218+
FName("CollisionScale"),
219+
FName("LowBoundOriginRadius")});
220+
221+
EAttribOwner AttribOwner;
222+
switch (InAttributeOwner)
223+
{
224+
case HAPI_ATTROWNER_POINT:
225+
AttribOwner = EAttribOwner::Point;
226+
break;
227+
case HAPI_ATTROWNER_VERTEX:
228+
AttribOwner = EAttribOwner::Vertex;
229+
break;
230+
case HAPI_ATTROWNER_PRIM:
231+
AttribOwner = EAttribOwner::Prim;
232+
break;
233+
case HAPI_ATTROWNER_DETAIL:
234+
AttribOwner = EAttribOwner::Detail;
235+
break;
236+
case HAPI_ATTROWNER_INVALID:
237+
case HAPI_ATTROWNER_MAX:
238+
default:
239+
HOUDINI_LOG_WARNING(TEXT("Unsupported Attribute Owner: %d"), InAttributeOwner);
240+
return false;
241+
}
242+
FHoudiniGenericAttribute GenericAttribute;
243+
GenericAttribute.AttributeCount = 1;
244+
GenericAttribute.AttributeOwner = AttribOwner;
245+
246+
// Reserve enough space in the arrays (we only have a single point (or all are detail attributes), so attribute
247+
// count is 1, but the tuple size could be up to 10 for transforms
248+
GenericAttribute.DoubleValues.Reserve(10);
249+
GenericAttribute.IntValues.Reserve(10);
250+
GenericAttribute.StringValues.Reserve(10);
251+
252+
for (const FName& PropertyName : FoliageTypePropertyNames)
253+
{
254+
const FString PropertyNameStr = PropertyName.ToString();
255+
GenericAttribute.AttributeName = FString::Printf(TEXT("unreal_uproperty_%s"), *PropertyNameStr);
256+
// Find the property on the foliage type instance
257+
FProperty* FoundProperty = nullptr;
258+
UObject* FoundPropertyObject = nullptr;
259+
void* Container = nullptr;
260+
if (!FHoudiniGenericAttribute::FindPropertyOnObject(
261+
InFoliageType,
262+
PropertyNameStr,
263+
FoundProperty,
264+
FoundPropertyObject,
265+
Container))
266+
continue;
267+
268+
if (!FHoudiniGenericAttribute::GetAttributeTupleSizeAndStorageFromProperty(
269+
InFoliageType,
270+
FoundProperty,
271+
Container,
272+
GenericAttribute.AttributeTupleSize,
273+
GenericAttribute.AttributeType))
274+
continue;
275+
276+
const int32 AtIndex = 0;
277+
if (!FHoudiniGenericAttribute::GetPropertyValueFromObject(
278+
InFoliageType,
279+
FoundProperty,
280+
Container,
281+
GenericAttribute,
282+
AtIndex))
283+
continue;
284+
285+
FHoudiniEngineUtils::SetGenericPropertyAttribute(InNodeId, InPartId, GenericAttribute);
286+
}
287+
288+
return bSuccess;
289+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) <2021> Side Effects Software Inc.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* 1. Redistributions of source code must retain the above copyright notice,
9+
* this list of conditions and the following disclaimer.
10+
*
11+
* 2. The name of Side Effects Software may not be used to endorse or
12+
* promote products derived from this software without specific prior
13+
* written permission.
14+
*
15+
* THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE "AS IS" AND ANY EXPRESS
16+
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
18+
* NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
19+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
21+
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22+
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24+
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25+
*/
26+
27+
#pragma once
28+
29+
#include "HAPI/HAPI_Common.h"
30+
31+
#include "CoreMinimal.h"
32+
#include "UObject/ObjectMacros.h"
33+
34+
#include "UnrealMeshTranslator.h"
35+
36+
class UFoliageType;
37+
class UFoliageType_InstancedStaticMesh;
38+
class UStaticMeshComponent;
39+
40+
struct HOUDINIENGINE_API FUnrealFoliageTypeTranslator : public FUnrealMeshTranslator
41+
{
42+
public:
43+
// HAPI : Marshaling, extract geometry and create input asset for it - return true on success
44+
static bool HapiCreateInputNodeForFoliageType_InstancedStaticMesh(
45+
UFoliageType_InstancedStaticMesh* InFoliageType,
46+
HAPI_NodeId& InputObjectNodeId,
47+
const FString& InputNodeName,
48+
const bool& ExportAllLODs = false,
49+
const bool& ExportSockets = false,
50+
const bool& ExportColliders = false);
51+
52+
// Create an input node that references the asset via InRef (unreal_instance).
53+
// Also calls CreateHoudiniFoliageTypeAttributes, to create the unreal_foliage attribute, as well as
54+
// unreal_uproperty_ attributes for the foliage type settings.
55+
static bool CreateInputNodeForReference(
56+
UFoliageType* InFoliageType,
57+
HAPI_NodeId& InInputNodeId,
58+
const FString& InRef,
59+
const FString& InInputNodeName,
60+
const FTransform& InTransform);
61+
62+
protected:
63+
// Creates the unreal_foliage and unreal_uproperty_ attributes for the foliage type.
64+
static bool CreateHoudiniFoliageTypeAttributes(
65+
UFoliageType* InFoliageType, const int32& InNodeId, const int32& InPartId, HAPI_AttributeOwner InAttributeOwner);
66+
};

0 commit comments

Comments
 (0)