Antkeeper  0.0.1
billboard.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/config.hpp>
24 #include <engine/scene/camera.hpp>
25 
26 namespace scene {
27 
28 namespace {
29 
30  constexpr gl::vertex_input_attribute billboard_vertex_attributes[2] =
31  {
32  {
34  0,
36  0
37  },
38  {
40  0,
42  2 * sizeof(float)
43  }
44  };
45 
46  constexpr float billboard_vertex_data[] =
47  {
48  -1.0f, 1.0f, 0.0f, 1.0f,
49  -1.0f, -1.0f, 0.0f, 0.0f,
50  1.0f, 1.0f, 1.0f, 1.0f,
51  1.0f, -1.0f, 1.0f, 0.0f
52  };
53 
54  constexpr std::size_t billboard_vertex_stride = 4 * sizeof(float);
55 }
56 
58 {
59  // Construct vertex array
60  m_vertex_array = std::make_unique<gl::vertex_array>(billboard_vertex_attributes);
61 
62  // Construct vertex buffer
63  m_vertex_buffer = std::make_unique<gl::vertex_buffer>
64  (
66  std::as_bytes(std::span{billboard_vertex_data})
67  );
68 
69  // Init render operation
71  m_render_op.vertex_array = m_vertex_array.get();
72  m_render_op.vertex_buffer = m_vertex_buffer.get();
73  m_render_op.vertex_offset = 0;
74  m_render_op.vertex_stride = billboard_vertex_stride;
75  m_render_op.first_vertex = 0;
76  m_render_op.vertex_count = 4;
77  m_render_op.first_instance = 0;
78  m_render_op.instance_count = 1;
79 }
80 
82 {
83  // Align billboard
84  switch (m_billboard_type)
85  {
87  {
88  auto transform = get_transform();
89 
90  transform.rotation = math::normalize(math::look_rotation(ctx.camera->get_forward(), ctx.camera->get_up()) * transform.rotation);
91 
92  m_render_op.transform = transform.matrix();
93 
94  break;
95  }
96 
98  {
99  auto transform = get_transform();
100 
101  auto look = math::normalize(geom::project_on_plane(transform.translation - ctx.camera->get_translation(), {0.0f, 0.0f, 0.0f}, m_alignment_axis));
102  const auto right = math::normalize(math::cross(m_alignment_axis, look));
103  look = math::cross(right, m_alignment_axis);
104  const auto up = math::cross(look, right);
105  transform.rotation = math::normalize(math::look_rotation(look, up) * transform.rotation);
106 
107  m_render_op.transform = transform.matrix();
108 
109  break;
110  }
111 
113  break;
114 
115  default:
116  break;
117  }
118 
119  m_render_op.depth = ctx.camera->get_view_frustum().near().distance(get_translation());
120  m_render_op.layer_mask = get_layer_mask();
121 
122  ctx.operations.emplace_back(&m_render_op);
123 }
124 
125 void billboard::set_material(std::shared_ptr<render::material> material)
126 {
127  m_render_op.material = material;
128 }
129 
131 {
132  m_billboard_type = type;
133 
134  if (m_billboard_type == scene::billboard_type::flat)
135  {
136  m_render_op.transform = get_transform().matrix();
137  }
138 }
139 
140 void billboard::transformed()
141 {
142  m_bounds = {get_translation() - get_scale(), get_translation() + get_scale()};
143 
144  if (m_billboard_type == scene::billboard_type::flat)
145  {
146  m_render_op.transform = get_transform().matrix();
147  }
148 }
149 
150 } // namespace scene
void render(render::context &ctx) const override
Adds render operations to a render context.
Definition: billboard.cpp:81
void set_billboard_type(billboard_type type)
Sets the billboard type.
Definition: billboard.cpp:130
billboard()
Constructs a billboard.
Definition: billboard.cpp:57
void set_material(std::shared_ptr< render::material > material)
Sets the billboard material.
Definition: billboard.cpp:125
constexpr const math::fvec3 & get_up() const noexcept
Returns the camera's up vector.
Definition: camera.hpp:265
constexpr const math::fvec3 & get_forward() const noexcept
Returns the camera's forward vector.
Definition: camera.hpp:259
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 vector_type & get_scale() const noexcept
Returns the scale of the object.
Definition: object.hpp:145
constexpr const transform_type & get_transform() const noexcept
Returns the transform of the object.
Definition: object.hpp:127
math::vec3< T > project_on_plane(const math::vec3< T > &v, const math::vec3< T > &p, const math::vec3< T > &n)
@ static_draw
Data will be modified once, by the application, and used many times, for drawing commands.
@ triangle_strip
Connected triangle primitives with consecutive triangles sharing an edge.
quaternion< T > normalize(const quaternion< T > &q)
Normalizes a quaternion.
Definition: quaternion.hpp:679
quaternion< T > look_rotation(const vec3< T > &forward, vec3< T > up)
Creates a unit quaternion rotation using forward and up vectors.
Definition: quaternion.hpp:618
constexpr vector< T, 3 > cross(const vector< T, 3 > &x, const vector< T, 3 > &y) noexcept
Calculates the cross product of two vectors.
Definition: vector.hpp:1095
@ uv
Vertex UV texture coordinates (vec2)
3D scene.
Definition: context.hpp:28
billboard_type
Billboard types.
@ flat
Billboard is unaligned.
@ spherical
Billboard aligns to face camera.
@ cylindrical
Billboard rotates about an alignment axis to face camera.
Text and typography.
Definition: bitmap-font.cpp:24
constexpr T distance(const vector_type &point) const noexcept
Calculates the signed distance from the hyperplane to a point.
Definition: hyperplane.hpp:78
constexpr const plane_type & near() const noexcept
Returns the near clipping plane.
constexpr matrix_type matrix() const noexcept
Constructs a matrix representing the transformation.
Definition: transform.hpp:87
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
std::uint32_t vertex_count
Definition: operation.hpp:45
std::uint32_t instance_count
Definition: operation.hpp:47
std::size_t vertex_offset
Definition: operation.hpp:42
std::size_t vertex_stride
Definition: operation.hpp:43
std::uint32_t layer_mask
Definition: operation.hpp:56
std::uint32_t first_instance
Definition: operation.hpp:46
math::fmat4 transform
Definition: operation.hpp:51
gl::primitive_topology primitive_topology
Definition: operation.hpp:39
std::uint32_t first_vertex
Definition: operation.hpp:44
const gl::vertex_buffer * vertex_buffer
Definition: operation.hpp:41
std::shared_ptr< render::material > material
Definition: operation.hpp:49
const gl::vertex_array * vertex_array
Definition: operation.hpp:40