141 lines
4.0 KiB
C++
141 lines
4.0 KiB
C++
//
|
|
// Created by kj16609 on 11/28/23.
|
|
//
|
|
|
|
#include "Model.hpp"
|
|
|
|
#include <cassert>
|
|
#include <iostream>
|
|
|
|
#include "builders/ModelBuilder.hpp"
|
|
#include "builders/SceneBuilder.hpp"
|
|
#include "engine/buffers/Buffer.hpp"
|
|
#include "engine/buffers/SuballocationView.hpp"
|
|
#include "engine/image/ImageView.hpp"
|
|
|
|
namespace fgl::engine
|
|
{
|
|
|
|
std::vector< vk::DrawIndexedIndirectCommand > Model::buildParameters( const std::vector< Primitive >& primitives )
|
|
{
|
|
ZoneScoped;
|
|
std::vector< vk::DrawIndexedIndirectCommand > draw_parameters {};
|
|
draw_parameters.reserve( primitives.size() );
|
|
|
|
for ( const auto& primitive : primitives )
|
|
{
|
|
vk::DrawIndexedIndirectCommand cmd;
|
|
cmd.indexCount = primitive.m_index_buffer.size();
|
|
cmd.firstIndex = primitive.m_index_buffer.getOffsetCount();
|
|
|
|
cmd.vertexOffset = static_cast< std::int32_t >( primitive.m_vertex_buffer.getOffsetCount() );
|
|
|
|
cmd.firstInstance = 0;
|
|
cmd.instanceCount = 1;
|
|
|
|
draw_parameters.emplace_back( std::move( cmd ) );
|
|
}
|
|
|
|
return draw_parameters;
|
|
}
|
|
|
|
OrientedBoundingBox< CoordinateSpace::Model > Model::buildBoundingBox( const std::vector< Primitive >& primitives )
|
|
{
|
|
ZoneScoped;
|
|
assert( primitives.size() > 0 );
|
|
if ( primitives.size() <= 0 ) return {};
|
|
|
|
OrientedBoundingBox< CoordinateSpace::Model > box { primitives.at( 0 ).m_bounding_box };
|
|
|
|
for ( std::uint64_t i = 1; i < primitives.size(); i++ ) box = box.combine( primitives[ i ].m_bounding_box );
|
|
|
|
return box;
|
|
}
|
|
|
|
std::vector< vk::DrawIndexedIndirectCommand > Model::getDrawCommand( const std::uint32_t index ) const
|
|
{
|
|
ZoneScoped;
|
|
std::vector< vk::DrawIndexedIndirectCommand > draw_commands {};
|
|
draw_commands.reserve( m_primitives.size() );
|
|
for ( const auto& cmd : m_draw_parameters )
|
|
{
|
|
auto new_cmd { cmd };
|
|
new_cmd.firstInstance = index;
|
|
|
|
draw_commands.push_back( new_cmd );
|
|
}
|
|
|
|
return draw_commands;
|
|
}
|
|
|
|
Model::Model( ModelBuilder& builder, const OrientedBoundingBox< CoordinateSpace::Model > bounding_box ) :
|
|
Model( std::move( builder.m_primitives ), bounding_box )
|
|
{}
|
|
|
|
Model::Model(
|
|
std::vector< Primitive >&& primitives, const OrientedBoundingBox< CoordinateSpace::Model > bounding_box ) :
|
|
m_draw_parameters( buildParameters( primitives ) ),
|
|
m_bounding_box( bounding_box )
|
|
{
|
|
assert( bounding_box.middle.vec() != constants::DEFAULT_VEC3 );
|
|
m_primitives = std::move( primitives );
|
|
}
|
|
|
|
std::shared_ptr< Model > Model::
|
|
createModel( const std::filesystem::path& path, Buffer& vertex_buffer, Buffer& index_buffer )
|
|
{
|
|
ZoneScoped;
|
|
std::cout << "Creating model: " << path << std::endl;
|
|
ModelBuilder builder { vertex_buffer, index_buffer };
|
|
builder.loadModel( path );
|
|
|
|
//Calculate bounding box
|
|
OrientedBoundingBox bounding_box { buildBoundingBox( builder.m_primitives ) };
|
|
|
|
auto model_ptr { std::make_shared< Model >( builder, bounding_box ) };
|
|
|
|
std::cout << "Finished making model: " << path << std::endl;
|
|
return model_ptr;
|
|
}
|
|
|
|
std::vector< std::shared_ptr< Model > > Model::
|
|
createModelsFromScene( const std::filesystem::path& path, Buffer& vertex_buffer, Buffer& index_buffer )
|
|
{
|
|
ZoneScoped;
|
|
std::cout << "Loading scene: " << path << std::endl;
|
|
SceneBuilder builder { vertex_buffer, index_buffer };
|
|
builder.loadScene( path );
|
|
|
|
std::cout << "Finished loading scene: " << path << std::endl;
|
|
|
|
return builder.getModels();
|
|
}
|
|
|
|
std::shared_ptr< Model > Model::createModelFromVerts(
|
|
std::vector< Vertex > verts,
|
|
std::vector< std::uint32_t > indicies,
|
|
Buffer& vertex_buffer,
|
|
Buffer& index_buffer )
|
|
{
|
|
ZoneScoped;
|
|
ModelBuilder builder { vertex_buffer, index_buffer };
|
|
builder.loadVerts( std::move( verts ), std::move( indicies ) );
|
|
|
|
OrientedBoundingBox bounding_box { buildBoundingBox( builder.m_primitives ) };
|
|
|
|
auto model_ptr { std::make_shared< Model >( builder, bounding_box ) };
|
|
|
|
return model_ptr;
|
|
}
|
|
|
|
void Model::stage( vk::raii::CommandBuffer& cmd_buffer )
|
|
{
|
|
assert( !m_primitives.empty() );
|
|
for ( auto& primitive : m_primitives )
|
|
{
|
|
primitive.m_vertex_buffer.stage( cmd_buffer );
|
|
primitive.m_index_buffer.stage( cmd_buffer );
|
|
}
|
|
}
|
|
|
|
} // namespace fgl::engine
|