#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