diff --git a/Source/Engine/Graphics/Models/Mesh.h b/Source/Engine/Graphics/Models/Mesh.h index 09c04ab34..ee16c16e3 100644 --- a/Source/Engine/Graphics/Models/Mesh.h +++ b/Source/Engine/Graphics/Models/Mesh.h @@ -6,14 +6,11 @@ #include "ModelInstanceEntry.h" #include "Config.h" #include "Types.h" -#include "Engine/Level/Types.h" #if USE_PRECISE_MESH_INTERSECTS #include "CollisionProxy.h" #endif -struct GeometryDrawStateData; class Lightmap; -class GPUBuffer; /// /// Represents part of the model that is made of vertices and can be rendered using custom material and transformation. @@ -275,77 +272,6 @@ public: /// The draw call. void GetDrawCallGeometry(DrawCall& drawCall) const; - /// - /// Model instance drawing packed data. - /// - struct DrawInfo - { - /// - /// The instance buffer to use during model rendering. - /// - ModelInstanceEntries* Buffer; - - /// - /// The world transformation of the model. - /// - Matrix* World; - - /// - /// The instance drawing state data container. Used for LOD transition handling and previous world transformation matrix updating. - /// - GeometryDrawStateData* DrawState; - - /// - /// The lightmap. - /// - const Lightmap* Lightmap; - - /// - /// The lightmap UVs. - /// - const Rectangle* LightmapUVs; - - /// - /// The model instance vertex colors buffers (per-lod all meshes packed in a single allocation, array length equal to model lods count). - /// - GPUBuffer** VertexColors; - - /// - /// The object static flags. - /// - StaticFlags Flags; - - /// - /// The object draw modes. - /// - DrawPass DrawModes; - - /// - /// The bounds of the model (used to select a proper LOD during rendering). - /// - BoundingSphere Bounds; - - /// - /// The per-instance random value. - /// - float PerInstanceRandom; - - /// - /// The LOD bias value. - /// - char LODBias; - - /// - /// The forced LOD to use. Value -1 disables this feature. - /// - char ForcedLOD; - - /// - /// The object sorting key. - /// - int16 SortOrder; - }; - /// /// Draws the mesh. Binds vertex and index buffers and invokes the draw call. /// diff --git a/Source/Engine/Graphics/Models/MeshBase.h b/Source/Engine/Graphics/Models/MeshBase.h index 8f2c80e20..0d07ec4ec 100644 --- a/Source/Engine/Graphics/Models/MeshBase.h +++ b/Source/Engine/Graphics/Models/MeshBase.h @@ -5,12 +5,20 @@ #include "Engine/Core/Math/BoundingBox.h" #include "Engine/Core/Math/BoundingSphere.h" #include "Engine/Core/Types/DataContainer.h" +#include "Engine/Graphics/Enums.h" #include "Engine/Graphics/Models/Types.h" +#include "Engine/Level/Types.h" #include "Engine/Scripting/ScriptingObject.h" +struct GeometryDrawStateData; +struct RenderContext; +struct RenderContextBatch; class Task; class ModelBase; -struct RenderContextBatch; +class Lightmap; +class GPUBuffer; +class SkinnedMeshDrawData; +class BlendShapesInstance; /// /// Base class for model resources meshes. @@ -143,4 +151,95 @@ public: /// The amount of items inside the result buffer. /// True if failed, otherwise false virtual bool DownloadDataCPU(MeshBufferType type, BytesContainer& result, int32& count) const = 0; + +public: + /// + /// Model instance drawing packed data. + /// + struct DrawInfo + { + /// + /// The instance buffer to use during model rendering + /// + ModelInstanceEntries* Buffer; + + /// + /// The world transformation of the model. + /// + Matrix* World; + + /// + /// The instance drawing state data container. Used for LOD transition handling and previous world transformation matrix updating. + /// + GeometryDrawStateData* DrawState; + + union + { + struct + { + /// + /// The skinning. + /// + SkinnedMeshDrawData* Skinning; + + /// + /// The blend shapes. + /// + BlendShapesInstance* BlendShapes; + }; + + struct + { + /// + /// The lightmap. + /// + const Lightmap* Lightmap; + + /// + /// The lightmap UVs. + /// + const Rectangle* LightmapUVs; + }; + }; + + /// + /// The model instance vertex colors buffers (per-lod all meshes packed in a single allocation, array length equal to model lods count). + /// + GPUBuffer** VertexColors; + + /// + /// The object static flags. + /// + StaticFlags Flags; + + /// + /// The object draw modes. + /// + DrawPass DrawModes; + + /// + /// The bounds of the model (used to select a proper LOD during rendering). + /// + BoundingSphere Bounds; + + /// + /// The per-instance random value. + /// + float PerInstanceRandom; + + /// + /// The LOD bias value. + /// + char LODBias; + + /// + /// The forced LOD to use. Value -1 disables this feature. + /// + char ForcedLOD; + + /// + /// The object sorting key. + /// + int16 SortOrder; + }; }; diff --git a/Source/Engine/Graphics/Models/SkinnedMesh.cpp b/Source/Engine/Graphics/Models/SkinnedMesh.cpp index 979d9e250..89db8ff8b 100644 --- a/Source/Engine/Graphics/Models/SkinnedMesh.cpp +++ b/Source/Engine/Graphics/Models/SkinnedMesh.cpp @@ -119,28 +119,22 @@ bool SkinnedMesh::UpdateMesh(uint32 vertexCount, uint32 triangleCount, VB0Skinne bool SkinnedMesh::Intersects(const Ray& ray, const Matrix& world, Real& distance, Vector3& normal) const { // Transform points - Vector3 min, max; - Vector3::Transform(_box.Minimum, world, min); - Vector3::Transform(_box.Maximum, world, max); + BoundingBox transformedBox; + Vector3::Transform(_box.Minimum, world, transformedBox.Minimum); + Vector3::Transform(_box.Maximum, world, transformedBox.Maximum); - // Get transformed box - BoundingBox transformedBox(min, max); - - // Test ray on a box + // Test ray on a transformed box return transformedBox.Intersects(ray, distance, normal); } bool SkinnedMesh::Intersects(const Ray& ray, const Transform& transform, Real& distance, Vector3& normal) const { // Transform points - Vector3 min, max; - transform.LocalToWorld(_box.Minimum, min); - transform.LocalToWorld(_box.Maximum, max); + BoundingBox transformedBox; + transform.LocalToWorld(_box.Minimum, transformedBox.Minimum); + transform.LocalToWorld(_box.Maximum, transformedBox.Maximum); - // Get transformed box - BoundingBox transformedBox(min, max); - - // Test ray on a box + // Test ray on a transformed box return transformedBox.Intersects(ray, distance, normal); } @@ -216,7 +210,7 @@ void SkinnedMesh::Draw(const RenderContext& renderContext, const DrawInfo& info, drawCall.PerInstanceRandom = info.PerInstanceRandom; // Push draw call to the render list - renderContext.List->AddDrawCall(renderContext, drawModes, StaticFlags::None, drawCall, entry.ReceiveDecals); + renderContext.List->AddDrawCall(renderContext, drawModes, StaticFlags::None, drawCall, entry.ReceiveDecals, info.SortOrder); } void SkinnedMesh::Draw(const RenderContextBatch& renderContextBatch, const DrawInfo& info, float lodDitherFactor) const @@ -279,7 +273,7 @@ void SkinnedMesh::Draw(const RenderContextBatch& renderContextBatch, const DrawI const auto shadowsMode = entry.ShadowsMode & slot.ShadowsMode; const auto drawModes = info.DrawModes & material->GetDrawModes(); if (drawModes != DrawPass::None) - renderContextBatch.GetMainContext().List->AddDrawCall(renderContextBatch, drawModes, StaticFlags::None, shadowsMode, info.Bounds, drawCall, entry.ReceiveDecals); + renderContextBatch.GetMainContext().List->AddDrawCall(renderContextBatch, drawModes, StaticFlags::None, shadowsMode, info.Bounds, drawCall, entry.ReceiveDecals, info.SortOrder); } bool SkinnedMesh::DownloadDataGPU(MeshBufferType type, BytesContainer& result) const diff --git a/Source/Engine/Graphics/Models/SkinnedMesh.h b/Source/Engine/Graphics/Models/SkinnedMesh.h index c4893c8ac..8bf957554 100644 --- a/Source/Engine/Graphics/Models/SkinnedMesh.h +++ b/Source/Engine/Graphics/Models/SkinnedMesh.h @@ -6,11 +6,6 @@ #include "Types.h" #include "BlendShape.h" -struct GeometryDrawStateData; -struct RenderContext; -class GPUBuffer; -class SkinnedMeshDrawData; - /// /// Represents part of the skinned model that is made of vertices and can be rendered using custom material, transformation and skeleton bones hierarchy. /// @@ -170,62 +165,6 @@ public: } public: - /// - /// Model instance drawing packed data. - /// - struct DrawInfo - { - /// - /// The instance buffer to use during model rendering - /// - ModelInstanceEntries* Buffer; - - /// - /// The skinning. - /// - SkinnedMeshDrawData* Skinning; - - /// - /// The blend shapes. - /// - BlendShapesInstance* BlendShapes; - - /// - /// The world transformation of the model. - /// - Matrix* World; - - /// - /// The instance drawing state data container. Used for LOD transition handling and previous world transformation matrix updating. - /// - GeometryDrawStateData* DrawState; - - /// - /// The object draw modes. - /// - DrawPass DrawModes; - - /// - /// The bounds of the model (used to select a proper LOD during rendering). - /// - BoundingSphere Bounds; - - /// - /// The per-instance random value. - /// - float PerInstanceRandom; - - /// - /// The LOD bias value. - /// - char LODBias; - - /// - /// The forced LOD to use. Value -1 disables this feature. - /// - char ForcedLOD; - }; - /// /// Draws the mesh. Binds vertex and index buffers and invokes the draw call. /// diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp index ecaed39cb..9605119a3 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.cpp +++ b/Source/Engine/Level/Actors/AnimatedModel.cpp @@ -737,6 +737,7 @@ void AnimatedModel::Draw(RenderContext& renderContext) draw.PerInstanceRandom = GetPerInstanceRandom(); draw.LODBias = LODBias; draw.ForcedLOD = ForcedLOD; + draw.SortOrder = SortOrder; SkinnedModel->Draw(renderContext, draw); } @@ -777,6 +778,7 @@ void AnimatedModel::Draw(RenderContextBatch& renderContextBatch) draw.PerInstanceRandom = GetPerInstanceRandom(); draw.LODBias = LODBias; draw.ForcedLOD = ForcedLOD; + draw.SortOrder = SortOrder; PRAGMA_DISABLE_DEPRECATION_WARNINGS if (ShadowsMode != ShadowsCastingMode::All) @@ -851,6 +853,7 @@ void AnimatedModel::Serialize(SerializeStream& stream, const void* otherObj) SERIALIZE(CustomBounds); SERIALIZE(LODBias); SERIALIZE(ForcedLOD); + SERIALIZE(SortOrder); SERIALIZE(DrawModes); PRAGMA_DISABLE_DEPRECATION_WARNINGS SERIALIZE(ShadowsMode); @@ -877,6 +880,7 @@ void AnimatedModel::Deserialize(DeserializeStream& stream, ISerializeModifier* m DESERIALIZE(CustomBounds); DESERIALIZE(LODBias); DESERIALIZE(ForcedLOD); + DESERIALIZE(SortOrder); DESERIALIZE(DrawModes); PRAGMA_DISABLE_DEPRECATION_WARNINGS DESERIALIZE(ShadowsMode); diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h index f8cb18907..3c578d244 100644 --- a/Source/Engine/Level/Actors/AnimatedModel.h +++ b/Source/Engine/Level/Actors/AnimatedModel.h @@ -138,6 +138,12 @@ public: API_FIELD(Attributes="EditorOrder(100), DefaultValue(DrawPass.Default), EditorDisplay(\"Skinned Model\")") DrawPass DrawModes = DrawPass::Default; + /// + /// The object sort order key used when sorting drawable objects during rendering. Use lower values to draw object before others, higher values are rendered later (on top). Can be use to control transparency drawing. + /// + API_FIELD(Attributes="EditorDisplay(\"Skinned Model\"), EditorOrder(110), DefaultValue(0)") + int16 SortOrder = 0; + /// /// The shadows casting mode. /// [Deprecated on 26.10.2022, expires on 26.10.2024]