281 lines
8.1 KiB
C++
281 lines
8.1 KiB
C++
// Copyright (C) 2017 Jérôme Leclercq
|
|
// This file is part of the "Nazara Engine - Graphics module"
|
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
|
|
|
#include <Nazara/Graphics/InstancedRenderable.hpp>
|
|
#include <Nazara/Graphics/Debug.hpp>
|
|
|
|
namespace Nz
|
|
{
|
|
/*!
|
|
* \brief Constructs a InstancedRenderable object by default
|
|
*/
|
|
inline InstancedRenderable::InstancedRenderable() :
|
|
m_boundingVolumeUpdated(false)
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* \brief Constructs a InstancedRenderable object by assignation
|
|
*
|
|
* \param renderable InstancedRenderable to copy into this
|
|
*/
|
|
inline InstancedRenderable::InstancedRenderable(const InstancedRenderable& renderable) :
|
|
RefCounted(),
|
|
m_boundingVolume(renderable.m_boundingVolume),
|
|
m_matCount(renderable.m_matCount),
|
|
m_skin(renderable.m_skin),
|
|
m_skinCount(renderable.m_skinCount),
|
|
m_materials(renderable.m_materials),
|
|
m_boundingVolumeUpdated(renderable.m_boundingVolumeUpdated)
|
|
{
|
|
}
|
|
|
|
/*!
|
|
* \brief Ensures that the bounding volume is up to date
|
|
*/
|
|
|
|
inline void InstancedRenderable::EnsureBoundingVolumeUpdated() const
|
|
{
|
|
if (!m_boundingVolumeUpdated)
|
|
UpdateBoundingVolume();
|
|
}
|
|
|
|
/*!
|
|
* \brief Gets one of the material used by the object.
|
|
* \return A reference to the material.
|
|
*
|
|
* This function returns the active material at the specified index, depending on the current active skin.
|
|
*
|
|
* \param matIndex Material index to query
|
|
*
|
|
* \see GetSkin, GetMaterialCount, SetSkin
|
|
*/
|
|
inline const MaterialRef& InstancedRenderable::GetMaterial(std::size_t matIndex) const
|
|
{
|
|
return GetMaterial(m_skin, matIndex);
|
|
}
|
|
|
|
/*!
|
|
* \brief Gets one of the material used by the object, independently from the active skin.
|
|
* \return A reference to the material.
|
|
*
|
|
* This function returns the active material at the specified index and the specified skin index.
|
|
* This function is the only way to query a material independently from the active skin.
|
|
*
|
|
* \param skinIndex Skin index to query
|
|
* \param matIndex Material index to query
|
|
*
|
|
* \see GetSkinCount, GetMaterialCount, SetSkin
|
|
*/
|
|
inline const MaterialRef& InstancedRenderable::GetMaterial(std::size_t skinIndex, std::size_t matIndex) const
|
|
{
|
|
NazaraAssert(skinIndex < m_skinCount, "Skin index out of bounds");
|
|
NazaraAssert(matIndex < m_materials.size(), "Material index out of bounds");
|
|
|
|
return m_materials[m_matCount * skinIndex + matIndex];
|
|
}
|
|
|
|
/*!
|
|
* \brief Gets the number of material per skin.
|
|
* \return The current material count per skin
|
|
*
|
|
* This function returns how many different materials entries exists per skin
|
|
* and is independent from the number of skin.
|
|
*/
|
|
inline std::size_t InstancedRenderable::GetMaterialCount() const
|
|
{
|
|
return m_matCount;
|
|
}
|
|
|
|
/*!
|
|
* \brief Gets the current active skin index
|
|
* \return Current skin index
|
|
*
|
|
* \see SetSkin
|
|
*/
|
|
inline std::size_t InstancedRenderable::GetSkin() const
|
|
{
|
|
return m_skin;
|
|
}
|
|
|
|
/*!
|
|
* \brief Gets the number of skins this object has
|
|
* \return Skin count
|
|
*
|
|
* \see GetSkin, SetSkinCount
|
|
*/
|
|
inline std::size_t InstancedRenderable::GetSkinCount() const
|
|
{
|
|
return m_skinCount;
|
|
}
|
|
|
|
/*!
|
|
* \brief Changes the material used at the specified index by another one
|
|
*
|
|
* This function changes the active material at the specified index, depending on the current active skin, to the one passed as parameter.
|
|
*
|
|
* \param matIndex Material index
|
|
* \param material New material, cannot be null
|
|
*
|
|
* \remark If you wish to reset the material to the default one, use the default material (see Material::GetDefault)
|
|
*
|
|
* \see SetMaterial
|
|
*/
|
|
inline void InstancedRenderable::SetMaterial(std::size_t matIndex, MaterialRef material)
|
|
{
|
|
SetMaterial(m_skin, matIndex, std::move(material));
|
|
}
|
|
|
|
/*!
|
|
* \brief Changes the material used at the specified index by another one, independently from the active skin.
|
|
*
|
|
* This function changes the active material at the specified index and for the specified skin index, to the one passed as parameter.
|
|
*
|
|
* \param skinIndex Skin index
|
|
* \param matIndex Material index
|
|
* \param material New material, cannot be null
|
|
*
|
|
* \remark If you wish to reset the material to the default one, use the default material (see Material::GetDefault)
|
|
*
|
|
* \see SetMaterial
|
|
*/
|
|
inline void InstancedRenderable::SetMaterial(std::size_t skinIndex, std::size_t matIndex, MaterialRef material)
|
|
{
|
|
NazaraAssert(skinIndex < m_skinCount, "Skin index out of bounds");
|
|
NazaraAssert(matIndex < m_materials.size(), "Material index out of bounds");
|
|
NazaraAssert(material.IsValid(), "Material must be valid");
|
|
|
|
MaterialRef& matEntry = m_materials[m_matCount * skinIndex + matIndex];
|
|
if (matEntry != material)
|
|
{
|
|
OnInstancedRenderableInvalidateMaterial(this, skinIndex, matIndex, material);
|
|
|
|
matEntry = std::move(material);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \brief Changes the active skin
|
|
*
|
|
* Each InstancedRenderable has the possibility to have multiples skins, which are sets of materials.
|
|
* Using this function allows you to have an object reference multiple materials, while using only some of thems (depending on the type of the object, see GetMaterialCount).
|
|
*
|
|
* \param skinIndex Skin index to change to
|
|
*
|
|
* \see SetSkinCount
|
|
*/
|
|
inline void InstancedRenderable::SetSkin(std::size_t skinIndex)
|
|
{
|
|
NazaraAssert(skinIndex < m_skinCount, "Skin index out of bounds");
|
|
|
|
if (m_skin != skinIndex)
|
|
{
|
|
OnInstancedRenderableSkinChange(this, skinIndex);
|
|
|
|
m_skin = skinIndex;
|
|
|
|
// Force render queue invalidation
|
|
InvalidateInstanceData(0);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \brief Changes the maximum skin count of the object
|
|
*
|
|
* This functions allows the object to store up to skinCount skins, which can then be switched to using SetSkin.
|
|
* Please note that the possibly new skins will be set to the default material, which should not be changed.
|
|
*
|
|
* \param skinCount Skin index to change to
|
|
*
|
|
* \see SetSkin
|
|
*/
|
|
inline void InstancedRenderable::SetSkinCount(std::size_t skinCount)
|
|
{
|
|
m_materials.resize(m_matCount * skinCount, Material::GetDefault());
|
|
m_skinCount = skinCount;
|
|
}
|
|
|
|
/*!
|
|
* \brief Invalidates the bounding volume
|
|
*/
|
|
|
|
inline void InstancedRenderable::InvalidateBoundingVolume()
|
|
{
|
|
m_boundingVolumeUpdated = false;
|
|
|
|
OnInstancedRenderableInvalidateBoundingVolume(this);
|
|
}
|
|
|
|
/*!
|
|
* \brief Invalidates the instance data based on flags
|
|
*
|
|
* \param flags Flags to invalidate
|
|
*/
|
|
|
|
inline void InstancedRenderable::InvalidateInstanceData(UInt32 flags)
|
|
{
|
|
OnInstancedRenderableInvalidateData(this, flags);
|
|
}
|
|
|
|
/*!
|
|
* \brief Resets the materials, material count and skin count
|
|
*
|
|
* This function clears the materials in use by the InstancedRenderable and resets its material count per skin along with its skin count.
|
|
* This is the only way of setting the material count per skin and should be called at least by the constructor of the derived class.
|
|
* Please note that all materials will be set to the default material, which should not be changed.
|
|
*
|
|
* This function also resets the current skin to the first one.
|
|
*
|
|
* \param matCount The new material count per skin value, must be at least 1
|
|
* \param skinCount The new skin count value
|
|
*
|
|
* \see GetMaterial, GetMaterialCount, GetSkinCount, SetSkinCount
|
|
*/
|
|
inline void InstancedRenderable::ResetMaterials(std::size_t matCount, std::size_t skinCount)
|
|
{
|
|
NazaraAssert(skinCount != 0, "Invalid skin count (cannot be zero)");
|
|
|
|
OnInstancedRenderableResetMaterials(this, matCount);
|
|
|
|
m_materials.clear();
|
|
m_materials.resize(matCount * skinCount, Material::GetDefault());
|
|
|
|
m_matCount = matCount;
|
|
m_skinCount = skinCount;
|
|
m_skin = 0;
|
|
}
|
|
|
|
/*!
|
|
* \brief Sets the current instanced renderable with the content of the other one
|
|
* \return A reference to this
|
|
*
|
|
* \param renderable The other InstancedRenderable
|
|
*/
|
|
|
|
inline InstancedRenderable& InstancedRenderable::operator=(const InstancedRenderable& renderable)
|
|
{
|
|
m_boundingVolume = renderable.m_boundingVolume;
|
|
m_boundingVolumeUpdated = renderable.m_boundingVolumeUpdated;
|
|
m_matCount = renderable.m_matCount;
|
|
m_materials = renderable.m_materials;
|
|
m_skin = renderable.m_skin;
|
|
m_skinCount = renderable.m_skinCount;
|
|
|
|
return *this;
|
|
}
|
|
|
|
/*!
|
|
* \brief Updates the bounding volume
|
|
*/
|
|
|
|
inline void InstancedRenderable::UpdateBoundingVolume() const
|
|
{
|
|
MakeBoundingVolume();
|
|
|
|
m_boundingVolumeUpdated = true;
|
|
}
|
|
}
|
|
|
|
#include <Nazara/Graphics/DebugOff.hpp>
|