Antkeeper  0.0.1
skeletal-mesh.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2023 Christopher J. Howard
3  *
4  * This file is part of Antkeeper source code.
5  *
6  * Antkeeper source code is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Antkeeper source code is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
21 #include <engine/scene/camera.hpp>
22 
23 namespace scene {
24 
25 skeletal_mesh::skeletal_mesh(std::shared_ptr<render::model> model)
26 {
27  set_model(model);
28 }
29 
30 void skeletal_mesh::set_model(std::shared_ptr<render::model> model)
31 {
32  m_model = model;
33 
34  if (m_model)
35  {
36  m_pose = animation_pose(model->get_skeleton());
37 
38  m_operations.resize(m_model->get_groups().size());
39  for (std::size_t i = 0; i < m_operations.size(); ++i)
40  {
41  const auto& group = m_model->get_groups()[i];
42  auto& operation = m_operations[i];
43 
44  operation.primitive_topology = group.primitive_topology;
45  operation.vertex_array = m_model->get_vertex_array().get();
46  operation.vertex_buffer = m_model->get_vertex_buffer().get();
47  operation.vertex_offset = m_model->get_vertex_offset();
48  operation.vertex_stride = m_model->get_vertex_stride();
49  operation.first_vertex = group.first_vertex;
50  operation.vertex_count = group.vertex_count;
51  operation.first_instance = 0;
52  operation.instance_count = 1;
53  operation.material = group.material;
54  operation.matrix_palette = m_pose.get_matrix_palette();
55  }
56 
57  }
58  else
59  {
60  m_operations.clear();
61  }
62 
63  transformed();
64 }
65 
66 void skeletal_mesh::set_material(std::size_t index, std::shared_ptr<render::material> material)
67 {
68  if (material)
69  {
70  m_operations[index].material = material;
71  }
72  else
73  {
74  m_operations[index].material = m_model->get_groups()[index].material;
75  }
76 }
77 
79 {
80  for (std::size_t i = 0; i < m_operations.size(); ++i)
81  {
82  m_operations[i].material = m_model->get_groups()[i].material;
83  }
84 }
85 
86 void skeletal_mesh::update_bounds()
87 {
88  if (m_model)
89  {
90  // Get model bounds
91  const auto& model_bounds = m_model->get_bounds();
92 
93  // Naive algorithm: transform each corner of the model AABB
95  for (std::size_t i = 0; i < 8; ++i)
96  {
97  m_bounds.extend(get_transform() * model_bounds.corner(i));
98  }
99  }
100  else
101  {
102  m_bounds = {get_translation(), get_translation()};
103  }
104 }
105 
106 void skeletal_mesh::transformed()
107 {
108  update_bounds();
109 
110  const math::fmat4 transform_matrix = get_transform().matrix();
111  for (auto& operation: m_operations)
112  {
113  operation.transform = transform_matrix;
114  }
115 }
116 
118 {
119  const float depth = ctx.camera->get_view_frustum().near().distance(get_translation());
120  for (auto& operation: m_operations)
121  {
122  operation.depth = depth;
123  operation.layer_mask = get_layer_mask();
124  ctx.operations.push_back(&operation);
125  }
126 }
127 
128 } // namespace scene
Animatable skeleton pose.
const std::vector< bone_matrix_type > & get_matrix_palette() const noexcept
Returns the skinning matrix palette of the animation pose.
constexpr const view_frustum_type & get_view_frustum() const noexcept
Returns the camera's view frustum.
Definition: camera.hpp:271
constexpr std::uint32_t get_layer_mask() const noexcept
Returns the layer mask of the object.
Definition: object.hpp:121
constexpr const vector_type & get_translation() const noexcept
Returns the translation of the object.
Definition: object.hpp:133
constexpr const transform_type & get_transform() const noexcept
Returns the transform of the object.
Definition: object.hpp:127
void set_material(std::size_t index, std::shared_ptr< render::material > material)
Overwrites the material of a model group for this model instance.
skeletal_mesh()=default
Constructs a model instance.
void reset_materials()
Resets all overwritten materials.
void set_model(std::shared_ptr< render::model > model)
Sets the model with which this model instance is associated.
void render(render::context &ctx) const override
Adds render operations to a render context.
3D scene.
Definition: context.hpp:28
constexpr T distance(const vector_type &point) const noexcept
Calculates the signed distance from the hyperplane to a point.
Definition: hyperplane.hpp:78
void extend(const vector_type &point) noexcept
Extends the hyperrectangle to include a point.
constexpr const plane_type & near() const noexcept
Returns the near clipping plane.
n by m column-major matrix.
Definition: math/matrix.hpp:44
constexpr matrix_type matrix() const noexcept
Constructs a matrix representing the transformation.
Definition: transform.hpp:87
static constexpr vector infinity() noexcept
Returns a vector of infinities, where every element is equal to infinity.
Definition: vector.hpp:342
Context of a renderer.
Definition: context.hpp:40
const scene::camera * camera
Pointer to the camera.
Definition: context.hpp:42
std::vector< const operation * > operations
Render operations generated by visible objects.
Definition: context.hpp:60