/* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #pragma once #include "WhiteBoxBuffer.h" #include #include namespace WhiteBox { //! Attributes for white box mesh vertices. enum class AttributeType { Position, Normal, Tangent, Bitangent, UV, Color }; //! The number of attributes required by the white box mesh. inline constexpr uint32_t NumAttributes = 6; //! Trait to describe white box mesh vertex attribute format. template struct AttributeTrait { }; //! Attribute trait specialization for vertex position attribute. template<> struct AttributeTrait { static constexpr const char* ShaderSemantic = "POSITION"; using BufferType = Vector3Buffer; }; //! Attribute trait specialization for vertex normal attribute template<> struct AttributeTrait { static constexpr const char* ShaderSemantic = "NORMAL"; using BufferType = Vector3Buffer; }; //! Attribute trait specialization for vertex tangent attribute. template<> struct AttributeTrait { static constexpr const char* ShaderSemantic = "TANGENT"; using BufferType = Vector4Buffer; }; //! Attribute trait specialization for vertex bitangent attribute. template<> struct AttributeTrait { static constexpr const char* ShaderSemantic = "BITANGENT"; using BufferType = Vector3Buffer; }; //! Attribute trait specialization for vertex uv attribute. template<> struct AttributeTrait { static constexpr const char* ShaderSemantic = "UV"; using BufferType = Vector2Buffer; }; //! Attribute trait specialization for vertex color attribute. template<> struct AttributeTrait { static constexpr const char* ShaderSemantic = "COLOR"; using BufferType = Vector4Buffer; }; //! Buffer to hold white box mesh vertex attribute data. template class AttributeBuffer { public: using Trait = AttributeTrait; //! Construct a new Attribute Buffer object from the specified data. template AttributeBuffer(const AZStd::vector& data); //! Retrieves the buffer asset. const AZ::Data::Asset& GetBuffer() const; //! Retrieves the buffer view descriptor. const AZ::RHI::BufferViewDescriptor& GetBufferViewDescriptor() const; //! Retrieves the buffer asset view. const AZ::RPI::BufferAssetView& GetBufferAssetView() const; //! Retrieves the attribute's shader semantic. const AZ::RHI::ShaderSemantic& GetShaderSemantic() const; //! Adds this attribute buffer to the Lod. void AddLodStreamBuffer(AZ::RPI::ModelLodAssetCreator& modelLodCreator) const; //! Adds this attribute buffer to the mesh. void AddMeshStreamBuffer(AZ::RPI::ModelLodAssetCreator& modelLodCreator) const; //! Returns true of the attribute buffer is valid, otherwise false. bool IsValid() const; //! Update the attribute buffer contents with the new data. template bool UpdateData(const AZStd::vector& data); private: typename Trait::BufferType m_buffer; AZ::RHI::ShaderSemantic m_shaderSemantic; }; template template AttributeBuffer::AttributeBuffer(const AZStd::vector& data) : m_buffer(data) , m_shaderSemantic(AZ::Name(Trait::ShaderSemantic)) { if (!IsValid()) { AZ_Error( "AttributeBuffer", false, "Couldn't create buffer for attribute %s", m_shaderSemantic.ToString().c_str()); } } template const AZ::Data::Asset& AttributeBuffer::GetBuffer() const { return m_buffer.GetBuffer(); } template const AZ::RHI::BufferViewDescriptor& AttributeBuffer::GetBufferViewDescriptor() const { return m_buffer.GetBufferViewDescriptor(); } template const AZ::RPI::BufferAssetView& AttributeBuffer::GetBufferAssetView() const { return m_buffer.GetBufferAssetView(); } template const AZ::RHI::ShaderSemantic& AttributeBuffer::GetShaderSemantic() const { return m_shaderSemantic; } template void AttributeBuffer::AddLodStreamBuffer(AZ::RPI::ModelLodAssetCreator& modelLodCreator) const { modelLodCreator.AddLodStreamBuffer(GetBuffer()); } template void AttributeBuffer::AddMeshStreamBuffer(AZ::RPI::ModelLodAssetCreator& modelLodCreator) const { modelLodCreator.AddMeshStreamBuffer(GetShaderSemantic(), AZ::Name(), GetBufferAssetView()); } template bool AttributeBuffer::IsValid() const { return m_buffer.IsValid(); } template template bool AttributeBuffer::UpdateData(const AZStd::vector& data) { if (!m_buffer.UpdateData(data)) { AZ_Error( "AttributeBuffer", false, "Couldn't update buffer for attribute %s", m_shaderSemantic.ToString().c_str()); return false; } return true; } //! Attribute buffer alias for position attributes. using PositionAttribute = AttributeBuffer; //! Attribute buffer alias for normal attributes. using NormalAttribute = AttributeBuffer; //! Attribute buffer alias for tangent attributes. using TangentAttribute = AttributeBuffer; //! Attribute buffer alias for bitangent attributes. using BitangentAttribute = AttributeBuffer; //! Attribute buffer alias for uv attributes. using UVAttribute = AttributeBuffer; //! Attribute buffer alias for color attributes. using ColorAttribute = AttributeBuffer; } // namespace WhiteBox