136 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Mass扩展笔记
date: 2024-09-12 15:32:15
excerpt:
tags:
rating: ⭐
---
#
1. 创建 UMassEntityTraitBase UMassVisualizationTrait
2. 相关的渲染设置逻辑位于UMassVisualizationComponent。
# UMassVisualizationComponent
```c++
void UMassVisualizationComponent::ConstructStaticMeshComponents()
{
AActor* ActorOwner = GetOwner();
check(ActorOwner);
UE_MT_SCOPED_WRITE_ACCESS(InstancedStaticMeshInfosDetector);
for (FMassInstancedStaticMeshInfo& Info : InstancedStaticMeshInfos)
{
// Check if it is already created
if (!Info.InstancedStaticMeshComponents.IsEmpty())
{
continue;
}
// Check if there are any specified meshes for this visual type
if(Info.Desc.Meshes.Num() == 0)
{
UE_LOG(LogMassRepresentation, Error, TEXT("No associated meshes for this intanced static mesh type"));
continue;
}
for (const FStaticMeshInstanceVisualizationMeshDesc& MeshDesc : Info.Desc.Meshes)
{
FISMCSharedData* SharedData = ISMCSharedData.Find(MeshDesc);
UInstancedStaticMeshComponent* ISMC = SharedData ? SharedData->ISMC : nullptr;
if (SharedData)
{
SharedData->RefCount += 1;
}
else
{
ISMC = NewObject<UInstancedStaticMeshComponent>(ActorOwner);
ISMC->SetStaticMesh(MeshDesc.Mesh);
for (int32 ElementIndex = 0; ElementIndex < MeshDesc.MaterialOverrides.Num(); ++ElementIndex)
{
if (UMaterialInterface* MaterialOverride = MeshDesc.MaterialOverrides[ElementIndex])
{
ISMC->SetMaterial(ElementIndex, MaterialOverride);
}
}
ISMC->SetCullDistances(0, 1000000); // @todo: Need to figure out what to do here, either LOD or cull distances.
ISMC->SetupAttachment(ActorOwner->GetRootComponent());
ISMC->SetCanEverAffectNavigation(false);
ISMC->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
ISMC->SetCastShadow(MeshDesc.bCastShadows);
ISMC->Mobility = MeshDesc.Mobility;
ISMC->SetReceivesDecals(false);
ISMC->RegisterComponent();
ISMCSharedData.Emplace(MeshDesc, FISMCSharedData(ISMC));
}
Info.InstancedStaticMeshComponents.Add(ISMC);
}
// Build the LOD significance ranges
TArray<float> AllLODSignificances;
auto UniqueInsertOrdered = [&AllLODSignificances](const float Significance)
{
int i = 0;
for (; i < AllLODSignificances.Num(); ++i)
{
// I did not use epsilon check here on purpose, because it will make it hard later meshes inside.
if (Significance == AllLODSignificances[i])
{
return;
}
if (AllLODSignificances[i] > Significance)
{
break;
}
}
AllLODSignificances.Insert(Significance, i);
};
for (const FStaticMeshInstanceVisualizationMeshDesc& MeshDesc : Info.Desc.Meshes)
{
UniqueInsertOrdered(MeshDesc.MinLODSignificance);
UniqueInsertOrdered(MeshDesc.MaxLODSignificance);
}
Info.LODSignificanceRanges.SetNum(AllLODSignificances.Num() - 1);
for (int i = 0; i < Info.LODSignificanceRanges.Num(); ++i)
{
FMassLODSignificanceRange& Range = Info.LODSignificanceRanges[i];
Range.MinSignificance = AllLODSignificances[i];
Range.MaxSignificance = AllLODSignificances[i+1];
Range.ISMCSharedDataPtr = &ISMCSharedData;
for (int j = 0; j < Info.Desc.Meshes.Num(); ++j)
{
const FStaticMeshInstanceVisualizationMeshDesc& MeshDesc = Info.Desc.Meshes[j];
const bool bAddMeshInRange = (Range.MinSignificance >= MeshDesc.MinLODSignificance && Range.MinSignificance < MeshDesc.MaxLODSignificance);
if (bAddMeshInRange)
{
Range.StaticMeshRefs.Add(MeshDesc);
}
}
}
}
}
```
设置灯光通道:
```c++
void UPrimitiveComponent::SetLightingChannels(bool bChannel0, bool bChannel1, bool bChannel2)
{
if (bChannel0 != LightingChannels.bChannel0 ||
bChannel1 != LightingChannels.bChannel1 ||
bChannel2 != LightingChannels.bChannel2)
{
LightingChannels.bChannel0 = bChannel0;
LightingChannels.bChannel1 = bChannel1;
LightingChannels.bChannel2 = bChannel2;
if (SceneProxy)
{
SceneProxy->SetLightingChannels_GameThread(LightingChannels);
}
MarkRenderStateDirty();
}
}
```