2626#include " Materials/MaterialExpressionFunctionOutput.h"
2727#include " Materials/MaterialExpressionIf.h"
2828#include " Materials/MaterialExpressionMaterialFunctionCall.h"
29+ #include " Materials/MaterialExpressionPerInstanceCustomData.h"
30+ #include " Materials/MaterialExpressionRound.h"
2931#include " Materials/MaterialExpressionScalarParameter.h"
3032#include " Materials/MaterialExpressionSetMaterialAttributes.h"
3133#include " Materials/MaterialExpressionTextureCoordinate.h"
@@ -268,9 +270,15 @@ void AutoFillPropertyTextureDescriptions(
268270void AutoFillFeatureIdSetDescriptions (
269271 TArray<FCesiumFeatureIdSetDescription>& Descriptions,
270272 const FCesiumPrimitiveFeatures& Features,
273+ const FCesiumPrimitiveFeatures* InstanceFeatures,
271274 const TArray<FCesiumPropertyTable>& PropertyTables) {
272- const TArray<FCesiumFeatureIdSet> featureIDSets =
275+ TArray<FCesiumFeatureIdSet> featureIDSets =
273276 UCesiumPrimitiveFeaturesBlueprintLibrary::GetFeatureIDSets (Features);
277+ if (InstanceFeatures) {
278+ featureIDSets.Append (
279+ UCesiumPrimitiveFeaturesBlueprintLibrary::GetFeatureIDSets (
280+ *InstanceFeatures));
281+ }
274282 int32 featureIDTextureCounter = 0 ;
275283
276284 for (const FCesiumFeatureIdSet& featureIDSet : featureIDSets) {
@@ -385,9 +393,16 @@ void UCesiumFeaturesMetadataComponent::AutoFill() {
385393 const TArray<FCesiumPropertyTable>& propertyTables =
386394 UCesiumModelMetadataBlueprintLibrary::GetPropertyTables (
387395 modelMetadata);
396+ const FCesiumPrimitiveFeatures* pInstanceFeatures = nullptr ;
397+ const auto * pInstancedComponent =
398+ Cast<UCesiumGltfInstancedComponent>(pChildComponent);
399+ if (pInstancedComponent) {
400+ pInstanceFeatures = pInstancedComponent->pInstanceFeatures .Get ();
401+ }
388402 AutoFillFeatureIdSetDescriptions (
389403 this ->FeatureIdSets ,
390404 primitiveFeatures,
405+ pInstanceFeatures,
391406 propertyTables);
392407
393408 const FCesiumPrimitiveMetadata& primitiveMetadata = primData.Metadata ;
@@ -438,6 +453,7 @@ struct MaterialFunctionLibrary {
438453 UMaterialFunction* TransformTexCoords = nullptr ;
439454 UMaterialFunction* GetFeatureIdsFromAttribute = nullptr ;
440455 UMaterialFunction* GetFeatureIdsFromTexture = nullptr ;
456+ UMaterialFunction* GetFeatureIdsFromInstance = nullptr ;
441457
442458 MaterialFunctionLibrary ()
443459 : SelectTexCoords(LoadMaterialFunction(
@@ -447,13 +463,16 @@ struct MaterialFunctionLibrary {
447463 GetFeatureIdsFromAttribute(LoadMaterialFunction(
448464 " /CesiumForUnreal/Materials/MaterialFunctions/CesiumGetFeatureIdsFromAttribute.CesiumGetFeatureIdsFromAttribute" )),
449465 GetFeatureIdsFromTexture(LoadMaterialFunction(
450- " /CesiumForUnreal/Materials/MaterialFunctions/CesiumGetFeatureIdsFromTexture.CesiumGetFeatureIdsFromTexture" )) {
466+ " /CesiumForUnreal/Materials/MaterialFunctions/CesiumGetFeatureIdsFromTexture.CesiumGetFeatureIdsFromTexture" )),
467+ GetFeatureIdsFromInstance(LoadMaterialFunction(
468+ " /CesiumForUnreal/Materials/MaterialFunctions/CesiumGetFeatureIdsFromInstance.CesiumGetFeatureIdsFromInstance" )) {
451469 }
452470
453471 bool isValid () {
454472 return SelectTexCoords != nullptr &&
455473 GetFeatureIdsFromAttribute != nullptr &&
456- GetFeatureIdsFromTexture != nullptr ;
474+ GetFeatureIdsFromTexture != nullptr &&
475+ GetFeatureIdsFromInstance != nullptr ;
457476 }
458477};
459478} // namespace
@@ -468,7 +487,8 @@ static void ClassifyNodes(
468487 FunctionLibrary.GetFeatureIdsFromAttribute ;
469488 const UMaterialFunction* GetFeatureIdsFromTextureFunction =
470489 FunctionLibrary.GetFeatureIdsFromTexture ;
471-
490+ const UMaterialFunction* GetFeatureIdsFromInstanceFunction =
491+ FunctionLibrary.GetFeatureIdsFromInstance ;
472492 for (const TObjectPtr<UMaterialExpression>& Node :
473493 Layer->GetExpressionCollection ().Expressions ) {
474494 // Check if this node is marked as autogenerated.
@@ -507,7 +527,8 @@ static void ClassifyNodes(
507527
508528 const FName& name = FunctionCallNode->MaterialFunction ->GetFName ();
509529 if (name == GetFeatureIdsFromAttributeFunction->GetFName () ||
510- name == GetFeatureIdsFromTextureFunction->GetFName ()) {
530+ name == GetFeatureIdsFromTextureFunction->GetFName () ||
531+ name == GetFeatureIdsFromInstanceFunction->GetFName ()) {
511532 Classification.GetFeatureIdNodes .Add (FunctionCallNode);
512533 }
513534 } else {
@@ -742,15 +763,17 @@ static void RemapUserConnections(
742763 for (UMaterialExpressionMaterialFunctionCall* GetFeatureIdNode :
743764 Classification.GetFeatureIdNodes ) {
744765 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 ();
748770
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+ }
754777 }
755778 }
756779 }
@@ -1803,7 +1826,7 @@ void GenerateNodesForPropertyTable(
18031826 UMaterialFunctionMaterialLayer* TargetMaterialLayer,
18041827 int32& NodeX,
18051828 int32& NodeY,
1806- UMaterialExpressionMaterialFunctionCall* GetFeatureIdCall ) {
1829+ UMaterialExpression* GetFeatureExpression ) {
18071830 int32 BeginSectionX = NodeX;
18081831 // This value is used by parameters on the left side of the
18091832 // "GetPropertyValues" function...
@@ -1843,7 +1866,7 @@ void GenerateNodesForPropertyTable(
18431866
18441867 FCustomInput& FeatureIDInput = GetPropertyValuesFunction->Inputs [0 ];
18451868 FeatureIDInput.InputName = FName (" FeatureID" );
1846- FeatureIDInput.Input .Expression = GetFeatureIdCall ;
1869+ FeatureIDInput.Input .Expression = GetFeatureExpression ;
18471870
18481871 GetPropertyValuesFunction->AdditionalOutputs .Reserve (
18491872 PropertyTable.Properties .Num ());
@@ -2327,6 +2350,27 @@ void GenerateNodesForPropertyTexture(
23272350 NodeY = FMath::Max (PropertyDataSectionY, PropertyTransformsSectionY) + Incr;
23282351}
23292352
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+
23302374void GenerateMaterialNodes (
23312375 UCesiumFeaturesMetadataComponent* pComponent,
23322376 TArray<UMaterialExpression*>& AutoGeneratedNodes,
@@ -2348,17 +2392,25 @@ void GenerateMaterialNodes(
23482392 }
23492393
23502394 UMaterialExpressionMaterialFunctionCall* GetFeatureIdCall = nullptr ;
2395+ UMaterialExpression* LastNode = nullptr ;
23512396 if (featureIdSet.Type == ECesiumFeatureIdSetType::Texture) {
2352- GetFeatureIdCall = GenerateNodesForFeatureIdTexture (
2397+ LastNode = GenerateNodesForFeatureIdTexture (
23532398 featureIdSet,
23542399 AutoGeneratedNodes,
23552400 pComponent->TargetMaterialLayer ,
23562401 FunctionLibrary,
23572402 NodeX,
23582403 NodeY);
2404+ } else if (featureIdSet.Type == ECesiumFeatureIdSetType::Instance) {
2405+ LastNode = GenerateInstanceNodes (
2406+ AutoGeneratedNodes,
2407+ pComponent->TargetMaterialLayer ,
2408+ FunctionLibrary.GetFeatureIdsFromInstance ,
2409+ NodeX,
2410+ NodeY);
23592411 } else {
23602412 // Handle implicit feature IDs the same as feature ID attributes
2361- GetFeatureIdCall = GenerateNodesForFeatureIdAttribute (
2413+ LastNode = GenerateNodesForFeatureIdAttribute (
23622414 featureIdSet,
23632415 AutoGeneratedNodes,
23642416 pComponent->TargetMaterialLayer ,
@@ -2367,7 +2419,6 @@ void GenerateMaterialNodes(
23672419 NodeY);
23682420 }
23692421
2370- UMaterialExpression* LastNode = GetFeatureIdCall;
23712422 int32 BeginSectionY = NodeY;
23722423
23732424 if (!featureIdSet.PropertyTableName .IsEmpty ()) {
@@ -2386,7 +2437,7 @@ void GenerateMaterialNodes(
23862437 pComponent->TargetMaterialLayer ,
23872438 NodeX,
23882439 NodeY,
2389- GetFeatureIdCall );
2440+ LastNode );
23902441 GeneratedPropertyTableNames.Add (pPropertyTable->Name );
23912442 }
23922443 }
0 commit comments