Overte C++ Documentation
DebugDraw.h
1 //
2 // DebugDraw.h
3 //
4 // Copyright 2015 High Fidelity, Inc.
5 //
6 // Distributed under the Apache License, Version 2.0.
7 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
8 //
9 
10 #ifndef hifi_DebugDraw_h
11 #define hifi_DebugDraw_h
12 
13 #include <mutex>
14 #include <unordered_map>
15 #include <tuple>
16 #include <string>
17 #include <vector>
18 #include <glm/glm.hpp>
19 #include <glm/gtc/quaternion.hpp>
20 
21 #include <QObject>
22 #include <QString>
23 
24 /*@jsdoc
25  * The <code>DebugDraw</code> API renders debug markers and lines. These markers are only visible locally; they are not visible
26  * to other users.
27  *
28  * @namespace DebugDraw
29  *
30  * @hifi-interface
31  * @hifi-client-entity
32  * @hifi-avatar
33  * @hifi-server-entity
34  * @hifi-assignment-client
35  */
36 class DebugDraw : public QObject {
37  Q_OBJECT
38 public:
39  static DebugDraw& getInstance();
40 
41  DebugDraw();
42  ~DebugDraw();
43 
44  /*@jsdoc
45  * Draws a line in world space, visible for a single frame. To make the line visually persist, you need to repeatedly draw
46  * it.
47  * @function DebugDraw.drawRay
48  * @param {Vec3} start - The start position of the line, in world coordinates.
49  * @param {Vec3} end - The end position of the line, in world coordinates.
50  * @param {Vec4} color - The color of the line. Each component should be in the range <code>0.0</code> &ndash;
51  * <code>1.0</code>, with <code>x</code> = red, <code>y</code> = green, <code>z</code> = blue, and <code>w</code> = alpha.
52  * @example <caption>Draw a red ray from your initial avatar position to 10m in front of it.</caption>
53  * var start = MyAvatar.position;
54  * var end = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -10 }));
55  * var color = { x: 1.0, y: 0.0, z: 0.0, w: 1.0 };
56  *
57  * Script.update.connect(function () {
58  * DebugDraw.drawRay(start, end, color);
59  * });
60  */
61  Q_INVOKABLE void drawRay(const glm::vec3& start, const glm::vec3& end, const glm::vec4& color);
62 
63  /*@jsdoc
64  * Draws lines in world space, visible for a single frame. To make the lines visually persist, you need to repeatedly draw
65  * them.
66  * <p><strong>Note:</strong> Currently doesn't work.
67  * @function DebugDraw.drawRays
68  * @param {Vec3Pair[]} lines - The start and end points of the lines to draw.
69  * @param {Vec4} color - The color of the lines. Each component should be in the range <code>0.0</code> &ndash;
70  * <code>1.0</code>, with <code>x</code> = red, <code>y</code> = green, <code>z</code> = blue, and <code>w</code> = alpha.
71  * @param {Vec3} [translation=0,0,0] - A translation applied to each line.
72  * @param {Quat} [rotation=Quat.IDENTITY] - A rotation applied to each line.
73  * @example <caption>Draw a red "V" in front of your initial avatar position.</caption>
74  * var lines = [
75  * [{ x: -1, y: 0.5, z: 0 }, { x: 0, y: 0, z: 0 }],
76  * [{ x: 0, y: 0, z: 0 }, { x: 1, y: 0.5, z: 0 }]
77  * ];
78  * var color = { x: 1, y: 0, z: 0, w: 1 };
79  * var translation = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0.75, z: -5 }));
80  * var rotation = MyAvatar.orientation;
81  *
82  * Script.update.connect(function () {
83  * DebugDraw.drawRays(lines, color, translation, rotation);
84  * });
85  */
86  Q_INVOKABLE void drawRays(const std::vector<std::pair<glm::vec3, glm::vec3>>& lines, const glm::vec4& color,
87  const glm::vec3& translation = glm::vec3(0.0f, 0.0f, 0.0f), const glm::quat& rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f));
88 
89  /*@jsdoc
90  * Adds or updates a debug marker in world coordinates. This marker is drawn every frame until it is removed using
91  * {@link DebugDraw.removeMarker|removeMarker}. If a world coordinates debug marker of the specified <code>name</code>
92  * already exists, its parameters are updated.
93  * @function DebugDraw.addMarker
94  * @param {string} key - A name that uniquely identifies the marker.
95  * @param {Quat} rotation - The orientation of the marker in world coordinates.
96  * @param {Vec3} position - The position of the market in world coordinates.
97  * @param {Vec4} color - The color of the marker.
98  * @param {float} size - A float between 0.0 and 1.0 (10 cm) to control the size of the marker.
99  * @example <caption>Briefly draw a debug marker in front of your avatar, in world coordinates.</caption>
100  * var MARKER_NAME = "my marker";
101  * DebugDraw.addMarker(
102  * MARKER_NAME,
103  * Quat.ZERO,
104  * Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5})),
105  * { red: 255, green: 0, blue: 0 },
106  * 1.0
107  * );
108  * Script.setTimeout(function () {
109  * DebugDraw.removeMarker(MARKER_NAME);
110  * }, 5000);
111  */
112  Q_INVOKABLE void addMarker(const QString& key, const glm::quat& rotation, const glm::vec3& position,
113  const glm::vec4& color, float size = 1.0f);
114 
115  /*@jsdoc
116  * Removes a debug marker that was added in world coordinates.
117  * @function DebugDraw.removeMarker
118  * @param {string} key - The name of the world coordinates debug marker to remove.
119  */
120  Q_INVOKABLE void removeMarker(const QString& key);
121 
122  /*@jsdoc
123  * Adds or updates a debug marker to the world in avatar coordinates. This marker is drawn every frame until it is removed
124  * using {@link DebugDraw.removeMyAvatarMarker|removeMyAvatarMarker}. If an avatar coordinates debug marker of the
125  * specified <code>name</code> already exists, its parameters are updated. The debug marker moves with your avatar.
126  * @function DebugDraw.addMyAvatarMarker
127  * @param {string} key - A name that uniquely identifies the marker.
128  * @param {Quat} rotation - The orientation of the marker in avatar coordinates.
129  * @param {Vec3} position - The position of the market in avatar coordinates.
130  * @param {Vec4} color - color of the marker.
131  * @param {float} size - A float between 0.0 and 1.0 (10 cm) to control the size of the marker.
132  * @example <caption>Briefly draw a debug marker in front of your avatar, in avatar coordinates.</caption>
133  * var MARKER_NAME = "My avatar marker";
134  * DebugDraw.addMyAvatarMarker(
135  * MARKER_NAME,
136  * Quat.ZERO,
137  * { x: 0, y: 0, z: -5 },
138  * { red: 255, green: 0, blue: 0 },
139  * 1.0
140  * );
141  * Script.setTimeout(function () {
142  * DebugDraw.removeMyAvatarMarker(MARKER_NAME);
143  * }, 5000);
144  */
145  Q_INVOKABLE void addMyAvatarMarker(const QString& key, const glm::quat& rotation, const glm::vec3& position,
146  const glm::vec4& color, float size = 1.0f);
147 
148  /*@jsdoc
149  * Removes a debug marker that was added in avatar coordinates.
150  * @function DebugDraw.removeMyAvatarMarker
151  * @param {string} key - The name of the avatar coordinates debug marker to remove.
152  */
153  Q_INVOKABLE void removeMyAvatarMarker(const QString& key);
154 
155  using MarkerInfo = std::tuple<glm::quat, glm::vec3, glm::vec4, float>;
156  using MarkerMap = std::map<QString, MarkerInfo>;
157  using Ray = std::tuple<glm::vec3, glm::vec3, glm::vec4>;
158  using Rays = std::vector<Ray>;
159 
160  //
161  // accessors used by renderer
162  //
163 
164  MarkerMap getMarkerMap() const;
165  MarkerMap getMyAvatarMarkerMap() const;
166  void updateMyAvatarPos(const glm::vec3& pos) { _myAvatarPos = pos; }
167  const glm::vec3& getMyAvatarPos() const { return _myAvatarPos; }
168  void updateMyAvatarRot(const glm::quat& rot) { _myAvatarRot = rot; }
169  const glm::quat& getMyAvatarRot() const { return _myAvatarRot; }
170  Rays getRays() const;
171  void clearRays();
172 
173 protected:
174  mutable std::mutex _mapMutex;
175  MarkerMap _markers;
176  MarkerMap _myAvatarMarkers;
177  glm::quat _myAvatarRot;
178  glm::vec3 _myAvatarPos;
179  Rays _rays;
180 };
181 
182 #endif // hifi_DebugDraw_h