CARLA
 
载入中...
搜索中...
未找到
TaggedComponent.cpp
浏览该文件的文档.
1#include "Carla.h"
2#include "TaggedComponent.h"
3#include "ConstructorHelpers.h"
4
5#include "Rendering/SkeletalMeshRenderData.h"
6#include "SkeletalRenderPublic.h"
7
8//
9// UTaggedComponent
10//
11UTaggedComponent::UTaggedComponent(const FObjectInitializer& ObjectInitializer) :
12 UPrimitiveComponent(ObjectInitializer),
13 Color(1, 1, 1, 1)
14{
15 FString MaterialPath = TEXT("Material'/Carla/PostProcessingMaterials/AnnotationColor.AnnotationColor'");
16 static ConstructorHelpers::FObjectFinder<UMaterial> TaggedMaterialObject(*MaterialPath);
17 // TODO: Replace with VertexColorViewModeMaterial_ColorOnly?
18
19 TaggedMaterial = TaggedMaterialObject.Object;
20 PrimaryComponentTick.bCanEverTick = true;
21 PrimaryComponentTick.bStartWithTickEnabled = false;
22}
23
24// UTaggedComponent类的成员函数,用于在组件注册时调用
26{
27 // 调用父类的OnRegister函数
28 Super::OnRegister();
29
30 // 创建动态材质实例
31 TaggedMID = UMaterialInstanceDynamic::Create(TaggedMaterial, this, TEXT("TaggedMaterialMID"));
32
33 // 检查动态材质实例是否创建成功
34 if (!IsValid(TaggedMID))
35 {
36 // 如果失败,记录错误日志
37 UE_LOG(LogCarla, Error, TEXT("Failed to create MID!"));
38 }
39
40 // 设置组件的颜色
41 SetColor(Color);
42}
43
44// UTaggedComponent类的成员函数,用于设置组件的颜色
45void UTaggedComponent::SetColor(FLinearColor NewColor)
46{
47 // 更新颜色成员变量
48 Color = NewColor;
49
50 // 如果动态材质实例有效,则设置其颜色参数
51 if (IsValid(TaggedMID))
52 {
53 TaggedMID->SetVectorParameterValue("AnnotationColor", Color);
54 }
55}
56
57// UTaggedComponent类的成员函数,用于获取组件的颜色
59{
60 return Color;
61}
62
63// UTaggedComponent类的成员函数,用于计算组件的边界
64FBoxSphereBounds UTaggedComponent::CalcBounds(const FTransform & LocalToWorld) const
65{
66 // 获取父组件
67 USceneComponent * ParentComponent = GetAttachParent();
68 if(ParentComponent)
69 {
70 // 如果父组件有效,返回父组件的边界
71 return ParentComponent->CalcBounds(LocalToWorld);
72 }
73 // 如果没有父组件,返回空的边界
74 return FBoxSphereBounds();
75}
76
77// UTaggedComponent类的成员函数,用于创建场景代理
78FPrimitiveSceneProxy * UTaggedComponent::CreateSceneProxy()
79{
80 USceneComponent * ParentComponent = GetAttachParent();
81
82 // 如果父组件无效,记录错误日志并返回NULL
83 if (!IsValid(ParentComponent))
84 {
85 UE_LOG(LogCarla, Error, TEXT("Invalid parent component"));
86 return NULL;
87 }
88
89 // 尝试将父组件转换为不同类型的网格组件
90 USkeletalMeshComponent * SkeletalMeshComponent = Cast<USkeletalMeshComponent>(ParentComponent);
91 UStaticMeshComponent * StaticMeshComponent = Cast<UStaticMeshComponent>(ParentComponent);
92 UHierarchicalInstancedStaticMeshComponent * HierarchicalInstancedStaticMeshComponent =
93 Cast<UHierarchicalInstancedStaticMeshComponent>(ParentComponent);
94 UInstancedStaticMeshComponent* InstancedStaticMeshComponent = Cast<UInstancedStaticMeshComponent>(ParentComponent);
95 // 如果父组件是层级实例化静态网格组件,创建对应的场景代理
96 if (HierarchicalInstancedStaticMeshComponent)
97 {
98 return CreateSceneProxy(HierarchicalInstancedStaticMeshComponent);
99 }
100 // 如果父组件是实例化静态网格组件,创建对应的场景代理
101 else if (InstancedStaticMeshComponent)
102 {
103 return CreateSceneProxy(InstancedStaticMeshComponent);
104 }
105 // 如果父组件是静态网格组件,创建对应的场景代理
106 else
107 if (IsValid(StaticMeshComponent))
108 {
109 return CreateSceneProxy(StaticMeshComponent);
110 }
111 // 如果父组件是骨骼网格组件,设置bSkeletalMesh标志并创建对应的场景代理
112 else if (IsValid(SkeletalMeshComponent))
113 {
114 bSkeletalMesh = true;
115 return CreateSceneProxy(SkeletalMeshComponent);
116 }
117
118 // 如果父组件类型未知,记录错误日志并返回NULL
119 UE_LOG(LogCarla, Error, TEXT("Unknown type of parent component: %s"), *ParentComponent->GetClass()->GetName());
120
121 return NULL;
122}
123
124FPrimitiveSceneProxy * UTaggedComponent::CreateSceneProxy(UStaticMeshComponent * StaticMeshComponent)
125{
126 // 确保静态网格具有渲染数据。
127 UStaticMesh * StaticMesh = StaticMeshComponent->GetStaticMesh();
128
129 // 检查静态网格是否为空,如果为空则记录错误日志并返回NULL
130 if (StaticMesh == NULL)
131 {
132 UE_LOG(LogCarla, Error, TEXT("Failed to create scene proxy for static mesh component (because static mesh is null): %s"), *StaticMeshComponent->GetReadableName());
133 return NULL;
134 }
135
136 // 检查静态网格的渲染数据是否为空,如果为空则记录错误日志并返回NULL
137 if (StaticMesh->RenderData == NULL)
138 {
139 UE_LOG(LogCarla, Error, TEXT("Failed to create scene proxy for static mesh component (because render data is null): %s"), *StaticMeshComponent->GetReadableName());
140 return NULL;
141 }
142
143 // 检查静态网格的LOD资源数量是否为0,如果是则记录错误日志并返回NULL
144 if (StaticMesh->RenderData->LODResources.Num() == 0)
145 {
146 UE_LOG(LogCarla, Error, TEXT("Failed to create scene proxy for static mesh component (because num LOD resources is 0): %s"), *StaticMeshComponent->GetReadableName());
147 return NULL;
148 }
149
150 // 如果所有检查通过,则创建并返回标记的静态网格场景代理
151 return new FTaggedStaticMeshSceneProxy(StaticMeshComponent, true, TaggedMID);
152}
153
154// UTaggedComponent类的成员函数,用于为骨骼网格组件创建场景代理
155FPrimitiveSceneProxy * UTaggedComponent::CreateSceneProxy(USkeletalMeshComponent * SkeletalMeshComponent)
156{
157 // 如果应该等待当前帧,则返回nullptr
159 {
160 return nullptr;
161 }
162 // 获取当前场景的特征级别
163 ERHIFeatureLevel::Type SceneFeatureLevel = GetWorld()->FeatureLevel;
164 // 获取骨骼网格渲染数据
165 FSkeletalMeshRenderData* SkelMeshRenderData = SkeletalMeshComponent->GetSkeletalMeshRenderData();
166
167 // 只有在正确初始化后,才为渲染创建场景代理。
168 if (SkelMeshRenderData &&
169 SkelMeshRenderData->LODRenderData.IsValidIndex(SkeletalMeshComponent->PredictedLODLevel) &&
170 !SkeletalMeshComponent->bHideSkin &&
171 SkeletalMeshComponent->MeshObject)
172 {
173 // 只有在使用的骨骼数量被支持的情况下,或者如果没有骨架(如破坏物体的情况),才创建场景代理。
174 int32 MinLODIndex = SkeletalMeshComponent->ComputeMinLOD();
175 int32 MaxBonesPerChunk = SkelMeshRenderData->GetMaxBonesPerSection(MinLODIndex);
176 int32 MaxSupportedNumBones = SkeletalMeshComponent->MeshObject->IsCPUSkinned() ? MAX_int32 : GetFeatureLevelMaxNumberOfBones(SceneFeatureLevel);
177 if (MaxBonesPerChunk <= MaxSupportedNumBones)
178 {
179 return new FTaggedSkeletalMeshSceneProxy(SkeletalMeshComponent, SkelMeshRenderData, TaggedMID);
180 }
181 }
182 return nullptr;
183}
184
185FPrimitiveSceneProxy * UTaggedComponent::CreateSceneProxy(UHierarchicalInstancedStaticMeshComponent * MeshComponent)
186{
187 // 在使用网格之前,验证其是否有效。
188 const bool bMeshIsValid =
189 //确保我们拥有实例。
190 (MeshComponent->PerInstanceRenderData.IsValid()) &&
191 // 确保我们拥有一个实际的静态网格。
192 MeshComponent->GetStaticMesh() &&
193 MeshComponent->GetStaticMesh()->HasValidRenderData(false) &&
194 // 在控制台上,无法使用硬件实例化处理多个元素,因为它们共享相同的索引缓冲区。
195 // @todo: Level error or something to let LDs know this
196 1;//GetStaticMesh()->LODModels(0).Elements.Num() == 1;
197
198 if (bMeshIsValid)
199 {
200 bool bIsGrass = !MeshComponent->PerInstanceSMData.Num();
201 return new FTaggedHierarchicalStaticMeshSceneProxy(MeshComponent, bIsGrass, GetWorld()->FeatureLevel, TaggedMID);
202 }
203 return nullptr;
204}
205
206FPrimitiveSceneProxy * UTaggedComponent::CreateSceneProxy(UInstancedStaticMeshComponent * MeshComponent)
207{
208 // 在使用网格之前,验证其是否有效。
209 const bool bMeshIsValid =
210 // 确保我们拥有实例。
211 (MeshComponent->PerInstanceRenderData.IsValid()) &&
212 // 确保我们拥有一个实际的静态网格。
213 MeshComponent->GetStaticMesh() &&
214 MeshComponent->GetStaticMesh()->HasValidRenderData(false) &&
215 // 在控制台上,无法使用硬件实例化处理多个元素,因为它们共享相同的索引缓冲区。
216 // @todo: Level error or something to let LDs know this
217 1;//GetStaticMesh()->LODModels(0).Elements.Num() == 1;
218
219 if (bMeshIsValid)
220 {
221 return new FTaggedInstancedStaticMeshSceneProxy(MeshComponent, GetWorld()->FeatureLevel, TaggedMID);
222 }
223 return nullptr;
224}
225
226void UTaggedComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction)
227{
228 Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
229
230 // // TODO: Try removing this
231 if (bSkeletalMesh)
232 {
233 // MarkRenderTransformDirty();
234 MarkRenderStateDirty();
236 {
237 if(NumFramesToWait < 0)
238 {
239 bShouldWaitFrame = false;
240 }
242 }
243 }
244}
245
246//
247// FTaggedStaticMeshSceneProxy
248//
249FTaggedStaticMeshSceneProxy::FTaggedStaticMeshSceneProxy(UStaticMeshComponent * Component, bool bForceLODsShareStaticLighting, UMaterialInstance * MaterialInstance) :
250 FStaticMeshSceneProxy(Component, bForceLODsShareStaticLighting)
251{
252 TaggedMaterialInstance = MaterialInstance;
253
254 // 用带标签的材质替换材质。
255 bVerifyUsedMaterials = false;
256
257 for (FLODInfo& LODInfo : LODs) {
258 for (FLODInfo::FSectionInfo& SectionInfo : LODInfo.Sections) {
259 SectionInfo.Material = TaggedMaterialInstance;
260 }
261 }
262}
263
264FPrimitiveViewRelevance FTaggedStaticMeshSceneProxy::GetViewRelevance(const FSceneView * View) const
265{
266 FPrimitiveViewRelevance ViewRelevance = FStaticMeshSceneProxy::GetViewRelevance(View);
267
268 ViewRelevance.bDrawRelevance = ViewRelevance.bDrawRelevance && !View->Family->EngineShowFlags.NotDrawTaggedComponents;
269 ViewRelevance.bShadowRelevance = false;
270
271 return ViewRelevance;
272}
273
274//
275// FTaggedSkeletalMeshSceneProxy
276//
277FTaggedSkeletalMeshSceneProxy::FTaggedSkeletalMeshSceneProxy(const USkinnedMeshComponent * Component, FSkeletalMeshRenderData * InSkeletalMeshRenderData, UMaterialInstance * MaterialInstance) :
278 FSkeletalMeshSceneProxy(Component, InSkeletalMeshRenderData)
279{
280 TaggedMaterialInstance = MaterialInstance;
281
282 // Replace materials with tagged material
283 bVerifyUsedMaterials = false;
284
285 for (FLODSectionElements& LODSection : LODSections) {
286 for (FSectionElementInfo& ElementInfo : LODSection.SectionElements) {
287 ElementInfo.Material = TaggedMaterialInstance;
288 }
289 }
290}
291
292FPrimitiveViewRelevance FTaggedSkeletalMeshSceneProxy::GetViewRelevance(const FSceneView * View) const
293{
294 FPrimitiveViewRelevance ViewRelevance = FSkeletalMeshSceneProxy::GetViewRelevance(View);
295
296 ViewRelevance.bDrawRelevance = ViewRelevance.bDrawRelevance && !View->Family->EngineShowFlags.NotDrawTaggedComponents;
297 ViewRelevance.bShadowRelevance = false;
298
299 return ViewRelevance;
300}
301
303 UInstancedStaticMeshComponent * Component, ERHIFeatureLevel::Type InFeatureLevel, UMaterialInstance * MaterialInstance)
304 : FInstancedStaticMeshSceneProxy(Component, InFeatureLevel)
305{
306 TaggedMaterialInstance = MaterialInstance;
307
308 // Replace materials with tagged material
309 bVerifyUsedMaterials = false;
310
311 for (FLODInfo& LODInfo : LODs) {
312 for (FLODInfo::FSectionInfo& SectionInfo : LODInfo.Sections) {
313 SectionInfo.Material = TaggedMaterialInstance;
314 }
315 }
316}
317
318FPrimitiveViewRelevance FTaggedInstancedStaticMeshSceneProxy::GetViewRelevance(const FSceneView * View) const
319{
320 FPrimitiveViewRelevance ViewRelevance = FInstancedStaticMeshSceneProxy::GetViewRelevance(View);
321
322 ViewRelevance.bDrawRelevance = ViewRelevance.bDrawRelevance && !View->Family->EngineShowFlags.NotDrawTaggedComponents;
323 ViewRelevance.bShadowRelevance = false;
324
325 return ViewRelevance;
326}
327
328
330 UHierarchicalInstancedStaticMeshComponent * Component, bool bInIsGrass, ERHIFeatureLevel::Type InFeatureLevel, UMaterialInstance * MaterialInstance)
331 : FHierarchicalStaticMeshSceneProxy(bInIsGrass, Component, InFeatureLevel)
332{
333 TaggedMaterialInstance = MaterialInstance;
334
335 // Replace materials with tagged material
336 bVerifyUsedMaterials = false;
337
338 for (FLODInfo& LODInfo : LODs) {
339 for (FLODInfo::FSectionInfo& SectionInfo : LODInfo.Sections) {
340 SectionInfo.Material = TaggedMaterialInstance;
341 }
342 }
343}
344
345FPrimitiveViewRelevance FTaggedHierarchicalStaticMeshSceneProxy::GetViewRelevance(const FSceneView * View) const
346{
347 FPrimitiveViewRelevance ViewRelevance = FHierarchicalStaticMeshSceneProxy::GetViewRelevance(View);
348
349 ViewRelevance.bDrawRelevance = ViewRelevance.bDrawRelevance && !View->Family->EngineShowFlags.NotDrawTaggedComponents;
350 ViewRelevance.bShadowRelevance = false;
351
352 return ViewRelevance;
353}
UE_LOG(LogCarla, Log, TEXT("UActorDispatcher::Destroying actor: '%s' %x"), *Id, Actor)
static bool IsValid(const ACarlaWheeledVehicle *Vehicle)
FTaggedHierarchicalStaticMeshSceneProxy(UHierarchicalInstancedStaticMeshComponent *Component, bool bInIsGrass, ERHIFeatureLevel::Type InFeatureLevel, UMaterialInstance *MaterialInstance)
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView *View) const override
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView *View) const override
FTaggedInstancedStaticMeshSceneProxy(UInstancedStaticMeshComponent *Component, ERHIFeatureLevel::Type InFeatureLevel, UMaterialInstance *MaterialInstance)
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView *View) const override
UMaterialInstance * TaggedMaterialInstance
FTaggedSkeletalMeshSceneProxy(const USkinnedMeshComponent *Component, FSkeletalMeshRenderData *InSkeletalMeshRenderData, UMaterialInstance *MaterialInstance)
FTaggedStaticMeshSceneProxy(UStaticMeshComponent *Component, bool bForceLODsShareStaticLighting, UMaterialInstance *MaterialInstance)
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView *View) const override
UMaterialInstance * TaggedMaterialInstance
virtual FPrimitiveSceneProxy * CreateSceneProxy() override
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override
virtual void OnRegister() override
UTaggedComponent(const FObjectInitializer &ObjectInitializer)
FLinearColor Color
UMaterial * TaggedMaterial
FLinearColor GetColor()
virtual FBoxSphereBounds CalcBounds(const FTransform &LocalToWorld) const
void SetColor(FLinearColor color)
UMaterialInstanceDynamic * TaggedMID