// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Types/Guid.h" #include "Engine/Graphics/Enums.h" #include "Types.h" #include "Config.h" #include "SkeletonData.h" #include "BlendShape.h" #include "Engine/Animations/AnimationData.h" class WriteStream; /// /// Data container for the common model meshes data. Supports holding all types of data related to the models pipeline. /// class FLAXENGINE_API MeshData { public: /// /// The slot index in the model materials to use during rendering. /// int32 MaterialSlotIndex = 0; /// /// The model skeleton node index. Used during importing and by the animated models. /// int32 NodeIndex = 0; /// /// The name of the mesh. /// String Name; /// /// Mesh positions buffer /// Array Positions; /// /// Texture coordinates (list of channels) /// Array, FixedAllocation> UVs; /// /// Normals vector /// Array Normals; /// /// Tangents vectors /// Array Tangents; /// /// Bitangents vectors signs (used for bitangent reconstruction). Can be +1 or -1. /// bitangent = cross(normal, tangent) * sign /// sign = dot(cross(bitangent, normal), tangent) /// Array BitangentSigns; /// /// Mesh index buffer /// Array Indices; /// /// Vertex colors /// Array Colors; /// /// Skinned mesh blend indices (max 4 per bone) /// Array BlendIndices; /// /// Skinned mesh index buffer (max 4 per bone) /// Array BlendWeights; /// /// Blend shapes used by this mesh /// Array BlendShapes; /// /// Lightmap texture coordinates channel index. Value -1 indicates that channel is not available. /// int32 LightmapUVsIndex = -1; /// /// Local translation for this mesh to be at it's local origin. /// Vector3 OriginTranslation = Vector3::Zero; /// /// Orientation for this mesh at its local origin. /// Quaternion OriginOrientation = Quaternion::Identity; /// /// Meshes scaling. /// Vector3 Scaling = Vector3::One; public: /// /// Clear arrays /// void Clear(); /// /// Ensure that buffers will have given space for data /// /// Amount of vertices. /// Amount of indices. /// Failed if clear data otherwise will try to preserve the buffers contents. /// True if use vertex colors buffer. /// True if use vertex blend indices and weights buffer. /// Amount of texture coordinate channels to use. void EnsureCapacity(int32 vertices, int32 indices, bool preserveContents = false, bool withColors = true, bool withSkin = true, int32 texcoords = 1); /// /// Swaps the vertex and index buffers contents (without a data copy) with the other mesh. /// /// The other mesh to swap data with. void SwapBuffers(MeshData& other); /// /// Clean data /// void Release(); public: PRAGMA_DISABLE_DEPRECATION_WARNINGS /// /// Init from model vertices array /// /// Array of vertices /// Amount of vertices void InitFromModelVertices(ModelVertex19* vertices, uint32 verticesCount); /// /// Init from model vertices array /// /// Array of data for vertex buffer 0 /// Array of data for vertex buffer 1 /// Amount of vertices void InitFromModelVertices(VB0ElementType18* vb0, VB1ElementType18* vb1, uint32 verticesCount); /// /// Init from model vertices array /// /// Array of data for vertex buffer 0 /// Array of data for vertex buffer 1 /// Array of data for vertex buffer 2 /// Amount of vertices void InitFromModelVertices(VB0ElementType18* vb0, VB1ElementType18* vb1, VB2ElementType18* vb2, uint32 verticesCount); PRAGMA_ENABLE_DEPRECATION_WARNINGS /// /// Sets the index buffer data. /// /// The data. /// The indices count. void SetIndexBuffer(void* data, uint32 indicesCount); public: /// /// Calculate bounding box for the mesh /// /// Output box void CalculateBox(BoundingBox& result) const; /// /// Calculate bounding sphere for the mesh /// /// Output sphere void CalculateSphere(BoundingSphere& result) const; /// /// Calculates bounding box and sphere for the mesh. /// /// Output box. /// Output sphere. void CalculateBounds(BoundingBox& box, BoundingSphere& sphere) const; #if COMPILE_WITH_MODEL_TOOL /// /// Setups Lightmap UVs based on the option. /// void SetLightmapUVsSource(ModelLightmapUVsSource source); /// /// Generate lightmap uvs for the mesh entry /// /// True if generating lightmap uvs failed, otherwise false bool GenerateLightmapUVs(); /// /// Iterates over the vertex buffers to remove the duplicated vertices and generate the optimized index buffer. /// void BuildIndexBuffer(); /// /// Generate lightmap uvs for the mesh entry /// /// The target position to check. /// The position comparision epsilon. /// The output vertices indices array. void FindPositions(const Float3& position, float epsilon, Array& result); /// /// Generates the normal vectors for the mesh geometry. /// /// Specifies the maximum angle (in degrees) that may be between two face normals at the same vertex position that their are smoothed together. /// True if generating failed, otherwise false bool GenerateNormals(float smoothingAngle = 175.0f); /// /// Generates the tangent vectors for the mesh geometry. Requires normal vector and texture coords channel to be valid. /// /// Specifies the maximum angle (in degrees) that may be between two vertex tangents that their tangents and bi-tangents are smoothed. /// True if generating failed, otherwise false. bool GenerateTangents(float smoothingAngle = 45.0f); /// /// Reorders all triangles for improved vertex cache locality. It tries to arrange all triangles to fans and to render triangles which share vertices directly one after the other. /// void ImproveCacheLocality(); /// /// Sums the area of all triangles in the mesh. /// /// The area sum of all mesh triangles. float CalculateTrianglesArea() const; #endif /// /// Transform a vertex buffer positions, normals, tangents and bitangents using the given matrix. /// /// The matrix to use for the transformation. void TransformBuffer(const Matrix& matrix); /// /// Normalizes the blend weights. Requires to have vertices with positions and blend weights setup. /// void NormalizeBlendWeights(); /// /// Merges this mesh data with the specified other mesh. /// /// The other mesh to merge with. void Merge(MeshData& other); }; /// /// Model texture resource descriptor. /// struct FLAXENGINE_API TextureEntry { enum class TypeHint { ColorRGB, ColorRGBA, Normals, }; /// /// The absolute path to the file. /// String FilePath; /// /// The texture contents hint based on the usage/context. /// TypeHint Type; /// /// The texture asset identifier. /// Guid AssetID; }; /// /// Model material slot entry that describes model mesh appearance. /// struct FLAXENGINE_API MaterialSlotEntry { /// /// The slot name. /// String Name; /// /// Gets or sets shadows casting mode by this visual element /// ShadowsCastingMode ShadowsMode = ShadowsCastingMode::All; /// /// The material asset identifier (material or material instance). /// Guid AssetID; struct { Color Color = Color::White; int32 TextureIndex = -1; bool HasAlphaMask = false; } Diffuse; struct { Color Color = Color::Transparent; int32 TextureIndex = -1; } Emissive; struct { float Value = 1.0f; int32 TextureIndex = -1; } Opacity; struct { float Value = 0.5f; int32 TextureIndex = -1; } Roughness; struct { int32 TextureIndex = -1; } Normals; bool TwoSided = false; bool UsesProperties() const; static float ShininessToRoughness(float shininess); }; /// /// Data container for model hierarchy node. /// struct FLAXENGINE_API ModelDataNode { /// /// The parent node index. The root node uses value -1. /// int32 ParentIndex; /// /// The local transformation of the node, relative to the parent node. /// Transform LocalTransform; /// /// The name of this node. /// String Name; }; /// /// Data container for LOD metadata and sub meshes. /// struct FLAXENGINE_API ModelLodData { /// /// The screen size to switch LODs. Bottom limit of the model screen size to render this LOD. /// float ScreenSize = 1.0f; /// /// The meshes array. /// Array Meshes; /// /// Finalizes an instance of the class. /// ~ModelLodData(); /// /// Gets the bounding box combined for all meshes in this model LOD. /// BoundingBox GetBox() const; }; /// /// Data container for model metadata and LODs. /// class FLAXENGINE_API ModelData { public: /// /// The minimum screen size to draw model (the bottom limit). /// float MinScreenSize = 0.0f; /// /// The texture slots. /// Array Textures; /// /// The material slots. /// Array Materials; /// /// Array with all Level Of Details that contain meshes. The first element is the top most LOD0 followed by the LOD1, LOD2, etc. /// Array LODs; /// /// The skeleton bones hierarchy. /// SkeletonData Skeleton; /// /// The scene nodes (in hierarchy). /// Array Nodes; /// /// The node animations. /// Array Animations; public: // See ModelTool::PositionFormat enum class PositionFormats { Float32, Float16, } PositionFormat = PositionFormats::Float32; // See ModelTool::TexCoordFormats enum class TexCoordFormats { Float16, UNorm8, } TexCoordFormat = TexCoordFormats::Float16; public: /// /// Automatically calculates the screen size for every model LOD for a proper transitions. /// void CalculateLODsScreenSizes(); /// /// Transform a vertex buffer positions, normals, tangents and bitangents using the given matrix. Applies to all the LODs and meshes. /// /// The matrix to use for the transformation. void TransformBuffer(const Matrix& matrix); };