// Copyright (C) 2009-2022, Panagiotis Christopoulos Charitos and contributors. // All rights reserved. // Code licensed under the BSD License. // http://www.anki3d.org/LICENSE #pragma once #include #include #include #include #include #include namespace anki { /// @addtogroup resource /// @{ /// @memberof ModelResource class ModelVertexBufferBinding { public: BufferPtr m_buffer; PtrSize m_offset; PtrSize m_stride; Bool operator==(const ModelVertexBufferBinding& b) const { return m_buffer == b.m_buffer && m_offset == b.m_offset && m_stride == b.m_stride; } Bool operator!=(const ModelVertexBufferBinding& b) const { return !(*this == b); } }; /// @memberof ModelResource class ModelVertexAttribute { public: VertexAttributeId m_location; Format m_format; U32 m_bufferBinding; U32 m_relativeOffset; Bool operator==(const ModelVertexAttribute& b) const { return m_bufferBinding == b.m_bufferBinding && m_format == b.m_format && m_relativeOffset == b.m_relativeOffset && m_location == b.m_location; } Bool operator!=(const ModelVertexAttribute& b) const { return !(*this == b); } }; /// @memberof ModelResource /// Part of the information required render the model. class ModelRenderingInfo { public: ShaderProgramPtr m_program; Array m_vertexBufferBindings; U32 m_vertexBufferBindingCount; Array m_vertexAttributes; U32 m_vertexAttributeCount; BufferPtr m_indexBuffer; PtrSize m_indexBufferOffset; IndexType m_indexType; U32 m_firstIndex; U32 m_indexCount; }; /// Part of the information required to create a TLAS and a SBT. /// @memberof ModelResource class ModelRayTracingInfo { public: AccelerationStructurePtr m_bottomLevelAccelerationStructure; U32 m_shaderGroupHandleIndex; /// Get some pointers to pass to the command buffer for refcounting. ConstWeakArray m_grObjectReferences; }; /// Model patch class. Its very important class and it binds a material with a few mesh (one for each LOD). class ModelPatch { friend class ModelResource; public: const MaterialResourcePtr& getMaterial() const { return m_mtl; } const MeshResourcePtr& getMesh(U32 lod) const { return m_meshes[lod]; } const Aabb& getBoundingShape() const { return m_meshes[0]->getBoundingShape(); } /// Get information for rendering. void getRenderingInfo(const RenderingKey& key, ModelRenderingInfo& inf) const; /// Get the ray tracing info. void getRayTracingInfo(const RenderingKey& key, ModelRayTracingInfo& info) const; private: #if ANKI_ENABLE_ASSERTIONS ModelResource* m_model = nullptr; #endif MaterialResourcePtr m_mtl; Array m_meshes; ///< Just keep the references. DynamicArray m_grObjectRefs; // Begin cached data class VertexAttributeInfo { public: U32 m_bufferBinding : 8; U32 m_relativeOffset : 24; Format m_format = Format::NONE; }; Array m_vertexAttributeInfos; class VertexBufferInfo { public: BufferPtr m_buffer; PtrSize m_stride : 16; PtrSize m_offset : 48; }; Array2d m_vertexBufferInfos; class IndexBufferInfo { public: BufferPtr m_buffer; PtrSize m_offset; U32 m_firstIndex = MAX_U32; U32 m_indexCount = MAX_U32; }; Array m_indexBufferInfos; BitSet m_presentVertexAttributes = {false}; IndexType m_indexType : 2; // End cached data U8 m_meshLodCount : 6; Error init(ModelResource* model, ConstWeakArray meshFNames, const CString& mtlFName, U32 subMeshIndex, Bool async, ResourceManager* resources); [[nodiscard]] Bool supportsSkinning() const { return m_meshes[0]->hasBoneWeights() && m_mtl->supportsSkinning(); } }; /// Model is an entity that acts as a container for other resources. Models are all the non static objects in a map. /// /// XML file format: /// @code /// /// /// /// path/to/mesh.mesh /// [path/to/mesh_lod_1.ankimesh] /// [path/to/mesh_lod_2.ankimesh] /// path/to/material.ankimtl /// /// ... /// ... /// /// /// @endcode /// /// Notes: /// - If the materials need texture coords then mesh should have them /// - If the subMeshIndex is not present then assume the whole mesh class ModelResource : public ResourceObject { public: ModelResource(ResourceManager* manager); ~ModelResource(); ConstWeakArray getModelPatches() const { return m_modelPatches; } /// The volume that includes all the geometry of all model patches. const Aabb& getBoundingVolume() const { return m_boundingVolume; } Error load(const ResourceFilename& filename, Bool async); private: DynamicArray m_modelPatches; Aabb m_boundingVolume; }; /// @} } // end namespace anki