#22 Add road segment class
This commit is contained in:
parent
aac57cd14d
commit
4a7b934d96
|
@ -0,0 +1,53 @@
|
|||
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
|
||||
|
||||
#include "Carla.h"
|
||||
#include "StaticMeshCollection.h"
|
||||
|
||||
#include "Components/InstancedStaticMeshComponent.h"
|
||||
#include "Engine/StaticMesh.h"
|
||||
|
||||
AStaticMeshCollection::AStaticMeshCollection(
|
||||
const FObjectInitializer& ObjectInitializer) :
|
||||
Super(ObjectInitializer)
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = false;
|
||||
RootComponent =
|
||||
ObjectInitializer.CreateDefaultSubobject<USceneComponent>(this, TEXT("SceneComponent"));
|
||||
RootComponent->SetMobility(EComponentMobility::Static);
|
||||
}
|
||||
|
||||
void AStaticMeshCollection::PushBackInstantiator(UStaticMesh *Mesh)
|
||||
{
|
||||
auto Instantiator = NewObject<UInstancedStaticMeshComponent>(this);
|
||||
check(Instantiator != nullptr);
|
||||
Instantiator->SetMobility(EComponentMobility::Static);
|
||||
Instantiator->SetupAttachment(RootComponent);
|
||||
Instantiator->SetStaticMesh(Mesh);
|
||||
Instantiator->RegisterComponent();
|
||||
MeshInstatiators.Add(Instantiator);
|
||||
}
|
||||
|
||||
void AStaticMeshCollection::SetStaticMesh(uint32 i, UStaticMesh *Mesh)
|
||||
{
|
||||
check(GetNumberOfInstantiators() > i);
|
||||
MeshInstatiators[i]->SetStaticMesh(Mesh);
|
||||
}
|
||||
|
||||
void AStaticMeshCollection::AddInstance(uint32 i, const FTransform &Transform)
|
||||
{
|
||||
check(GetNumberOfInstantiators() > i);
|
||||
MeshInstatiators[i]->AddInstance(Transform);
|
||||
}
|
||||
|
||||
void AStaticMeshCollection::ClearInstances()
|
||||
{
|
||||
for (auto *Instantiator : MeshInstatiators) {
|
||||
Instantiator->ClearInstances();
|
||||
}
|
||||
}
|
||||
|
||||
void AStaticMeshCollection::ClearInstantiators()
|
||||
{
|
||||
ClearInstances();
|
||||
MeshInstatiators.Empty();
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "StaticMeshCollection.generated.h"
|
||||
|
||||
class UInstancedStaticMeshComponent;
|
||||
|
||||
/// Holds static mesh instatiators.
|
||||
UCLASS(Abstract)
|
||||
class CARLA_API AStaticMeshCollection : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
AStaticMeshCollection(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
protected:
|
||||
|
||||
uint32 GetNumberOfInstantiators() const
|
||||
{
|
||||
return MeshInstatiators.Num();
|
||||
}
|
||||
|
||||
void PushBackInstantiator(UStaticMesh *Mesh);
|
||||
|
||||
void SetStaticMesh(uint32 i, UStaticMesh *Mesh);
|
||||
|
||||
void AddInstance(uint32 i, const FTransform &Transform);
|
||||
|
||||
void ClearInstances();
|
||||
|
||||
/// Clear the instances too.
|
||||
void ClearInstantiators();
|
||||
|
||||
private:
|
||||
|
||||
UPROPERTY(Category = "Instanced Static Mesh Collection", VisibleAnywhere)
|
||||
TArray<UInstancedStaticMeshComponent *> MeshInstatiators;
|
||||
};
|
|
@ -0,0 +1,84 @@
|
|||
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
|
||||
|
||||
#include "Carla.h"
|
||||
#include "RoadSegment.h"
|
||||
|
||||
#include "Engine/StaticMesh.h"
|
||||
|
||||
enum RoadSegmentItems {
|
||||
ELaneLeft,
|
||||
ELaneRight,
|
||||
ESidewalkLeft,
|
||||
ESidewalkRight,
|
||||
ELaneMarkingSolid,
|
||||
ELaneMarkingBroken,
|
||||
NUMBER_OF_ITEMS
|
||||
};
|
||||
|
||||
ARoadSegment::ARoadSegment(const FObjectInitializer& ObjectInitializer) :
|
||||
Super(ObjectInitializer)
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = false;
|
||||
}
|
||||
|
||||
void ARoadSegment::OnConstruction(const FTransform &Transform)
|
||||
{
|
||||
Super::OnConstruction(Transform);
|
||||
UpdateMeshes();
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
void ARoadSegment::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
||||
{
|
||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
||||
if (PropertyChangedEvent.Property) {
|
||||
GenerateRoad();
|
||||
}
|
||||
}
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
void ARoadSegment::GenerateRoad()
|
||||
{
|
||||
UpdateMeshes();
|
||||
UpdateRoad();
|
||||
}
|
||||
|
||||
void ARoadSegment::UpdateMeshes()
|
||||
{
|
||||
if (GetNumberOfInstantiators() != NUMBER_OF_ITEMS) {
|
||||
ClearInstantiators();
|
||||
for (auto i = 0u; i < NUMBER_OF_ITEMS; ++i) {
|
||||
PushBackInstantiator(nullptr);
|
||||
}
|
||||
}
|
||||
SetStaticMesh(ELaneLeft, LaneLeft);
|
||||
SetStaticMesh(ELaneRight, LaneRight);
|
||||
SetStaticMesh(ESidewalkLeft, SidewalkLeft);
|
||||
SetStaticMesh(ESidewalkRight, SidewalkRight);
|
||||
SetStaticMesh(ELaneMarkingSolid, LaneMarkingSolid);
|
||||
SetStaticMesh(ELaneMarkingBroken, LaneMarkingBroken);
|
||||
}
|
||||
|
||||
void ARoadSegment::UpdateRoad()
|
||||
{
|
||||
ClearInstances();
|
||||
Scale = (LaneLeft != nullptr ? LaneLeft->GetBoundingBox().GetSize().X : 1.0f);
|
||||
FVector Translation(0.0f, 0.0f, 0.0f);
|
||||
for (auto &Item : RoadDescription) {
|
||||
FTransform Transform{Translation};
|
||||
AddInstance(ELaneLeft, Transform);
|
||||
AddInstance(ELaneRight, Transform);
|
||||
if (Item.bHasRightSidewalk) {
|
||||
AddInstance(ESidewalkRight, Transform);
|
||||
}
|
||||
if (Item.bHasLeftSidewalk) {
|
||||
AddInstance(ESidewalkLeft, Transform);
|
||||
}
|
||||
if (Item.LaneMarking == ELaneMarkingType::Solid) {
|
||||
AddInstance(ELaneMarkingSolid, Transform);
|
||||
} else if (Item.LaneMarking == ELaneMarkingType::Broken) {
|
||||
AddInstance(ELaneMarkingBroken, Transform);
|
||||
}
|
||||
Translation.X += Scale;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "MapGen/StaticMeshCollection.h"
|
||||
#include "RoadSegment.generated.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class ELaneMarkingType : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
Solid UMETA(DisplayName = "Solid Lane Marking"),
|
||||
Broken UMETA(DisplayName = "Broken Lane Marking")
|
||||
};
|
||||
|
||||
/// Description of a road segment piece.
|
||||
USTRUCT()
|
||||
struct FRoadSegmentPiece
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool bHasLeftSidewalk = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
bool bHasRightSidewalk = true;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
ELaneMarkingType LaneMarking = ELaneMarkingType::Solid;
|
||||
};
|
||||
|
||||
/// A straight segment of road.
|
||||
///
|
||||
/// Please call GenerateRoad after modifying it.
|
||||
UCLASS()
|
||||
class CARLA_API ARoadSegment : public AStaticMeshCollection
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
ARoadSegment(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
virtual void OnConstruction(const FTransform &Transform) override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Road Description")
|
||||
void GenerateRoad();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Road Description")
|
||||
int32 GetNumberOfPieces() const
|
||||
{
|
||||
return RoadDescription.Num();
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Road Description")
|
||||
void AppendPiece(const FRoadSegmentPiece &RoadSegmentPiece)
|
||||
{
|
||||
RoadDescription.Add(RoadSegmentPiece);
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Road Description")
|
||||
void RemoveAllPieces()
|
||||
{
|
||||
RoadDescription.Empty();
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Set Static Mesh")
|
||||
void SetStaticMesh_LaneLeft(UStaticMesh *StaticMesh)
|
||||
{
|
||||
LaneLeft = StaticMesh;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Set Static Mesh")
|
||||
void SetStaticMesh_LaneRight(UStaticMesh *StaticMesh)
|
||||
{
|
||||
LaneRight = StaticMesh;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Set Static Mesh")
|
||||
void SetStaticMesh_SidewalkLeft(UStaticMesh *StaticMesh)
|
||||
{
|
||||
SidewalkLeft = StaticMesh;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Set Static Mesh")
|
||||
void SetStaticMesh_SidewalkRight(UStaticMesh *StaticMesh)
|
||||
{
|
||||
SidewalkRight = StaticMesh;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Set Static Mesh")
|
||||
void SetStaticMesh_LaneMarkingSolid(UStaticMesh *StaticMesh)
|
||||
{
|
||||
LaneMarkingSolid = StaticMesh;
|
||||
}
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Set Static Mesh")
|
||||
void SetStaticMesh_LaneMarkingBroken(UStaticMesh *StaticMesh)
|
||||
{
|
||||
LaneMarkingBroken = StaticMesh;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void UpdateMeshes();
|
||||
|
||||
void UpdateRoad();
|
||||
|
||||
UPROPERTY(Category = "Road Description", EditAnywhere)
|
||||
TArray<FRoadSegmentPiece> RoadDescription;
|
||||
|
||||
UPROPERTY(Category = "Road Description", AdvancedDisplay, EditAnywhere)
|
||||
float Scale = 1.0f;
|
||||
|
||||
UPROPERTY(Category = "Meshes", EditAnywhere)
|
||||
UStaticMesh *LaneLeft;
|
||||
|
||||
UPROPERTY(Category = "Meshes", EditAnywhere)
|
||||
UStaticMesh *LaneRight;
|
||||
|
||||
UPROPERTY(Category = "Meshes", EditAnywhere)
|
||||
UStaticMesh *SidewalkLeft;
|
||||
|
||||
UPROPERTY(Category = "Meshes", EditAnywhere)
|
||||
UStaticMesh *SidewalkRight;
|
||||
|
||||
UPROPERTY(Category = "Meshes", EditAnywhere)
|
||||
UStaticMesh *LaneMarkingSolid;
|
||||
|
||||
UPROPERTY(Category = "Meshes", EditAnywhere)
|
||||
UStaticMesh *LaneMarkingBroken;
|
||||
};
|
Loading…
Reference in New Issue