Add Sort Order to animated models too

This commit is contained in:
Wojtek Figat
2023-01-28 17:03:18 +01:00
parent 87549a3e6c
commit a214c14a4d
6 changed files with 120 additions and 152 deletions

View File

@@ -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;
/// <summary>
/// Represents part of the model that is made of vertices and can be rendered using custom material and transformation.
@@ -275,77 +272,6 @@ public:
/// <param name="drawCall">The draw call.</param>
void GetDrawCallGeometry(DrawCall& drawCall) const;
/// <summary>
/// Model instance drawing packed data.
/// </summary>
struct DrawInfo
{
/// <summary>
/// The instance buffer to use during model rendering.
/// </summary>
ModelInstanceEntries* Buffer;
/// <summary>
/// The world transformation of the model.
/// </summary>
Matrix* World;
/// <summary>
/// The instance drawing state data container. Used for LOD transition handling and previous world transformation matrix updating.
/// </summary>
GeometryDrawStateData* DrawState;
/// <summary>
/// The lightmap.
/// </summary>
const Lightmap* Lightmap;
/// <summary>
/// The lightmap UVs.
/// </summary>
const Rectangle* LightmapUVs;
/// <summary>
/// The model instance vertex colors buffers (per-lod all meshes packed in a single allocation, array length equal to model lods count).
/// </summary>
GPUBuffer** VertexColors;
/// <summary>
/// The object static flags.
/// </summary>
StaticFlags Flags;
/// <summary>
/// The object draw modes.
/// </summary>
DrawPass DrawModes;
/// <summary>
/// The bounds of the model (used to select a proper LOD during rendering).
/// </summary>
BoundingSphere Bounds;
/// <summary>
/// The per-instance random value.
/// </summary>
float PerInstanceRandom;
/// <summary>
/// The LOD bias value.
/// </summary>
char LODBias;
/// <summary>
/// The forced LOD to use. Value -1 disables this feature.
/// </summary>
char ForcedLOD;
/// <summary>
/// The object sorting key.
/// </summary>
int16 SortOrder;
};
/// <summary>
/// Draws the mesh. Binds vertex and index buffers and invokes the draw call.
/// </summary>

View File

@@ -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;
/// <summary>
/// Base class for model resources meshes.
@@ -143,4 +151,95 @@ public:
/// <param name="count">The amount of items inside the result buffer.</param>
/// <returns>True if failed, otherwise false</returns>
virtual bool DownloadDataCPU(MeshBufferType type, BytesContainer& result, int32& count) const = 0;
public:
/// <summary>
/// Model instance drawing packed data.
/// </summary>
struct DrawInfo
{
/// <summary>
/// The instance buffer to use during model rendering
/// </summary>
ModelInstanceEntries* Buffer;
/// <summary>
/// The world transformation of the model.
/// </summary>
Matrix* World;
/// <summary>
/// The instance drawing state data container. Used for LOD transition handling and previous world transformation matrix updating.
/// </summary>
GeometryDrawStateData* DrawState;
union
{
struct
{
/// <summary>
/// The skinning.
/// </summary>
SkinnedMeshDrawData* Skinning;
/// <summary>
/// The blend shapes.
/// </summary>
BlendShapesInstance* BlendShapes;
};
struct
{
/// <summary>
/// The lightmap.
/// </summary>
const Lightmap* Lightmap;
/// <summary>
/// The lightmap UVs.
/// </summary>
const Rectangle* LightmapUVs;
};
};
/// <summary>
/// The model instance vertex colors buffers (per-lod all meshes packed in a single allocation, array length equal to model lods count).
/// </summary>
GPUBuffer** VertexColors;
/// <summary>
/// The object static flags.
/// </summary>
StaticFlags Flags;
/// <summary>
/// The object draw modes.
/// </summary>
DrawPass DrawModes;
/// <summary>
/// The bounds of the model (used to select a proper LOD during rendering).
/// </summary>
BoundingSphere Bounds;
/// <summary>
/// The per-instance random value.
/// </summary>
float PerInstanceRandom;
/// <summary>
/// The LOD bias value.
/// </summary>
char LODBias;
/// <summary>
/// The forced LOD to use. Value -1 disables this feature.
/// </summary>
char ForcedLOD;
/// <summary>
/// The object sorting key.
/// </summary>
int16 SortOrder;
};
};

View File

@@ -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

View File

@@ -6,11 +6,6 @@
#include "Types.h"
#include "BlendShape.h"
struct GeometryDrawStateData;
struct RenderContext;
class GPUBuffer;
class SkinnedMeshDrawData;
/// <summary>
/// Represents part of the skinned model that is made of vertices and can be rendered using custom material, transformation and skeleton bones hierarchy.
/// </summary>
@@ -170,62 +165,6 @@ public:
}
public:
/// <summary>
/// Model instance drawing packed data.
/// </summary>
struct DrawInfo
{
/// <summary>
/// The instance buffer to use during model rendering
/// </summary>
ModelInstanceEntries* Buffer;
/// <summary>
/// The skinning.
/// </summary>
SkinnedMeshDrawData* Skinning;
/// <summary>
/// The blend shapes.
/// </summary>
BlendShapesInstance* BlendShapes;
/// <summary>
/// The world transformation of the model.
/// </summary>
Matrix* World;
/// <summary>
/// The instance drawing state data container. Used for LOD transition handling and previous world transformation matrix updating.
/// </summary>
GeometryDrawStateData* DrawState;
/// <summary>
/// The object draw modes.
/// </summary>
DrawPass DrawModes;
/// <summary>
/// The bounds of the model (used to select a proper LOD during rendering).
/// </summary>
BoundingSphere Bounds;
/// <summary>
/// The per-instance random value.
/// </summary>
float PerInstanceRandom;
/// <summary>
/// The LOD bias value.
/// </summary>
char LODBias;
/// <summary>
/// The forced LOD to use. Value -1 disables this feature.
/// </summary>
char ForcedLOD;
};
/// <summary>
/// Draws the mesh. Binds vertex and index buffers and invokes the draw call.
/// </summary>

View File

@@ -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);

View File

@@ -138,6 +138,12 @@ public:
API_FIELD(Attributes="EditorOrder(100), DefaultValue(DrawPass.Default), EditorDisplay(\"Skinned Model\")")
DrawPass DrawModes = DrawPass::Default;
/// <summary>
/// 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.
/// </summary>
API_FIELD(Attributes="EditorDisplay(\"Skinned Model\"), EditorOrder(110), DefaultValue(0)")
int16 SortOrder = 0;
/// <summary>
/// The shadows casting mode.
/// [Deprecated on 26.10.2022, expires on 26.10.2024]