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 #include <ViewFrustum.h>
21 
22 namespace render {
23 
24  // This holds the configuration for a particular outline style
25  class HighlightStyle {
26  public:
27  struct RGBA {
28  glm::vec3 color { 1.0f, 0.7f, 0.2f };
29  float alpha { 0.9f };
30 
31  RGBA(const glm::vec3& c, float a) : color(c), alpha(a) {}
32 
33  std::string toString() const { return glm::to_string(color) + " " + std::to_string(alpha); }
34  };
35 
36  RGBA _outlineUnoccluded { { 1.0f, 0.7f, 0.2f }, 0.9f };
37  RGBA _outlineOccluded { { 1.0f, 0.7f, 0.2f }, 0.9f };
38  RGBA _fillUnoccluded { { 0.2f, 0.7f, 1.0f }, 0.0f };
39  RGBA _fillOccluded { { 0.2f, 0.7f, 1.0f }, 0.0f };
40 
41  float _outlineWidth { 2.0f };
42  bool _isOutlineSmooth { false };
43 
44  bool isFilled() const {
45  return _fillUnoccluded.alpha > 5e-3f || _fillOccluded.alpha > 5e-3f;
46  }
47 
48  std::string toString() const {
49  return _outlineUnoccluded.toString() + _outlineOccluded.toString() + _fillUnoccluded.toString() +
50  _fillOccluded.toString() + std::to_string(_outlineWidth) + std::to_string(_isOutlineSmooth);
51  }
52 
53  static HighlightStyle calculateOutlineStyle(uint8_t mode, float outlineWidth, const glm::vec3& outline,
54  const glm::vec3& position, const ViewFrustum& viewFrustum, size_t screenHeight) {
55  HighlightStyle style;
56  style._outlineUnoccluded.color = outline;
57  style._outlineUnoccluded.alpha = 1.0f;
58  style._outlineOccluded.alpha = 0.0f;
59  style._fillUnoccluded.alpha = 0.0f;
60  style._fillOccluded.alpha = 0.0f;
61  style._isOutlineSmooth = false;
62 
63  if (mode == 1) { // OUTLINE_WORLD
64  // FIXME: this is a hacky approximation, which gives us somewhat accurate widths with distance based falloff.
65  // Our outline implementation doesn't support the necessary vertex based extrusion to do real world based outlines.
66  glm::vec4 viewPos = glm::inverse(viewFrustum.getView()) * glm::vec4(position, 1.0f);
67 
68  const glm::mat4& projection = viewFrustum.getProjection();
69  glm::vec4 p1 = projection * (viewPos + glm::vec4(0.0f, 0.5f * outlineWidth, 0.0f, 0.0f));
70  p1 /= p1.w;
71  glm::vec4 p2 = projection * (viewPos - glm::vec4(0.0f, 0.5f * outlineWidth, 0.0f, 0.0f));
72  p2 /= p2.w;
73 
74  style._outlineWidth = floor(0.5f * (float)screenHeight * fabs(p1.y - p2.y));
75  } else { // OUTLINE_SCREEN
76  style._outlineWidth = floor(outlineWidth * (float)screenHeight);
77  }
78 
79  return style;
80  }
81  };
82 
83 }
84 
85 #endif // hifi_render_utils_HighlightStyle_h