Skip to content

Commit

Permalink
Interior Decorator Verification
Browse files Browse the repository at this point in the history
  • Loading branch information
shun126 committed Jun 22, 2023
1 parent 20a9018 commit fc9be6c
Show file tree
Hide file tree
Showing 24 changed files with 888 additions and 20 deletions.
10 changes: 5 additions & 5 deletions Source/DungeonGenerator/Private/Core/Room.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,11 @@ namespace dungeon
const std::string_view& Room::GetPartsName() const noexcept
{
static const std::array<std::string_view, PartsSize> names = {
"Unidentified",
"Start",
"Goal",
"Hall",
"Hanare",
"unidentified",
"start",
"goal",
"hall",
"hanare",
};
return names[static_cast<size_t>(mParts)];
}
Expand Down
3 changes: 2 additions & 1 deletion Source/DungeonGenerator/Private/DungeonGenerateActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ All Rights Reserved.
#include <NavMesh/RecastNavMesh.h>

#if WITH_EDITOR
#include <DrawDebugHelpers.h>
#include <Kismet/KismetSystemLibrary.h>
#endif

Expand Down Expand Up @@ -656,7 +657,7 @@ void ADungeonGenerateActor::DrawDebugInformation()
message.Append(line);
message.Append(TEXT("\n"));
}
UKismetSystemLibrary::DrawDebugString(playerPawn->GetWorld(), playerPawn->GetPawnViewLocation(), message, nullptr, FLinearColor::White);
DrawDebugString(playerPawn->GetWorld(), playerPawn->GetPawnViewLocation(), message, nullptr, FColor::White, 0, true, 1.f);
}
}
}
Expand Down
95 changes: 90 additions & 5 deletions Source/DungeonGenerator/Private/DungeonGeneratorCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ bool CDungeonGeneratorCore::Create(const UDungeonGenerateParameter* parameter)
generateParameter.mVerticalRoomMargin = parameter->VerticalRoomMargin;
mParameter = parameter;

mAisleInteriorDecorator.Initialize(mParameter->DungeonInteriorAsset);
mSlopeInteriorDecorator.Initialize(mParameter->DungeonInteriorAsset);
mRoomInteriorDecorator.Initialize(mParameter->DungeonInteriorAsset);

mGenerator = std::make_shared<dungeon::Generator>();
mGenerator->OnQueryParts([this, parameter](const std::shared_ptr<dungeon::Room>& room)
{
Expand Down Expand Up @@ -226,6 +230,10 @@ void CDungeonGeneratorCore::AddTerrain()
return;
}

mAisleInteriorDecorator.ClearDecorationLocation();
mSlopeInteriorDecorator.ClearDecorationLocation();
mRoomInteriorDecorator.ClearDecorationLocation();

mGenerator->GetVoxel()->Each([this, parameter](const FIntVector& location, const dungeon::Grid& grid)
{
const size_t gridIndex = mGenerator->GetVoxel()->Index(location);
Expand Down Expand Up @@ -272,27 +280,47 @@ void CDungeonGeneratorCore::AddTerrain()
FVector wallPosition = centerPosition;
wallPosition.Y -= halfGridSize;
mOnAddWall(parts->StaticMesh, parts->CalculateWorldTransform(wallPosition, 0.f));

if (grid.IsKindOfAisleType())
mAisleInteriorDecorator.AddDecorationLocation(wallPosition, 0.f);
else if (grid.GetType() == dungeon::Grid::Type::Deck)
mRoomInteriorDecorator.AddDecorationLocation(wallPosition, 0.f);
}
if (grid.CanBuildWall(mGenerator->GetVoxel()->Get(location.X, location.Y + 1, location.Z), dungeon::Direction::South, parameter->MergeRooms))
{
// 南側の壁
FVector wallPosition = centerPosition;
wallPosition.Y += halfGridSize;
mOnAddWall(parts->StaticMesh, parts->CalculateWorldTransform(wallPosition, 180.f));

if (grid.IsKindOfAisleType())
mAisleInteriorDecorator.AddDecorationLocation(wallPosition, 180.f);
else if (grid.GetType() == dungeon::Grid::Type::Deck)
mRoomInteriorDecorator.AddDecorationLocation(wallPosition, 180.f);
}
if (grid.CanBuildWall(mGenerator->GetVoxel()->Get(location.X + 1, location.Y, location.Z), dungeon::Direction::East, parameter->MergeRooms))
{
// 東側の壁
FVector wallPosition = centerPosition;
wallPosition.X += halfGridSize;
mOnAddWall(parts->StaticMesh, parts->CalculateWorldTransform(wallPosition, 90.f));

if (grid.IsKindOfAisleType())
mAisleInteriorDecorator.AddDecorationLocation(wallPosition, 90.f);
else if (grid.GetType() == dungeon::Grid::Type::Deck)
mRoomInteriorDecorator.AddDecorationLocation(wallPosition, 90.f);
}
if (grid.CanBuildWall(mGenerator->GetVoxel()->Get(location.X - 1, location.Y, location.Z), dungeon::Direction::West, parameter->MergeRooms))
{
// 西側の壁
FVector wallPosition = centerPosition;
wallPosition.X -= halfGridSize;
mOnAddWall(parts->StaticMesh, parts->CalculateWorldTransform(wallPosition, -90.f));

if (grid.IsKindOfAisleType())
mAisleInteriorDecorator.AddDecorationLocation(wallPosition, -90.f);
else if (grid.GetType() == dungeon::Grid::Type::Deck)
mRoomInteriorDecorator.AddDecorationLocation(wallPosition, -90.f);
}
}
}
Expand Down Expand Up @@ -461,13 +489,26 @@ void CDungeonGeneratorCore::AddTerrain()
return true;
}
);
{
mAisleInteriorDecorator.ShuffleDecorationLocation(dungeon::Random::Instance());
mAisleInteriorDecorator.SpawnActors(mWorld.Get(), TArray<FString>({ TEXT("aisle"), TEXT("wall"), TEXT("major") }), dungeon::Random::Instance());
mAisleInteriorDecorator.SpawnActors(mWorld.Get(), TArray<FString>({ TEXT("aisle"), TEXT("wall") }), dungeon::Random::Instance());
mAisleInteriorDecorator.ClearDecorationLocation();
}

