Overte C++ Documentation
HighlightStyle.h
1 //
2 // HighlightStyle.h
3 
4 // Created by Olivier Prat on 11/06/2017.
5 // Copyright 2017 High Fidelity, Inc.
6 // Copyright 2024 Overte e.V.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_render_utils_HighlightStyle_h
13 #define hifi_render_utils_HighlightStyle_h
14 
15 #include <glm/vec3.hpp>
16 #include <glm/gtx/string_cast.hpp>
17 
18 #include <string>
19 
20 namespace render {
21 
22  // This holds the configuration for a particular outline style
23  class HighlightStyle {
24  public:
25  struct RGBA {
26  glm::vec3 color { 1.0f, 0.7f, 0.2f };
27  float alpha { 0.9f };
28 
29  RGBA(const glm::vec3& c, float a) : color(c), alpha(a) {}
30 
31  std::string toString() const { return glm::to_string(color) + " " + std::to_string(alpha); }
32  };
33 
34  RGBA _outlineUnoccluded { { 1.0f, 0.7f, 0.2f }, 0.9f };
35  RGBA _outlineOccluded { { 1.0f, 0.7f, 0.2f }, 0.9f };
36  RGBA _fillUnoccluded { { 0.2f, 0.7f, 1.0f }, 0.0f };
37  RGBA _fillOccluded { { 0.2f, 0.7f, 1.0f }, 0.0f };
38 
39  float _outlineWidth { 2.0f };
40  bool _isOutlineSmooth { false };
41 
42  bool isFilled() const {
43  return _fillUnoccluded.alpha > 5e-3f || _fillOccluded.alpha > 5e-3f;
44  }
45 
46  std::string toString() const {
47  return _outlineUnoccluded.toString() + _outlineOccluded.toString() + _fillUnoccluded.toString() +
48  _fillOccluded.toString() + std::to_string(_outlineWidth) + std::to_string(_isOutlineSmooth);
49  }
50 
51  static HighlightStyle calculateOutlineStyle(uint8_t mode, float outlineWidth, const glm::vec3& outline,
52  const glm::vec3& position, const ViewFrustum& viewFrustum, size_t screenHeight) {
53  HighlightStyle style;
54  style._outlineUnoccluded.color = outline;
55  style._outlineUnoccluded.alpha = 1.0f;
56  style._outlineOccluded.alpha = 0.0f;
57  style._fillUnoccluded.alpha = 0.0f;
58  style._fillOccluded.alpha = 0.0f;
59  style._isOutlineSmooth = false;
60 
61  if (mode == 1) { // OUTLINE_WORLD
62  // FIXME: this is a hacky approximation, which gives us somewhat accurate widths with distance based falloff.
63  // Our outline implementation doesn't support the necessary vertex based extrusion to do real world based outlines.
64  glm::vec4 viewPos = glm::inverse(viewFrustum.getView()) * glm::vec4(position, 1.0f);
65 
66  const glm::mat4& projection = viewFrustum.getProjection();
67  glm::vec4 p1 = projection * (viewPos + glm::vec4(0.0f, 0.5f * outlineWidth, 0.0f, 0.0f));
68  p1 /= p1.w;
69  glm::vec4 p2 = projection * (viewPos - glm::vec4(0.0f, 0.5f * outlineWidth, 0.0f, 0.0f));
70  p2 /= p2.w;
71 
72  style._outlineWidth = floor(0.5f * (float)screenHeight * fabs(p1.y - p2.y));
73  } else { // OUTLINE_SCREEN
74  style._outlineWidth = floor(outlineWidth * (float)screenHeight);
75  }
76 
77  return style;
78  }
79  };
80 
81 }
82 
83 #endif // hifi_render_utils_HighlightStyle_h