26
26
#include " Materials/MaterialExpressionFunctionOutput.h"
27
27
#include " Materials/MaterialExpressionIf.h"
28
28
#include " Materials/MaterialExpressionMaterialFunctionCall.h"
29
+ #include " Materials/MaterialExpressionPerInstanceCustomData.h"
30
+ #include " Materials/MaterialExpressionRound.h"
29
31
#include " Materials/MaterialExpressionScalarParameter.h"
30
32
#include " Materials/MaterialExpressionSetMaterialAttributes.h"
31
33
#include " Materials/MaterialExpressionTextureCoordinate.h"
@@ -268,9 +270,15 @@ void AutoFillPropertyTextureDescriptions(
268
270
void AutoFillFeatureIdSetDescriptions (
269
271
TArray<FCesiumFeatureIdSetDescription>& Descriptions,
270
272
const FCesiumPrimitiveFeatures& Features,
273
+ const FCesiumPrimitiveFeatures* InstanceFeatures,
271
274
const TArray<FCesiumPropertyTable>& PropertyTables) {
272
- const TArray<FCesiumFeatureIdSet> featureIDSets =
275
+ TArray<FCesiumFeatureIdSet> featureIDSets =
273
276
UCesiumPrimitiveFeaturesBlueprintLibrary::GetFeatureIDSets (Features);
277
+ if (InstanceFeatures) {
278
+ featureIDSets.Append (
279
+ UCesiumPrimitiveFeaturesBlueprintLibrary::GetFeatureIDSets (
280
+ *InstanceFeatures));
281
+ }
274
282
int32 featureIDTextureCounter = 0 ;
275
283
276
284
for (const FCesiumFeatureIdSet& featureIDSet : featureIDSets) {
@@ -385,9 +393,16 @@ void UCesiumFeaturesMetadataComponent::AutoFill() {
385
393
const TArray<FCesiumPropertyTable>& propertyTables =
386
394
UCesiumModelMetadataBlueprintLibrary::GetPropertyTables (
387
395
modelMetadata);
396
+ const FCesiumPrimitiveFeatures* pInstanceFeatures = nullptr ;
397
+ const auto * pInstancedComponent =
398
+ Cast<UCesiumGltfInstancedComponent>(pChildComponent);
399
+ if (pInstancedComponent) {
400
+ pInstanceFeatures = pInstancedComponent->pInstanceFeatures .Get ();
401
+ }
388
402
AutoFillFeatureIdSetDescriptions (
389
403
this ->FeatureIdSets ,
390
404
primitiveFeatures,
405
+ pInstanceFeatures,
391
406
propertyTables);
392
407
393
408
const FCesiumPrimitiveMetadata& primitiveMetadata = primData.Metadata ;
@@ -438,6 +453,7 @@ struct MaterialFunctionLibrary {
438
453
UMaterialFunction* TransformTexCoords = nullptr ;
439
454
UMaterialFunction* GetFeatureIdsFromAttribute = nullptr ;
440
455
UMaterialFunction* GetFeatureIdsFromTexture = nullptr ;
456
+ UMaterialFunction* GetFeatureIdsFromInstance = nullptr ;
441
457
442
458
MaterialFunctionLibrary ()
443
459
: SelectTexCoords(LoadMaterialFunction(
@@ -447,13 +463,16 @@ struct MaterialFunctionLibrary {
447
463
GetFeatureIdsFromAttribute(LoadMaterialFunction(
448
464
" /CesiumForUnreal/Materials/MaterialFunctions/CesiumGetFeatureIdsFromAttribute.CesiumGetFeatureIdsFromAttribute" )),
449
465
GetFeatureIdsFromTexture(LoadMaterialFunction(
450
- " /CesiumForUnreal/Materials/MaterialFunctions/CesiumGetFeatureIdsFromTexture.CesiumGetFeatureIdsFromTexture" )) {
466
+ " /CesiumForUnreal/Materials/MaterialFunctions/CesiumGetFeatureIdsFromTexture.CesiumGetFeatureIdsFromTexture" )),
467
+ GetFeatureIdsFromInstance(LoadMaterialFunction(
468
+ " /CesiumForUnreal/Materials/MaterialFunctions/CesiumGetFeatureIdsFromInstance.CesiumGetFeatureIdsFromInstance" )) {
451
469
}
452
470
453
471
bool isValid () {
454
472
return SelectTexCoords != nullptr &&
455
473
GetFeatureIdsFromAttribute != nullptr &&
456
- GetFeatureIdsFromTexture != nullptr ;
474
+ GetFeatureIdsFromTexture != nullptr &&
475
+ GetFeatureIdsFromInstance != nullptr ;
457
476
}
458
477
};
459
478
} // namespace
@@ -468,7 +487,8 @@ static void ClassifyNodes(
468
487
FunctionLibrary.GetFeatureIdsFromAttribute ;
469
488
const UMaterialFunction* GetFeatureIdsFromTextureFunction =
470
489
FunctionLibrary.GetFeatureIdsFromTexture ;
471
-
490
+ const UMaterialFunction* GetFeatureIdsFromInstanceFunction =
491
+ FunctionLibrary.GetFeatureIdsFromInstance ;
472
492
for (const TObjectPtr<UMaterialExpression>& Node :
473
493
Layer->GetExpressionCollection ().Expressions ) {
474
494
// Check if this node is marked as autogenerated.
@@ -507,7 +527,8 @@ static void ClassifyNodes(
507
527
508
528
const FName& name = FunctionCallNode->MaterialFunction ->GetFName ();
509
529
if (name == GetFeatureIdsFromAttributeFunction->GetFName () ||
510
- name == GetFeatureIdsFromTextureFunction->GetFName ()) {
530
+ name == GetFeatureIdsFromTextureFunction->GetFName () ||
531
+ name == GetFeatureIdsFromInstanceFunction->GetFName ()) {
511
532
Classification.GetFeatureIdNodes .Add (FunctionCallNode);
512
533
}
513
534
} else {
@@ -742,15 +763,17 @@ static void RemapUserConnections(
742
763
for (UMaterialExpressionMaterialFunctionCall* GetFeatureIdNode :
743
764
Classification.GetFeatureIdNodes ) {
744
765
const auto Inputs = GetFeatureIdNode->FunctionInputs ;
745
- const auto Parameter =
746
- Cast<UMaterialExpressionParameter>(Inputs[0 ].Input .Expression );
747
- FString ParameterName = Parameter->ParameterName .ToString ();
766
+ if (!Inputs.IsEmpty ()) {
767
+ const auto Parameter =
768
+ Cast<UMaterialExpressionParameter>(Inputs[0 ].Input .Expression );
769
+ FString ParameterName = Parameter->ParameterName .ToString ();
748
770
749
- FString Key = GetFeatureIdNode->GetDescription () + ParameterName;
750
- TArray<FExpressionInput*>* pConnections = ConnectionOutputRemap.Find (Key);
751
- if (pConnections) {
752
- for (FExpressionInput* pConnection : *pConnections) {
753
- pConnection->Connect (0 , GetFeatureIdNode);
771
+ FString Key = GetFeatureIdNode->GetDescription () + ParameterName;
772
+ TArray<FExpressionInput*>* pConnections = ConnectionOutputRemap.Find (Key);
773
+ if (pConnections) {
774
+ for (FExpressionInput* pConnection : *pConnections) {
775
+ pConnection->Connect (0 , GetFeatureIdNode);
776
+ }
754
777
}
755
778
}
756
779
}
@@ -1803,7 +1826,7 @@ void GenerateNodesForPropertyTable(
1803
1826
UMaterialFunctionMaterialLayer* TargetMaterialLayer,
1804
1827
int32& NodeX,
1805
1828
int32& NodeY,
1806
- UMaterialExpressionMaterialFunctionCall* GetFeatureIdCall ) {
1829
+ UMaterialExpression* GetFeatureExpression ) {
1807
1830
int32 BeginSectionX = NodeX;
1808
1831
// This value is used by parameters on the left side of the
1809
1832
// "GetPropertyValues" function...
@@ -1843,7 +1866,7 @@ void GenerateNodesForPropertyTable(
1843
1866
1844
1867
FCustomInput& FeatureIDInput = GetPropertyValuesFunction->Inputs [0 ];
1845
1868
FeatureIDInput.InputName = FName (" FeatureID" );
1846
- FeatureIDInput.Input .Expression = GetFeatureIdCall ;
1869
+ FeatureIDInput.Input .Expression = GetFeatureExpression ;
1847
1870
1848
1871
GetPropertyValuesFunction->AdditionalOutputs .Reserve (
1849
1872
PropertyTable.Properties .Num ());
@@ -2327,6 +2350,27 @@ void GenerateNodesForPropertyTexture(
2327
2350
NodeY = FMath::Max (PropertyDataSectionY, PropertyTransformsSectionY) + Incr;
2328
2351
}
2329
2352
2353
+ UMaterialExpression* GenerateInstanceNodes (
2354
+ TArray<UMaterialExpression*>& AutoGeneratedNodes,
2355
+ UMaterialFunctionMaterialLayer* TargetMaterialLayer,
2356
+ UMaterialFunction* GetFeatureIdsFromInstanceFunction,
2357
+ int32& NodeX,
2358
+ int32& NodeY) {
2359
+ UMaterialExpressionMaterialFunctionCall* GetFeatureIds =
2360
+ NewObject<UMaterialExpressionMaterialFunctionCall>(TargetMaterialLayer);
2361
+ GetFeatureIds->MaterialFunction = GetFeatureIdsFromInstanceFunction;
2362
+ GetFeatureIds->MaterialExpressionEditorX = NodeX;
2363
+ GetFeatureIds->MaterialExpressionEditorY = NodeY;
2364
+
2365
+ GetFeatureIdsFromInstanceFunction->GetInputsAndOutputs (
2366
+ GetFeatureIds->FunctionInputs ,
2367
+ GetFeatureIds->FunctionOutputs );
2368
+
2369
+ NodeX += 2 * Incr;
2370
+ AutoGeneratedNodes.Add (GetFeatureIds);
2371
+ return GetFeatureIds;
2372
+ }
2373
+
2330
2374
void GenerateMaterialNodes (
2331
2375
UCesiumFeaturesMetadataComponent* pComponent,
2332
2376
TArray<UMaterialExpression*>& AutoGeneratedNodes,
@@ -2348,17 +2392,25 @@ void GenerateMaterialNodes(
2348
2392
}
2349
2393
2350
2394
UMaterialExpressionMaterialFunctionCall* GetFeatureIdCall = nullptr ;
2395
+ UMaterialExpression* LastNode = nullptr ;
2351
2396
if (featureIdSet.Type == ECesiumFeatureIdSetType::Texture) {
2352
- GetFeatureIdCall = GenerateNodesForFeatureIdTexture (
2397
+ LastNode = GenerateNodesForFeatureIdTexture (
2353
2398
featureIdSet,
2354
2399
AutoGeneratedNodes,
2355
2400
pComponent->TargetMaterialLayer ,
2356
2401
FunctionLibrary,
2357
2402
NodeX,
2358
2403
NodeY);
2404
+ } else if (featureIdSet.Type == ECesiumFeatureIdSetType::Instance) {
2405
+ LastNode = GenerateInstanceNodes (
2406
+ AutoGeneratedNodes,
2407
+ pComponent->TargetMaterialLayer ,
2408
+ FunctionLibrary.GetFeatureIdsFromInstance ,
2409
+ NodeX,
2410
+ NodeY);
2359
2411
} else {
2360
2412
// Handle implicit feature IDs the same as feature ID attributes
2361
- GetFeatureIdCall = GenerateNodesForFeatureIdAttribute (
2413
+ LastNode = GenerateNodesForFeatureIdAttribute (
2362
2414
featureIdSet,
2363
2415
AutoGeneratedNodes,
2364
2416
pComponent->TargetMaterialLayer ,
@@ -2367,7 +2419,6 @@ void GenerateMaterialNodes(
2367
2419
NodeY);
2368
2420
}
2369
2421
2370
- UMaterialExpression* LastNode = GetFeatureIdCall;
2371
2422
int32 BeginSectionY = NodeY;
2372
2423
2373
2424
if (!featureIdSet.PropertyTableName .IsEmpty ()) {
@@ -2386,7 +2437,7 @@ void GenerateMaterialNodes(
2386
2437
pComponent->TargetMaterialLayer ,
2387
2438
NodeX,
2388
2439
NodeY,
2389
- GetFeatureIdCall );
2440
+ LastNode );
2390
2441
GeneratedPropertyTableNames.Add (pPropertyTable->Name );
2391
2442
}
2392
2443
}
0 commit comments