Description

Following code works as a work around.
The code updates placement information of instances.


TMap<UFoliageType*, TArray<const FFoliageInstancePlacementInfo*>> AInstancedFoliageActor::GetInstancesForComponent(UActorComponent* InComponent)
{
	TMap<UFoliageType*, TArray<const FFoliageInstancePlacementInfo*>> Result;
	const auto BaseId = InstanceBaseCache.GetInstanceBaseId(InComponent);

	if (BaseId != FFoliageInstanceBaseCache::InvalidBaseId)
	{
#if 0
		for (auto& Pair : FoliageInfos)
		{
			const FFoliageInfo& Info = *Pair.Value;
			const auto* InstanceSet = Info.ComponentHash.Find(BaseId);
			if (InstanceSet)
			{
				TArray<const FFoliageInstancePlacementInfo*>& Array = Result.Add(Pair.Key, TArray<const FFoliageInstancePlacementInfo*>());
				Array.Empty(InstanceSet->Num());

				for (int32 InstanceIndex : *InstanceSet)
				{
					const FFoliageInstancePlacementInfo* Instance = &Info.Instances[InstanceIndex];
					Array.Add(Instance);
				}
			}
		}
#else
		const auto CurrentBaseInfo = InstanceBaseCache.GetInstanceBaseInfo(BaseId);
		const auto NewBaseInfo = InstanceBaseCache.UpdateInstanceBaseInfoTransform(InComponent);

		FMatrix DeltaTransfrom =
			FTranslationMatrix(-CurrentBaseInfo.CachedLocation) *
			FInverseRotationMatrix(CurrentBaseInfo.CachedRotation) *
			FScaleMatrix(NewBaseInfo.CachedDrawScale / CurrentBaseInfo.CachedDrawScale) *
			FRotationMatrix(NewBaseInfo.CachedRotation) *
			FTranslationMatrix(NewBaseInfo.CachedLocation);

		for (auto& Pair : FoliageInfos)
		{
			FFoliageInfo& Info = *Pair.Value;
			const auto* InstanceSet = Info.ComponentHash.Find(BaseId);
			if (InstanceSet)
			{
				TArray<const FFoliageInstancePlacementInfo*>& Array = Result.Add(Pair.Key, TArray<const FFoliageInstancePlacementInfo*>());
				Array.Empty(InstanceSet->Num());

				for (int32 InstanceIndex : *InstanceSet)
				{
					FFoliageInstancePlacementInfo& Instance = Info.Instances[InstanceIndex];

					FMatrix NewTransform =
						FRotationMatrix(Instance.Rotation) *
						FTranslationMatrix(Instance.Location) *
						DeltaTransfrom;

					// Update rotation and position
					Instance.Location = NewTransform.GetOrigin();
					Instance.Rotation = NewTransform.Rotator();
					Array.Add(&Instance);
				}
			}
		}
#endif
	}

	return Result;
}

Steps to Reproduce
  1. Create a empty basic level
  2. Place a static mesh & some foliage instances
  3. Save the level
  4. Create a new level using open world template
  5. Drag & drop a level asset(step 3) into the level
  6. Select it and break the level instance via right-click context menu

Result:

  Foliage instances is placed in wrong location 

 
[Link Removed]
[Link Removed]

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-190262 in the post.

1
Login to Vote

Unresolved
CreatedJul 8, 2023
UpdatedFeb 13, 2024