{
mSlopeInteriorDecorator.ShuffleDecorationLocation(dungeon::Random::Instance());
mSlopeInteriorDecorator.SpawnActors(mWorld.Get(), TArray<FString>({ TEXT("slope"), TEXT("wall"), TEXT("major") }), dungeon::Random::Instance());
mSlopeInteriorDecorator.SpawnActors(mWorld.Get(), TArray<FString>({ TEXT("slope"), TEXT("wall") }), dungeon::Random::Instance());
mSlopeInteriorDecorator.ClearDecorationLocation();
}

// RoomSensorActorを生成
mGenerator->ForEach([this, parameter](const std::shared_ptr<const dungeon::Room>& room)
{
const FVector center = room->GetCenter() * parameter->GetGridSize();
const FVector extent = room->GetExtent() * parameter->GetGridSize();
SpawnRoomSensorActor(
ADungeonRoomSensor* roomSensorActor = SpawnRoomSensorActor(
parameter->GetRoomSensorClass(),
room->GetIdentifier(),
center,
Expand All @@ -478,9 +519,52 @@ void CDungeonGeneratorCore::AddTerrain()
room->GetDepthFromStart(),
mGenerator->GetDeepestDepthFromStart() //!< TODO:適切な関数名に変えて下さい
);

// center
{
FVector C = center + FVector(0, 0, -extent.Z);
FIntVector location = parameter->ToGrid(C);
const auto& grid = mGenerator->GetVoxel()->Get(location.X, location.Y, location.Z);
if (grid.IsKindOfRoomTypeWithoutGate())
{
FDungeonInteriorDecorator localRoomCenterInteriorDecorator(mRoomInteriorDecorator.GetAsset());
localRoomCenterInteriorDecorator.AddDecorationLocation(C, 0.f);
{
TArray<FString> tags = { TEXT("center"), TEXT("major") };
tags.Add(FString(room->GetPartsName().size(), room->GetPartsName().data()));
tags.Append(roomSensorActor->OnDecorateInteria());
localRoomCenterInteriorDecorator.SpawnActors(mWorld.Get(), tags, dungeon::Random::Instance());
}
{
TArray<FString> tags = { TEXT("center") };
tags.Add(FString(room->GetPartsName().size(), room->GetPartsName().data()));
tags.Append(roomSensorActor->OnDecorateInteria());
localRoomCenterInteriorDecorator.SpawnActors(mWorld.Get(), tags, dungeon::Random::Instance());
}
}
}
// wall
{
const std::shared_ptr<FDungeonInteriorDecorator> localRoomWallInteriorDecorator = mRoomInteriorDecorator.Room(FBox(center - extent, center + extent));
localRoomWallInteriorDecorator->ShuffleDecorationLocation(dungeon::Random::Instance());
{
TArray<FString> tags = { TEXT("wall"), TEXT("major") };
tags.Add(FString(room->GetPartsName().size(), room->GetPartsName().data()));
tags.Append(roomSensorActor->OnDecorateInteria());
localRoomWallInteriorDecorator->SpawnActors(mWorld.Get(), tags, dungeon::Random::Instance());
}
{
TArray<FString> tags = { TEXT("wall") };
tags.Add(FString(room->GetPartsName().size(), room->GetPartsName().data()));
tags.Append(roomSensorActor->OnDecorateInteria());
localRoomWallInteriorDecorator->SpawnActors(mWorld.Get(), tags, dungeon::Random::Instance());
}
}
}
);

mRoomInteriorDecorator.ClearDecorationLocation();

SpawnRecastNavMesh();
#if 0
//SpawnRecastNavMesh();
Expand Down Expand Up @@ -602,6 +686,9 @@ void CDungeonGeneratorCore::AddObject()
void CDungeonGeneratorCore::Clear()
{
mGenerator.reset();
mAisleInteriorDecorator.Finalize();
mSlopeInteriorDecorator.Finalize();
mRoomInteriorDecorator.Finalize();
mParameter = nullptr;
}

Expand Down Expand Up @@ -782,7 +869,7 @@ void CDungeonGeneratorCore::SpawnDoorActor(UClass* actorClass, const FTransform&
}
}

