// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/String.h"
#include "Engine/Core/Types/Pair.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Collections/Dictionary.h"
#include "Engine/Core/Math/Vector3.h"
#include "Engine/Graphics/DynamicBuffer.h"
class SkinnedMesh;
class SkinnedModel;
class GPUBuffer;
///
/// The blend shape vertex data optimized for runtime meshes morphing.
///
struct BlendShapeVertex
{
///
/// The position offset.
///
Float3 PositionDelta;
///
/// The normal vector offset (tangent Z).
///
Float3 NormalDelta;
///
/// The index of the vertex in the mesh to blend.
///
uint32 VertexIndex;
};
template<>
struct TIsPODType
{
enum { Value = true };
};
///
/// Data container for the blend shape.
///
class BlendShape
{
public:
///
/// The name of the blend shape.
///
String Name;
///
/// The weight of the blend shape.
///
float Weight;
///
/// True if blend shape contains deltas for normal vectors of the mesh, otherwise calculations related to tangent space can be skipped.
///
bool UseNormals;
///
/// The minimum index of the vertex in all blend shape vertices. Used to optimize blend shapes updating.
///
uint32 MinVertexIndex;
///
/// The maximum index of the vertex in all blend shape vertices. Used to optimize blend shapes updating.
///
uint32 MaxVertexIndex;
///
/// The list of shape vertices.
///
Array Vertices;
};
///
/// The blend shapes runtime instance data. Handles blend shapes updating, blending and preparing for skinned mesh rendering.
///
class BlendShapesInstance
{
public:
///
/// The runtime data for blend shapes used for on a mesh.
///
class MeshInstance
{
public:
bool IsUsed;
bool IsDirty;
uint32 DirtyMinVertexIndex;
uint32 DirtyMaxVertexIndex;
DynamicVertexBuffer VertexBuffer;
MeshInstance();
~MeshInstance();
};
public:
///
/// The blend shapes weights (pair of blend shape name and the weight).
///
Array> Weights;
///
/// Flag that marks if blend shapes weights has been modified.
///
bool WeightsDirty = false;
///
/// The blend shapes meshes data.
///
Dictionary Meshes;
public:
///
/// Finalizes an instance of the class.
///
~BlendShapesInstance();
///
/// Updates the instanced meshes. Performs the blend shapes blending (only if weights were modified).
///
/// The skinned model used for blend shapes.
void Update(SkinnedModel* skinnedModel);
///
/// Clears the runtime data.
///
void Clear();
};