void FPrimitiveComponentDetails::CustomizeDetails( IDetailLayoutBuilder& DetailBuilder )
{
	// Get the objects being customized so we can enable/disable editing of 'Simulate Physics'
	DetailBuilder.GetObjectsBeingCustomized(ObjectsCustomized);

	// See if we are hiding Physics category
	TArray<FString> HideCategories;
	FEditorCategoryUtils::GetClassHideCategories(DetailBuilder.GetDetailsView().GetBaseClass(), HideCategories);

	if(!HideCategories.Contains("Materials"))
	{
		AddMaterialCategory(DetailBuilder);
	}

	TSharedRef<IPropertyHandle> MobilityHandle = DetailBuilder.GetProperty(GET_MEMBER_NAME_CHECKED(UPrimitiveComponent, Mobility), USceneComponent::StaticClass());
	MobilityHandle->SetToolTipText(LOCTEXT("PrimitiveMobilityTooltip", "Mobility for primitive components controls how they can be modified in game and therefore how they interact with lighting and physics.\n● A movable primitive component can be changed in game, but requires dynamic lighting and shadowing from lights which have a large performance cost.\n● A static primitive component can't be changed in game, but can have its lighting baked, which allows rendering to be very efficient."));


	if(!HideCategories.Contains("Physics"))
	{
		AddPhysicsCategory(DetailBuilder);
	}

	if (!HideCategories.Contains("Collision"))
	{
		AddCollisionCategory(DetailBuilder);
	}

	if(!HideCategories.Contains("Lighting"))
	{
		AddLightingCategory(DetailBuilder);
	}

	AddAdvancedSubCategory( DetailBuilder, "Rendering", "TextureStreaming" );
	AddAdvancedSubCategory( DetailBuilder, "Rendering", "LOD");
}
void FPrimitiveComponentDetails::CustomizeDetails( IDetailLayoutBuilder& DetailBuilder )
{
	TSharedRef<IPropertyHandle> MobilityHandle = DetailBuilder.GetProperty("Mobility", USceneComponent::StaticClass());
	MobilityHandle->SetToolTipText(LOCTEXT("PrimitiveMobilityTooltip", "Mobility for primitive components controls how they can be modified in game and therefore how they interact with lighting and physics.\n● A movable primitive component can be changed in game, but requires dynamic lighting and shadowing from lights which have a large performance cost.\n● A static primitive component can't be changed in game, but can have its lighting baked, which allows rendering to be very efficient.").ToString());

	if ( DetailBuilder.GetProperty("BodyInstance")->IsValidHandle() )
	{
		TSharedPtr<IPropertyHandle> BodyInstanceHandler = DetailBuilder.GetProperty("BodyInstance");
		uint32 NumChildren = 0;
		BodyInstanceHandler->GetNumChildren(NumChildren);

		// See if we are hiding Physics category
		TArray<FString> HideCategories;
		FEditorCategoryUtils::GetClassHideCategories(DetailBuilder.GetDetailsView().GetBaseClass(), HideCategories);
		if (!HideCategories.Contains(TEXT("Physics")))
		{
			IDetailCategoryBuilder& PhysicsCategory = DetailBuilder.EditCategory("Physics");

			// Get the objects being customized so we can enable/disable editing of 'Simulate Physics'
			DetailBuilder.GetObjectsBeingCustomized(ObjectsCustomized);

			bool bDisplayMass = true;
			bool bDisplayMassOverride = true;

			for (int32 i = 0; i < ObjectsCustomized.Num(); ++i)
			{
				if (ObjectsCustomized[i].IsValid() && ObjectsCustomized[i]->IsA(UDestructibleComponent::StaticClass()))
				{
					bDisplayMass = false;
					bDisplayMassOverride = false;
				}

				if (ObjectsCustomized[i].IsValid() && ObjectsCustomized[i]->IsA(USkeletalMeshComponent::StaticClass()))
				{
					bDisplayMassOverride = false;
				}
			}

			// add all physics properties now - after adding mass
			for (uint32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex)
			{
				TSharedPtr<IPropertyHandle> ChildProperty = BodyInstanceHandler->GetChildHandle(ChildIndex);
				FString Category = FObjectEditorUtils::GetCategory(ChildProperty->GetProperty());
				FString PropName = ChildProperty->GetProperty()->GetName();
				if (Category == TEXT("Physics"))
				{
					// Only permit modifying bSimulatePhysics when the body has some geometry.
					if (PropName == TEXT("bSimulatePhysics"))
					{
						PhysicsCategory.AddProperty(ChildProperty).EditCondition(TAttribute<bool>(this, &FPrimitiveComponentDetails::IsSimulatePhysicsEditable), NULL);
					}
					else if (PropName == TEXT("bUseAsyncScene"))
					{
						//we only enable bUseAsyncScene if the project uses an AsyncScene
						PhysicsCategory.AddProperty(ChildProperty).EditCondition(TAttribute<bool>(this, &FPrimitiveComponentDetails::IsUseAsyncEditable), NULL);
					}
					else if (PropName == TEXT("LockedAxisMode"))
					{
						LockedAxisProperty = ChildProperty;
						PhysicsCategory.AddProperty(ChildProperty);
					}
					else if (PropName == TEXT("CustomLockedAxis"))
					{
						//we only enable bUseAsyncScene if the project uses an AsyncScene
						PhysicsCategory.AddProperty(ChildProperty).Visibility(TAttribute<EVisibility>(this, &FPrimitiveComponentDetails::IsCustomLockedAxisSelected));
					}
					else if (PropName == TEXT("bAutoWeld"))
					{
						PhysicsCategory.AddProperty(ChildProperty).Visibility(TAttribute<EVisibility>(this, &FPrimitiveComponentDetails::IsAutoWeldVisible))
																  .EditCondition(TAttribute<bool>(this, &FPrimitiveComponentDetails::IsAutoWeldEditable), NULL);
					}
					else if (PropName == TEXT("bOverrideMass"))
					{
						if (bDisplayMassOverride)
						{
							PhysicsCategory.AddProperty(ChildProperty);
						}
					}
					else if (PropName == TEXT("MassInKg"))
					{
						
						if (bDisplayMass)
						{
							PhysicsCategory.AddCustomRow(TEXT("Mass"), false)
								.IsEnabled(TAttribute<bool>(this, &FPrimitiveComponentDetails::IsBodyMassEnabled))
								.NameContent()
								[
									ChildProperty->CreatePropertyNameWidget()
								]
							.ValueContent()
								[
									SNew(SVerticalBox)
									+ SVerticalBox::Slot()
									.AutoHeight()
									[
										SNew(SEditableTextBox)
										.Text(this, &FPrimitiveComponentDetails::OnGetBodyMass)
										.IsReadOnly(this, &FPrimitiveComponentDetails::IsBodyMassReadOnly)
										.Font(IDetailLayoutBuilder::GetDetailFont())
										.Visibility(this, &FPrimitiveComponentDetails::IsMassVisible, false)
									]

									+ SVerticalBox::Slot()
									.AutoHeight()
									[
										SNew(SVerticalBox)
										.Visibility(this, &FPrimitiveComponentDetails::IsMassVisible, true)
										+ SVerticalBox::Slot()
										.AutoHeight()
										[
											ChildProperty->CreatePropertyValueWidget()
										]
									]
									
								];
						}
					}
					else
					{
						PhysicsCategory.AddProperty(ChildProperty);
					}
				}
			}
		}

		// Collision
		{
			IDetailCategoryBuilder& CollisionCategory = DetailBuilder.EditCategory("Collision");

			// add all collision properties
			for (uint32 ChildIndex = 0; ChildIndex < NumChildren; ++ChildIndex)
			{
				TSharedPtr<IPropertyHandle> ChildProperty = BodyInstanceHandler->GetChildHandle(ChildIndex);
				FString Category = FObjectEditorUtils::GetCategory(ChildProperty->GetProperty());
				if (Category == TEXT("Collision"))
				{
					CollisionCategory.AddProperty(ChildProperty);
				}
			}
		}		
	}


	AddAdvancedSubCategory( DetailBuilder, "Rendering", "TextureStreaming" );
	AddAdvancedSubCategory( DetailBuilder, "Rendering", "LOD");
}