zoukankan      html  css  js  c++  java
  • UE3植被工具-支持刷Actor)

    【目标】

    植被工具-刷Actor

    【思路】

    1 添加类型FFoliageMeshInfo.AddInstance 的函数

     

     

    2 添加Instance就直接SpawnActor

     

     

    3 类结构


     

    4 修改的函数

    FEdModeFoliage.AddInstancesForBrush.

     

    FEdModeFoliage.AddFoliageMesh 

     

     

     

     

    【步骤】

    1 添加AcheType支持,添加FEdModeFoliage.AddFoliageAcheType 

     

     

    2 添加一个AActor的表,用于记录ArcheType

     

    1. var    const native Map_MirrorFoliageArcheTypes{TMap<classAActor*,structFFoliageMeshInfo>};
     

     

    MFoliageEditWindow.OnDrop,资源拖到面板上

     

    1. else
      {
      AActor*ArcheTypeActor=LoadObject<AActor>(NULL,*CurInfo.ObjectPathName, NULL, LOAD_None, NULL);
      if(ArcheTypeActor&&ArchetypeActor->HasAnyFlags(RF_ArchetypeObject))
      {
      FoliageEditSystem->AddFoliageAcheType(ArcheTypeActor);
      FoliageMeshesProperty->NotifyChanged();
      }
      }
     
    MFoliageEditWindow.OnDragOver 过滤不支持的类型,添加Actor类型的支持
    1. for(TArray<FSelectedAssetInfo>::TConstIteratorDroppedAssetsIter(*(DroppedAssets.Get()));DroppedAssetsIter;++DroppedAssetsIter)
      {
      constFSelectedAssetInfo&CurInfo=*DroppedAssetsIter;
      if(CurInfo.ObjectClass!=UStaticMesh::StaticClass()&&CurInfo.ObjectClass!=AActor::StaticClass())
      {
      Args->Effects=DragDropEffects::None;
      break;
      }
    还是拖不上去
    在MFoliageEditWindow.OnDragEnter 中有
     
     
     
    需要设置这个才能调试
     
     

    MFoliageEditWindow.OnDragOver 改成 IsChildOf 判断

     

    1. voidOnDragOver(Object^Owner,DragEventArgs^Args)
      {
      Args->Effects=DragDropEffects::Copy;
      if(DroppedAssets.Get()!= NULL )
      {
      for(TArray<FSelectedAssetInfo>::TConstIteratorDroppedAssetsIter(*(DroppedAssets.Get()));DroppedAssetsIter;++DroppedAssetsIter)
      {
      constFSelectedAssetInfo&CurInfo=*DroppedAssetsIter;
      if(CurInfo.ObjectClass!=UStaticMesh::StaticClass()&&!CurInfo.ObjectClass->IsChildOf(AActor::StaticClass()))
      {
      Args->Effects=DragDropEffects::None;
      break;
      }
      }
      }
      Args->Handled= TRUE;
      }
     

     

    5 目前拖上去没有效果显示,

    MFoliageMeshWrapper 


    列表和FEdModeFoliage.GetFoliageMeshList 绑定了,所以显示了FFoliageMeshUIInfo列表

     

     

    6 添加FFoliageArcheTypeUIInfo 继承于FFoliageMeshUIInfo 

     

    1. 1 structFFoliageResourceUIInfo:publicFFoliageMeshUIInfo
      2 {
      3 AActor*ArcheTypeActor;
      4 FFoliageResourceUIInfo(UStaticMesh*InStaticMesh,AActor*InArcheTypeActor,FFoliageMeshInfo*InMeshInfo)
      5 :FFoliageMeshUIInfo(InStaticMesh,InMeshInfo)
      6 :ArcheTypeActor(InArcheTypeActor)
      7 {}
      8 };
     

     

    FEdModeFoliage.GetFoliageMeshList 返回值

     

    1. 1 TArray<structFFoliageResourceUIInfo>&GetFoliageMeshList();
     

    FEdModeFoliage.FoliageMeshList 

     

    1. // Placed level data
      TArray<structFFoliageResourceUIInfo>FoliageMeshList;
     

    9

     

    1. 1 IMPLEMENT_COMPARE_CONSTREF(FFoliageResourceUIInfo,FoliageEdMode,{return A.MeshInfo->Settings->DisplayOrder- B.MeshInfo->Settings->DisplayOrder;});
     

    10 FEdModeFoliage.UpdateFoliageMeshList 

     

    1.  1 voidFEdModeFoliage::UpdateFoliageMeshList()
       2 {
       3 FoliageMeshList.Empty();
       4 AInstancedFoliageActor* IFA =AInstancedFoliageActor::GetInstancedFoliageActor();
       5 for(TMap<classUStaticMesh*,structFFoliageMeshInfo>::TIteratorMeshIt(IFA->FoliageMeshes);MeshIt;++MeshIt)
       6 {
       7 new(FoliageMeshList)FFoliageResourceUIInfo(MeshIt.Key(),NULL,&MeshIt.Value());
       8 }
       9 for(TMap<classAActor*,structFFoliageMeshInfo>::TIteratorArcheTypeIt(IFA->FoliageArcheTypes);ArcheTypeIt;++ArcheTypeIt)
      10 {
      11 new(FoliageArcheTypeList)FFoliageResourceUIInfo(NULL,ArcheTypeIt.Key(),&ArcheTypeIt.Value());
      12 }
      13 Sort<USE_COMPARE_CONSTREF(FFoliageResourceUIInfo,FoliageEdMode)>(&FoliageMeshList(0),FoliageMeshList.Num());
      14 }
     

    11 MFoliageMeshWrapper 类构造需要用新类FFoliageResourceUIInfo 

     

    1.  1 ref classMFoliageMeshWrapper:publicINotifyPropertyChanged
       2 {
       3 int index;
       4 FFoliageResourceUIInfo& mesh;
       5 UInstancedFoliageSettings* settings;
       6 BitmapSource^ bitmap;
       7 public:
       8 virtual event PropertyChangedEventHandler^PropertyChanged;
       9 MFoliageMeshWrapper( INT InIndex,FFoliageResourceUIInfo&InMesh)
      10 :    index(InIndex)
      11 ,    mesh(InMesh)
      12 ,    settings(mesh.MeshInfo->Settings)
      13 {
      14 if(mesh.StaticMesh)
      15 bitmap =ThumbnailToolsCLR::GetBitmapSourceForObject(mesh.StaticMesh);
      16 elseif(mesh.ArcheTypeActor)
      17 bitmap =ThumbnailToolsCLR::GetBitmapSourceForObject(mesh.ArcheTypeActor);
      18 }
     

    12

     

    1. typedefMEnumerableTArrayWrapper<MFoliageMeshWrapper,FFoliageResourceUIInfo>MFoliageMeshes;
     
    终于看到效果了
     

    13 跟FFoliageMeshUIInfo.StaticMesh 相关的修改

    MFoliageMeshWrapper.StaticMeshName.get  获取名字的

     

    1. 1 propertyString^StaticMeshName{
      2 String^ get()
      3 {
      4 FStringName= mesh.StaticMesh? mesh.StaticMesh->GetName()? mesh.ArcheTypeActor->GetName();
      5 returnCLRTools::ToString(Name);
      6 }
      7 }
     
    MFoliageEditWindow.FoliageMeshRemoveButton_Click 
    1.  1 // Remove the current mesh
       2 voidFoliageMeshRemoveButton_Click(Object^Owner,ExecutedRoutedEventArgs^Args)
       3 {
       4 MFoliageMeshWrapper^Mesh= safe_cast<MFoliageMeshWrapper^>(Args->Parameter);
       5 if(Mesh->GetStaticMesh())
       6 FoliageEditSystem->RemoveFoliageMesh(Mesh->GetStaticMesh());
       7 else
       8 FoliageEditSystem->RemoveFoliageAcheType(Mesh->GetArcheTypeActor());
       9 FoliageMeshesProperty->NotifyChanged();
      10 }
     
     

    添加MFoliageMeshWrapper.GetStaticMesh 

     

    1. AActor*GetStaticMesh(){return mesh.ArcheTypeActor;}
     

    MFoliageEditWindow.FoliageMeshCopySettings_Click 

     

    1. voidFoliageMeshUseSettings_Click(Object^Owner,ExecutedRoutedEventArgs^Args)
      {
      GCallbackEvent->Send(CALLBACK_LoadSelectedAssetsIfNeeded);
      USelection*SelectedSet=GEditor->GetSelectedSet(UInstancedFoliageSettings::StaticClass());
      UInstancedFoliageSettings*SelectedSettings=Cast<UInstancedFoliageSettings>(SelectedSet->GetTop(UInstancedFoliageSettings::StaticClass()));
      if(SelectedSettings!= NULL )
      {
      MFoliageMeshWrapper^Mesh= safe_cast<MFoliageMeshWrapper^>(Args->Parameter);
      if(Mesh->GetStaticMesh())
      FoliageEditSystem->ReplaceSettingsObject(Mesh->GetStaticMesh(),SelectedSettings);
      else
      FoliageEditSystem->ReplaceSettingsObject(Mesh->GetArcheTypeActor(),SelectedSettings);
     
    MFoliageEditWindow.FoliageMeshReplaceButton_Click 
    1. if(SelectedActor&&SelectedActor->HasAnyFlags(RF_ArchetypeObject))
      {
      MFoliageMeshWrapper^Mesh= safe_cast<MFoliageMeshWrapper^>(Args->Parameter);
      FoliageEditSystem->ReplaceArchtypeActor(Mesh->GetArcheTypeActor(),SelectedActor);
      FoliageMeshesProperty->NotifyChanged();
      }
     

     

     

    13 FEdModeFoliage.ReplaceArchtypeActor 

     

    1.  1 voidFEdModeFoliage::ReplaceArchtypeActor(AActor*OldArcheType,AActor*NewArcheType)
       2 {
       3 AInstancedFoliageActor* IFA =AInstancedFoliageActor::GetInstancedFoliageActor();
       4 FFoliageMeshInfo*OldMeshInfo= IFA->FoliageArcheTypes.Find(OldArcheType);
       5 if(OldMeshInfo!= NULL &&OldArcheType!=NewArcheType&&NewArcheType->HasAnyFlags(RF_ArchetypeObject))
       6 {
       7 INT InstancesNum=OldMeshInfo->Instances.Num()-OldMeshInfo->FreeInstanceIndices.Num();
       8 // Look for the new mesh in the mesh list, and either create a new mesh or merge the instances.
       9 FFoliageMeshInfo*NewMeshInfo= IFA->FoliageArcheTypes.Find(NewArcheType);
      10 if(NewMeshInfo== NULL )
      11 {
      12 if(InstancesNum>0&&
      13 appMsgf(AMT_YesNo,LocalizeSecure(LocalizeUnrealEd("FoliageMode_ReplaceMesh"),InstancesNum,*OldArcheType->GetName(),*NewArcheType->GetName()))!= ART_Yes )
      14 {
      15 return;
      16 }
      17 GEditor->BeginTransaction(*LocalizeUnrealEd("FoliageMode_ChangeStaticMeshTransaction"));
      18 IFA->Modify();
      19 NewMeshInfo= IFA->AddArcheType(NewArcheType);
      20 NewMeshInfo->Settings->DisplayOrder=OldMeshInfo->Settings->DisplayOrder;
      21 NewMeshInfo->Settings->ShowNothing=OldMeshInfo->Settings->ShowNothing;
      22 NewMeshInfo->Settings->ShowPaintSettings=OldMeshInfo->Settings->ShowPaintSettings;
      23 NewMeshInfo->Settings->ShowInstanceSettings=OldMeshInfo->Settings->ShowInstanceSettings;
      24 }
      25 else
      26 if(InstancesNum>0&&
      27 appMsgf(AMT_YesNo,LocalizeSecure(LocalizeUnrealEd("FoliageMode_ReplaceMeshMerge"),InstancesNum,*OldArcheType->GetName(),*NewArcheType->GetName()))!= ART_Yes )
      28 {
      29 return;
      30 }
      31 else
      32 {
      33 GEditor->BeginTransaction(*LocalizeUnrealEd("FoliageMode_ChangeStaticMeshTransaction"));
      34 IFA->Modify();
      35 }
      36 if(InstancesNum>0)
      37 {
      38 // copy instances from old to new.
      39 for( INT Idx=0;Idx<OldMeshInfo->Instances.Num();Idx++)
      40 {
      41 if(OldMeshInfo->Instances(Idx).ClusterIndex!=-1)
      42 {
      43 NewMeshInfo->AddInstanceAT( IFA,NewArcheType,OldMeshInfo->Instances(Idx));
      44 }
      45 }
      46 }
      47 // Remove the old mesh.
      48 IFA->RemoveArcheType(OldArcheType);
      49 GEditor->EndTransaction();
      50 // Update mesh list.
      51 UpdateFoliageMeshList();
      52 }
      53 }
     

     

    14 添加FFoliageMeshInfo.AddInstanceAT 

     

    1. 1 voidFFoliageMeshInfo::AddInstanceAT(classAInstancedFoliageActor*InIFA,classAActor*InActor,constFFoliageInstance&InNewInstance)
      2 {
      3 }
     

     

    目前是刷不上Actor模型吗,主要是FEdModeFoliage.ApplyBrush 函数里没有处理

    15 修改FEdModeFoliage.ApplyBrush 

     

    1.  1 // ArcheType
       2 for(TMap<classAActor*,structFFoliageMeshInfo>::TIteratorArcheTypeIt(IFA->FoliageArcheTypes);ArcheTypeIt;++ArcheTypeIt)
       3 {
       4 FFoliageMeshInfo&MeshInfo=ArcheTypeIt.Value();
       5 UInstancedFoliageSettings*MeshSettings=MeshInfo.Settings;
       6 if(MeshSettings->IsSelected)
       7 {
       8 // Find the instances already in the area.
       9 TArray<INT>Instances;
      10 FSphereBrushSphere(BrushLocation,UISettings.GetRadius());
      11 MeshInfo.GetInstancesInsideSphere(BrushSphere,Instances);
      12 if(UISettings.GetLassoSelectToolSelected())
      13 {
      14 // Shift unpaints
      15 MeshInfo.SelectInstances( IFA,!IsShiftDown(ViewportClient->Viewport),Instances);
      16 }
      17 else
      18 if(UISettings.GetReapplyToolSelected())
      19 {
      20 if(MeshSettings->ReapplyDensity)
      21 {
      22 // Adjust instance density
      23 FMeshInfoSnapshot*SnapShot=InstanceATSnapshot.Find(ArcheTypeIt.Key());
      24 if(SnapShot)
      25 {
      26 // Use snapshot to determine number of instances at the start of the brush stroke
      27 INT NewInstanceCount= appRound((FLOAT)SnapShot->CountInstancesInsideSphere(BrushSphere)*MeshSettings->ReapplyDensityAmount);
      28 if(MeshSettings->ReapplyDensityAmount>1.f&&NewInstanceCount>Instances.Num())
      29 {
      30 AddInstancesATForBrush( IFA,ArcheTypeIt.Key(),MeshInfo,NewInstanceCount,Instances,Pressure);
      31 }
      32 else
      33 if(MeshSettings->ReapplyDensityAmount<1.f&&NewInstanceCount<Instances.Num())
      34 {
      35 RemoveInstancesForBrush( IFA,MeshInfo,NewInstanceCount,Instances,Pressure);
      36 }
      37 }
      38 }
      39 // Reapply any settings checked by the user
      40 ReapplyInstancesForBrush( IFA,MeshInfo,Instances);
      41 }
      42 else
      43 if(UISettings.GetPaintToolSelected())
      44 {
      45 // Shift unpaints
      46 if(IsShiftDown(ViewportClient->Viewport))
      47 {
      48 INT DesiredInstanceCount= appRound(BrushArea*MeshSettings->Density*UISettings.GetUnpaintDensity()/(1000.f*1000.f));
      49 if(DesiredInstanceCount<Instances.Num())
      50 {
      51 RemoveInstancesForBrush( IFA,MeshInfo,DesiredInstanceCount,Instances,Pressure);
      52 }
      53 }
      54 else
      55 {
      56 // This is the total set of instances disregarding parameters like slope, height or layer.
      57 FLOAT DesiredInstanceCountFloat=BrushArea*MeshSettings->Density*UISettings.GetPaintDensity()/(1000.f*1000.f);
      58 // Allow a single instance with a random chance, if the brush is smaller than the density
      59 INT DesiredInstanceCount=DesiredInstanceCountFloat>1.f? appRound(DesiredInstanceCountFloat): appFrand()<DesiredInstanceCountFloat?1:0;
      60 AddInstancesATForBrush( IFA,ArcheTypeIt.Key(),MeshInfo,DesiredInstanceCount,Instances,Pressure);
      61 }
      62 }
      63 }
      64 }
     

     

    16 添加Instance的函数FEdModeFoliage.AddInstancesATForBrush 

     

    1.   1 /** Add instances inside the brush to match DesiredInstanceCount */
        2 voidFEdModeFoliage::AddInstancesATForBrush(AInstancedFoliageActor* IFA,AActor*AchetypeActor,FFoliageMeshInfo&MeshInfo, INT DesiredInstanceCount,TArray<INT>&ExistingInstances, FLOAT Pressure)
        3 {
        4 UInstancedFoliageSettings*MeshSettings=MeshInfo.Settings;
        5 if(DesiredInstanceCount>ExistingInstances.Num())
        6 {
        7 INT ExistingInstanceBuckets[NUM_INSTANCE_BUCKETS];
        8 appMemzero(ExistingInstanceBuckets,sizeof(ExistingInstanceBuckets));
        9 // Cache store mapping between component and weight data
       10 TMap<ULandscapeComponent*,TArray<BYTE>>*LandscapeLayerCache= NULL;
       11 FNameLandscapeLayerName=MeshSettings->LandscapeLayer;
       12 if(LandscapeLayerName!= NAME_None )
       13 {
       14 LandscapeLayerCache=&LandscapeLayerCaches.FindOrAdd(LandscapeLayerName);
       15 // Find the landscape weights of existing ExistingInstances
       16 for( INT Idx=0;Idx<ExistingInstances.Num();Idx++)
       17 {
       18 FFoliageInstance&Instance=MeshInfo.Instances(ExistingInstances(Idx));
       19 ULandscapeHeightfieldCollisionComponent*HitLandscapeCollision=Cast<ULandscapeHeightfieldCollisionComponent>(Instance.Base);
       20 if(HitLandscapeCollision)
       21 {
       22 ULandscapeComponent*HitLandscape=HitLandscapeCollision->GetLandscapeComponent();
       23 if(HitLandscape)
       24 {
       25 TArray<BYTE>*LayerCache=&LandscapeLayerCache->FindOrAdd(HitLandscape);
       26 FLOAT HitWeight=HitLandscape->GetLayerWeightAtLocation(Instance.Location,LandscapeLayerName,LayerCache);
       27 // Add count to bucket.
       28 ExistingInstanceBuckets[appRound(HitWeight*(FLOAT)(NUM_INSTANCE_BUCKETS-1))]++;
       29 }
       30 }
       31 }
       32 }
       33 else
       34 {
       35 // When not tied to a layer, put all the ExistingInstances in the last bucket.
       36 ExistingInstanceBuckets[NUM_INSTANCE_BUCKETS-1]=ExistingInstances.Num();
       37 }
       38 // We calculate a set of potential ExistingInstances for the brush area.
       39 TArray<FPotentialInstance>PotentialInstanceBuckets[NUM_INSTANCE_BUCKETS];
       40 appMemzero(PotentialInstanceBuckets,sizeof(PotentialInstanceBuckets));
       41 // Quick lookup of potential instance locations, used for overlapping check.
       42 TArray<FVector>PotentialInstanceLocations;
       43 FFoliageInstanceHashPotentialInstanceHash(7);// use 128x128 cell size, as the brush radius is typically small.
       44 PotentialInstanceLocations.Empty(DesiredInstanceCount);
       45 // Radius where we expect to have a single instance, given the density rules
       46 const FLOAT DensityCheckRadius=Max<FLOAT>( appSqrt((1000.f*1000.f)/(PI *MeshSettings->Density)),MeshSettings->Radius);
       47 for( INT DesiredIdx=0;DesiredIdx<DesiredInstanceCount;DesiredIdx++)
       48 {
       49 FVectorStart,End;
       50 GetRandomVectorInBrush(Start,End);
       51 FCheckResultHit;
       52 if(!GWorld->SingleLineCheck(Hit, NULL,End,Start, TRACE_World | TRACE_Level,FVector(0.f,0.f,0.f), NULL))
       53 {
       54 // Check filters
       55 if((Hit.Component&&
       56 (Hit.Component->GetOutermost()!=GWorld->CurrentLevel->GetOutermost()||
       57 (!UISettings.bFilterLandscape &&Hit.Component->IsA(ULandscapeHeightfieldCollisionComponent::StaticClass()))||
       58 (!UISettings.bFilterStaticMesh &&Hit.Component->IsA(UStaticMeshComponent::StaticClass()))||
       59 (!UISettings.bFilterTerrain &&Hit.Component->IsA(UTerrainComponent::StaticClass()))))||
       60 (Hit.Actor&&Hit.Actor->IsA(AWorldInfo::StaticClass())&&(!UISettings.bFilterBSP ||GWorld->Levels(Hit.LevelIndex)!=GWorld->CurrentLevel)))
       61 {
       62 continue;
       63 }
       64 if(!CheckLocationForPotentialInstance(MeshInfo,MeshSettings,DensityCheckRadius,Hit.Location,Hit.Normal,PotentialInstanceLocations,PotentialInstanceHash))
       65 {
       66 continue;
       67 }
       68 // Check landscape layer
       69 FLOAT HitWeight=1.f;
       70 if(LandscapeLayerName!= NAME_None )
       71 {
       72 ULandscapeHeightfieldCollisionComponent*HitLandscapeCollision=Cast<ULandscapeHeightfieldCollisionComponent>(Hit.Component);
       73 if(HitLandscapeCollision)
       74 {
       75 ULandscapeComponent*HitLandscape=HitLandscapeCollision->GetLandscapeComponent();
       76 if(HitLandscape)
       77 {
       78 TArray<BYTE>*LayerCache=&LandscapeLayerCache->FindOrAdd(HitLandscape);
       79 HitWeight=HitLandscape->GetLayerWeightAtLocation(Hit.Location,LandscapeLayerName,LayerCache);
       80 // Reject instance randomly in proportion to weight
       81 if(HitWeight<= appFrand())
       82 {
       83 continue;
       84 }
       85 }
       86 }
       87 }
       88 new(PotentialInstanceBuckets[appRound(HitWeight*(FLOAT)(NUM_INSTANCE_BUCKETS-1))])FPotentialInstance(Hit.Location,Hit.Normal,Hit.Component,HitWeight);
       89 }
       90 }
       91 for( INT BucketIdx=0;BucketIdx< NUM_INSTANCE_BUCKETS;BucketIdx++)
       92 {
       93 TArray<FPotentialInstance>&PotentialInstances=PotentialInstanceBuckets[BucketIdx];
       94 FLOAT BucketFraction=(FLOAT)(BucketIdx+1)/(FLOAT)NUM_INSTANCE_BUCKETS;
       95 // We use the number that actually succeeded in placement (due to parameters) as the target
       96 // for the number that should be in the brush region.
       97 INT AdditionalInstances=Clamp<INT>( appRound(BucketFraction*(FLOAT)(PotentialInstances.Num()-ExistingInstanceBuckets[BucketIdx])*Pressure),0,PotentialInstances.Num());
       98 for( INT Idx=0;Idx<AdditionalInstances;Idx++)
       99 {
      100 FFoliageInstanceInst=PotentialInstances(Idx).PlaceInstance(MeshSettings);
      101 MeshInfo.AddInstanceAT( IFA,AchetypeActor,Inst);
      102 }
      103 }
      104 }
      105 }
     
    17 在FFoliageInstanceCluster 上添加Actor列表成员

     

    1.  1 structFFoliageInstanceCluster
       2 {
       3 UInstancedStaticMeshComponent*ClusterComponent;
       4 TArray<AActor*>ActorInstances;
       5 FFoliageInstanceCluster.GetInstanceCount 
       6 INT GetInstanceCount()
       7 {
       8 INT TotalCount=0;
       9 if(ClusterComponent)
      10 TotalCount+=ClusterComponent->PerInstanceSMData.Num();
      11 TotalCount+=ActorInstances.Num();
      12 }
     
     

     

    18 添加FFoliageMeshInfo.AddInstanceAT 

    1.  1 voidFFoliageMeshInfo::AddInstanceAT(classAInstancedFoliageActor*InIFA,classAActor*InArchetypeActor,constFFoliageInstance&InNewInstance)
       2 {
       3 InIFA->Modify();
       4 // Add the instance taking either a free slot or adding a new item.
       5 INT InstanceIndex=FreeInstanceIndices.Num()>0?FreeInstanceIndices.Pop():Instances.Add();
       6 FFoliageInstance&AddedInstance=Instances(InstanceIndex);
       7 AddedInstance=InNewInstance;
       8 // Add the instance to the hash
       9 InstanceHash->InsertInstance(InNewInstance.Location,InstanceIndex);
      10 FFoliageComponentHashInfo&ComponentHashInfo=ComponentHash.FindOrAddKey(InNewInstance.Base);
      11 ComponentHashInfo.Instances.Add(InstanceIndex);
      12 // Find the best cluster to allocate the instance to.
      13 FFoliageInstanceCluster*BestCluster= NULL;
      14 INT BestClusterIndex= INDEX_NONE;
      15 FLOAT BestClusterDistSq= FLT_MAX;
      16 INT MaxInstancesPerCluster=Settings->MaxInstancesPerCluster;
      17 FLOAT MaxClusterRadiusSq=Square(Settings->MaxClusterRadius);
      18 for( INT ClusterIdx=0;ClusterIdx<InstanceClusters.Num();ClusterIdx++)
      19 {
      20 FFoliageInstanceCluster&Cluster=InstanceClusters(ClusterIdx);
      21 if(Cluster.InstanceIndices.Num()<MaxInstancesPerCluster)
      22 {
      23 FLOAT DistSq=(Cluster.Bounds.Origin-InNewInstance.Location).SizeSquared();
      24 if(DistSq<BestClusterDistSq&&DistSq<MaxClusterRadiusSq)
      25 {
      26 BestCluster=&Cluster;
      27 BestClusterIndex=ClusterIdx;
      28 BestClusterDistSq=DistSq;
      29 }
      30 }
      31 }
      32 // Calculate transform for the instance
      33 FMatrixInstanceTransform=InNewInstance.GetInstanceTransform();
      34 if(BestCluster== NULL )
      35 {
      36 BestClusterIndex=InstanceClusters.Num();
      37 BestCluster=new(InstanceClusters)FFoliageInstanceCluster(
      38 NULL,
      39 FBoxSphereBounds()// LWF_TODO
      40 );
      41 //ApplyInstancedFoliageSettings( BestCluster->ClusterComponent );
      42 }
      43 else
      44 {
      45 // BestCluster->ClusterComponent->Modify();
      46 // BestCluster->ClusterComponent->InvalidateLightingCache();
      47 // BestCluster->Bounds = BestCluster->Bounds + InMesh->Bounds.TransformBy(InstanceTransform);
      48 }
      49 BestCluster->InstanceIndices.AddItem(InstanceIndex);
      50 // Save the cluster index
      51 AddedInstance.ClusterIndex=BestClusterIndex;
      52 // Add the instance to the ActorList
      53 AActor* pActor =GWorld->SpawnActor(InArchetypeActor->GetClass(), NAME_None,InNewInstance.Location,InNewInstance.Rotation,InArchetypeActor);// Spawn Actor
      54 BestCluster->ActorInstances.AddItem(pActor);
      55 // FInstancedStaticMeshInstanceData* NewInstanceData = new(BestCluster->ClusterComponent->PerInstanceSMData) FInstancedStaticMeshInstanceData();
      56 if(BestCluster->ClusterComponent->SelectedInstances.Num()>0)
      57 {
      58 BestCluster->ClusterComponent->SelectedInstances.AddItem(FALSE);
      59 }
      60 // NewInstanceData->Transform = InstanceTransform;
      61 // NewInstanceData->LightmapUVBias = FVector2D( -1.0f, -1.0f );
      62 // NewInstanceData->ShadowmapUVBias = FVector2D( -1.0f, -1.0f );
      63 // BestCluster->ClusterComponent->bNeedsReattach = TRUE;
      64 #if _DEBUG
      65 CheckValid();
      66 #endif
      67 InIFA->ConditionalUpdateComponents();
      68 }
     

     

     

     

    18 修改所有FFoliageInstanceCluster.ClusterComponent 的地方

    太多地方了

     

    FFoliageMeshInfo.CheckValid 

     

    终于能刷出东西来了


     

     



  • 相关阅读:
    nginx配置
    day5 业务开发中较有用代码
    day4 Vue基础
    npm vue的一些命令
    day3 ES6基础
    python_矩阵的加法和乘法计算(包括矩阵的动态输入,纯列表实现不引入其他模块)
    python_利用元组实现剪刀石头布
    python_整型与IP地址的转换
    python_判断标识符的合法性
    python_生成随机数与列表排序
  • 原文地址:https://www.cnblogs.com/username/p/5821186.html
Copyright © 2011-2022 走看看