// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Level/Actor.h"
#include "Engine/Graphics/Models/ModelInstanceEntry.h"
///
/// Base class for actor types that use ModelInstanceEntries for mesh rendering.
///
///
API_CLASS(Abstract) class FLAXENGINE_API ModelInstanceActor : public Actor
{
DECLARE_SCENE_OBJECT_ABSTRACT(ModelInstanceActor);
protected:
int32 _sceneRenderingKey = -1; // Uses SceneRendering::DrawCategory::SceneDrawAsync
public:
///
/// The model instance buffer.
///
ModelInstanceEntries Entries;
///
/// Gets the model entries collection. Each entry contains data how to render meshes using this entry (transformation, material, shadows casting, etc.).
///
API_PROPERTY(Attributes="Serialize, EditorOrder(1000), EditorDisplay(\"Entries\", EditorDisplayAttribute.InlineStyle), Collection(CanReorderItems = false, NotNullItems = true, ReadOnly = true, Spacing = 10)")
FORCE_INLINE Array GetEntries() const
{
return Entries;
}
///
/// Sets the model entries collection. Each entry contains data how to render meshes using this entry (transformation, material, shadows casting, etc.).
///
API_PROPERTY() void SetEntries(const Array& value);
///
/// Sets the material to the entry slot. Can be used to override the material of the meshes using this slot.
///
/// The material slot entry index.
/// The material to set.
API_FUNCTION() void SetMaterial(int32 entryIndex, MaterialBase* material);
///
/// Utility to crate a new virtual Material Instance asset, set its parent to the currently applied material, and assign it to the entry. Can be used to modify the material parameters from code.
///
/// The material slot entry index.
/// The created virtual material instance.
API_FUNCTION() MaterialInstance* CreateAndSetVirtualMaterialInstance(int32 entryIndex);
///
/// Determines if there is an intersection between the model actor mesh entry and a ray.
/// If mesh data is available on the CPU performs exact intersection check with the geometry.
/// Otherwise performs simple vs test.
/// For more efficient collisions detection and ray casting use physics.
///
/// The material slot entry index to test.
/// The ray to test.
/// When the method completes and returns true, contains the distance of the intersection (if any valid).
/// When the method completes, contains the intersection surface normal vector (if any valid).
/// True if the actor is intersected by the ray, otherwise false.
API_FUNCTION() virtual bool IntersectsEntry(int32 entryIndex, API_PARAM(Ref) const Ray& ray, API_PARAM(Out) Real& distance, API_PARAM(Out) Vector3& normal)
{
return false;
}
///
/// Determines if there is an intersection between the model actor mesh entry and a ray.
/// If mesh data is available on the CPU performs exact intersection check with the geometry.
/// Otherwise performs simple vs test.
/// For more efficient collisions detection and ray casting use physics.
///
/// The ray to test.
/// When the method completes and returns true, contains the distance of the intersection (if any valid).
/// When the method completes, contains the intersection surface normal vector (if any valid).
/// When the method completes, contains the intersection entry index (if any valid).
/// True if the actor is intersected by the ray, otherwise false.
API_FUNCTION() virtual bool IntersectsEntry(API_PARAM(Ref) const Ray& ray, API_PARAM(Out) Real& distance, API_PARAM(Out) Vector3& normal, API_PARAM(Out) int32& entryIndex)
{
return false;
}
protected:
virtual void WaitForModelLoad();
public:
// [Actor]
void OnLayerChanged() override;
protected:
// [Actor]
void OnEnable() override;
void OnDisable() override;
};