Commit b08a4301 authored by Patrick Schmidt's avatar Patrick Schmidt

Merge branch 'develop' into born/viewer-style-tweaks

parents 45f94934 2c3cb630
......@@ -226,6 +226,9 @@ void glow::viewer::ViewerRenderer::renderSubview(tg::isize2 const& res, tg::ipos
auto const& renderables = scene.getRenderables();
auto const& boundingInfo = scene.getBoundingInfo();
auto sunPos = boundingInfo.center
+ tg::vec3::unit_y * (0.5f * (boundingInfo.aabb.max.y - boundingInfo.aabb.min.y) + mSunOffsetFactor * boundingInfo.diagonal);
// pass lambdas
auto performOutput = [&]() {
// output
......@@ -241,8 +244,10 @@ void glow::viewer::ViewerRenderer::renderSubview(tg::isize2 const& res, tg::ipos
// glow-extras-vector overlay
{
RenderInfo info{cam.computeViewMatrix(), cam.computeProjMatrix(), sunPos, res,
cam.getPosition(), subViewData.accumCount, mReverseZEnabled};
for (auto const& r : renderables)
r->renderOverlay(&mVectorRenderer, res, offset);
r->renderOverlay(info, &mVectorRenderer, res, offset);
mVectorImage.clear();
{
......@@ -326,8 +331,6 @@ void glow::viewer::ViewerRenderer::renderSubview(tg::isize2 const& res, tg::ipos
}
// compute sun
auto sunPos = boundingInfo.center
+ tg::vec3::unit_y * (0.5f * (boundingInfo.aabb.max.y - boundingInfo.aabb.min.y) + mSunOffsetFactor * boundingInfo.diagonal);
if (distance(boundingInfo.center, sunPos) <= boundingInfo.diagonal / 10000)
sunPos += tg::vec3::unit_y * tg::max(1.0f, distance_to_origin(sunPos) / 50);
......
......@@ -4,18 +4,146 @@
#include <glow-extras/colors/color.hh>
void glow::viewer::canvas_t::set_color(std::string_view hex)
// TODO: more performant from_hex
void glow::viewer::canvas_data::set_color(std::string_view hex)
{
auto c = glow::colors::color::from_hex(std::string(hex));
set_color(c.r, c.g, c.b, c.a);
}
glow::viewer::canvas_t::~canvas_t()
glow::viewer::material::material(std::string_view color_str) : type(material_type::diffuse)
{
auto v = gv::view();
auto c = glow::colors::color::from_hex(std::string(color_str));
color = {c.r, c.g, c.b, c.a};
}
glow::viewer::material::material(const char* color_str) : type(material_type::diffuse)
{
auto c = glow::colors::color::from_hex(color_str);
color = {c.r, c.g, c.b, c.a};
}
glow::viewer::canvas_t::point_ref& glow::viewer::canvas_t::point_ref::color(std::string_view color_str)
{
auto c = glow::colors::color::from_hex(std::string(color_str));
return color(tg::color4(c.r, c.g, c.b, c.a));
}
glow::viewer::canvas_t::splat_ref& glow::viewer::canvas_t::splat_ref::color(std::string_view color_str)
{
auto c = glow::colors::color::from_hex(std::string(color_str));
return color(tg::color4(c.r, c.g, c.b, c.a));
}
glow::viewer::canvas_t::line_ref& glow::viewer::canvas_t::line_ref::color(std::string_view color_str)
{
auto c = glow::colors::color::from_hex(std::string(color_str));
return color(tg::color4(c.r, c.g, c.b, c.a));
}
glow::viewer::canvas_t::triangle_ref& glow::viewer::canvas_t::triangle_ref::color(std::string_view color_str)
{
auto c = glow::colors::color::from_hex(std::string(color_str));
return color(tg::color4(c.r, c.g, c.b, c.a));
}
void glow::viewer::canvas_data::add_label(const glow::viewer::label& label) { _labels.push_back(label); }
void glow::viewer::canvas_data::add_labels(glow::array_view<const glow::viewer::label> labels)
{
for (auto l : labels)
_labels.push_back(l);
}
void glow::viewer::canvas_data::add_arrow(tg::pos3 from, tg::pos3 to, float world_size, tg::color3 color, const glow::viewer::arrow_style& style)
{
auto mat = material(color);
auto const length = distance(to, from);
auto const dir = normalize_safe(to - from);
tg::pos3 center;
// compute 3 pos
{
auto const length_arrow = world_size * style.length_factor;
auto const length_shaft = world_size * style.shaft_min_length_factor;
auto const margin_arrow = world_size * style.margin_arrow_factor;
auto const margin_shaft = world_size * style.margin_shaft_factor;
if (length_arrow + length_shaft + margin_arrow + margin_shaft <= length) // enough space
{
to -= dir * margin_arrow;
center = to - dir * length_arrow;
from += dir * margin_shaft;
}
else // not enough space: start from to and go backwards
{
to -= dir * margin_arrow;
center = to - dir * length_arrow;
from = center - dir * length_shaft;
}
}
auto const TA = tg::any_normal(dir);
auto const TB = normalize_safe(cross(TA, dir));
auto const r_shaft = world_size / 2;
auto const r_arrow = world_size * style.radius_factor / 2;
for (auto i = 0; i < style.segments; ++i)
{
auto a0 = 360_deg * i / style.segments;
auto a1 = 360_deg * (i == style.segments - 1 ? 0 : i + 1) / style.segments;
auto [s0, c0] = tg::sin_cos(a0);
auto [s1, c1] = tg::sin_cos(a1);
auto n0 = TA * s0 + TB * c0;
auto n1 = TA * s1 + TB * c1;
auto const from_shaft_0 = from + n0 * r_shaft;
auto const from_shaft_1 = from + n1 * r_shaft;
auto const center_shaft_0 = center + n0 * r_shaft;
auto const center_shaft_1 = center + n1 * r_shaft;
auto const center_arrow_0 = center + n0 * r_arrow;
auto const center_arrow_1 = center + n1 * r_arrow;
// shaft end
_add_triangle(from, from_shaft_0, from_shaft_1, -dir, -dir, -dir, mat);
// shaft mantle
_add_triangle(from_shaft_0, center_shaft_0, center_shaft_1, n0, n0, n1, mat);
_add_triangle(from_shaft_0, center_shaft_1, from_shaft_1, n0, n1, n1, mat);
// arrow end
_add_triangle(center, center_arrow_0, center_arrow_1, -dir, -dir, -dir, mat);
// arrow mantle
// TODO: normal?
_add_triangle(center_arrow_0, to, center_arrow_1, n0, n0, n1, mat);
}
}
void glow::viewer::canvas_data::add_arrow(tg::pos3 from_pos, tg::vec3 extent, float world_size, tg::color3 color, const glow::viewer::arrow_style& style)
{
add_arrow(from_pos, from_pos + extent, world_size, color, style);
}
void glow::viewer::canvas_data::add_arrow(tg::vec3 extent, tg::pos3 to_pos, float world_size, tg::color3 color, const glow::viewer::arrow_style& style)
{
add_arrow(to_pos - extent, to_pos, world_size, color, style);
}
std::vector<glow::viewer::SharedRenderable> glow::viewer::canvas_data::create_renderables() const
{
std::vector<glow::viewer::SharedRenderable> r;
pm::Mesh m;
auto pos = m.vertices().make_attribute<tg::pos3>();
auto normals = m.vertices().make_attribute<tg::vec3>();
auto size = m.vertices().make_attribute<float>();
auto color3 = m.vertices().make_attribute<tg::color3>();
auto color4 = m.vertices().make_attribute<tg::color4>();
......@@ -45,7 +173,8 @@ glow::viewer::canvas_t::~canvas_t()
size[v] = p.size;
}
gv::view(gv::points(pos).point_size_px(size), color3);
if (!m.vertices().empty())
r.push_back(gv::make_and_configure_renderable(gv::points(pos).point_size_px(size), color3));
if (has_transparent)
{
......@@ -61,7 +190,7 @@ glow::viewer::canvas_t::~canvas_t()
size[v] = p.size;
}
gv::view(gv::points(pos).point_size_px(size), color4, gv::transparent);
r.push_back(gv::make_and_configure_renderable(gv::points(pos).point_size_px(size), color4, gv::transparent));
}
}
if (!_points_world.empty())
......@@ -86,7 +215,8 @@ glow::viewer::canvas_t::~canvas_t()
size[v] = p.size;
}
gv::view(gv::points(pos).point_size_world(size), color3);
if (!m.vertices().empty())
r.push_back(gv::make_and_configure_renderable(gv::points(pos).point_size_world(size), color3));
if (has_transparent)
{
......@@ -102,7 +232,57 @@ glow::viewer::canvas_t::~canvas_t()
size[v] = p.size;
}
gv::view(gv::points(pos).point_size_world(size), color4, gv::transparent);
r.push_back(gv::make_and_configure_renderable(gv::points(pos).point_size_world(size), color4, gv::transparent));
}
}
//
// splats
//
if (!_splats.empty())
{
auto has_transparent = false;
m.clear();
m.vertices().reserve(_splats.size());
for (auto const& p : _splats)
{
TG_ASSERT(p.size >= 0 && "no splat size set (forgot to call .set_splat_size() or .add_splats(...).size(...)?)");
if (p.color.a <= 0)
continue;
if (p.color.a < 1)
{
has_transparent = true;
continue;
}
auto v = m.vertices().add();
pos[v] = p.pos;
color3[v] = tg::color3(p.color);
size[v] = p.size;
normals[v] = p.normal;
}
if (!m.vertices().empty())
r.push_back(gv::make_and_configure_renderable(gv::points(pos).round().normals(normals).point_size_world(size), color3));
if (has_transparent)
{
m.clear();
for (auto const& p : _splats)
{
if (p.color.a <= 0 || p.color.a >= 1)
continue;
auto v = m.vertices().add();
pos[v] = p.pos;
color4[v] = p.color;
size[v] = p.size;
normals[v] = p.normal;
}
r.push_back(gv::make_and_configure_renderable(gv::points(pos).round().normals(normals).point_size_world(size), color4, gv::transparent));
}
}
......@@ -136,7 +316,8 @@ glow::viewer::canvas_t::~canvas_t()
m.edges().add_or_get(v0, v1);
}
gv::view(gv::lines(pos).line_width_px(size), color3);
if (!m.vertices().empty())
r.push_back(gv::make_and_configure_renderable(gv::lines(pos).line_width_px(size), color3));
if (has_transparent)
{
......@@ -160,7 +341,7 @@ glow::viewer::canvas_t::~canvas_t()
m.edges().add_or_get(v0, v1);
}
gv::view(gv::lines(pos).line_width_px(size), color4, gv::transparent);
r.push_back(gv::make_and_configure_renderable(gv::lines(pos).line_width_px(size), color4, gv::transparent));
}
}
if (!_lines_world.empty())
......@@ -190,7 +371,8 @@ glow::viewer::canvas_t::~canvas_t()
m.edges().add_or_get(v0, v1);
}
gv::view(gv::lines(pos).line_width_world(size), color3);
if (!m.vertices().empty())
r.push_back(gv::make_and_configure_renderable(gv::lines(pos).line_width_world(size), color3));
if (has_transparent)
{
......@@ -214,9 +396,89 @@ glow::viewer::canvas_t::~canvas_t()
m.edges().add_or_get(v0, v1);
}
gv::view(gv::lines(pos).line_width_world(size), color4, gv::transparent);
r.push_back(gv::make_and_configure_renderable(gv::lines(pos).line_width_world(size), color4, gv::transparent));
}
}
//
// faces
//
if (!_triangles.empty())
{
auto has_transparent = false;
m.clear();
m.vertices().reserve(_triangles.size() * 3);
for (auto const& t : _triangles)
{
if (t.color[0].a <= 0 && t.color[1].a <= 0 && t.color[2].a <= 0)
continue;
if (t.color[0].a < 1 || t.color[1].a < 1 || t.color[2].a < 1)
{
has_transparent = true;
continue;
}
auto v0 = m.vertices().add();
auto v1 = m.vertices().add();
auto v2 = m.vertices().add();
pos[v0] = t.pos[0];
pos[v1] = t.pos[1];
pos[v2] = t.pos[2];
normals[v0] = t.normal[0];
normals[v1] = t.normal[1];
normals[v2] = t.normal[2];
color3[v0] = tg::color3(t.color[0]);
color3[v1] = tg::color3(t.color[1]);
color3[v2] = tg::color3(t.color[2]);
m.faces().add(v0, v1, v2);
}
if (!m.vertices().empty())
r.push_back(gv::make_and_configure_renderable(gv::polygons(pos).normals(normals), color3));
if (has_transparent)
{
m.clear();
for (auto const& t : _triangles)
{
if (t.color[0].a <= 0 && t.color[1].a <= 0 && t.color[2].a <= 0)
continue;
if (t.color[0].a >= 1 && t.color[1].a >= 1 && t.color[2].a >= 1)
continue;
auto v0 = m.vertices().add();
auto v1 = m.vertices().add();
auto v2 = m.vertices().add();
pos[v0] = t.pos[0];
pos[v1] = t.pos[1];
pos[v2] = t.pos[2];
normals[v0] = t.normal[0];
normals[v1] = t.normal[1];
normals[v2] = t.normal[2];
color4[v0] = t.color[0];
color4[v1] = t.color[1];
color4[v2] = t.color[2];
m.faces().add(v0, v1, v2);
}
r.push_back(gv::make_and_configure_renderable(gv::lines(pos).line_width_px(size), color4, gv::transparent));
}
}
// TODO
//
// labels
//
if (!_labels.empty())
r.push_back(gv::make_and_configure_renderable(_labels));
return r;
}
glow::viewer::canvas_t::~canvas_t()
{
auto v = gv::view();
for (auto const& r : create_renderables())
gv::view(r);
}
This diff is collapsed.
......@@ -3,8 +3,11 @@
#include <cstring>
#include <typed-geometry/tg.hh>
#include <glow/objects/TextureCubeMap.hh>
#include "Scene.hh"
#include "detail/command_queue.hh"
#include "materials/envmap.hh"
#include "renderables/GeometricRenderable.hh"
#include "renderables/MeshRenderable.hh"
#include "renderables/PointRenderable.hh"
......@@ -193,4 +196,10 @@ void configure(Renderable&, const grid_center& v)
void configure(GeometricRenderable& r, const clip_plane& p) { r.setClipPlane(tg::vec4(p.normal, dot(p.normal, p.pos))); }
void configure(GeometricRenderable& r, const EnvMap& em)
{
r.setEnvMap(em.texture);
r.setEnvReflectivity(em.reflectivity);
}
}
......@@ -228,6 +228,7 @@ void configure(GeometricRenderable& r, clip_plane const& p);
/// shading
void configure(GeometricRenderable& r, no_shading_t s);
void configure(GeometricRenderable& r, EnvMap const& em);
// ================== Implementation ==================
template <class Color, class>
......
......@@ -257,6 +257,45 @@ std::shared_ptr<PolyMeshDefinition> make_mesh_definition(tg::triangle<D, ScalarT
return make_mesh_definition(std::vector<tg::triangle<D, ScalarT>>{tri});
}
template <int D, class ScalarT>
std::shared_ptr<PolyMeshDefinition> make_mesh_definition(std::vector<tg::quad<D, ScalarT>> const& quads)
{
static_assert(D == 2 || D == 3, "currently only 2D and 3D supported");
auto pm = std::make_shared<PolyMeshDefinition>();
pm->info.type = MeshType::PolygonList;
pm->info.vertexCount = 4 * int(quads.size());
pm->info.edgeCount = 4 * int(quads.size());
pm->info.faceCount = int(quads.size());
for (auto const& q : quads)
{
auto v00 = pm->mesh.vertices().add();
auto v01 = pm->mesh.vertices().add();
auto v10 = pm->mesh.vertices().add();
auto v11 = pm->mesh.vertices().add();
pm->mesh.faces().add(v00, v10, v11, v01);
auto to_pos = [](tg::pos<D, ScalarT> p) -> tg::pos3 {
if constexpr (D == 2)
return tg::pos3(p.x, 0, p.y);
else
return tg::pos3(p.x, p.y, p.z);
};
pm->pos[v00] = to_pos(q.pos00);
pm->pos[v01] = to_pos(q.pos01);
pm->pos[v10] = to_pos(q.pos10);
pm->pos[v11] = to_pos(q.pos11);
}
return pm;
}
template <int D, class ScalarT>
std::shared_ptr<PolyMeshDefinition> make_mesh_definition(tg::quad<D, ScalarT> const& quads)
{
return make_mesh_definition(std::vector<tg::quad<D, ScalarT>>{quads});
}
template <int D, class ScalarT>
std::shared_ptr<PolyMeshDefinition> make_mesh_definition(std::vector<tg::aabb<D, ScalarT>> const& aabbs)
{
static_assert(D == 3, "currently only 3D supported");
......
......@@ -24,11 +24,15 @@ GLOW_SHARED(class, PointRenderable);
GLOW_SHARED(class, LineRenderable);
GLOW_SHARED(class, Vector2DRenderable);
GLOW_SHARED(class, TextureRenderable);
GLOW_SHARED(class, LabelRenderable);
class ColorMapping;
class Texturing;
class Masking;
class ViewerApp;
struct EnvMap;
struct label;
}
namespace colors
......
......@@ -42,4 +42,8 @@ SharedTextureRenderable make_renderable(const SharedTexture2D& tex) { return Tex
SharedTextureRenderable make_renderable(const SharedTextureRectangle& tex) { return TextureRenderable::create(tex); }
SharedLabelRenderable make_renderable(const label& label) { return LabelRenderable::create({label}); }
SharedLabelRenderable make_renderable(glow::array_view<const label> labels) { return LabelRenderable::create(labels); }
} // namespace viewer
......@@ -2,6 +2,7 @@
#include <vector>
#include "renderables/LabelRenderable.hh"
#include "renderables/LineRenderable.hh"
#include "renderables/MeshRenderable.hh"
#include "renderables/PointRenderable.hh"
......@@ -13,9 +14,9 @@
#include "objects/objects.hh"
#include "traits.hh"
#include <glow/fwd.hh>
#include <glow-extras/vector/fwd.hh>
#include <glow-extras/viewer/objects/other/file.hh>
#include <glow/fwd.hh>
#include <typed-geometry/tg-lean.hh>
......@@ -69,6 +70,10 @@ SharedMeshRenderable make_renderable(std::vector<std::vector<Pos3>> const& pos);
template <class Pos3, class = std::enable_if_t<detail::is_pos3_like<Pos3>>>
SharedPointRenderable make_renderable(Pos3 const& pos);
// labels
SharedLabelRenderable make_renderable(label const& label);
SharedLabelRenderable make_renderable(glow::array_view<label const> labels);
// ================== TG Support ==================
// tg:pos already works
......@@ -93,6 +98,16 @@ SharedMeshRenderable make_renderable(std::vector<tg::triangle<D, ScalarT>> const
return make_renderable(viewer::polygons(tris));
}
template <int D, class ScalarT>
SharedMeshRenderable make_renderable(tg::quad<D, ScalarT> const& quads)
{
return make_renderable(viewer::polygons(quads));
}
template <int D, class ScalarT>
SharedMeshRenderable make_renderable(std::vector<tg::quad<D, ScalarT>> const& quads)
{
return make_renderable(viewer::polygons(quads));
}
template <int D, class ScalarT>
SharedMeshRenderable make_renderable(tg::aabb<D, ScalarT> const& aabb)
{
return make_renderable(viewer::polygons(aabb));
......
#pragma once
#include <glow/fwd.hh>
#include <glow/objects/TextureCubeMap.hh>
#include <glow/util/AsyncTexture.hh>
namespace glow::viewer
{
struct EnvMap
{
AsyncTextureCubeMap texture;
float reflectivity = 1;
};
inline EnvMap envmap(AsyncTextureCubeMap texture, float reflectivity = 1) { return {std::move(texture), reflectivity}; }
}
#pragma once
#include "envmap.hh"
#include "mapping.hh"
#include "textured.hh"
#include "masked.hh"
#include "textured.hh"
#pragma once
#include <typed-geometry/tg-lean.hh>
#include <glow-extras/vector/graphics2D.hh>
namespace glow::viewer
{
struct label_style
{
tg::color3 foreground = tg::color3::black;
tg::color3 background = tg::color3::white;
tg::color3 border = tg::color3::black;
int border_width = 2;
float border_width = 2;
int padding_x = 8;
int padding_y = 4;