void CDungeonGeneratorCore::SpawnRoomSensorActor(
ADungeonRoomSensor* CDungeonGeneratorCore::SpawnRoomSensorActor(
UClass* actorClass,
const dungeon::Identifier& identifier,
const FVector& center,
Expand All @@ -798,11 +885,9 @@ void CDungeonGeneratorCore::SpawnRoomSensorActor(
if (IsValid(actor))
{
actor->Initialize(identifier.Get(), extent, parts, item, branchId, depthFromStart, deepestDepthFromStart);
}
if (IsValid(actor))
{
actor->FinishSpawning(transform);
}
return actor;
};

void CDungeonGeneratorCore::DestroySpawnedActors() const
Expand Down
55 changes: 55 additions & 0 deletions Source/DungeonGenerator/Private/DungeonInteriorAsset.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
\author Shun Moriya
\copyright 2023- Shun Moriya
All Rights Reserved.
*/

#include "DungeonInteriorAsset.h"
#include "Core/Math/Random.h"

TArray<FDungeonInteriorParts> UDungeonInteriorAsset::Select(const TArray<FString>& interiorTags, dungeon::Random& random) const
{
TArray<FDungeonInteriorParts> selects;

if (interiorTags.IsEmpty())
{
for (const FDungeonInteriorParts& parts : Parts)
{
if (parts.Frequency >= random.Get<uint8>(100))
{
selects.Emplace(parts);
}
}
}
else
{
for (const FDungeonInteriorParts& parts : Parts)
{
if (parts.Frequency >= random.Get<uint8>(100) &&
parts.Match(interiorTags))
{
selects.Emplace(parts);
}
}
}

return selects;
}

void UDungeonInteriorAsset::EachInteriorLocation(const AActor* actor, std::function<void(UDungeonInteriorLocationComponent* component)> function) const
{
actor->ForEachComponent<UDungeonInteriorLocationComponent>(false, [this, &function](UDungeonInteriorLocationComponent* interiorLocationComponent)
{
if (IsValid(interiorLocationComponent))
{
TArray<FDungeonInteriorParts> partsResult;
for (const FDungeonInteriorParts& parts : Parts)
{
if (parts.Match(interiorLocationComponent->GetInteriorTags()))
partsResult.Emplace(parts);
}
function(interiorLocationComponent);
}
}
);
}
Loading

0 comments on commit fc9be6c

Please sign in to comment.