CARLA
TaggedComponent.cpp
Go to the documentation of this file.
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 //
11 UTaggedComponent::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 
25 {
26  Super::OnRegister();
27 
28  TaggedMID = UMaterialInstanceDynamic::Create(TaggedMaterial, this, TEXT("TaggedMaterialMID"));
29 
30  if (!IsValid(TaggedMID))
31  {
32  UE_LOG(LogCarla, Error, TEXT("Failed to create MID!"));
33  }
34 
35  SetColor(Color);
36 }
37 
38 void UTaggedComponent::SetColor(FLinearColor NewColor)
39 {
40  Color = NewColor;
41 
42  if (IsValid(TaggedMID))
43  {
44  TaggedMID->SetVectorParameterValue("AnnotationColor", Color);
45  }
46 }
47 
49 {
50  return Color;
51 }
52 
53 FBoxSphereBounds UTaggedComponent::CalcBounds(const FTransform & LocalToWorld) const
54 {
55  USceneComponent * ParentComponent = GetAttachParent();
56  if(ParentComponent)
57  {
58  return ParentComponent->CalcBounds(LocalToWorld);
59  }
60  return FBoxSphereBounds();
61 }
62 
63 FPrimitiveSceneProxy * UTaggedComponent::CreateSceneProxy()
64 {
65  USceneComponent * ParentComponent = GetAttachParent();
66 
67  if (!IsValid(ParentComponent))
68  {
69  UE_LOG(LogCarla, Error, TEXT("Invalid parent component"));
70  return NULL;
71  }
72 
73  USkeletalMeshComponent * SkeletalMeshComponent = Cast<USkeletalMeshComponent>(ParentComponent);
74  UStaticMeshComponent * StaticMeshComponent = Cast<UStaticMeshComponent>(ParentComponent);
75  UHierarchicalInstancedStaticMeshComponent * HierarchicalInstancedStaticMeshComponent =
76  Cast<UHierarchicalInstancedStaticMeshComponent>(ParentComponent);
77  UInstancedStaticMeshComponent* InstancedStaticMeshComponent = Cast<UInstancedStaticMeshComponent>(ParentComponent);
78  if (HierarchicalInstancedStaticMeshComponent)
79  {
80  return CreateSceneProxy(HierarchicalInstancedStaticMeshComponent);
81  }
82  else if (InstancedStaticMeshComponent)
83  {
84  return CreateSceneProxy(InstancedStaticMeshComponent);
85  }
86  else
87  if (IsValid(StaticMeshComponent))
88  {
89  return CreateSceneProxy(StaticMeshComponent);
90  }
91  else if (IsValid(SkeletalMeshComponent))
92  {
93  bSkeletalMesh = true;
94  return CreateSceneProxy(SkeletalMeshComponent);
95  }
96 
97  UE_LOG(LogCarla, Error, TEXT("Unknown type of parent component: %s"), *ParentComponent->GetClass()->GetName());
98 
99  return NULL;
100 }
101 
102 FPrimitiveSceneProxy * UTaggedComponent::CreateSceneProxy(UStaticMeshComponent * StaticMeshComponent)
103 {
104  // Make sure static mesh has render data
105  UStaticMesh * StaticMesh = StaticMeshComponent->GetStaticMesh();
106 
107  if (StaticMesh == NULL)
108  {
109  UE_LOG(LogCarla, Error, TEXT("Failed to create scene proxy for static mesh component (because static mesh is null): %s"), *StaticMeshComponent->GetReadableName());
110  return NULL;
111  }
112 
113  if (StaticMesh->RenderData == NULL)
114  {
115  UE_LOG(LogCarla, Error, TEXT("Failed to create scene proxy for static mesh component (because render data is null): %s"), *StaticMeshComponent->GetReadableName());
116  return NULL;
117  }
118 
119 
120  if (StaticMesh->RenderData->LODResources.Num() == 0)
121  {
122  UE_LOG(LogCarla, Error, TEXT("Failed to create scene proxy for static mesh component (because num LOD resources is 0): %s"), *StaticMeshComponent->GetReadableName());
123  return NULL;
124  }
125 
126  return new FTaggedStaticMeshSceneProxy(StaticMeshComponent, true, TaggedMID);
127 }
128 
129 FPrimitiveSceneProxy * UTaggedComponent::CreateSceneProxy(USkeletalMeshComponent * SkeletalMeshComponent)
130 {
131  if (bShouldWaitFrame)
132  {
133  return nullptr;
134  }
135  ERHIFeatureLevel::Type SceneFeatureLevel = GetWorld()->FeatureLevel;
136  FSkeletalMeshRenderData* SkelMeshRenderData = SkeletalMeshComponent->GetSkeletalMeshRenderData();
137 
138  // Only create a scene proxy for rendering if properly initialized
139  if (SkelMeshRenderData &&
140  SkelMeshRenderData->LODRenderData.IsValidIndex(SkeletalMeshComponent->PredictedLODLevel) &&
141  !SkeletalMeshComponent->bHideSkin &&
142  SkeletalMeshComponent->MeshObject)
143  {
144  // Only create a scene proxy if the bone count being used is supported, or if we don't have a skeleton (this is the case with destructibles)
145  int32 MinLODIndex = SkeletalMeshComponent->ComputeMinLOD();
146  int32 MaxBonesPerChunk = SkelMeshRenderData->GetMaxBonesPerSection(MinLODIndex);
147  int32 MaxSupportedNumBones = SkeletalMeshComponent->MeshObject->IsCPUSkinned() ? MAX_int32 : GetFeatureLevelMaxNumberOfBones(SceneFeatureLevel);
148  if (MaxBonesPerChunk <= MaxSupportedNumBones)
149  {
150  return new FTaggedSkeletalMeshSceneProxy(SkeletalMeshComponent, SkelMeshRenderData, TaggedMID);
151  }
152  }
153  return nullptr;
154 }
155 
156 FPrimitiveSceneProxy * UTaggedComponent::CreateSceneProxy(UHierarchicalInstancedStaticMeshComponent * MeshComponent)
157 {
158  // Verify that the mesh is valid before using it.
159  const bool bMeshIsValid =
160  // make sure we have instances
161  (MeshComponent->PerInstanceRenderData.IsValid()) &&
162  // make sure we have an actual staticmesh
163  MeshComponent->GetStaticMesh() &&
164  MeshComponent->GetStaticMesh()->HasValidRenderData(false) &&
165  // You really can't use hardware instancing on the consoles with multiple elements because they share the same index buffer.
166  // @todo: Level error or something to let LDs know this
167  1;//GetStaticMesh()->LODModels(0).Elements.Num() == 1;
168 
169  if (bMeshIsValid)
170  {
171  bool bIsGrass = !MeshComponent->PerInstanceSMData.Num();
172  return new FTaggedHierarchicalStaticMeshSceneProxy(MeshComponent, bIsGrass, GetWorld()->FeatureLevel, TaggedMID);
173  }
174  return nullptr;
175 }
176 
177 FPrimitiveSceneProxy * UTaggedComponent::CreateSceneProxy(UInstancedStaticMeshComponent * MeshComponent)
178 {
179  // Verify that the mesh is valid before using it.
180  const bool bMeshIsValid =
181  // make sure we have instances
182  (MeshComponent->PerInstanceRenderData.IsValid()) &&
183  // make sure we have an actual staticmesh
184  MeshComponent->GetStaticMesh() &&
185  MeshComponent->GetStaticMesh()->HasValidRenderData(false) &&
186  // You really can't use hardware instancing on the consoles with multiple elements because they share the same index buffer.
187  // @todo: Level error or something to let LDs know this
188  1;//GetStaticMesh()->LODModels(0).Elements.Num() == 1;
189 
190  if (bMeshIsValid)
191  {
192  return new FTaggedInstancedStaticMeshSceneProxy(MeshComponent, GetWorld()->FeatureLevel, TaggedMID);
193  }
194  return nullptr;
195 }
196 
197 void UTaggedComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction * ThisTickFunction)
198 {
199  Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
200 
201  // // TODO: Try removing this
202  if (bSkeletalMesh)
203  {
204  // MarkRenderTransformDirty();
205  MarkRenderStateDirty();
206  if(bShouldWaitFrame)
207  {
208  if(NumFramesToWait < 0)
209  {
210  bShouldWaitFrame = false;
211  }
212  NumFramesToWait--;
213  }
214  }
215 }
216 
217 //
218 // FTaggedStaticMeshSceneProxy
219 //
220 FTaggedStaticMeshSceneProxy::FTaggedStaticMeshSceneProxy(UStaticMeshComponent * Component, bool bForceLODsShareStaticLighting, UMaterialInstance * MaterialInstance) :
221  FStaticMeshSceneProxy(Component, bForceLODsShareStaticLighting)
222 {
223  TaggedMaterialInstance = MaterialInstance;
224 
225  // Replace materials with tagged material
226  bVerifyUsedMaterials = false;
227 
228  for (FLODInfo& LODInfo : LODs) {
229  for (FLODInfo::FSectionInfo& SectionInfo : LODInfo.Sections) {
230  SectionInfo.Material = TaggedMaterialInstance;
231  }
232  }
233 }
234 
235 FPrimitiveViewRelevance FTaggedStaticMeshSceneProxy::GetViewRelevance(const FSceneView * View) const
236 {
237  FPrimitiveViewRelevance ViewRelevance = FStaticMeshSceneProxy::GetViewRelevance(View);
238 
239  ViewRelevance.bDrawRelevance = ViewRelevance.bDrawRelevance && !View->Family->EngineShowFlags.NotDrawTaggedComponents;
240  ViewRelevance.bShadowRelevance = false;
241 
242  return ViewRelevance;
243 }
244 
245 //
246 // FTaggedSkeletalMeshSceneProxy
247 //
248 FTaggedSkeletalMeshSceneProxy::FTaggedSkeletalMeshSceneProxy(const USkinnedMeshComponent * Component, FSkeletalMeshRenderData * InSkeletalMeshRenderData, UMaterialInstance * MaterialInstance) :
249  FSkeletalMeshSceneProxy(Component, InSkeletalMeshRenderData)
250 {
251  TaggedMaterialInstance = MaterialInstance;
252 
253  // Replace materials with tagged material
254  bVerifyUsedMaterials = false;
255 
256  for (FLODSectionElements& LODSection : LODSections) {
257  for (FSectionElementInfo& ElementInfo : LODSection.SectionElements) {
258  ElementInfo.Material = TaggedMaterialInstance;
259  }
260  }
261 }
262 
263 FPrimitiveViewRelevance FTaggedSkeletalMeshSceneProxy::GetViewRelevance(const FSceneView * View) const
264 {
265  FPrimitiveViewRelevance ViewRelevance = FSkeletalMeshSceneProxy::GetViewRelevance(View);
266 
267  ViewRelevance.bDrawRelevance = ViewRelevance.bDrawRelevance && !View->Family->EngineShowFlags.NotDrawTaggedComponents;
268  ViewRelevance.bShadowRelevance = false;
269 
270  return ViewRelevance;
271 }
272 
274  UInstancedStaticMeshComponent * Component, ERHIFeatureLevel::Type InFeatureLevel, UMaterialInstance * MaterialInstance)
275  : FInstancedStaticMeshSceneProxy(Component, InFeatureLevel)
276 {
277  TaggedMaterialInstance = MaterialInstance;
278 
279  // Replace materials with tagged material
280  bVerifyUsedMaterials = false;
281 
282  for (FLODInfo& LODInfo : LODs) {
283  for (FLODInfo::FSectionInfo& SectionInfo : LODInfo.Sections) {
284  SectionInfo.Material = TaggedMaterialInstance;
285  }
286  }
287 }
288 
289 FPrimitiveViewRelevance FTaggedInstancedStaticMeshSceneProxy::GetViewRelevance(const FSceneView * View) const
290 {
291  FPrimitiveViewRelevance ViewRelevance = FInstancedStaticMeshSceneProxy::GetViewRelevance(View);
292 
293  ViewRelevance.bDrawRelevance = ViewRelevance.bDrawRelevance && !View->Family->EngineShowFlags.NotDrawTaggedComponents;
294  ViewRelevance.bShadowRelevance = false;
295 
296  return ViewRelevance;
297 }
298 
299 
301  UHierarchicalInstancedStaticMeshComponent * Component, bool bInIsGrass, ERHIFeatureLevel::Type InFeatureLevel, UMaterialInstance * MaterialInstance)
302  : FHierarchicalStaticMeshSceneProxy(bInIsGrass, Component, InFeatureLevel)
303 {
304  TaggedMaterialInstance = MaterialInstance;
305 
306  // Replace materials with tagged material
307  bVerifyUsedMaterials = false;
308 
309  for (FLODInfo& LODInfo : LODs) {
310  for (FLODInfo::FSectionInfo& SectionInfo : LODInfo.Sections) {
311  SectionInfo.Material = TaggedMaterialInstance;
312  }
313  }
314 }
315 
316 FPrimitiveViewRelevance FTaggedHierarchicalStaticMeshSceneProxy::GetViewRelevance(const FSceneView * View) const
317 {
318  FPrimitiveViewRelevance ViewRelevance = FHierarchicalStaticMeshSceneProxy::GetViewRelevance(View);
319 
320  ViewRelevance.bDrawRelevance = ViewRelevance.bDrawRelevance && !View->Family->EngineShowFlags.NotDrawTaggedComponents;
321  ViewRelevance.bShadowRelevance = false;
322 
323  return ViewRelevance;
324 }
FTaggedHierarchicalStaticMeshSceneProxy(UHierarchicalInstancedStaticMeshComponent *Component, bool bInIsGrass, ERHIFeatureLevel::Type InFeatureLevel, UMaterialInstance *MaterialInstance)
FTaggedSkeletalMeshSceneProxy(const USkinnedMeshComponent *Component, FSkeletalMeshRenderData *InSkeletalMeshRenderData, UMaterialInstance *MaterialInstance)
sensor::data::Color Color
UMaterialInstance * TaggedMaterialInstance
UMaterial * TaggedMaterial
UMaterialInstance * TaggedMaterialInstance
FLinearColor GetColor()
FLinearColor Color
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView *View) const override
FTaggedInstancedStaticMeshSceneProxy(UInstancedStaticMeshComponent *Component, ERHIFeatureLevel::Type InFeatureLevel, UMaterialInstance *MaterialInstance)
UMaterialInstance * TaggedMaterialInstance
static bool IsValid(const ACarlaWheeledVehicle *Vehicle)
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override
FTaggedStaticMeshSceneProxy(UStaticMeshComponent *Component, bool bForceLODsShareStaticLighting, UMaterialInstance *MaterialInstance)
virtual FPrimitiveSceneProxy * CreateSceneProxy() override
virtual FBoxSphereBounds CalcBounds(const FTransform &LocalToWorld) const
virtual void OnRegister() override
UMaterialInstanceDynamic * TaggedMID
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView *View) const override
UTaggedComponent(const FObjectInitializer &ObjectInitializer)
void SetColor(FLinearColor color)
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView *View) const override
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView *View) const override