1#ifndef TATOOINE_RENDERING_INTERACTIVE_POINTSET_H
2#define TATOOINE_RENDERING_INTERACTIVE_POINTSET_H
15template <
floating_po
int Real>
17 static constexpr std::array<std::string_view, 5> vector_component_names = {
18 "magnitude",
"x",
"y",
"z",
"w"};
26 static constexpr std::string_view vertex_shader =
28 "layout (location = 0) in vec2 position;\n"
29 "layout (location = 1) in float prop;\n"
30 "out float prop_frag;\n"
31 "uniform mat4 projection_matrix;\n"
32 "uniform mat4 view_matrix;\n"
34 " prop_frag = prop;\n"
35 " gl_Position = projection_matrix * view_matrix *\n"
36 " vec4(position, 0, 1);\n"
39 static constexpr std::string_view fragment_shader =
41 "uniform vec4 color;\n"
42 "in float prop_frag;\n"
43 "out vec4 out_color;\n"
44 "uniform int show_property;\n"
45 "uniform int invert_scale;\n"
46 "uniform float min;\n"
47 "uniform float max;\n"
48 "uniform sampler1D color_scale;\n"
50 " if (show_property == 0) {\n"
51 " out_color = color;\n"
53 " float scalar = prop_frag;\n"
54 " if (isnan(scalar)) { discard; }\n"
55 " scalar = clamp((scalar - min) / (max - min), 0, 1);\n"
56 " if (invert_scale == 1) {\n"
57 " scalar = 1 - scalar;\n"
59 " vec3 col = texture(color_scale, scalar).rgb;\n"
60 " out_color = vec4(col, 1);\n"
64 static auto get() ->
auto& {
83 auto set_color(GLfloat
const r, GLfloat
const g, GLfloat
const b,
84 GLfloat
const a = 1) ->
void {
119 struct property_settings {
121 GLfloat min_scalar = std::numeric_limits<GLfloat>::max();
122 GLfloat max_scalar = -std::numeric_limits<GLfloat>::max();
123 bool scale_inverted =
false;
126 GLfloat point_size = 1;
132 std::string
const* selected_property_name =
nullptr;
133 std::unordered_map<std::string, property_settings>
settings;
136 bool show_property =
false;
150 m[v.index()] = v.index();
156 template <
typename T>
162 if (prop->type() ==
typeid(
float)) {
163 f(*cast_prop<float>(prop));
164 }
else if (prop->type() ==
typeid(
double)) {
165 f(*cast_prop<double>(prop));
166 }
else if (prop->type() ==
typeid(
vec2d)) {
167 f(*cast_prop<vec2d>(prop));
168 }
else if (prop->type() ==
typeid(
vec2f)) {
169 f(*cast_prop<vec2f>(prop));
170 }
else if (prop->type() ==
typeid(
vec3d)) {
171 f(*cast_prop<vec3d>(prop));
172 }
else if (prop->type() ==
typeid(
vec3f)) {
173 f(*cast_prop<vec3f>(prop));
174 }
else if (prop->type() ==
typeid(
vec4d)) {
175 f(*cast_prop<vec4d>(prop));
176 }
else if (prop->type() ==
typeid(
vec4f)) {
177 f(*cast_prop<vec4f>(prop));
182 return prop->template holds_type<float>() ||
183 prop->template holds_type<double>();
187 return prop->template holds_type<vec2f>() ||
188 prop->template holds_type<vec2d>() ||
189 prop->template holds_type<vec3f>() ||
190 prop->template holds_type<vec3d>() ||
191 prop->template holds_type<vec4f>() ||
192 prop->template holds_type<vec4d>();
197 auto const& [name, prop] = key_value;
198 if (prop_holds_scalar(prop)) {
199 auto min_scalar = std::numeric_limits<GLfloat>::max();
200 auto max_scalar = -std::numeric_limits<GLfloat>::max();
201 retrieve_typed_prop(prop.get(), [&](
auto const& prop) {
202 using prop_type = std::decay_t<decltype(prop)>;
203 using value_type = typename prop_type::value_type;
204 if constexpr (is_arithmetic<value_type>) {
205 for (auto const v: ps.vertices()) {
206 auto const p = prop[v];
207 min_scalar = std::min<GLfloat>(min_scalar, p);
208 max_scalar = std::max<GLfloat>(max_scalar, p);
213 }
else if (prop_holds_vector(prop)) {
214 retrieve_typed_prop(prop.get(), [&](
auto const& prop) {
215 using prop_type = std::decay_t<decltype(prop)>;
216 using value_type = typename prop_type::value_type;
217 if constexpr (static_vec<value_type>) {
218 auto constexpr num_comps = value_type::num_components();
219 auto min_scalars = std::vector<GLfloat>(
220 num_comps + 1, std::numeric_limits<GLfloat>::max());
221 auto max_scalars = std::vector<GLfloat>(
222 num_comps + 1, -std::numeric_limits<GLfloat>::max());
223 for (auto const v: ps.vertices()) {
224 auto const p = prop[v];
225 auto mag = typename value_type::value_type{};
226 for (std::size_t j = 0; j < num_comps; ++j) {
229 std::min<GLfloat>(min_scalars[j + 1], p(j));
231 std::max<GLfloat>(max_scalars[j + 1], p(j));
233 mag = std::sqrt(mag);
234 min_scalars[0] = std::min<GLfloat>(min_scalars[0], mag);
235 max_scalars[0] = std::max<GLfloat>(max_scalars[0], mag);
237 auto const& [name, prop] = key_value;
238 for (std::size_t j = 0; j < num_comps + 1; ++j) {
239 settings[name +
'_' + std::string{vector_component_names[j]}] = {
240 &color_scale::viridis(), min_scalars[j], max_scalars[j]};
242 selected_component[name] = vector_component_names[0];
250 auto name = std::string{};
251 if (selected_property_name !=
nullptr) {
252 name = *selected_property_name;
253 if (
auto c = selected_component.find(name);
254 c !=
end(selected_component)) {
264 auto map = geometry.vertexbuffer().wmap();
265 for (
auto const v : ps.
vertices()) {
271 retrieve_typed_prop(prop, [&](
auto&& prop) {
272 using prop_type = std::decay_t<
decltype(prop)>;
273 using value_type =
typename prop_type::value_type;
274 if constexpr (is_arithmetic<value_type>) {
276 prop, [](
auto const& prop,
auto const v) {
return prop[v]; },
grid);
282 retrieve_typed_prop(prop, [&](
auto&& prop) {
283 using prop_type = std::decay_t<
decltype(prop)>;
284 using value_type =
typename prop_type::value_type;
288 [](
auto const& prop,
auto const v) {
289 auto mag =
typename value_type::value_type{};
291 mag += prop[v](j) * prop[v](j);
301 retrieve_typed_prop(prop, [&](
auto&& prop) {
302 using prop_type = std::decay_t<
decltype(prop)>;
303 using value_type =
typename prop_type::value_type;
306 prop, [](
auto const& prop,
auto const v) {
return prop[v].x(); },
313 retrieve_typed_prop(prop, [&](
auto&& prop) {
314 using prop_type = std::decay_t<
decltype(prop)>;
315 using value_type =
typename prop_type::value_type;
318 prop, [](
auto const& prop,
auto const v) {
return prop[v].y(); },
325 retrieve_typed_prop(prop, [&](
auto&& prop) {
326 using prop_type = std::decay_t<
decltype(prop)>;
327 using value_type =
typename prop_type::value_type;
331 prop, [](
auto const& prop,
auto const v) {
return prop[v].z(); },
339 retrieve_typed_prop(prop, [&](
auto&& prop) {
340 using prop_type = std::decay_t<
decltype(prop)>;
341 using value_type =
typename prop_type::value_type;
345 prop, [](
auto const& prop,
auto const v) {
return prop[v].w(); },
353 if (ImGui::BeginCombo(
"##combo", selected_property_name !=
nullptr
354 ? selected_property_name->c_str()
357 if (prop->type() ==
typeid(
float) || prop->type() ==
typeid(
double) ||
358 prop->type() ==
typeid(
vec2f) || prop->type() ==
typeid(
vec2d) ||
359 prop->type() ==
typeid(
vec3f) || prop->type() ==
typeid(
vec3d) ||
360 prop->type() ==
typeid(
vec4f) || prop->type() ==
typeid(
vec4d)) {
361 auto is_selected = selected_property == prop.get();
362 if (ImGui::Selectable(name.c_str(), is_selected)) {
363 selected_property = prop.get();
364 selected_property_name = &name;
365 if (prop_holds_scalar(prop)) {
366 upload_scalar(selected_property, ps);
368 }
else if (prop_holds_vector(prop)) {
369 upload_magnitude(selected_property, ps);
374 ImGui::SetItemDefaultFocus();
383 ImGui::Text(
"Pointset");
384 ImGui::DragFloat(
"Point Size", &point_size, 1.0f, 1.0f, 2.0f,
"%.01f");
385 ImGui::ColorEdit4(
"Color", color.data());
386 ImGui::Checkbox(
"Show Property", &show_property);
387 pointset_property_selection(ps);
388 if (selected_property !=
nullptr) {
389 auto& setting = settings[selected_settings_name()];
390 ImGui::DragFloat(
"Min", &setting.min_scalar, 0.01f, -FLT_MAX,
391 setting.max_scalar,
"%.06f");
392 ImGui::DragFloat(
"Max", &setting.max_scalar, 0.01f, setting.min_scalar,
399 shader::get().set_color(color(0), color(1), color(2), color(3));
400 gl::point_size(point_size);
401 auto show = selected_property !=
nullptr && show_property;
404 auto& setting = settings[selected_settings_name()];
405 setting.c->tex.bind(0);
408 shader::get().invert_scale(setting.scale_inverted);
410 geometry.draw_points();
417static_assert(interactively_renderable<renderer<pointset2>>);
Definition: indexeddata.h:13
auto indexbuffer() -> auto &
Definition: indexeddata.h:145
auto vertexbuffer() -> auto &
Definition: indexeddata.h:148
DLL_API void set_uniform(const std::string &, GLfloat)
DLL_API void set_uniform_mat4(const std::string &, GLfloat const *)
Definition: grid_edge.h:16
Definition: tensor_concepts.h:23
button
Definition: mouse.h:8
Definition: interactive.h:15
auto show(std::index_sequence< Is... >, Renderables &&... renderables)
Definition: interactive.h:60
Definition: algorithm.h:6
typename get_impl< Container, I >::type get
Definition: get.h:11
typename value_type_impl< T >::type value_type
Definition: type_traits.h:280
auto end(Range &&range)
Definition: iterator_facade.h:322
auto constexpr map(F &&f, Ts &&... ts)
maps unary function f to all single parameters of parameter pack ts
Definition: map.h:10
constexpr auto max(A &&a, B &&b)
Definition: math.h:20
constexpr auto min(A &&a, B &&b)
Definition: math.h:15
static constexpr GLsizei num_components
Definition: texcomponents.h:10
Definition: shadersource.h:8
Definition: pointset.h:69
auto vertices() const
Definition: pointset.h:226
auto vertex_properties() const -> auto const &
Definition: pointset.h:191
Definition: color_scale.h:25
static auto viridis() -> auto &
Definition: color_scale.h:82
auto invert_scale(bool const invert) -> void
Definition: pointset.h:96
auto show_property(bool const show) -> void
Definition: pointset.h:100
shader()
Definition: pointset.h:71
auto set_projection_matrix(Mat4< GLfloat > const &P) -> void
Definition: pointset.h:88
static auto get() -> auto &
Definition: pointset.h:64
auto set_max(GLfloat const max) -> void
Definition: pointset.h:108
auto set_min(GLfloat const min) -> void
Definition: pointset.h:104
auto set_color(GLfloat const r, GLfloat const g, GLfloat const b, GLfloat const a=1) -> void
Definition: pointset.h:83
auto set_view_matrix(Mat4< GLfloat > const &V) -> void
Definition: pointset.h:92
auto upload_data(auto &&prop, auto &&get_data, renderable_type const &ps)
Definition: pointset.h:262
auto upload_z(auto &&prop, renderable_type const &grid)
Definition: pointset.h:324
auto render()
Definition: pointset.h:397
auto prop_holds_vector(auto const &prop)
Definition: pointset.h:186
gl::indexeddata< Vec2< GLfloat >, GLfloat > geometry
Definition: pointset.h:128
auto on_button_pressed(gl::button)
Definition: pointset.h:414
typename renderable_type::template typed_vertex_property_type< T > typed_vertex_property_type
Definition: pointset.h:22
auto on_cursor_moved(double const x, double const y)
Definition: pointset.h:413
auto upload_w(auto &&prop, renderable_type const &grid)
Definition: pointset.h:338
auto properties(renderable_type const &ps)
Definition: pointset.h:382
auto init_properties(renderable_type const &ps)
Definition: pointset.h:195
std::unordered_map< std::string, std::string_view > selected_component
Definition: pointset.h:134
auto retrieve_typed_prop(auto &&prop, auto &&f)
Definition: pointset.h:161
auto selected_settings_name() const
Definition: pointset.h:249
auto upload_scalar(auto &&prop, renderable_type const &grid)
Definition: pointset.h:270
auto pointset_property_selection(renderable_type const &ps)
Definition: pointset.h:352
auto upload_magnitude(auto &&prop, renderable_type const &grid)
Definition: pointset.h:281
std::unordered_map< std::string, property_settings > settings
Definition: pointset.h:133
auto upload_x(auto &&prop, renderable_type const &grid)
Definition: pointset.h:300
static auto set_view_matrix(Mat4< GLfloat > const &V)
Definition: pointset.h:115
vec2d cursor_pos
Definition: pointset.h:129
auto upload_y(auto &&prop, renderable_type const &grid)
Definition: pointset.h:312
auto on_button_released(gl::button)
Definition: pointset.h:415
static auto set_projection_matrix(Mat4< GLfloat > const &P)
Definition: pointset.h:112
renderer(renderable_type const &ps)
Definition: pointset.h:138
auto prop_holds_scalar(auto const &prop)
Definition: pointset.h:181
static auto cast_prop(auto &&prop)
Definition: pointset.h:157
Definition: pointset.h:10
Definition: property.h:16