calibration_tools_v1.0/lidar_driver/include/open3d/3rdparty/filament/RenderableManager.h
2025-02-20 10:45:17 +08:00

523 lines
20 KiB
C++

/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TNT_FILAMENT_RENDERABLECOMPONENTMANAGER_H
#define TNT_FILAMENT_RENDERABLECOMPONENTMANAGER_H
#include <filament/Box.h>
#include <filament/FilamentAPI.h>
#include <filament/MaterialEnums.h>
#include <backend/DriverEnums.h>
#include <utils/compiler.h>
#include <utils/EntityInstance.h>
#include <math/mathfwd.h>
#include <type_traits>
namespace utils {
class Entity;
} // namespace utils
namespace filament {
class Engine;
class IndexBuffer;
class Material;
class MaterialInstance;
class Renderer;
class VertexBuffer;
class FEngine;
class FRenderPrimitive;
class FRenderableManager;
/**
* Factory and manager for \em renderables, which are entities that can be drawn.
*
* Renderables are bundles of \em primitives, each of which has its own geometry and material. All
* primitives in a particular renderable share a set of rendering attributes, such as whether they
* cast shadows or use vertex skinning.
*
* Usage example:
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* auto renderable = utils::EntityManager::get().create();
*
* RenderableManager::Builder(1)
* .boundingBox({{ -1, -1, -1 }, { 1, 1, 1 }})
* .material(0, matInstance)
* .geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vertBuffer, indBuffer, 0, 3)
* .receiveShadows(false)
* .build(engine, renderable);
*
* scene->addEntity(renderable);
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* To modify the state of an existing renderable, clients should first use RenderableManager
* to get a temporary handle called an \em instance. The instance can then be used to get or set
* the renderable's state. Please note that instances are ephemeral; clients should store entities,
* not instances.
*
* - For details about constructing renderables, see RenderableManager::Builder.
* - To associate a 4x4 transform with an entity, see TransformManager.
* - To associate a human-readable label with an entity, see utils::NameComponentManager.
*/
class UTILS_PUBLIC RenderableManager : public FilamentAPI {
struct BuilderDetails;
public:
using Instance = utils::EntityInstance<RenderableManager>;
using PrimitiveType = backend::PrimitiveType;
/**
* Checks if the given entity already has a renderable component.
*/
bool hasComponent(utils::Entity e) const noexcept;
/**
* Gets a temporary handle that can be used to access the renderable state.
*
* @return Non-zero handle if the entity has a renderable component, 0 otherwise.
*/
Instance getInstance(utils::Entity e) const noexcept;
/**
* The transformation associated with a skinning joint.
*
* Clients can specify bones either using this quat-vec3 pair, or by using 4x4 matrices.
*/
struct Bone {
math::quatf unitQuaternion = { 1, 0, 0, 0 };
math::float3 translation = { 0, 0, 0 };
float reserved = 0;
};
/**
* Adds renderable components to entities using a builder pattern.
*/
class Builder : public BuilderBase<BuilderDetails> {
friend struct BuilderDetails;
public:
enum Result { Error = -1, Success = 0 };
/**
* Creates a builder for renderable components.
*
* @param count the number of primitives that will be supplied to the builder
*
* Note that builders typically do not have a long lifetime since clients should discard
* them after calling build(). For a usage example, see RenderableManager.
*/
explicit Builder(size_t count) noexcept;
/*! \cond PRIVATE */
Builder(Builder const& rhs) = delete;
Builder(Builder&& rhs) noexcept;
~Builder() noexcept;
Builder& operator=(Builder& rhs) = delete;
Builder& operator=(Builder&& rhs) noexcept;
/*! \endcond */
/**
* Specifies the geometry data for a primitive.
*
* Filament primitives must have an associated VertexBuffer and IndexBuffer. Typically, each
* primitive is specified with a pair of daisy-chained calls: \c geometry(...) and \c
* material(...).
*
* @param index zero-based index of the primitive, must be less than the count passed to Builder constructor
* @param type specifies the topology of the primitive (e.g., \c RenderableManager::PrimitiveType::TRIANGLES)
* @param vertices specifies the vertex buffer, which in turn specifies a set of attributes
* @param indices specifies the index buffer (either u16 or u32)
* @param offset specifies where in the index buffer to start reading (expressed as a number of bytes)
* @param minIndex specifies the minimum index contained in the index buffer
* @param maxIndex specifies the maximum index contained in the index buffer
* @param count number of indices to read (for triangles, this should be a multiple of 3)
*/
Builder& geometry(size_t index, PrimitiveType type, VertexBuffer* vertices, IndexBuffer* indices, size_t offset, size_t minIndex, size_t maxIndex, size_t count) noexcept;
Builder& geometry(size_t index, PrimitiveType type, VertexBuffer* vertices, IndexBuffer* indices, size_t offset, size_t count) noexcept; //!< \overload
Builder& geometry(size_t index, PrimitiveType type, VertexBuffer* vertices, IndexBuffer* indices) noexcept; //!< \overload
/**
* Binds a material instance to the specified primitive.
*
* If no material is specified for a given primitive, Filament will fall back to a basic default material.
*
* @param index zero-based index of the primitive, must be less than the count passed to Builder constructor
* @param materialInstance the material to bind
*/
Builder& material(size_t index, MaterialInstance const* materialInstance) noexcept;
/**
* The axis-aligned bounding box of the renderable.
*
* This is an object-space AABB used for frustum culling. For skinning and morphing, this
* should encompass all possible vertex positions. It is mandatory unless culling is
* disabled for the renderable.
*
* \see computeAABB()
*/
Builder& boundingBox(const Box& axisAlignedBoundingBox) noexcept;
/**
* Sets bits in a visibility mask. By default, this is 0x1.
*
* This feature provides a simple mechanism for hiding and showing groups of renderables
* in a Scene. See View::setVisibleLayers().
*
* For example, to set bit 1 and reset bits 0 and 2 while leaving all other bits unaffected,
* do: `builder.layerMask(7, 2)`.
*
* To change this at run time, see RenderableManager::setLayerMask.
*
* @param select the set of bits to affect
* @param values the replacement values for the affected bits
*/
Builder& layerMask(uint8_t select, uint8_t values) noexcept;
/**
* Provides coarse-grained control over draw order.
*
* In general Filament reserves the right to re-order renderables to allow for efficient
* rendering. However clients can control ordering at a coarse level using \em priority.
*
* For example, this could be used to draw a semitransparent HUD, if a client wishes to
* avoid using a separate View for the HUD. Note that priority is completely orthogonal to
* Builder::layerMask, which merely controls visibility.
*
* \see Builder::blendOrder()
*
* The priority is clamped to the range [0..7], defaults to 4; 7 is lowest priority
* (rendered last).
*/
Builder& priority(uint8_t priority) noexcept;
/**
* Controls frustum culling, true by default.
*
* \note Do not confuse frustum culling with backface culling. The latter is controlled via
* the material.
*/
Builder& culling(bool enable) noexcept;
/**
* Controls if this renderable casts shadows, false by default.
*
* If the View's shadow type is set to ShadowType::VSM, castShadows should only be disabled
* if either is true:
* - receiveShadows is also disabled
* - the object is guaranteed to not cast shadows on itself or other objects (for example,
* a ground plane)
*/
Builder& castShadows(bool enable) noexcept;
/**
* Controls if this renderable receives shadows, true by default.
*/
Builder& receiveShadows(bool enable) noexcept;
/**
* Controls if this renderable uses screen-space contact shadows. This is more
* expensive but can improve the quality of shadows, especially in large scenes.
* (off by default).
*/
Builder& screenSpaceContactShadows(bool enable) noexcept;
/**
* Enables GPU vertex skinning for up to 255 bones, 0 by default.
*
* Each vertex can be affected by up to 4 bones simultaneously. The attached
* VertexBuffer must provide data in the \c BONE_INDICES slot (uvec4) and the
* \c BONE_WEIGHTS slot (float4).
*
* See also RenderableManager::setBones(), which can be called on a per-frame basis
* to advance the animation.
*
* @param boneCount 0 to disable, otherwise the number of bone transforms (up to 255)
* @param transforms the initial set of transforms (one for each bone)
*/
Builder& skinning(size_t boneCount, math::mat4f const* transforms) noexcept;
Builder& skinning(size_t boneCount, Bone const* bones) noexcept; //!< \overload
Builder& skinning(size_t boneCount) noexcept; //!< \overload
/**
* Controls if the renderable has vertex morphing targets, false by default.
*
* This is required to enable GPU morphing for up to 4 attributes. The attached VertexBuffer
* must provide data in the appropriate VertexAttribute slots (\c MORPH_POSITION_0 etc).
*
* See also RenderableManager::setMorphWeights(), which can be called on a per-frame basis
* to advance the animation.
*/
Builder& morphing(bool enable) noexcept;
/**
* Sets an ordering index for blended primitives that all live at the same Z value.
*
* @param primitiveIndex the primitive of interest
* @param order draw order number (0 by default). Only the lowest 15 bits are used.
*/
Builder& blendOrder(size_t primitiveIndex, uint16_t order) noexcept;
/**
* Adds the Renderable component to an entity.
*
* @param engine Reference to the filament::Engine to associate this Renderable with.
* @param entity Entity to add the Renderable component to.
* @return Success if the component was created successfully, Error otherwise.
*
* If exceptions are disabled and an error occurs, this function is a no-op.
* Success can be checked by looking at the return value.
*
* If this component already exists on the given entity and the construction is successful,
* it is first destroyed as if destroy(utils::Entity e) was called. In case of error,
* the existing component is unmodified.
*
* @exception utils::PostConditionPanic if a runtime error occurred, such as running out of
* memory or other resources.
* @exception utils::PreConditionPanic if a parameter to a builder function was invalid.
*/
Result build(Engine& engine, utils::Entity entity);
private:
friend class FEngine;
friend class FRenderPrimitive;
friend class FRenderableManager;
struct Entry {
VertexBuffer* vertices = nullptr;
IndexBuffer* indices = nullptr;
size_t offset = 0;
size_t minIndex = 0;
size_t maxIndex = 0;
size_t count = 0;
MaterialInstance const* materialInstance = nullptr;
PrimitiveType type = PrimitiveType::TRIANGLES;
uint16_t blendOrder = 0;
};
};
/**
* Destroys the renderable component in the given entity.
*/
void destroy(utils::Entity e) noexcept;
/**
* Changes the bounding box used for frustum culling.
*
* \see Builder::boundingBox()
* \see RenderableManager::getAxisAlignedBoundingBox()
*/
void setAxisAlignedBoundingBox(Instance instance, const Box& aabb) noexcept;
/**
* Changes the visibility bits.
*
* \see Builder::layerMask()
* \see View::setVisibleLayers().
* \see RenderableManager::getLayerMask()
*/
void setLayerMask(Instance instance, uint8_t select, uint8_t values) noexcept;
/**
* Changes the coarse-level draw ordering.
*
* \see Builder::priority().
*/
void setPriority(Instance instance, uint8_t priority) noexcept;
/**
* Changes whether or not frustum culling is on.
*
* \see Builder::culling()
*/
void setCulling(Instance instance, bool enable) noexcept;
/**
* Changes whether or not the renderable casts shadows.
*
* \see Builder::castShadows()
*/
void setCastShadows(Instance instance, bool enable) noexcept;
/**
* Changes whether or not the renderable can receive shadows.
*
* \see Builder::receiveShadows()
*/
void setReceiveShadows(Instance instance, bool enable) noexcept;
/**
* Changes whether or not the renderable can use screen-space contact shadows.
*
* \see Builder::screenSpaceContactShadows()
*/
void setScreenSpaceContactShadows(Instance instance, bool enable) noexcept;
/**
* Checks if the renderable can cast shadows.
*
* \see Builder::castShadows().
*/
bool isShadowCaster(Instance instance) const noexcept;
/**
* Checks if the renderable can receive shadows.
*
* \see Builder::receiveShadows().
*/
bool isShadowReceiver(Instance instance) const noexcept;
/**
* Updates the bone transforms in the range [offset, offset + boneCount).
* The bones must be pre-allocated using Builder::skinning().
*/
void setBones(Instance instance, Bone const* transforms, size_t boneCount = 1, size_t offset = 0) noexcept;
void setBones(Instance instance, math::mat4f const* transforms, size_t boneCount = 1, size_t offset = 0) noexcept; //!< \overload
/**
* Updates the vertex morphing weights on a renderable, all zeroes by default.
*
* This is specified using a 4-tuple, one float per morph target. If the renderable has fewer
* than 4 morph targets, then clients should fill the unused components with zeroes.
*
* The renderable must be built with morphing enabled, see Builder::morphing().
*/
void setMorphWeights(Instance instance, math::float4 const& weights) noexcept;
/**
* Gets the bounding box used for frustum culling.
*
* \see Builder::boundingBox()
* \see RenderableManager::setAxisAlignedBoundingBox()
*/
const Box& getAxisAlignedBoundingBox(Instance instance) const noexcept;
/**
* Get the visibility bits.
*
* \see Builder::layerMask()
* \see View::setVisibleLayers().
* \see RenderableManager::getLayerMask()
*/
uint8_t getLayerMask(Instance instance) const noexcept;
/**
* Gets the immutable number of primitives in the given renderable.
*/
size_t getPrimitiveCount(Instance instance) const noexcept;
/**
* Changes the material instance binding for the given primitive.
*
* \see Builder::material()
*/
void setMaterialInstanceAt(Instance instance,
size_t primitiveIndex, MaterialInstance const* materialInstance) noexcept;
/**
* Retrieves the material instance that is bound to the given primitive.
*/
MaterialInstance* getMaterialInstanceAt(Instance instance, size_t primitiveIndex) const noexcept;
/**
* Changes the geometry for the given primitive.
*
* \see Builder::geometry()
*/
void setGeometryAt(Instance instance, size_t primitiveIndex,
PrimitiveType type, VertexBuffer* vertices, IndexBuffer* indices,
size_t offset, size_t count) noexcept;
/**
* Changes the active range of indices or topology for the given primitive.
*
* \see Builder::geometry()
*/
void setGeometryAt(Instance instance, size_t primitiveIndex,
PrimitiveType type, size_t offset, size_t count) noexcept;
/**
* Changes the ordering index for blended primitives that all live at the same Z value.
*
* \see Builder::blendOrder()
*
* @param instance the renderable of interest
* @param primitiveIndex the primitive of interest
* @param order draw order number (0 by default). Only the lowest 15 bits are used.
*/
void setBlendOrderAt(Instance instance, size_t primitiveIndex, uint16_t order) noexcept;
/**
* Retrieves the set of enabled attribute slots in the given primitive's VertexBuffer.
*/
AttributeBitset getEnabledAttributesAt(Instance instance, size_t primitiveIndex) const noexcept;
/*! \cond PRIVATE */
template<typename T>
struct is_supported_vector_type {
using type = typename std::enable_if<
std::is_same<math::float4, T>::value ||
std::is_same<math::half4, T>::value ||
std::is_same<math::float3, T>::value ||
std::is_same<math::half3, T>::value
>::type;
};
template<typename T>
struct is_supported_index_type {
using type = typename std::enable_if<
std::is_same<uint16_t, T>::value ||
std::is_same<uint32_t, T>::value
>::type;
};
/*! \endcond */
/**
* Utility method that computes the axis-aligned bounding box from a set of vertices.
*
* - The index type must be \c uint16_t or \c uint32_t.
* - The vertex type must be \c float4, \c half4, \c float3, or \c half3.
* - For 4-component vertices, the w component is ignored (implicitly replaced with 1.0).
*/
template<typename VECTOR, typename INDEX,
typename = typename is_supported_vector_type<VECTOR>::type,
typename = typename is_supported_index_type<INDEX>::type>
static Box computeAABB(VECTOR const* vertices, INDEX const* indices, size_t count,
size_t stride = sizeof(VECTOR)) noexcept;
};
template<typename VECTOR, typename INDEX, typename, typename>
Box RenderableManager::computeAABB(VECTOR const* vertices, INDEX const* indices, size_t count,
size_t stride) noexcept {
math::float3 bmin(std::numeric_limits<float>::max());
math::float3 bmax(std::numeric_limits<float>::lowest());
for (size_t i = 0; i < count; ++i) {
VECTOR const* p = reinterpret_cast<VECTOR const*>(
(char const*)vertices + indices[i] * stride);
const math::float3 v(p->x, p->y, p->z);
bmin = min(bmin, v);
bmax = max(bmax, v);
}
return Box().set(bmin, bmax);
}
} // namespace filament
#endif // TNT_FILAMENT_RENDERABLECOMPONENTMANAGER_H