// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#pragma once
#include "Types.h"
#include "Engine/Graphics/Models/Types.h"
#include "Engine/Core/Types/Guid.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Collections/Dictionary.h"
#include "Engine/Core/Math/Rectangle.h"
#include "Engine/Core/Math/Triangle.h"
class ModelData;
namespace CSG
{
class Brush;
///
/// Represents raw CSG mesh data after triangulation. Can be used to export it to model vertex/index buffers. Separates triangles by materials.
///
class RawData
{
public:
struct Surface
{
float ScaleInLightmap;
Rectangle LightmapUVsBox;
Vector2 Size;
Rectangle UVsArea;
Array Vertices;
};
struct SurfaceData
{
Array Triangles;
};
struct BrushData
{
Array Surfaces;
};
class Slot
{
public:
Guid Material;
Array Surfaces;
public:
///
/// Initializes a new instance of the class.
///
/// The material.
Slot(const Guid& material)
: Material(material)
{
}
public:
bool IsEmpty() const
{
return Surfaces.IsEmpty();
}
void AddSurface(float scaleInLightmap, const Rectangle& lightmapUVsBox, const RawModelVertex* firstVertex, int32 vertexCount);
};
public:
///
/// The slots.
///
Array Slots;
///
/// The brushes.
///
Dictionary Brushes;
public:
///
/// Initializes a new instance of the class.
///
RawData()
{
}
///
/// Finalizes an instance of the class.
///
~RawData()
{
Slots.ClearDelete();
}
public:
///
/// Gets or adds the slot for the given material.
///
/// The material.
/// The geometry slot.
Slot* GetOrAddSlot(const Guid& material)
{
for (int32 i = 0; i < Slots.Count(); i++)
{
if (Slots[i]->Material == material)
return Slots[i];
}
auto slot = New(material);
Slots.Add(slot);
return slot;
}
public:
void AddSurface(Brush* brush, int32 brushSurfaceIndex, const Guid& surfaceMaterial, float scaleInLightmap, const Rectangle& lightmapUVsBox, const RawModelVertex* firstVertex, int32 vertexCount);
///
/// Removes the empty slots.
///
void RemoveEmptySlots()
{
for (int32 i = 0; i < Slots.Count() && Slots.HasItems(); i++)
{
if (Slots[i]->IsEmpty())
{
Delete(Slots[i]);
Slots.RemoveAt(i);
i--;
}
}
}
///
/// Outputs mesh data to the ModelData storage container.
///
/// The result model data.
void ToModelData(ModelData& modelData) const;
};
}