Techt3o commited on
Commit
99f38ca
Β·
verified Β·
1 Parent(s): bbe0c7f

9f6ef56b47ab9a4a46bd6dcc26aaed5c1573071e90029486e391948c5a32e647

Browse files
Files changed (50) hide show
  1. third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gltext.h +96 -0
  2. third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gltexturecache.h +116 -0
  3. third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glvbo.h +239 -0
  4. third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/opengl_render_state.h +446 -0
  5. third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/viewport.h +63 -0
  6. third-party/DPVO/Pangolin/components/pango_opengl/src/compat/gl2engine.cpp +39 -0
  7. third-party/DPVO/Pangolin/components/pango_opengl/src/fonts/AnonymousPro.ttf +0 -0
  8. third-party/DPVO/Pangolin/components/pango_opengl/src/fonts/AnonymousPro.txt +94 -0
  9. third-party/DPVO/Pangolin/components/pango_opengl/src/glchar.cpp +70 -0
  10. third-party/DPVO/Pangolin/components/pango_opengl/src/gldraw.cpp +55 -0
  11. third-party/DPVO/Pangolin/components/pango_opengl/src/glfont.cpp +207 -0
  12. third-party/DPVO/Pangolin/components/pango_opengl/src/glpangoglu.cpp +272 -0
  13. third-party/DPVO/Pangolin/components/pango_opengl/src/gltext.cpp +198 -0
  14. third-party/DPVO/Pangolin/components/pango_opengl/src/gltexturecache.cpp +38 -0
  15. third-party/DPVO/Pangolin/components/pango_opengl/src/opengl_render_state.cpp +707 -0
  16. third-party/DPVO/Pangolin/components/pango_opengl/src/stb_truetype.h +0 -0
  17. third-party/DPVO/Pangolin/components/pango_opengl/src/viewport.cpp +102 -0
  18. third-party/DPVO/Pangolin/components/pango_packetstream/CMakeLists.txt +20 -0
  19. third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packet.h +70 -0
  20. third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream.h +111 -0
  21. third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_reader.h +120 -0
  22. third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_source.h +63 -0
  23. third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_tags.h +46 -0
  24. third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_writer.h +173 -0
  25. third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/playback_session.h +55 -0
  26. third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/sync_time.h +237 -0
  27. third-party/DPVO/Pangolin/components/pango_packetstream/src/packet.cpp +79 -0
  28. third-party/DPVO/Pangolin/components/pango_packetstream/src/packetstream.cpp +146 -0
  29. third-party/DPVO/Pangolin/components/pango_packetstream/src/packetstream_reader.cpp +428 -0
  30. third-party/DPVO/Pangolin/components/pango_packetstream/src/packetstream_writer.cpp +156 -0
  31. third-party/DPVO/Pangolin/components/pango_packetstream/src/playback_session.cpp +32 -0
  32. third-party/DPVO/Pangolin/components/pango_plot/CMakeLists.txt +17 -0
  33. third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/datalog.h +243 -0
  34. third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/loaders/csv_table_loader.h +32 -0
  35. third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/loaders/table_loader.h +12 -0
  36. third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/plotter.h +295 -0
  37. third-party/DPVO/Pangolin/components/pango_plot/src/datalog.cpp +289 -0
  38. third-party/DPVO/Pangolin/components/pango_plot/src/loaders/csv_table_loader.cpp +81 -0
  39. third-party/DPVO/Pangolin/components/pango_plot/src/plotter.cpp +1174 -0
  40. third-party/DPVO/Pangolin/components/pango_python/CMakeLists.txt +90 -0
  41. third-party/DPVO/Pangolin/components/pango_python/include/pangolin/python/pyinterpreter.h +72 -0
  42. third-party/DPVO/Pangolin/components/pango_python/pybind11/.appveyor.yml +37 -0
  43. third-party/DPVO/Pangolin/components/pango_python/pybind11/.clang-format +19 -0
  44. third-party/DPVO/Pangolin/components/pango_python/pybind11/.clang-tidy +58 -0
  45. third-party/DPVO/Pangolin/components/pango_python/pybind11/.cmake-format.yaml +73 -0
  46. third-party/DPVO/Pangolin/components/pango_python/pybind11/.pre-commit-config.yaml +119 -0
  47. third-party/DPVO/Pangolin/components/pango_python/pybind11/.readthedocs.yml +3 -0
  48. third-party/DPVO/Pangolin/components/pango_python/pybind11/CMakeLists.txt +290 -0
  49. third-party/DPVO/Pangolin/components/pango_python/pybind11/docs/_static/theme_overrides.css +11 -0
  50. third-party/DPVO/Pangolin/components/pango_python/pybind11/docs/advanced/cast/chrono.rst +81 -0
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gltext.h ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2013 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #pragma once
29
+
30
+ #include <pangolin/gl/gl.h>
31
+ #include <pangolin/gl/glchar.h>
32
+
33
+ #include <vector>
34
+ #include <string>
35
+
36
+ namespace pangolin {
37
+
38
+ class PANGOLIN_EXPORT GlText
39
+ {
40
+ public:
41
+ GlText();
42
+
43
+ GlText(const GlText& txt);
44
+
45
+ GlText(const GlTexture& font_tex);
46
+
47
+ void AddSpace(GLfloat s);
48
+
49
+ // Add specified charector to this string.
50
+ void Add(unsigned char c, const GlChar& glc);
51
+
52
+ // Clear text
53
+ void Clear();
54
+
55
+ // Render without transform in text-centric pixel coordinates
56
+ void Draw() const;
57
+ void DrawGlSl() const;
58
+
59
+ // Render at (x,y,z)' in object coordinates,
60
+ // keeping text size and orientation constant
61
+ void Draw(GLfloat x, GLfloat y, GLfloat z = 0.0f) const;
62
+
63
+ // Render at (x,y,z)' in window coordinates.
64
+ void DrawWindow(GLfloat x, GLfloat y, GLfloat z = 0.0f) const;
65
+
66
+ // Return text that this object signifies.
67
+ const std::string& Text() const {
68
+ return str;
69
+ }
70
+
71
+ // Return width in pixels of this text.
72
+ GLfloat Width() const {
73
+ return width;
74
+ }
75
+
76
+ // Return height in pixels of this text.
77
+ GLfloat Height() const {
78
+ return ymax;
79
+ }
80
+
81
+ // Return height in pixels of this text, including under baseline
82
+ GLfloat FullHeight() const {
83
+ return ymax - ymin;
84
+ }
85
+
86
+ //protected:
87
+ const GlTexture* tex;
88
+ std::string str;
89
+ GLfloat width;
90
+ GLfloat ymin;
91
+ GLfloat ymax;
92
+
93
+ std::vector<XYUV> vs;
94
+ };
95
+
96
+ }
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gltexturecache.h ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2014 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #pragma once
29
+
30
+ #include <pangolin/gl/gl.h>
31
+ #include <pangolin/gl/glformattraits.h>
32
+ #include <pangolin/gl/glpixformat.h>
33
+ #include <pangolin/image/image.h>
34
+
35
+ #include <memory>
36
+ #include <map>
37
+
38
+ namespace pangolin
39
+ {
40
+
41
+ class PANGOLIN_EXPORT TextureCache
42
+ {
43
+ public:
44
+ static TextureCache& I();
45
+
46
+ GlTexture& GlTex(GLsizei w, GLsizei h, GLint internal_format, GLint glformat, GLenum gltype)
47
+ {
48
+ const long key =
49
+ (((long)internal_format)<<20) ^
50
+ (((long)glformat)<<10) ^ gltype;
51
+
52
+ // Lookup texture
53
+ std::shared_ptr<GlTexture>& ptex = texture_map[key];
54
+ if(!ptex) {
55
+ ptex = std::shared_ptr<GlTexture>(new GlTexture());
56
+ }
57
+ GlTexture& tex = *ptex;
58
+
59
+ // Initialise if it didn't already exist or the size was too small
60
+ if(!tex.tid || tex.width < w || tex.height < h) {
61
+ tex.Reinitialise(
62
+ std::max(tex.width,w), std::max(tex.height,h),
63
+ internal_format, default_sampling_linear, 0,
64
+ glformat, gltype
65
+ );
66
+ }
67
+
68
+ return tex;
69
+ }
70
+
71
+ template<typename T>
72
+ GlTexture& GlTex(GLsizei w, GLsizei h)
73
+ {
74
+ return GlTex( w, h,
75
+ GlFormatTraits<T>::glinternalformat,
76
+ GlFormatTraits<T>::glformat,
77
+ GlFormatTraits<T>::gltype
78
+ );
79
+ }
80
+
81
+ protected:
82
+ bool default_sampling_linear;
83
+ std::map<long, std::shared_ptr<GlTexture> > texture_map;
84
+
85
+ // Protected constructor
86
+ TextureCache()
87
+ : default_sampling_linear(true)
88
+ {
89
+ }
90
+ };
91
+
92
+ template<typename T>
93
+ void RenderToViewport(Image<T>& image, bool flipx=false, bool flipy=false)
94
+ {
95
+ // Retrieve texture that is at least as large as image and of appropriate type.
96
+ GlTexture& tex = TextureCache::I().GlTex<T>(image.w, image.h);
97
+ tex.Upload(image.ptr,0,0, image.w, image.h, GlFormatTraits<T>::glformat, GlFormatTraits<T>::gltype);
98
+ tex.RenderToViewport(Viewport(0,0,image.w, image.h), flipx, flipy);
99
+ }
100
+
101
+ // This method may dissapear in the future
102
+ inline void RenderToViewport(
103
+ Image<unsigned char>& image,
104
+ const pangolin::GlPixFormat& fmt,
105
+ bool flipx=false, bool flipy=false,
106
+ bool linear_sampling = true
107
+ ) {
108
+ pangolin::GlTexture& tex = pangolin::TextureCache::I().GlTex((GLsizei)image.w, (GLsizei)image.h, fmt.scalable_internal_format, fmt.glformat, fmt.gltype);
109
+ tex.Bind();
110
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, linear_sampling ? GL_LINEAR : GL_NEAREST);
111
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, linear_sampling ? GL_LINEAR : GL_NEAREST);
112
+ tex.Upload(image.ptr,0,0, (GLsizei)image.w, (GLsizei)image.h, fmt.glformat, fmt.gltype);
113
+ tex.RenderToViewport(pangolin::Viewport(0,0,(GLint)image.w, (GLint)image.h), flipx, flipy);
114
+ }
115
+
116
+ }
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glvbo.h ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2011 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #pragma once
29
+
30
+ #include <pangolin/gl/gl.h>
31
+
32
+ namespace pangolin
33
+ {
34
+
35
+ ////////////////////////////////////////////////
36
+ // Interface
37
+ ////////////////////////////////////////////////
38
+
39
+ void MakeTriangleStripIboForVbo(GlBuffer& ibo, int w, int h);
40
+
41
+ GlBuffer MakeTriangleStripIboForVbo(int w, int h);
42
+
43
+ void RenderVbo(GlBuffer& vbo, GLenum mode = GL_POINTS);
44
+
45
+ void RenderVbo(GlBuffer& vbo, const GLuint count, GLenum mode);
46
+
47
+ void RenderVboCbo(GlBuffer& vbo, GlBuffer& cbo, bool draw_color = true, GLenum mode = GL_POINTS);
48
+
49
+ void RenderVboIbo(GlBuffer& vbo, GlBuffer& ibo, bool draw_mesh = true);
50
+
51
+ void RenderVboIboCbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, bool draw_mesh = true, bool draw_color = true);
52
+
53
+ void RenderVboIboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& nbo, bool draw_mesh = true, bool draw_normals = true);
54
+
55
+ void RenderVboIboCboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, GlBuffer& nbo, bool draw_mesh = true, bool draw_color = true, bool draw_normals = true);
56
+
57
+ ////////////////////////////////////////////////
58
+ // Implementation
59
+ ////////////////////////////////////////////////
60
+
61
+ inline void MakeTriangleStripIboForVbo(GlBuffer& ibo, int w, int h)
62
+ {
63
+ const int num_elements = w*(h-1)*2;
64
+ unsigned int* buffer = new unsigned int[num_elements];
65
+ unsigned int* ptr = buffer;
66
+
67
+ for(int y=0; y < (h-1);)
68
+ {
69
+ for(int x=0; x<w; ++x) {
70
+ (*ptr++) = y*w+x;
71
+ (*ptr++) = (y+1)*w+x;
72
+ }
73
+ ++y;
74
+
75
+ if(y>=(h-1)) break;
76
+ for(int x=w-1; x>=0; --x) {
77
+ (*ptr++) = y*w+x;
78
+ (*ptr++) = (y+1)*w+x;
79
+ }
80
+ ++y;
81
+ }
82
+
83
+ ibo.Reinitialise(GlElementArrayBuffer, num_elements, GL_UNSIGNED_INT, 1, GL_STATIC_DRAW );
84
+ ibo.Upload(buffer, sizeof(unsigned int)*num_elements );
85
+
86
+ delete[] buffer;
87
+ }
88
+
89
+ inline GlBuffer MakeTriangleStripIboForVbo(int w, int h)
90
+ {
91
+ GlBuffer ibo;
92
+ MakeTriangleStripIboForVbo(ibo,w,h);
93
+ return ibo;
94
+ }
95
+
96
+ inline void RenderVbo(GlBuffer& vbo, GLenum mode)
97
+ {
98
+ vbo.Bind();
99
+ glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0);
100
+ glEnableClientState(GL_VERTEX_ARRAY);
101
+
102
+ glDrawArrays(mode, 0, vbo.num_elements);
103
+
104
+ glDisableClientState(GL_VERTEX_ARRAY);
105
+ vbo.Unbind();
106
+ }
107
+
108
+ inline void RenderVbo(GlBuffer& vbo, const GLuint count, GLenum mode)
109
+ {
110
+ vbo.Bind();
111
+ glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0);
112
+ glEnableClientState(GL_VERTEX_ARRAY);
113
+
114
+ glDrawArrays(mode, 0, std::min(count, vbo.num_elements));
115
+
116
+ glDisableClientState(GL_VERTEX_ARRAY);
117
+ vbo.Unbind();
118
+ }
119
+
120
+ inline void RenderVboCbo(GlBuffer& vbo, GlBuffer& cbo, bool draw_color, GLenum mode )
121
+ {
122
+ if(draw_color) {
123
+ cbo.Bind();
124
+ glColorPointer(cbo.count_per_element, cbo.datatype, 0, 0);
125
+ glEnableClientState(GL_COLOR_ARRAY);
126
+ }
127
+
128
+ RenderVbo(vbo,mode);
129
+
130
+ if(draw_color) {
131
+ glDisableClientState(GL_COLOR_ARRAY);
132
+ cbo.Unbind();
133
+ }
134
+ }
135
+
136
+ inline void RenderVboIbo(GlBuffer& vbo, GlBuffer& ibo, bool draw_mesh)
137
+ {
138
+ vbo.Bind();
139
+ glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0);
140
+ glEnableClientState(GL_VERTEX_ARRAY);
141
+
142
+ if(draw_mesh) {
143
+ ibo.Bind();
144
+ glDrawElements(GL_TRIANGLE_STRIP,ibo.num_elements, ibo.datatype, 0);
145
+ ibo.Unbind();
146
+ }else{
147
+ glDrawArrays(GL_POINTS, 0, vbo.num_elements);
148
+ }
149
+
150
+ glDisableClientState(GL_VERTEX_ARRAY);
151
+ vbo.Unbind();
152
+ }
153
+
154
+ inline void RenderVboIboCbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, bool draw_mesh, bool draw_color )
155
+ {
156
+ if(draw_color) {
157
+ cbo.Bind();
158
+ glColorPointer(cbo.count_per_element, cbo.datatype, 0, 0);
159
+ glEnableClientState(GL_COLOR_ARRAY);
160
+ }
161
+
162
+ RenderVboIbo(vbo,ibo,draw_mesh);
163
+
164
+ if(draw_color) {
165
+ glDisableClientState(GL_COLOR_ARRAY);
166
+ cbo.Unbind();
167
+ }
168
+ }
169
+
170
+ inline void RenderVboIboCboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& cbo, GlBuffer& nbo, bool draw_mesh, bool draw_color, bool draw_normals)
171
+ {
172
+ if(draw_color) {
173
+ cbo.Bind();
174
+ glColorPointer(cbo.count_per_element, cbo.datatype, 0, 0);
175
+ glEnableClientState(GL_COLOR_ARRAY);
176
+ }
177
+
178
+ if(draw_normals) {
179
+ nbo.Bind();
180
+ glNormalPointer(nbo.datatype, (GLsizei)(nbo.count_per_element * GlDataTypeBytes(nbo.datatype)),0);
181
+ glEnableClientState(GL_NORMAL_ARRAY);
182
+ }
183
+
184
+ vbo.Bind();
185
+ glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0);
186
+ glEnableClientState(GL_VERTEX_ARRAY);
187
+
188
+ if(draw_mesh) {
189
+ ibo.Bind();
190
+ glDrawElements(GL_TRIANGLE_STRIP,ibo.num_elements, ibo.datatype, 0);
191
+ ibo.Unbind();
192
+ }else{
193
+ glDrawArrays(GL_POINTS, 0, vbo.num_elements);
194
+ }
195
+
196
+ if(draw_color) {
197
+ glDisableClientState(GL_COLOR_ARRAY);
198
+ cbo.Unbind();
199
+ }
200
+
201
+ if(draw_normals) {
202
+ glDisableClientState(GL_NORMAL_ARRAY);
203
+ nbo.Unbind();
204
+ }
205
+
206
+ glDisableClientState(GL_VERTEX_ARRAY);
207
+ vbo.Unbind();
208
+ }
209
+
210
+ inline void RenderVboIboNbo(GlBuffer& vbo, GlBuffer& ibo, GlBuffer& nbo, bool draw_mesh, bool draw_normals)
211
+ {
212
+ vbo.Bind();
213
+ glVertexPointer(vbo.count_per_element, vbo.datatype, 0, 0);
214
+ glEnableClientState(GL_VERTEX_ARRAY);
215
+
216
+ if(draw_normals) {
217
+ nbo.Bind();
218
+ glNormalPointer(nbo.datatype, (GLsizei)(nbo.count_per_element * GlDataTypeBytes(nbo.datatype)), 0);
219
+ glEnableClientState(GL_NORMAL_ARRAY);
220
+ }
221
+
222
+ if(draw_mesh) {
223
+ ibo.Bind();
224
+ glDrawElements(GL_TRIANGLE_STRIP,ibo.num_elements, ibo.datatype, 0);
225
+ ibo.Unbind();
226
+ }else{
227
+ glDrawArrays(GL_POINTS, 0, vbo.num_elements);
228
+ }
229
+
230
+ if(draw_normals) {
231
+ glDisableClientState(GL_NORMAL_ARRAY);
232
+ nbo.Unbind();
233
+ }
234
+
235
+ glDisableClientState(GL_VERTEX_ARRAY);
236
+ vbo.Unbind();
237
+ }
238
+
239
+ }
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/opengl_render_state.h ADDED
@@ -0,0 +1,446 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2011 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #pragma once
29
+
30
+ #include <pangolin/platform.h>
31
+ #include <pangolin/utils/simple_math.h>
32
+
33
+ #include <vector>
34
+
35
+ #if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files
36
+ #define USE_EIGEN
37
+ #endif
38
+
39
+ #ifdef USE_EIGEN
40
+ #include <Eigen/Core>
41
+ #include <Eigen/Geometry>
42
+ #endif
43
+
44
+ #ifdef HAVE_TOON
45
+ #include <cstring>
46
+ #include <TooN/TooN.h>
47
+ #include <TooN/se3.h>
48
+ #endif
49
+
50
+ #ifdef HAVE_OCULUS
51
+ #include <pangolin/compat/ovr.h>
52
+ #endif
53
+
54
+ namespace pangolin {
55
+
56
+ #ifdef HAVE_GLES
57
+ typedef float GLprecision;
58
+ #else
59
+ typedef double GLprecision;
60
+ #endif
61
+
62
+ /// Capture OpenGL matrix types in enum to typing.
63
+ enum OpenGlStack {
64
+ GlModelViewStack = 0x1700, // GL_MODELVIEW
65
+ GlProjectionStack = 0x1701, // GL_PROJECTION
66
+ GlTextureStack = 0x1702 // GL_TEXTURE
67
+ };
68
+
69
+ enum AxisDirection
70
+ {
71
+ AxisNone,
72
+ AxisNegX, AxisX,
73
+ AxisNegY, AxisY,
74
+ AxisNegZ, AxisZ
75
+ };
76
+
77
+ struct CameraSpec {
78
+ GLprecision forward[3];
79
+ GLprecision up[3];
80
+ GLprecision right[3];
81
+ GLprecision img_up[2];
82
+ GLprecision img_right[2];
83
+ };
84
+
85
+ const static CameraSpec CameraSpecOpenGl = {{0,0,-1},{0,1,0},{1,0,0},{0,1},{1,0}};
86
+
87
+ const static CameraSpec CameraSpecYDownZForward = {{0,0,1},{0,-1,0},{1,0,0},{0,-1},{1,0}};
88
+
89
+ /// Direction vector for each AxisDirection enum
90
+ const static GLprecision AxisDirectionVector[7][3] = {
91
+ {0,0,0},
92
+ {-1,0,0}, {1,0,0},
93
+ {0,-1,0}, {0,1,0},
94
+ {0,0,-1}, {0,0,1}
95
+ };
96
+
97
+ /// Object representing OpenGl Matrix.
98
+ struct PANGOLIN_EXPORT OpenGlMatrix {
99
+ static OpenGlMatrix Translate(GLprecision x, GLprecision y, GLprecision z);
100
+ static OpenGlMatrix Scale(GLprecision x, GLprecision y, GLprecision z);
101
+ static OpenGlMatrix RotateX(GLprecision theta_rad);
102
+ static OpenGlMatrix RotateY(GLprecision theta_rad);
103
+ static OpenGlMatrix RotateZ(GLprecision theta_rad);
104
+
105
+
106
+ template<typename P>
107
+ static OpenGlMatrix ColMajor4x4(const P* col_major_4x4);
108
+
109
+ OpenGlMatrix();
110
+
111
+ #ifdef USE_EIGEN
112
+ template<typename P>
113
+ OpenGlMatrix(const Eigen::Matrix<P,4,4>& mat);
114
+
115
+ template<typename P>
116
+ OpenGlMatrix(const Eigen::Transform<P,3,Eigen::Affine>& mat) : OpenGlMatrix(mat.matrix()) { }
117
+
118
+ template<typename P>
119
+ operator Eigen::Matrix<P,4,4>() const;
120
+
121
+ template<typename P>
122
+ operator Eigen::Transform<P,3,Eigen::Affine>() const;
123
+ #endif // USE_EIGEN
124
+
125
+ #ifdef HAVE_TOON
126
+ OpenGlMatrix(const TooN::SE3<>& T);
127
+ OpenGlMatrix(const TooN::Matrix<4,4>& M);
128
+ operator const TooN::SE3<>() const;
129
+ operator const TooN::Matrix<4,4>() const;
130
+ #endif // HAVE_TOON
131
+
132
+ #ifdef HAVE_OCULUS
133
+ OpenGlMatrix(const OVR::Matrix4f& M);
134
+ operator const OVR::Matrix4f() const;
135
+ #endif // HAVE_OCULUS
136
+
137
+ // Load matrix on to OpenGl stack
138
+ void Load() const;
139
+
140
+ void Multiply() const;
141
+
142
+ void SetIdentity();
143
+
144
+ OpenGlMatrix Transpose() const;
145
+
146
+ OpenGlMatrix Inverse() const;
147
+
148
+ GLprecision& operator()(int r, int c) {
149
+ return m[4*c +r];
150
+ }
151
+
152
+ GLprecision operator()(int r, int c) const {
153
+ return m[4 * c + r];
154
+ }
155
+
156
+ // Column major Internal buffer
157
+ GLprecision m[16];
158
+ };
159
+
160
+ PANGOLIN_EXPORT
161
+ OpenGlMatrix operator*(const OpenGlMatrix& lhs, const OpenGlMatrix& rhs);
162
+
163
+ PANGOLIN_EXPORT
164
+ std::ostream& operator<<(std::ostream& os, const OpenGlMatrix& mat);
165
+
166
+ /// Deprecated.
167
+ struct PANGOLIN_EXPORT OpenGlMatrixSpec : public OpenGlMatrix {
168
+ // Specify which stack this refers to
169
+ OpenGlStack type;
170
+ };
171
+
172
+ /// Object representing attached OpenGl Matrices / transforms.
173
+ class PANGOLIN_EXPORT OpenGlRenderState
174
+ {
175
+ public:
176
+ OpenGlRenderState();
177
+ OpenGlRenderState(const OpenGlMatrix& projection_matrix);
178
+ OpenGlRenderState(const OpenGlMatrix& projection_matrix, const OpenGlMatrix& modelview_matrix);
179
+
180
+ static void ApplyIdentity();
181
+
182
+ void Apply() const;
183
+ OpenGlRenderState& SetProjectionMatrix(OpenGlMatrix m);
184
+ OpenGlRenderState& SetModelViewMatrix(OpenGlMatrix m);
185
+
186
+ OpenGlMatrix& GetProjectionMatrix();
187
+ OpenGlMatrix GetProjectionMatrix() const;
188
+
189
+ OpenGlMatrix& GetModelViewMatrix();
190
+ OpenGlMatrix GetModelViewMatrix() const;
191
+
192
+ OpenGlMatrix GetProjectionModelViewMatrix() const;
193
+ OpenGlMatrix GetProjectiveTextureMatrix() const;
194
+
195
+ void EnableProjectiveTexturing() const;
196
+ void DisableProjectiveTexturing() const;
197
+
198
+ //! Seemlessly move OpenGl camera relative to changes in T_wc,
199
+ //! whilst still enabling interaction
200
+ void Follow(const OpenGlMatrix& T_wc, bool follow = true);
201
+ void Unfollow();
202
+
203
+ // Experimental - subject to change
204
+ OpenGlMatrix& GetProjectionMatrix(unsigned int view);
205
+ OpenGlMatrix GetProjectionMatrix(unsigned int view) const;
206
+ OpenGlMatrix& GetViewOffset(unsigned int view);
207
+ OpenGlMatrix GetViewOffset(unsigned int view) const;
208
+ OpenGlMatrix GetModelViewMatrix(int i) const;
209
+ void ApplyNView(int view) const;
210
+
211
+ PANGOLIN_DEPRECATED("Use SetProjectionMatrix() or SetModelViewMatrix() instead.")
212
+ OpenGlRenderState& Set(OpenGlMatrixSpec spec);
213
+
214
+ protected:
215
+ OpenGlMatrix modelview;
216
+ std::vector<OpenGlMatrix> projection;
217
+ std::vector<OpenGlMatrix> modelview_premult;
218
+ OpenGlMatrix T_cw;
219
+ bool follow;
220
+ };
221
+
222
+ PANGOLIN_EXPORT
223
+ OpenGlMatrixSpec ProjectionMatrixRUB_BottomLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar );
224
+
225
+ PANGOLIN_EXPORT
226
+ OpenGlMatrixSpec ProjectionMatrixRUB_TopLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar );
227
+
228
+ PANGOLIN_EXPORT
229
+ OpenGlMatrixSpec ProjectionMatrixRDF_TopLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar );
230
+
231
+ PANGOLIN_EXPORT
232
+ OpenGlMatrixSpec ProjectionMatrixRDF_TopRight(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar );
233
+
234
+ PANGOLIN_EXPORT
235
+ OpenGlMatrixSpec ProjectionMatrixRDF_BottomLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar );
236
+
237
+ PANGOLIN_EXPORT
238
+ OpenGlMatrixSpec ProjectionMatrixRDF_BottomRight(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar );
239
+
240
+ //! Use OpenGl's default frame RUB_BottomLeft
241
+ PANGOLIN_EXPORT
242
+ OpenGlMatrixSpec ProjectionMatrix(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar );
243
+
244
+ PANGOLIN_EXPORT
245
+ OpenGlMatrixSpec ProjectionMatrixOrthographic(GLprecision l, GLprecision r, GLprecision b, GLprecision t, GLprecision n, GLprecision f );
246
+
247
+
248
+ //! Generate glulookat style model view matrix, looking at (lx,ly,lz)
249
+ //! X-Right, Y-Up, Z-Back
250
+ PANGOLIN_EXPORT
251
+ OpenGlMatrix ModelViewLookAtRUB(GLprecision ex, GLprecision ey, GLprecision ez, GLprecision lx, GLprecision ly, GLprecision lz, GLprecision ux, GLprecision uy, GLprecision uz);
252
+
253
+ //! Generate glulookat style model view matrix, looking at (lx,ly,lz)
254
+ //! X-Right, Y-Down, Z-Forward
255
+ PANGOLIN_EXPORT
256
+ OpenGlMatrix ModelViewLookAtRDF(GLprecision ex, GLprecision ey, GLprecision ez, GLprecision lx, GLprecision ly, GLprecision lz, GLprecision ux, GLprecision uy, GLprecision uz);
257
+
258
+ //! Generate glulookat style model view matrix, OpenGL Default camera convention (XYZ=RUB), looking at (lx,ly,lz)
259
+ PANGOLIN_EXPORT
260
+ OpenGlMatrix ModelViewLookAt(GLprecision x, GLprecision y, GLprecision z, GLprecision lx, GLprecision ly, GLprecision lz, AxisDirection up);
261
+
262
+ PANGOLIN_EXPORT
263
+ OpenGlMatrix ModelViewLookAt(GLprecision ex, GLprecision ey, GLprecision ez, GLprecision lx, GLprecision ly, GLprecision lz, GLprecision ux, GLprecision uy, GLprecision uz);
264
+
265
+
266
+ PANGOLIN_EXPORT
267
+ OpenGlMatrix IdentityMatrix();
268
+
269
+ PANGOLIN_EXPORT
270
+ OpenGlMatrixSpec IdentityMatrix(OpenGlStack type);
271
+
272
+ PANGOLIN_EXPORT
273
+ OpenGlMatrixSpec negIdentityMatrix(OpenGlStack type);
274
+
275
+ #ifdef HAVE_TOON
276
+ OpenGlMatrixSpec FromTooN(const TooN::SE3<>& T_cw);
277
+ OpenGlMatrixSpec FromTooN(OpenGlStack type, const TooN::Matrix<4,4>& M);
278
+ TooN::Matrix<4,4> ToTooN(const OpenGlMatrixSpec& ms);
279
+ TooN::SE3<> ToTooN_SE3(const OpenGlMatrixSpec& ms);
280
+ #endif
281
+
282
+ #ifdef USE_EIGEN
283
+ template<typename P>
284
+ Eigen::Matrix<P,4,4> ToEigen(const OpenGlMatrix& ms);
285
+ #endif
286
+
287
+ }
288
+
289
+ // Inline definitions
290
+ namespace pangolin
291
+ {
292
+
293
+ template<typename P>
294
+ inline OpenGlMatrix OpenGlMatrix::ColMajor4x4(const P* col_major_4x4)
295
+ {
296
+ OpenGlMatrix mat;
297
+ std::copy(col_major_4x4, col_major_4x4 + 16, mat.m);
298
+ return mat;
299
+ }
300
+
301
+ inline OpenGlMatrix::OpenGlMatrix() {
302
+ }
303
+
304
+ #ifdef USE_EIGEN
305
+ template<typename P> inline
306
+ OpenGlMatrix::OpenGlMatrix(const Eigen::Matrix<P,4,4>& mat)
307
+ {
308
+ for(int r=0; r<4; ++r ) {
309
+ for(int c=0; c<4; ++c ) {
310
+ m[c*4+r] = mat(r,c);
311
+ }
312
+ }
313
+ }
314
+
315
+ template<typename P>
316
+ OpenGlMatrix::operator Eigen::Matrix<P,4,4>() const
317
+ {
318
+ return ToEigen<P>(*this);
319
+ }
320
+
321
+ template<typename P>
322
+ OpenGlMatrix::operator Eigen::Transform<P,3,Eigen::Affine>() const
323
+ {
324
+ return Eigen::Transform<P,3,Eigen::Affine>(ToEigen<P>(*this));
325
+ }
326
+
327
+ template<typename P> inline
328
+ Eigen::Matrix<P,4,4> ToEigen(const OpenGlMatrix& ms)
329
+ {
330
+ Eigen::Matrix<P,4,4> mat;
331
+ for(int r=0; r<4; ++r ) {
332
+ for(int c=0; c<4; ++c ) {
333
+ mat(r,c) = (P)ms.m[c*4+r];
334
+ }
335
+ }
336
+ return mat;
337
+ }
338
+
339
+ #endif // USE_EIGEN
340
+
341
+ #ifdef HAVE_TOON
342
+ inline OpenGlMatrix::OpenGlMatrix(const TooN::SE3<>& T)
343
+ {
344
+ TooN::Matrix<4,4,GLprecision,TooN::ColMajor> M;
345
+ M.slice<0,0,3,3>() = T.get_rotation().get_matrix();
346
+ M.T()[3].slice<0,3>() = T.get_translation();
347
+ M[3] = TooN::makeVector(0,0,0,1);
348
+ std::memcpy(m, &(M[0][0]),16*sizeof(GLprecision));
349
+ }
350
+
351
+ inline OpenGlMatrix::OpenGlMatrix(const TooN::Matrix<4,4>& M)
352
+ {
353
+ // Read in remembering col-major convension for our matrices
354
+ int el = 0;
355
+ for(int c=0; c<4; ++c)
356
+ for(int r=0; r<4; ++r)
357
+ m[el++] = M[r][c];
358
+ }
359
+
360
+ inline OpenGlMatrix::operator const TooN::SE3<>() const
361
+ {
362
+ const TooN::Matrix<4,4> m = *this;
363
+ const TooN::SO3<> R(m.slice<0,0,3,3>());
364
+ const TooN::Vector<3> t = m.T()[3].slice<0,3>();
365
+ return TooN::SE3<>(R,t);
366
+ }
367
+
368
+ inline OpenGlMatrix::operator const TooN::Matrix<4,4>() const
369
+ {
370
+ TooN::Matrix<4,4> M;
371
+ int el = 0;
372
+ for( int c=0; c<4; ++c )
373
+ for( int r=0; r<4; ++r )
374
+ M(r,c) = m[el++];
375
+ return M;
376
+ }
377
+
378
+ PANGOLIN_DEPRECATED
379
+ inline OpenGlMatrixSpec FromTooN(const TooN::SE3<>& T_cw)
380
+ {
381
+ TooN::Matrix<4,4,GLprecision,TooN::ColMajor> M;
382
+ M.slice<0,0,3,3>() = T_cw.get_rotation().get_matrix();
383
+ M.T()[3].slice<0,3>() = T_cw.get_translation();
384
+ M[3] = TooN::makeVector(0,0,0,1);
385
+
386
+ OpenGlMatrixSpec P;
387
+ P.type = GlModelViewStack;
388
+ std::memcpy(P.m, &(M[0][0]),16*sizeof(GLprecision));
389
+ return P;
390
+ }
391
+
392
+ PANGOLIN_DEPRECATED
393
+ inline OpenGlMatrixSpec FromTooN(OpenGlStack type, const TooN::Matrix<4,4>& M)
394
+ {
395
+ // Read in remembering col-major convension for our matrices
396
+ OpenGlMatrixSpec P;
397
+ P.type = type;
398
+ int el = 0;
399
+ for(int c=0; c<4; ++c)
400
+ for(int r=0; r<4; ++r)
401
+ P.m[el++] = M[r][c];
402
+ return P;
403
+ }
404
+
405
+ PANGOLIN_DEPRECATED
406
+ inline TooN::Matrix<4,4> ToTooN(const OpenGlMatrix& ms)
407
+ {
408
+ TooN::Matrix<4,4> m;
409
+ int el = 0;
410
+ for( int c=0; c<4; ++c )
411
+ for( int r=0; r<4; ++r )
412
+ m(r,c) = ms.m[el++];
413
+ return m;
414
+ }
415
+
416
+ PANGOLIN_DEPRECATED
417
+ inline TooN::SE3<> ToTooN_SE3(const OpenGlMatrix& ms)
418
+ {
419
+ TooN::Matrix<4,4> m = ms;
420
+ const TooN::SO3<> R(m.slice<0,0,3,3>());
421
+ const TooN::Vector<3> t = m.T()[3].slice<0,3>();
422
+ return TooN::SE3<>(R,t);
423
+ }
424
+
425
+ #endif // HAVE_TOON
426
+
427
+ #ifdef HAVE_OCULUS
428
+ inline OpenGlMatrix::OpenGlMatrix(const OVR::Matrix4f& mat)
429
+ {
430
+ for(int r=0; r<4; ++r )
431
+ for(int c=0; c<4; ++c )
432
+ m[c*4+r] = mat.M[r][c];
433
+ }
434
+
435
+ inline OpenGlMatrix::operator const OVR::Matrix4f() const
436
+ {
437
+ OVR::Matrix4f mat;
438
+ for(int r=0; r<4; ++r )
439
+ for(int c=0; c<4; ++c )
440
+ mat.M[r][c] = m[c*4+r];
441
+ return mat;
442
+ }
443
+ #endif // HAVE_OCULUS
444
+
445
+
446
+ }
third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/viewport.h ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2011 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #pragma once
29
+
30
+ #include <pangolin/gl/glinclude.h>
31
+
32
+ namespace pangolin
33
+ {
34
+
35
+ /// Encapsulates OpenGl Viewport.
36
+ struct PANGOLIN_EXPORT Viewport
37
+ {
38
+ Viewport() : l(0),b(0),w(0),h(0) {}
39
+ Viewport(GLint l,GLint b,GLint w,GLint h) : l(l),b(b),w(w),h(h) {}
40
+
41
+ void Activate() const;
42
+ void ActivateIdentity() const;
43
+ void ActivatePixelOrthographic() const;
44
+
45
+ void Scissor() const;
46
+ void ActivateAndScissor() const;
47
+
48
+ bool Contains(int x, int y) const;
49
+
50
+ Viewport Inset(int i) const;
51
+ Viewport Inset(int horiz, int vert) const;
52
+ Viewport Intersect(const Viewport& vp) const;
53
+
54
+ static void DisableScissor();
55
+
56
+ GLint r() const { return l+w;}
57
+ GLint t() const { return b+h;}
58
+ GLfloat aspect() const { return (GLfloat)w / (GLfloat)h; }
59
+ GLint area() const { return w * h; }
60
+ GLint l,b,w,h;
61
+ };
62
+
63
+ }
third-party/DPVO/Pangolin/components/pango_opengl/src/compat/gl2engine.cpp ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2014 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <pangolin/gl/glinclude.h>
29
+
30
+ namespace pangolin
31
+ {
32
+
33
+ GlEngine& glEngine()
34
+ {
35
+ static GlEngine engine;
36
+ return engine;
37
+ }
38
+
39
+ }
third-party/DPVO/Pangolin/components/pango_opengl/src/fonts/AnonymousPro.ttf ADDED
Binary file (158 kB). View file
 
third-party/DPVO/Pangolin/components/pango_opengl/src/fonts/AnonymousPro.txt ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2009, Mark Simonson (http://www.ms-studio.com, [email protected]),
2
+ with Reserved Font Name Anonymous Pro.
3
+
4
+ This Font Software is licensed under the SIL Open Font License, Version 1.1.
5
+ This license is copied below, and is also available with a FAQ at:
6
+ http://scripts.sil.org/OFL
7
+
8
+
9
+ -----------------------------------------------------------
10
+ SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
11
+ -----------------------------------------------------------
12
+
13
+ PREAMBLE
14
+ The goals of the Open Font License (OFL) are to stimulate worldwide
15
+ development of collaborative font projects, to support the font creation
16
+ efforts of academic and linguistic communities, and to provide a free and
17
+ open framework in which fonts may be shared and improved in partnership
18
+ with others.
19
+
20
+ The OFL allows the licensed fonts to be used, studied, modified and
21
+ redistributed freely as long as they are not sold by themselves. The
22
+ fonts, including any derivative works, can be bundled, embedded,
23
+ redistributed and/or sold with any software provided that any reserved
24
+ names are not used by derivative works. The fonts and derivatives,
25
+ however, cannot be released under any other type of license. The
26
+ requirement for fonts to remain under this license does not apply
27
+ to any document created using the fonts or their derivatives.
28
+
29
+ DEFINITIONS
30
+ "Font Software" refers to the set of files released by the Copyright
31
+ Holder(s) under this license and clearly marked as such. This may
32
+ include source files, build scripts and documentation.
33
+
34
+ "Reserved Font Name" refers to any names specified as such after the
35
+ copyright statement(s).
36
+
37
+ "Original Version" refers to the collection of Font Software components as
38
+ distributed by the Copyright Holder(s).
39
+
40
+ "Modified Version" refers to any derivative made by adding to, deleting,
41
+ or substituting -- in part or in whole -- any of the components of the
42
+ Original Version, by changing formats or by porting the Font Software to a
43
+ new environment.
44
+
45
+ "Author" refers to any designer, engineer, programmer, technical
46
+ writer or other person who contributed to the Font Software.
47
+
48
+ PERMISSION & CONDITIONS
49
+ Permission is hereby granted, free of charge, to any person obtaining
50
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
51
+ redistribute, and sell modified and unmodified copies of the Font
52
+ Software, subject to the following conditions:
53
+
54
+ 1) Neither the Font Software nor any of its individual components,
55
+ in Original or Modified Versions, may be sold by itself.
56
+
57
+ 2) Original or Modified Versions of the Font Software may be bundled,
58
+ redistributed and/or sold with any software, provided that each copy
59
+ contains the above copyright notice and this license. These can be
60
+ included either as stand-alone text files, human-readable headers or
61
+ in the appropriate machine-readable metadata fields within text or
62
+ binary files as long as those fields can be easily viewed by the user.
63
+
64
+ 3) No Modified Version of the Font Software may use the Reserved Font
65
+ Name(s) unless explicit written permission is granted by the corresponding
66
+ Copyright Holder. This restriction only applies to the primary font name as
67
+ presented to the users.
68
+
69
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
70
+ Software shall not be used to promote, endorse or advertise any
71
+ Modified Version, except to acknowledge the contribution(s) of the
72
+ Copyright Holder(s) and the Author(s) or with their explicit written
73
+ permission.
74
+
75
+ 5) The Font Software, modified or unmodified, in part or in whole,
76
+ must be distributed entirely under this license, and must not be
77
+ distributed under any other license. The requirement for fonts to
78
+ remain under this license does not apply to any document created
79
+ using the Font Software.
80
+
81
+ TERMINATION
82
+ This license becomes null and void if any of the above conditions are
83
+ not met.
84
+
85
+ DISCLAIMER
86
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
87
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
88
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
89
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
90
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
91
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
92
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
93
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
94
+ OTHER DEALINGS IN THE FONT SOFTWARE.
third-party/DPVO/Pangolin/components/pango_opengl/src/glchar.cpp ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2013 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <pangolin/gl/glchar.h>
29
+
30
+ namespace pangolin
31
+ {
32
+
33
+ GlChar::GlChar()
34
+ : x_step(0.0f)
35
+ {
36
+ // Uninitialised
37
+ }
38
+
39
+ GlChar::GlChar(int tw, int th, int x, int y, int w, int h, GLfloat advance, GLfloat ox, GLfloat oy)
40
+ : x_step(advance)
41
+ {
42
+ const GLfloat u = (GLfloat)x / (GLfloat)tw;
43
+ const GLfloat v = (GLfloat)y / (GLfloat)th;
44
+ const GLfloat u2 = (GLfloat)(x + w) / (GLfloat)tw;
45
+ const GLfloat v2 = (GLfloat)(y + h) / (GLfloat)th;
46
+
47
+ // Setup u,v tex coords
48
+ vs[0] = XYUV(ox, oy, u,v );
49
+ vs[1] = XYUV(ox, oy-h, u,v2 );
50
+ vs[2] = XYUV(w+ox, oy-h, u2,v2 );
51
+ vs[3] = XYUV(w+ox, oy, u2,v );
52
+
53
+ y_min = oy-h;
54
+ y_max = oy;
55
+ }
56
+
57
+ void GlChar::Draw() const
58
+ {
59
+ glVertexPointer(2, GL_FLOAT, sizeof(XYUV), &vs[0].x);
60
+ glEnableClientState(GL_VERTEX_ARRAY);
61
+ glTexCoordPointer(2, GL_FLOAT, sizeof(XYUV), &vs[0].tu);
62
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
63
+ glEnable(GL_TEXTURE_2D);
64
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
65
+ glDisable(GL_TEXTURE_2D);
66
+ glDisableClientState(GL_VERTEX_ARRAY);
67
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
68
+ }
69
+
70
+ }
third-party/DPVO/Pangolin/components/pango_opengl/src/gldraw.cpp ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2011 Steven Lovegrove, Richard Newcombe
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+
29
+ #include <pangolin/gl/gldraw.h>
30
+ #include <pangolin/utils/timer.h>
31
+
32
+ namespace pangolin
33
+ {
34
+
35
+ void glRecordGraphic(float x, float y, float radius)
36
+ {
37
+ const int ticks = static_cast<int>(TimeNow_s());
38
+ if( ticks % 2 )
39
+ {
40
+ // now, render a little red "recording" dot
41
+ #ifndef HAVE_GLES
42
+ glPushAttrib(GL_ENABLE_BIT);
43
+ #endif
44
+ glDisable(GL_LIGHTING);
45
+ glDisable(GL_DEPTH_TEST);
46
+ glColor3f( 1.0f, 0.0f, 0.0f );
47
+ glDrawCircle( x, y, radius );
48
+ #ifndef HAVE_GLES
49
+ glPopAttrib();
50
+ #endif
51
+ }
52
+
53
+ }
54
+
55
+ }
third-party/DPVO/Pangolin/components/pango_opengl/src/glfont.cpp ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2013 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <pangolin/gl/glfont.h>
29
+ #include <pangolin/gl/glstate.h>
30
+ #include <pangolin/image/image_io.h>
31
+ #include <pangolin/utils/type_convert.h>
32
+ #include <pangolin/utils/file_utils.h>
33
+
34
+ #if !defined(HAVE_GLES) || defined(HAVE_GLES_2)
35
+ #include <pangolin/gl/glsl.h>
36
+ #endif
37
+
38
+ #define STB_TRUETYPE_IMPLEMENTATION
39
+ #define STBTT_STATIC
40
+
41
+ #if defined(__GNUC__)
42
+ # pragma GCC diagnostic push
43
+ # pragma GCC diagnostic ignored "-Wunused-function"
44
+ # include "stb_truetype.h"
45
+ # pragma GCC diagnostic pop
46
+ #else
47
+ # include "stb_truetype.h"
48
+ #endif
49
+
50
+ #define MAX_TEXT_LENGTH 500
51
+
52
+ // Embedded fonts:
53
+ PANGOLIN_EXPORT extern const unsigned char AnonymousPro_ttf[];
54
+
55
+ namespace pangolin
56
+ {
57
+
58
+ GlFont::GlFont(float pixel_height, int tex_w, int tex_h)
59
+ {
60
+ InitialiseFont(AnonymousPro_ttf, pixel_height, tex_w, tex_h);
61
+ }
62
+
63
+ GlFont::GlFont(const unsigned char* ttf_buffer, float pixel_height, int tex_w, int tex_h)
64
+ {
65
+ InitialiseFont(ttf_buffer, pixel_height, tex_w, tex_h);
66
+ }
67
+
68
+ GlFont::GlFont(const std::string& filename, float pixel_height, int tex_w, int tex_h)
69
+ {
70
+ const std::string file_contents = GetFileContents(filename);
71
+ InitialiseFont(reinterpret_cast<const unsigned char*>(file_contents.data()), pixel_height, tex_w, tex_h);
72
+ }
73
+
74
+ GlFont::~GlFont()
75
+ {
76
+ delete[] font_bitmap;
77
+ }
78
+
79
+ void GlFont::InitialiseFont(const unsigned char* ttf_buffer, float pixel_height, int tex_w, int tex_h)
80
+ {
81
+ font_height_px = pixel_height;
82
+ font_max_width_px = 0;
83
+
84
+ this->tex_w = tex_w;
85
+ this->tex_h = tex_h;
86
+ font_bitmap = new unsigned char[tex_w*tex_h];
87
+ const int offset = 0;
88
+
89
+ stbtt_fontinfo f;
90
+ if (!stbtt_InitFont(&f, ttf_buffer, offset)) {
91
+ throw std::runtime_error("Unable to initialise font: stbtt_InitFont failed.");
92
+ }
93
+
94
+ float scale = stbtt_ScaleForPixelHeight(&f, pixel_height);
95
+
96
+ STBTT_memset(font_bitmap, 0, tex_w*tex_h);
97
+ int x = 1;
98
+ int y = 1;
99
+ int bottom_y = 1;
100
+
101
+ // Generate bitmap and char indices
102
+ for (int i=0; i < NUM_CHARS; ++i) {
103
+ int advance, lsb, x0,y0,x1,y1,gw,gh;
104
+ int g = stbtt_FindGlyphIndex(&f, FIRST_CHAR + i);
105
+ stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb);
106
+ stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1);
107
+ gw = x1-x0;
108
+ gh = y1-y0;
109
+ font_max_width_px = std::max(font_max_width_px, (float)gw);
110
+
111
+ if (x + gw + 1 >= tex_w)
112
+ y = bottom_y, x = 1; // advance to next row
113
+ if (y + gh + 1 >= tex_h) // check if it fits vertically AFTER potentially moving to next row
114
+ throw std::runtime_error("Unable to initialise font: run out of texture pixel space.");
115
+ STBTT_assert(x+gw < tex_w);
116
+ STBTT_assert(y+gh < tex_h);
117
+ stbtt_MakeGlyphBitmap(&f, font_bitmap+x+y*tex_w, gw,gh,tex_w, scale,scale, g);
118
+
119
+ // Adjust offset for edges of pixels
120
+ chardata[i] = GlChar(tex_w,tex_h, x, y, gw, gh, scale*advance, x0 -0.5f, -y0 -0.5f);
121
+
122
+ x = x + gw + 1;
123
+ if (y+gh+1 > bottom_y)
124
+ bottom_y = y+gh+1;
125
+ }
126
+
127
+ // Generate kern table
128
+ for (int i=0; i < NUM_CHARS; ++i) {
129
+ for (int j=0; j < NUM_CHARS; ++j) {
130
+ kern_table[i*NUM_CHARS+j] = scale * stbtt_GetCodepointKernAdvance(&f,i,j);
131
+ }
132
+ }
133
+ }
134
+
135
+ void GlFont::InitialiseGlTexture()
136
+ {
137
+ if(font_bitmap) {
138
+ mTex.Reinitialise(tex_w,tex_h, GL_ALPHA, true, 0, GL_ALPHA,GL_UNSIGNED_BYTE, font_bitmap);
139
+ // mTex.SetNearestNeighbour();
140
+ delete[] font_bitmap;
141
+ font_bitmap = 0;
142
+ }
143
+ }
144
+
145
+ GlText GlFont::Text( const char* fmt, ... )
146
+ {
147
+ if(!mTex.IsValid()) InitialiseGlTexture();
148
+
149
+ GlText ret(mTex);
150
+
151
+ char text[MAX_TEXT_LENGTH];
152
+ va_list ap;
153
+
154
+ if( fmt != NULL ) {
155
+ va_start( ap, fmt );
156
+ vsnprintf( text, MAX_TEXT_LENGTH, fmt, ap );
157
+ va_end( ap );
158
+
159
+ const size_t len = strlen(text);
160
+ char lc = ' ' - FIRST_CHAR;
161
+ for(size_t i=0; i < len; ++i) {
162
+ char c = text[i];
163
+ if( !(FIRST_CHAR <= c /*&& c <FIRST_CHAR+NUM_CHARS*/) ) {
164
+ c = ' ';
165
+ }
166
+ const GlChar& ch = chardata[c-32];
167
+
168
+ // Kerning
169
+ if(i) {
170
+ const GLfloat kern = kern_table[ (lc-32)*NUM_CHARS + (c-32) ];
171
+ ret.AddSpace(kern);
172
+ }
173
+
174
+ ret.Add(c,ch);
175
+ lc = c;
176
+ }
177
+ }
178
+ return ret;
179
+ }
180
+
181
+ GlText GlFont::Text( const std::string& str )
182
+ {
183
+ if(!mTex.IsValid()) InitialiseGlTexture();
184
+
185
+ GlText ret(mTex);
186
+
187
+ char lc = ' ' - FIRST_CHAR;
188
+ for(size_t i=0; i < str.length(); ++i) {
189
+ char c = str[i];
190
+ if( !(FIRST_CHAR <= c /*&& c <FIRST_CHAR+NUM_CHARS*/) ) {
191
+ c = ' ';
192
+ }
193
+ const GlChar& ch = chardata[c-32];
194
+
195
+ // Kerning
196
+ if(i) {
197
+ const GLfloat kern = kern_table[ (lc-32)*NUM_CHARS + (c-32) ];
198
+ ret.AddSpace(kern);
199
+ }
200
+
201
+ ret.Add(c,ch);
202
+ lc = c;
203
+ }
204
+ return ret;
205
+ }
206
+
207
+ }
third-party/DPVO/Pangolin/components/pango_opengl/src/glpangoglu.cpp ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2014 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <pangolin/gl/glpangoglu.h>
29
+ #include <pangolin/utils/simple_math.h>
30
+ #include <unordered_map>
31
+
32
+ namespace pangolin {
33
+
34
+ const GLubyte* glErrorString(GLenum err)
35
+ {
36
+ switch (err)
37
+ {
38
+ case GL_NO_ERROR: return (GLubyte*)"GL_NO_ERROR: No error has been recorded.";
39
+ case GL_INVALID_ENUM: return (GLubyte*)"GL_INVALID_ENUM: An unacceptable value is specified for an enumerated argument.";
40
+ case GL_INVALID_VALUE: return (GLubyte*)"GL_INVALID_VALUE: A numeric argument is out of range.";
41
+ case GL_INVALID_OPERATION: return (GLubyte*)"GL_INVALID_OPERATION: The specified operation is not allowed in the current state.";
42
+ case GL_STACK_OVERFLOW: return (GLubyte*)"GL_STACK_OVERFLOW: An attempt has been made to perform an operation that would cause an internal stack to underflow.";
43
+ case GL_STACK_UNDERFLOW: return (GLubyte*)"GL_STACK_UNDERFLOW: An attempt has been made to perform an operation that would cause an internal stack to overflow.";
44
+ case GL_OUT_OF_MEMORY: return (GLubyte*)"GL_OUT_OF_MEMORY: There is not enough memory left to execute the command.";
45
+ case 0x8031: /* not core */ return (GLubyte*)"GL_TABLE_TOO_LARGE_EXT";
46
+ case 0x8065: /* not core */ return (GLubyte*)"GL_TEXTURE_TOO_LARGE_EXT";
47
+ case GL_INVALID_FRAMEBUFFER_OPERATION: return (GLubyte*)"GL_INVALID_FRAMEBUFFER_OPERATION: The framebuffer object is not complete.";
48
+ default:
49
+ return (GLubyte*)"[Unknown error code]";
50
+ }
51
+ }
52
+
53
+ // Based on glu implementation.
54
+ template<typename P>
55
+ int InvertMatrix(const P m[16], P invOut[16])
56
+ {
57
+ P inv[16], det;
58
+ int i;
59
+
60
+ inv[0] = m[5]*m[10]*m[15] - m[5]*m[11]*m[14] - m[9]*m[6]*m[15]
61
+ + m[9]*m[7]*m[14] + m[13]*m[6]*m[11] - m[13]*m[7]*m[10];
62
+ inv[4] = -m[4]*m[10]*m[15] + m[4]*m[11]*m[14] + m[8]*m[6]*m[15]
63
+ - m[8]*m[7]*m[14] - m[12]*m[6]*m[11] + m[12]*m[7]*m[10];
64
+ inv[8] = m[4]*m[9]*m[15] - m[4]*m[11]*m[13] - m[8]*m[5]*m[15]
65
+ + m[8]*m[7]*m[13] + m[12]*m[5]*m[11] - m[12]*m[7]*m[9];
66
+ inv[12] = -m[4]*m[9]*m[14] + m[4]*m[10]*m[13] + m[8]*m[5]*m[14]
67
+ - m[8]*m[6]*m[13] - m[12]*m[5]*m[10] + m[12]*m[6]*m[9];
68
+ inv[1] = -m[1]*m[10]*m[15] + m[1]*m[11]*m[14] + m[9]*m[2]*m[15]
69
+ - m[9]*m[3]*m[14] - m[13]*m[2]*m[11] + m[13]*m[3]*m[10];
70
+ inv[5] = m[0]*m[10]*m[15] - m[0]*m[11]*m[14] - m[8]*m[2]*m[15]
71
+ + m[8]*m[3]*m[14] + m[12]*m[2]*m[11] - m[12]*m[3]*m[10];
72
+ inv[9] = -m[0]*m[9]*m[15] + m[0]*m[11]*m[13] + m[8]*m[1]*m[15]
73
+ - m[8]*m[3]*m[13] - m[12]*m[1]*m[11] + m[12]*m[3]*m[9];
74
+ inv[13] = m[0]*m[9]*m[14] - m[0]*m[10]*m[13] - m[8]*m[1]*m[14]
75
+ + m[8]*m[2]*m[13] + m[12]*m[1]*m[10] - m[12]*m[2]*m[9];
76
+ inv[2] = m[1]*m[6]*m[15] - m[1]*m[7]*m[14] - m[5]*m[2]*m[15]
77
+ + m[5]*m[3]*m[14] + m[13]*m[2]*m[7] - m[13]*m[3]*m[6];
78
+ inv[6] = -m[0]*m[6]*m[15] + m[0]*m[7]*m[14] + m[4]*m[2]*m[15]
79
+ - m[4]*m[3]*m[14] - m[12]*m[2]*m[7] + m[12]*m[3]*m[6];
80
+ inv[10] = m[0]*m[5]*m[15] - m[0]*m[7]*m[13] - m[4]*m[1]*m[15]
81
+ + m[4]*m[3]*m[13] + m[12]*m[1]*m[7] - m[12]*m[3]*m[5];
82
+ inv[14] = -m[0]*m[5]*m[14] + m[0]*m[6]*m[13] + m[4]*m[1]*m[14]
83
+ - m[4]*m[2]*m[13] - m[12]*m[1]*m[6] + m[12]*m[2]*m[5];
84
+ inv[3] = -m[1]*m[6]*m[11] + m[1]*m[7]*m[10] + m[5]*m[2]*m[11]
85
+ - m[5]*m[3]*m[10] - m[9]*m[2]*m[7] + m[9]*m[3]*m[6];
86
+ inv[7] = m[0]*m[6]*m[11] - m[0]*m[7]*m[10] - m[4]*m[2]*m[11]
87
+ + m[4]*m[3]*m[10] + m[8]*m[2]*m[7] - m[8]*m[3]*m[6];
88
+ inv[11] = -m[0]*m[5]*m[11] + m[0]*m[7]*m[9] + m[4]*m[1]*m[11]
89
+ - m[4]*m[3]*m[9] - m[8]*m[1]*m[7] + m[8]*m[3]*m[5];
90
+ inv[15] = m[0]*m[5]*m[10] - m[0]*m[6]*m[9] - m[4]*m[1]*m[10]
91
+ + m[4]*m[2]*m[9] + m[8]*m[1]*m[6] - m[8]*m[2]*m[5];
92
+
93
+ det = m[0]*inv[0] + m[1]*inv[4] + m[2]*inv[8] + m[3]*inv[12];
94
+ if (det == 0)
95
+ return GL_FALSE;
96
+
97
+ det=1.0f/det;
98
+
99
+ for (i = 0; i < 16; i++)
100
+ invOut[i] = inv[i] * det;
101
+
102
+ return GL_TRUE;
103
+ }
104
+
105
+ // Based on glu implementation
106
+ GLint glProject(float objx, float objy, float objz,
107
+ const float * const modelMatrix,
108
+ const float * const projMatrix,
109
+ const GLint * const viewport,
110
+ float* winx, float* winy, float* winz)
111
+ {
112
+ float t1[4] = {objx, objy, objz, 1.0f};
113
+ float t2[4];
114
+
115
+ MatMul<4,4,1,float>(t2, modelMatrix, t1);
116
+ MatMul<4,4,1,float>(t1, projMatrix, t2);
117
+
118
+ if (t1[3] == 0.0) {
119
+ return(GL_FALSE);
120
+ }
121
+
122
+ // Normalise
123
+ t1[0]/=t1[3];
124
+ t1[1]/=t1[3];
125
+ t1[2]/=t1[3];
126
+
127
+ // Map x, y and z to range 0-1
128
+ t1[0]=t1[0]*0.5f+0.5f;
129
+ t1[1]=t1[1]*0.5f+0.5f;
130
+ t1[2]=t1[2]*0.5f+0.5f;
131
+
132
+ // Map x,y to viewport
133
+ t1[0]=t1[0] * viewport[2] + viewport[0];
134
+ t1[1]=t1[1] * viewport[3] + viewport[1];
135
+
136
+ *winx=t1[0];
137
+ *winy=t1[1];
138
+ *winz=t1[2];
139
+
140
+ return GL_TRUE;
141
+ }
142
+
143
+ // Based on glu implementation
144
+ GLint glUnProject(float winx, float winy, float winz,
145
+ const float * const mv,
146
+ const float * const proj,
147
+ const GLint * const viewport,
148
+ float* objx, float* objy, float* objz)
149
+ {
150
+ float t1[16];
151
+
152
+ MatMul<4,4,4,float>(t1, proj, mv);
153
+
154
+ if (!InvertMatrix<float>(t1, t1)) {
155
+ return(GL_FALSE);
156
+ }
157
+
158
+ // Map x and y from window coordinates
159
+ float in[4] = {winx, winy, winz, 1.0f};
160
+ in[0] = (in[0] - viewport[0]) / viewport[2];
161
+ in[1] = (in[1] - viewport[1]) / viewport[3];
162
+
163
+ // Map to range -1 to 1
164
+ in[0] = in[0] * 2 - 1;
165
+ in[1] = in[1] * 2 - 1;
166
+ in[2] = in[2] * 2 - 1;
167
+
168
+ float out[4];
169
+ MatMul<4,4,1,float>(out, t1, in);
170
+
171
+ if (out[3] == 0.0) {
172
+ return(GL_FALSE);
173
+ }
174
+
175
+ // Normalise
176
+ out[0] /= out[3];
177
+ out[1] /= out[3];
178
+ out[2] /= out[3];
179
+
180
+ // Copy out
181
+ *objx = out[0];
182
+ *objy = out[1];
183
+ *objz = out[2];
184
+
185
+ return GL_TRUE;
186
+ }
187
+
188
+ // Based on glu implementation
189
+ GLint glProject(double objx, double objy, double objz,
190
+ const double * const modelMatrix,
191
+ const double * const projMatrix,
192
+ const GLint * const viewport,
193
+ double* winx, double* winy, double* winz)
194
+ {
195
+ double t1[4] = {objx, objy, objz, 1.0f};
196
+ double t2[4];
197
+
198
+ MatMul<4,4,1,double>(t2, modelMatrix, t1);
199
+ MatMul<4,4,1,double>(t1, projMatrix, t2);
200
+
201
+ if (t1[3] == 0.0) {
202
+ return(GL_FALSE);
203
+ }
204
+
205
+ // Normalise
206
+ t1[0]/=t1[3];
207
+ t1[1]/=t1[3];
208
+ t1[2]/=t1[3];
209
+
210
+ // Map x, y and z to range 0-1
211
+ t1[0]=t1[0]*0.5f+0.5f;
212
+ t1[1]=t1[1]*0.5f+0.5f;
213
+ t1[2]=t1[2]*0.5f+0.5f;
214
+
215
+ // Map x,y to viewport
216
+ t1[0]=t1[0] * viewport[2] + viewport[0];
217
+ t1[1]=t1[1] * viewport[3] + viewport[1];
218
+
219
+ *winx=t1[0];
220
+ *winy=t1[1];
221
+ *winz=t1[2];
222
+
223
+ return GL_TRUE;
224
+ }
225
+
226
+ // Based on glu implementation
227
+ GLint glUnProject(double winx, double winy, double winz,
228
+ const double * const mv,
229
+ const double * const proj,
230
+ const GLint * const viewport,
231
+ double* objx, double* objy, double* objz)
232
+ {
233
+ double t1[16];
234
+
235
+ MatMul<4,4,4,double>(t1, proj, mv);
236
+
237
+ if (!InvertMatrix<double>(t1, t1)) {
238
+ return(GL_FALSE);
239
+ }
240
+
241
+ // Map x and y from window coordinates
242
+ double in[4] = {winx, winy, winz, 1.0f};
243
+ in[0] = (in[0] - viewport[0]) / viewport[2];
244
+ in[1] = (in[1] - viewport[1]) / viewport[3];
245
+
246
+ // Map to range -1 to 1
247
+ in[0] = in[0] * 2 - 1;
248
+ in[1] = in[1] * 2 - 1;
249
+ in[2] = in[2] * 2 - 1;
250
+
251
+ double out[4];
252
+ MatMul<4,4,1,double>(out, t1, in);
253
+
254
+ if (out[3] == 0.0) {
255
+ return(GL_FALSE);
256
+ }
257
+
258
+ // Normalise
259
+ out[0] /= out[3];
260
+ out[1] /= out[3];
261
+ out[2] /= out[3];
262
+
263
+ // Copy out
264
+ *objx = out[0];
265
+ *objy = out[1];
266
+ *objz = out[2];
267
+
268
+ return GL_TRUE;
269
+ }
270
+
271
+
272
+ }
third-party/DPVO/Pangolin/components/pango_opengl/src/gltext.cpp ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2013 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <pangolin/gl/gltext.h>
29
+ #include <pangolin/gl/glsl.h>
30
+
31
+ namespace pangolin
32
+ {
33
+
34
+ GlText::GlText()
35
+ : tex(NULL), width(0),
36
+ ymin(std::numeric_limits<GLfloat>::max()),
37
+ ymax(-std::numeric_limits<GLfloat>::max())
38
+ {
39
+
40
+ }
41
+
42
+ GlText::GlText(const GlText& txt)
43
+ : tex(txt.tex), str(txt.str), width(txt.width),
44
+ ymin(txt.ymin), ymax(txt.ymax), vs(txt.vs)
45
+ {
46
+ }
47
+
48
+ GlText::GlText(const GlTexture& font_tex)
49
+ : tex(&font_tex), width(0),
50
+ ymin(std::numeric_limits<GLfloat>::max()),
51
+ ymax(-std::numeric_limits<GLfloat>::max())
52
+ {
53
+ }
54
+
55
+ void GlText::AddSpace(GLfloat s)
56
+ {
57
+ width += s;
58
+ }
59
+
60
+ void GlText::Add(unsigned char c, const GlChar& glc)
61
+ {
62
+ GLfloat x = width;
63
+
64
+ vs.push_back(glc.GetVert(0) + x);
65
+ vs.push_back(glc.GetVert(1) + x);
66
+ vs.push_back(glc.GetVert(2) + x);
67
+ vs.push_back(glc.GetVert(0) + x);
68
+ vs.push_back(glc.GetVert(2) + x);
69
+ vs.push_back(glc.GetVert(3) + x);
70
+
71
+ ymin = std::min(ymin, glc.YMin());
72
+ ymax = std::max(ymax, glc.YMax());
73
+ width = x + glc.StepX();
74
+
75
+ str.append(1,c);
76
+ }
77
+
78
+ void GlText::Clear()
79
+ {
80
+ str.clear();
81
+ vs.clear();
82
+ width = 0;
83
+ ymin = +std::numeric_limits<GLfloat>::max();
84
+ ymax = -std::numeric_limits<GLfloat>::max();
85
+ }
86
+
87
+ void GlText::DrawGlSl() const
88
+ {
89
+ #if !defined(HAVE_GLES) || defined(HAVE_GLES_2)
90
+ if(vs.size() && tex) {
91
+ glEnableVertexAttribArray(pangolin::DEFAULT_LOCATION_POSITION);
92
+ glEnableVertexAttribArray(pangolin::DEFAULT_LOCATION_TEXCOORD);
93
+
94
+ glVertexAttribPointer(pangolin::DEFAULT_LOCATION_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(XYUV), &vs[0].x);
95
+ glVertexAttribPointer(pangolin::DEFAULT_LOCATION_TEXCOORD, 2, GL_FLOAT, GL_FALSE, sizeof(XYUV), &vs[0].tu);
96
+
97
+ tex->Bind();
98
+ glEnable(GL_TEXTURE_2D);
99
+ glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vs.size() );
100
+ glDisable(GL_TEXTURE_2D);
101
+
102
+ glDisableVertexAttribArray(pangolin::DEFAULT_LOCATION_POSITION);
103
+ glDisableVertexAttribArray(pangolin::DEFAULT_LOCATION_TEXCOORD);
104
+ }
105
+ #endif
106
+ }
107
+
108
+ void SetWindowOrthographic()
109
+ {
110
+ // We'll set an arbitrary viewport with known dimensions
111
+ // >= window dimensions so we can draw in pixel units.
112
+ GLint dims[2];
113
+ glGetIntegerv(GL_MAX_VIEWPORT_DIMS,dims);
114
+ glViewport(0,0,dims[0], dims[1]);
115
+
116
+ glMatrixMode(GL_PROJECTION);
117
+ ProjectionMatrixOrthographic(-0.5, dims[0]-0.5, -0.5, dims[1]-0.5, -1.0, 1.0).Load();
118
+ glMatrixMode(GL_MODELVIEW);
119
+ }
120
+
121
+ void GlText::Draw() const
122
+ {
123
+ if(vs.size() && tex) {
124
+ glVertexPointer(2, GL_FLOAT, sizeof(XYUV), &vs[0].x);
125
+ glEnableClientState(GL_VERTEX_ARRAY);
126
+ glTexCoordPointer(2, GL_FLOAT, sizeof(XYUV), &vs[0].tu);
127
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
128
+ tex->Bind();
129
+ glEnable(GL_TEXTURE_2D);
130
+ glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vs.size() );
131
+ glDisable(GL_TEXTURE_2D);
132
+ glDisableClientState(GL_VERTEX_ARRAY);
133
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
134
+ }
135
+ }
136
+
137
+ void GlText::Draw(GLfloat x, GLfloat y, GLfloat z) const
138
+ {
139
+ // find object point (x,y,z)' in pixel coords
140
+ GLdouble projection[16];
141
+ GLdouble modelview[16];
142
+ GLint view[4];
143
+ GLdouble scrn[3];
144
+
145
+ #ifdef HAVE_GLES_2
146
+ std::copy(glEngine().projection.top().m, glEngine().projection.top().m+16, projection);
147
+ std::copy(glEngine().modelview.top().m, glEngine().modelview.top().m+16, modelview);
148
+ #else
149
+ glGetDoublev(GL_PROJECTION_MATRIX, projection );
150
+ glGetDoublev(GL_MODELVIEW_MATRIX, modelview );
151
+ #endif
152
+ glGetIntegerv(GL_VIEWPORT, view );
153
+
154
+ pangolin::glProject(x, y, z, modelview, projection, view,
155
+ scrn, scrn + 1, scrn + 2);
156
+
157
+ // Save current state
158
+ glMatrixMode(GL_PROJECTION);
159
+ glPushMatrix();
160
+ glMatrixMode(GL_MODELVIEW);
161
+ glPushMatrix();
162
+
163
+ SetWindowOrthographic();
164
+ glTranslatef(std::floor((GLfloat)scrn[0]), std::floor((GLfloat)scrn[1]), (GLfloat)scrn[2]);
165
+ Draw();
166
+
167
+ // Restore viewport & matrices
168
+ glViewport(view[0],view[1],view[2],view[3]);
169
+ glMatrixMode(GL_PROJECTION);
170
+ glPopMatrix();
171
+ glMatrixMode(GL_MODELVIEW);
172
+ glPopMatrix();
173
+ }
174
+
175
+ // Render at (x,y) in window coordinates.
176
+ void GlText::DrawWindow(GLfloat x, GLfloat y, GLfloat z) const
177
+ {
178
+ // Backup viewport & matrices
179
+ GLint view[4];
180
+ glGetIntegerv(GL_VIEWPORT, view );
181
+ glMatrixMode(GL_PROJECTION);
182
+ glPushMatrix();
183
+ glMatrixMode(GL_MODELVIEW);
184
+ glPushMatrix();
185
+
186
+ SetWindowOrthographic();
187
+ glTranslatef( std::floor(x), std::floor(y), z);
188
+ Draw();
189
+
190
+ // Restore viewport & matrices
191
+ glViewport(view[0],view[1],view[2],view[3]);
192
+ glMatrixMode(GL_PROJECTION);
193
+ glPopMatrix();
194
+ glMatrixMode(GL_MODELVIEW);
195
+ glPopMatrix();
196
+ }
197
+
198
+ }
third-party/DPVO/Pangolin/components/pango_opengl/src/gltexturecache.cpp ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2013 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <pangolin/gl/gltexturecache.h>
29
+
30
+ namespace pangolin
31
+ {
32
+
33
+ TextureCache& TextureCache::I() {
34
+ static TextureCache instance;
35
+ return instance;
36
+ }
37
+
38
+ }
third-party/DPVO/Pangolin/components/pango_opengl/src/opengl_render_state.cpp ADDED
@@ -0,0 +1,707 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2011 Steven Lovegrove, Richard Newcombe
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <pangolin/gl/opengl_render_state.h>
29
+ #include <pangolin/gl/glinclude.h>
30
+
31
+ #include <stdexcept>
32
+
33
+ namespace pangolin
34
+ {
35
+
36
+ inline void glLoadMatrix(const float* m) { glLoadMatrixf(m); }
37
+ inline void glMultMatrix(const float* m) { glMultMatrixf(m); }
38
+
39
+ #ifndef HAVE_GLES
40
+ inline void glLoadMatrix(const double* m) { glLoadMatrixd(m); }
41
+ inline void glMultMatrix(const double* m) { glMultMatrixd(m); }
42
+ #endif
43
+
44
+ OpenGlMatrix OpenGlMatrix::Translate(GLprecision x, GLprecision y, GLprecision z)
45
+ {
46
+ OpenGlMatrix mat;
47
+ mat.SetIdentity();
48
+ mat(0, 3) = x;
49
+ mat(1, 3) = y;
50
+ mat(2, 3) = z;
51
+ return mat;
52
+ }
53
+
54
+ OpenGlMatrix OpenGlMatrix::Scale(GLprecision x, GLprecision y, GLprecision z)
55
+ {
56
+ OpenGlMatrix mat;
57
+ mat.SetIdentity();
58
+ mat(0, 0) = x;
59
+ mat(1, 1) = y;
60
+ mat(2, 2) = z;
61
+ return mat;
62
+ }
63
+
64
+ OpenGlMatrix OpenGlMatrix::RotateX(GLprecision theta_rad)
65
+ {
66
+ OpenGlMatrix mat;
67
+ mat.SetIdentity();
68
+ const GLprecision costh = cos(theta_rad);
69
+ const GLprecision sinth = sin(theta_rad);
70
+ mat(1, 1) = costh;
71
+ mat(1, 2) = -sinth;
72
+ mat(2, 1) = sinth;
73
+ mat(2, 2) = costh;
74
+ return mat;
75
+ }
76
+
77
+ OpenGlMatrix OpenGlMatrix::RotateY(GLprecision theta_rad)
78
+ {
79
+ OpenGlMatrix mat;
80
+ mat.SetIdentity();
81
+ const GLprecision costh = cos(theta_rad);
82
+ const GLprecision sinth = sin(theta_rad);
83
+ mat(0, 0) = costh;
84
+ mat(0, 2) = sinth;
85
+ mat(2, 0) = -sinth;
86
+ mat(2, 2) = costh;
87
+ return mat;
88
+ }
89
+
90
+ OpenGlMatrix OpenGlMatrix::RotateZ(GLprecision theta_rad)
91
+ {
92
+ OpenGlMatrix mat;
93
+ mat.SetIdentity();
94
+ const GLprecision costh = cos(theta_rad);
95
+ const GLprecision sinth = sin(theta_rad);
96
+ mat(0, 0) = costh;
97
+ mat(0, 1) = -sinth;
98
+ mat(1, 0) = sinth;
99
+ mat(1, 1) = costh;
100
+ return mat;
101
+ }
102
+
103
+ void OpenGlMatrix::Load() const
104
+ {
105
+ glLoadMatrix(m);
106
+ }
107
+
108
+ void OpenGlMatrix::Multiply() const
109
+ {
110
+ glMultMatrix(m);
111
+ }
112
+
113
+ void OpenGlMatrix::SetIdentity()
114
+ {
115
+ m[0] = 1.0f; m[1] = 0.0f; m[2] = 0.0f; m[3] = 0.0f;
116
+ m[4] = 0.0f; m[5] = 1.0f; m[6] = 0.0f; m[7] = 0.0f;
117
+ m[8] = 0.0f; m[9] = 0.0f; m[10] = 1.0f; m[11] = 0.0f;
118
+ m[12] = 0.0f; m[13] = 0.0f; m[14] = 0.0f; m[15] = 1.0f;
119
+ }
120
+
121
+ OpenGlMatrix OpenGlMatrix::Transpose() const
122
+ {
123
+ OpenGlMatrix trans;
124
+ trans.m[0] = m[0]; trans.m[4] = m[1]; trans.m[8] = m[2]; trans.m[12] = m[3];
125
+ trans.m[1] = m[4]; trans.m[5] = m[5]; trans.m[9] = m[6]; trans.m[13] = m[7];
126
+ trans.m[2] = m[8]; trans.m[6] = m[9]; trans.m[10] = m[10]; trans.m[14] = m[11];
127
+ trans.m[3] = m[12]; trans.m[7] = m[13]; trans.m[11] = m[14]; trans.m[15] = m[15];
128
+ return trans;
129
+ }
130
+
131
+ OpenGlMatrix OpenGlMatrix::Inverse() const
132
+ {
133
+ OpenGlMatrix inv;
134
+ inv.m[0] = m[0]; inv.m[4] = m[1]; inv.m[8] = m[2]; inv.m[12] = -(m[0]*m[12] + m[1]*m[13] + m[2]*m[14]);
135
+ inv.m[1] = m[4]; inv.m[5] = m[5]; inv.m[9] = m[6]; inv.m[13] = -(m[4]*m[12] + m[5]*m[13] + m[6]*m[14]);
136
+ inv.m[2] = m[8]; inv.m[6] = m[9]; inv.m[10] = m[10]; inv.m[14] = -(m[8]*m[12] + m[9]*m[13] + m[10]*m[14]);
137
+ inv.m[3] = 0; inv.m[7] = 0; inv.m[11] = 0; inv.m[15] = 1;
138
+ return inv;
139
+ }
140
+
141
+ std::ostream& operator<<(std::ostream& os, const OpenGlMatrix& mat)
142
+ {
143
+ for(int r=0; r< 4; ++r) {
144
+ for(int c=0; c<4; ++c) {
145
+ std::cout << mat.m[4*c+r] << '\t';
146
+ }
147
+ std::cout << std::endl;
148
+ }
149
+ return os;
150
+ }
151
+
152
+ void OpenGlRenderState::Apply() const
153
+ {
154
+ glMatrixMode(GL_PROJECTION);
155
+ projection[0].Load();
156
+
157
+ // Leave in MODEVIEW mode
158
+ glMatrixMode(GL_MODELVIEW);
159
+ modelview.Load();
160
+
161
+ if(follow) {
162
+ T_cw.Multiply();
163
+ }
164
+ }
165
+
166
+ OpenGlMatrix& OpenGlRenderState::GetProjectionMatrix(unsigned int view)
167
+ {
168
+ if( projection.size() <= view ) {
169
+ projection.resize(view+1);
170
+ }
171
+ return projection[view];
172
+ }
173
+
174
+ OpenGlMatrix OpenGlRenderState::GetProjectionMatrix(unsigned int view) const
175
+ {
176
+ if( projection.size() <= view ) {
177
+ return IdentityMatrix();
178
+ }
179
+ return projection[view];
180
+ }
181
+
182
+ OpenGlMatrix& OpenGlRenderState::GetViewOffset(unsigned int view)
183
+ {
184
+ if( modelview_premult.size() <= view ) {
185
+ modelview_premult.resize(view+1);
186
+ }
187
+ return modelview_premult[view];
188
+ }
189
+
190
+ OpenGlMatrix OpenGlRenderState::GetViewOffset(unsigned int view) const
191
+ {
192
+ if( modelview_premult.size() <= view ) {
193
+ return IdentityMatrix();
194
+ }
195
+ return modelview_premult[view];
196
+ }
197
+
198
+ void OpenGlRenderState::ApplyNView(int view) const
199
+ {
200
+ glMatrixMode(GL_PROJECTION);
201
+ projection[view].Load();
202
+
203
+ // Leave in MODEVIEW mode
204
+ glMatrixMode(GL_MODELVIEW);
205
+ OpenGlMatrix m = GetModelViewMatrix(view);
206
+ m.Load();
207
+
208
+ if(follow) {
209
+ T_cw.Multiply();
210
+ }
211
+ }
212
+
213
+ OpenGlRenderState::OpenGlRenderState()
214
+ : modelview(IdentityMatrix()), follow(false)
215
+ {
216
+ projection.push_back( IdentityMatrix() );
217
+ }
218
+
219
+ OpenGlRenderState::OpenGlRenderState(const OpenGlMatrix& projection_matrix)
220
+ : modelview(IdentityMatrix()), follow(false)
221
+ {
222
+ projection.push_back( projection_matrix );
223
+ }
224
+
225
+ OpenGlRenderState::OpenGlRenderState(const OpenGlMatrix& projection_matrix, const OpenGlMatrix& modelview_matrx)
226
+ : modelview(modelview_matrx), follow(false)
227
+ {
228
+ projection.push_back( projection_matrix );
229
+ }
230
+
231
+ void OpenGlRenderState::ApplyIdentity()
232
+ {
233
+ glMatrixMode(GL_PROJECTION);
234
+ glLoadIdentity();
235
+ glMatrixMode(GL_MODELVIEW);
236
+ glLoadIdentity();
237
+ }
238
+
239
+ OpenGlRenderState& OpenGlRenderState::SetProjectionMatrix(OpenGlMatrix m)
240
+ {
241
+ projection[0] = m;
242
+ return *this;
243
+ }
244
+
245
+ OpenGlRenderState& OpenGlRenderState::SetModelViewMatrix(OpenGlMatrix m)
246
+ {
247
+ modelview = m;
248
+ return *this;
249
+ }
250
+
251
+ OpenGlRenderState& OpenGlRenderState::Set(OpenGlMatrixSpec m)
252
+ {
253
+ switch (m.type) {
254
+ case GlProjectionStack:
255
+ projection[0] = m;
256
+ break;
257
+ case GlModelViewStack:
258
+ modelview = m;
259
+ break;
260
+ default:
261
+ throw std::runtime_error("Unexpected matrix type");
262
+ break;
263
+ }
264
+ return *this;
265
+ }
266
+
267
+ OpenGlMatrix operator*(const OpenGlMatrix& lhs, const OpenGlMatrix& rhs)
268
+ {
269
+ OpenGlMatrix ret;
270
+ pangolin::MatMul<4,4,4>(ret.m, lhs.m, rhs.m);
271
+ return ret;
272
+ }
273
+
274
+ OpenGlMatrix& OpenGlRenderState::GetProjectionMatrix()
275
+ {
276
+ // guarenteed to have at least one projection matrix element
277
+ return projection[0];
278
+ }
279
+
280
+ OpenGlMatrix OpenGlRenderState::GetProjectionMatrix() const
281
+ {
282
+ // guarenteed to have at least one projection matrix element
283
+ return projection[0];
284
+ }
285
+
286
+ OpenGlMatrix& OpenGlRenderState::GetModelViewMatrix()
287
+ {
288
+ return modelview;
289
+ }
290
+
291
+ OpenGlMatrix OpenGlRenderState::GetModelViewMatrix() const
292
+ {
293
+ return modelview;
294
+ }
295
+
296
+ OpenGlMatrix OpenGlRenderState::GetModelViewMatrix(int i) const
297
+ {
298
+ return modelview_premult[i] * modelview;
299
+ }
300
+
301
+ OpenGlMatrix OpenGlRenderState::GetProjectionModelViewMatrix() const
302
+ {
303
+ return GetProjectionMatrix() * GetModelViewMatrix();
304
+ }
305
+
306
+ OpenGlMatrix OpenGlRenderState::GetProjectiveTextureMatrix() const
307
+ {
308
+ return OpenGlMatrix::Translate(0.5,0.5,0.5) * OpenGlMatrix::Scale(0.5,0.5,0.5) * GetProjectionModelViewMatrix();
309
+ }
310
+
311
+ void OpenGlRenderState::EnableProjectiveTexturing() const
312
+ {
313
+ #ifndef HAVE_GLES
314
+ const pangolin::OpenGlMatrix projmattrans = GetProjectiveTextureMatrix().Transpose();
315
+ glEnable(GL_TEXTURE_GEN_S);
316
+ glEnable(GL_TEXTURE_GEN_T);
317
+ glEnable(GL_TEXTURE_GEN_R);
318
+ glEnable(GL_TEXTURE_GEN_Q);
319
+ glTexGendv(GL_S, GL_EYE_PLANE, projmattrans.m);
320
+ glTexGendv(GL_T, GL_EYE_PLANE, projmattrans.m+4);
321
+ glTexGendv(GL_R, GL_EYE_PLANE, projmattrans.m+8);
322
+ glTexGendv(GL_Q, GL_EYE_PLANE, projmattrans.m+12);
323
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
324
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
325
+ glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
326
+ glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
327
+ #endif
328
+ }
329
+
330
+ void OpenGlRenderState::DisableProjectiveTexturing() const
331
+ {
332
+ #ifndef HAVE_GLES
333
+ glDisable(GL_TEXTURE_GEN_S);
334
+ glDisable(GL_TEXTURE_GEN_T);
335
+ glDisable(GL_TEXTURE_GEN_R);
336
+ glDisable(GL_TEXTURE_GEN_Q);
337
+ #endif
338
+ }
339
+
340
+ void OpenGlRenderState::Follow(const OpenGlMatrix& T_wc, bool follow)
341
+ {
342
+ this->T_cw = T_wc.Inverse();
343
+
344
+ if(follow != this->follow) {
345
+ if(follow) {
346
+ const OpenGlMatrix T_vc = GetModelViewMatrix() * T_wc;
347
+ SetModelViewMatrix(T_vc);
348
+ this->follow = true;
349
+ }else{
350
+ Unfollow();
351
+ }
352
+ }
353
+ }
354
+
355
+ void OpenGlRenderState::Unfollow()
356
+ {
357
+ const OpenGlMatrix T_vw = GetModelViewMatrix() * T_cw;
358
+ SetModelViewMatrix(T_vw);
359
+ this->follow = false;
360
+ }
361
+
362
+ // Use OpenGl's default frame of reference
363
+ OpenGlMatrixSpec ProjectionMatrix(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar )
364
+ {
365
+ return ProjectionMatrixRUB_BottomLeft(w,h,fu,fv,u0,v0,zNear,zFar);
366
+ }
367
+
368
+ OpenGlMatrixSpec ProjectionMatrixOrthographic(GLprecision l, GLprecision r, GLprecision b, GLprecision t, GLprecision n, GLprecision f )
369
+ {
370
+ OpenGlMatrixSpec P;
371
+ P.type = GlProjectionStack;
372
+
373
+ P.m[0] = 2/(r-l);
374
+ P.m[1] = 0;
375
+ P.m[2] = 0;
376
+ P.m[3] = 0;
377
+
378
+ P.m[4] = 0;
379
+ P.m[5] = 2/(t-b);
380
+ P.m[6] = 0;
381
+ P.m[7] = 0;
382
+
383
+ P.m[8] = 0;
384
+ P.m[9] = 0;
385
+ P.m[10] = -2/(f-n);
386
+ P.m[11] = 0;
387
+
388
+ P.m[12] = -(r+l)/(r-l);
389
+ P.m[13] = -(t+b)/(t-b);
390
+ P.m[14] = -(f+n)/(f-n);
391
+ P.m[15] = 1;
392
+
393
+ return P;
394
+ }
395
+
396
+
397
+ // Camera Axis:
398
+ // X - Right, Y - Up, Z - Back
399
+ // Image Origin:
400
+ // Bottom Left
401
+ // Caution: Principal point defined with respect to image origin (0,0) at
402
+ // bottom left of bottom-left pixel (not center, and in different frame
403
+ // of reference to projection function image)
404
+ OpenGlMatrixSpec ProjectionMatrixRUB_BottomLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar )
405
+ {
406
+ // http://www.songho.ca/opengl/gl_projectionmatrix.html
407
+ const GLprecision L = +(u0) * zNear / -fu;
408
+ const GLprecision T = +(v0) * zNear / fv;
409
+ const GLprecision R = -(w-u0) * zNear / -fu;
410
+ const GLprecision B = -(h-v0) * zNear / fv;
411
+
412
+ OpenGlMatrixSpec P;
413
+ P.type = GlProjectionStack;
414
+ std::fill_n(P.m,4*4,0);
415
+
416
+ P.m[0*4+0] = 2 * zNear / (R-L);
417
+ P.m[1*4+1] = 2 * zNear / (T-B);
418
+ P.m[2*4+2] = -(zFar +zNear) / (zFar - zNear);
419
+ P.m[2*4+0] = (R+L)/(R-L);
420
+ P.m[2*4+1] = (T+B)/(T-B);
421
+ P.m[2*4+3] = -1.0;
422
+ P.m[3*4+2] = -(2*zFar*zNear)/(zFar-zNear);
423
+
424
+ return P;
425
+ }
426
+
427
+ // Camera Axis:
428
+ // X - Right, Y - Up, Z - Back
429
+ // Image Origin:
430
+ // Top Left
431
+ // Caution: Principal point defined with respect to image origin (0,0) at
432
+ // top left of top-left pixel (not center, and in different frame
433
+ // of reference to projection function image)
434
+ OpenGlMatrixSpec ProjectionMatrixRUB_TopLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar )
435
+ {
436
+ // http://www.songho.ca/opengl/gl_projectionmatrix.html
437
+ const GLprecision L = +(u0) * zNear / -fu;
438
+ const GLprecision R = -(w-u0) * zNear / -fu;
439
+ const GLprecision T = -(h-v0) * zNear / fv;
440
+ const GLprecision B = +(v0) * zNear / fv;
441
+
442
+ OpenGlMatrixSpec P;
443
+ P.type = GlProjectionStack;
444
+ std::fill_n(P.m,4*4,0);
445
+
446
+ P.m[0*4+0] = 2 * zNear / (R-L);
447
+ P.m[1*4+1] = 2 * zNear / (T-B);
448
+ P.m[2*4+2] = -(zFar +zNear) / (zFar - zNear);
449
+ P.m[2*4+0] = (R+L)/(R-L);
450
+ P.m[2*4+1] = (T+B)/(T-B);
451
+ P.m[2*4+3] = -1.0;
452
+ P.m[3*4+2] = -(2*zFar*zNear)/(zFar-zNear);
453
+
454
+ return P;
455
+ }
456
+
457
+ // Camera Axis:
458
+ // X - Right, Y - Down, Z - Forward
459
+ // Image Origin:
460
+ // Top Left
461
+ // Pricipal point specified with image origin (0,0) at top left of top-left pixel (not center)
462
+ OpenGlMatrixSpec ProjectionMatrixRDF_TopLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar )
463
+ {
464
+ // http://www.songho.ca/opengl/gl_projectionmatrix.html
465
+ const GLprecision L = -(u0) * zNear / fu;
466
+ const GLprecision R = +(w-u0) * zNear / fu;
467
+ const GLprecision T = -(v0) * zNear / fv;
468
+ const GLprecision B = +(h-v0) * zNear / fv;
469
+
470
+ OpenGlMatrixSpec P;
471
+ P.type = GlProjectionStack;
472
+ std::fill_n(P.m,4*4,0);
473
+
474
+ P.m[0*4+0] = 2 * zNear / (R-L);
475
+ P.m[1*4+1] = 2 * zNear / (T-B);
476
+
477
+ P.m[2*4+0] = (R+L)/(L-R);
478
+ P.m[2*4+1] = (T+B)/(B-T);
479
+ P.m[2*4+2] = (zFar +zNear) / (zFar - zNear);
480
+ P.m[2*4+3] = 1.0;
481
+
482
+ P.m[3*4+2] = (2*zFar*zNear)/(zNear - zFar);
483
+ return P;
484
+ }
485
+
486
+ // Camera Axis:
487
+ // X - Right, Y - Down, Z - Forward
488
+ // Image Origin:
489
+ // Top Right
490
+ // Pricipal point specified with image origin (0,0) at top right of top-right pixel (not center)
491
+ OpenGlMatrixSpec ProjectionMatrixRDF_TopRight(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar )
492
+ {
493
+ // http://www.songho.ca/opengl/gl_projectionmatrix.html
494
+ const GLprecision L = +(w-u0) * zNear / fu;
495
+ const GLprecision R = -(u0) * zNear / fu;
496
+ const GLprecision T = -(v0) * zNear / fv;
497
+ const GLprecision B = +(h-v0) * zNear / fv;
498
+
499
+ OpenGlMatrixSpec P;
500
+ P.type = GlProjectionStack;
501
+ std::fill_n(P.m,4*4,0);
502
+
503
+ P.m[0*4+0] = 2 * zNear / (R-L);
504
+ P.m[1*4+1] = 2 * zNear / (T-B);
505
+
506
+ P.m[2*4+0] = (R+L)/(L-R);
507
+ P.m[2*4+1] = (T+B)/(B-T);
508
+ P.m[2*4+2] = (zFar +zNear) / (zFar - zNear);
509
+ P.m[2*4+3] = 1.0;
510
+
511
+ P.m[3*4+2] = (2*zFar*zNear)/(zNear - zFar);
512
+ return P;
513
+ }
514
+
515
+ // Camera Axis:
516
+ // X - Right, Y - Down, Z - Forward
517
+ // Image Origin:
518
+ // Bottom Left
519
+ // Pricipal point specified with image origin (0,0) at bottom left of bottom-left pixel (not center)
520
+ OpenGlMatrixSpec ProjectionMatrixRDF_BottomLeft(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar )
521
+ {
522
+ // http://www.songho.ca/opengl/gl_projectionmatrix.html
523
+ const GLprecision L = -(u0) * zNear / fu;
524
+ const GLprecision R = +(w-u0) * zNear / fu;
525
+ const GLprecision B = -(v0) * zNear / fv;
526
+ const GLprecision T = +(h-v0) * zNear / fv;
527
+
528
+ OpenGlMatrixSpec P;
529
+ P.type = GlProjectionStack;
530
+ std::fill_n(P.m,4*4,0);
531
+
532
+ P.m[0*4+0] = 2 * zNear / (R-L);
533
+ P.m[1*4+1] = 2 * zNear / (T-B);
534
+
535
+ P.m[2*4+0] = (R+L)/(L-R);
536
+ P.m[2*4+1] = (T+B)/(B-T);
537
+ P.m[2*4+2] = (zFar +zNear) / (zFar - zNear);
538
+ P.m[2*4+3] = 1.0;
539
+
540
+ P.m[3*4+2] = (2*zFar*zNear)/(zNear - zFar);
541
+ return P;
542
+ }
543
+
544
+ // Camera Axis:
545
+ // X - Right, Y - Down, Z - Forward
546
+ // Image Origin:
547
+ // Bottom Right
548
+ // Pricipal point specified with image origin (0,0) at bottom right of bottom-right pixel (not center)
549
+ OpenGlMatrixSpec ProjectionMatrixRDF_BottomRight(int w, int h, GLprecision fu, GLprecision fv, GLprecision u0, GLprecision v0, GLprecision zNear, GLprecision zFar )
550
+ {
551
+ // http://www.songho.ca/opengl/gl_projectionmatrix.html
552
+ const GLprecision R = -(u0) * zNear / fu;
553
+ const GLprecision L = +(w-u0) * zNear / fu;
554
+ const GLprecision B = -(v0) * zNear / fv;
555
+ const GLprecision T = +(h-v0) * zNear / fv;
556
+
557
+ OpenGlMatrixSpec P;
558
+ P.type = GlProjectionStack;
559
+ std::fill_n(P.m,4*4,0);
560
+
561
+ P.m[0*4+0] = 2 * zNear / (R-L);
562
+ P.m[1*4+1] = 2 * zNear / (T-B);
563
+
564
+ P.m[2*4+0] = (R+L)/(L-R);
565
+ P.m[2*4+1] = (T+B)/(B-T);
566
+ P.m[2*4+2] = (zFar +zNear) / (zFar - zNear);
567
+ P.m[2*4+3] = 1.0;
568
+
569
+ P.m[3*4+2] = (2*zFar*zNear)/(zNear - zFar);
570
+ return P;
571
+ }
572
+
573
+ OpenGlMatrix ModelViewLookAtRUB(GLprecision ex, GLprecision ey, GLprecision ez, GLprecision lx, GLprecision ly, GLprecision lz, GLprecision ux, GLprecision uy, GLprecision uz)
574
+ {
575
+ OpenGlMatrix mat;
576
+ GLprecision* m = mat.m;
577
+
578
+ const GLprecision u_o[3] = {ux,uy,uz};
579
+
580
+ GLprecision x[3], y[3];
581
+ GLprecision z[] = {ex - lx, ey - ly, ez - lz};
582
+ Normalise<3>(z);
583
+
584
+ CrossProduct(x,u_o,z);
585
+ CrossProduct(y,z,x);
586
+
587
+ // Normalize x, y
588
+ const GLprecision lenx = Length<3>(x);
589
+ const GLprecision leny = Length<3>(y);
590
+
591
+ if( lenx > 0 && leny > 0) {
592
+ for(size_t r = 0; r < 3; ++r ) {
593
+ x[r] /= lenx;
594
+ y[r] /= leny;
595
+ }
596
+ #define M(row,col) m[col*4+row]
597
+ M(0,0) = x[0];
598
+ M(0,1) = x[1];
599
+ M(0,2) = x[2];
600
+ M(1,0) = y[0];
601
+ M(1,1) = y[1];
602
+ M(1,2) = y[2];
603
+ M(2,0) = z[0];
604
+ M(2,1) = z[1];
605
+ M(2,2) = z[2];
606
+ M(3,0) = 0.0;
607
+ M(3,1) = 0.0;
608
+ M(3,2) = 0.0;
609
+ M(0,3) = -(M(0,0)*ex + M(0,1)*ey + M(0,2)*ez);
610
+ M(1,3) = -(M(1,0)*ex + M(1,1)*ey + M(1,2)*ez);
611
+ M(2,3) = -(M(2,0)*ex + M(2,1)*ey + M(2,2)*ez);
612
+ M(3,3) = 1.0;
613
+ #undef M
614
+ return mat;
615
+ }else{
616
+ throw std::invalid_argument("'Look' and 'up' vectors cannot be parallel when calling ModelViewLookAt.");
617
+ }
618
+
619
+ }
620
+
621
+ OpenGlMatrix ModelViewLookAtRDF(GLprecision ex, GLprecision ey, GLprecision ez, GLprecision lx, GLprecision ly, GLprecision lz, GLprecision ux, GLprecision uy, GLprecision uz)
622
+ {
623
+ OpenGlMatrix mat;
624
+ GLprecision* m = mat.m;
625
+
626
+ const GLprecision u_o[3] = {ux,uy,uz};
627
+
628
+ GLprecision x[3], y[3];
629
+ GLprecision z[] = {lx - ex, ly - ey, lz - ez};
630
+ Normalise<3>(z);
631
+
632
+ CrossProduct(x,z,u_o);
633
+ CrossProduct(y,z,x);
634
+
635
+ // Normalize x, y
636
+ const GLprecision lenx = Length<3>(x);
637
+ const GLprecision leny = Length<3>(y);
638
+
639
+ if( lenx > 0 && leny > 0) {
640
+ for(size_t r = 0; r < 3; ++r ) {
641
+ x[r] /= lenx;
642
+ y[r] /= leny;
643
+ }
644
+ #define M(row,col) m[col*4+row]
645
+ M(0,0) = x[0];
646
+ M(0,1) = x[1];
647
+ M(0,2) = x[2];
648
+ M(1,0) = y[0];
649
+ M(1,1) = y[1];
650
+ M(1,2) = y[2];
651
+ M(2,0) = z[0];
652
+ M(2,1) = z[1];
653
+ M(2,2) = z[2];
654
+ M(3,0) = 0.0;
655
+ M(3,1) = 0.0;
656
+ M(3,2) = 0.0;
657
+ M(0,3) = -(M(0,0)*ex + M(0,1)*ey + M(0,2)*ez);
658
+ M(1,3) = -(M(1,0)*ex + M(1,1)*ey + M(1,2)*ez);
659
+ M(2,3) = -(M(2,0)*ex + M(2,1)*ey + M(2,2)*ez);
660
+ M(3,3) = 1.0;
661
+ #undef M
662
+ return mat;
663
+ }else{
664
+ throw std::invalid_argument("'Look' and 'up' vectors cannot be parallel when calling ModelViewLookAt.");
665
+ }
666
+ }
667
+
668
+ OpenGlMatrix ModelViewLookAt(GLprecision ex, GLprecision ey, GLprecision ez, GLprecision lx, GLprecision ly, GLprecision lz, GLprecision ux, GLprecision uy, GLprecision uz)
669
+ {
670
+ return ModelViewLookAtRUB(ex,ey,ez,lx,ly,lz,ux,uy,uz);
671
+ }
672
+
673
+ OpenGlMatrix ModelViewLookAt(GLprecision ex, GLprecision ey, GLprecision ez, GLprecision lx, GLprecision ly, GLprecision lz, AxisDirection up)
674
+ {
675
+ const GLprecision* u = AxisDirectionVector[up];
676
+ return ModelViewLookAtRUB(ex,ey,ez,lx,ly,lz,u[0],u[1],u[2]);
677
+ }
678
+
679
+ OpenGlMatrix IdentityMatrix()
680
+ {
681
+ OpenGlMatrix P;
682
+ std::fill_n(P.m,4*4,0);
683
+ for( int i=0; i<4; ++i ) P.m[i*4+i] = 1;
684
+ return P;
685
+ }
686
+
687
+ OpenGlMatrixSpec IdentityMatrix(OpenGlStack type)
688
+ {
689
+ OpenGlMatrixSpec P;
690
+ P.type = type;
691
+ std::fill_n(P.m,4*4,0);
692
+ for( int i=0; i<4; ++i ) P.m[i*4+i] = 1;
693
+ return P;
694
+ }
695
+
696
+ OpenGlMatrixSpec negIdentityMatrix(OpenGlStack type)
697
+ {
698
+ OpenGlMatrixSpec P;
699
+ P.type = type;
700
+ std::fill_n(P.m,4*4,0);
701
+ for( int i=0; i<4; ++i ) P.m[i*4+i] = -1;
702
+
703
+ P.m[3*4+3] =1;
704
+ return P;
705
+ }
706
+
707
+ }
third-party/DPVO/Pangolin/components/pango_opengl/src/stb_truetype.h ADDED
The diff for this file is too large to render. See raw diff
 
third-party/DPVO/Pangolin/components/pango_opengl/src/viewport.cpp ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2013 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <algorithm>
29
+ #include <pangolin/gl/viewport.h>
30
+ #include <pangolin/gl/opengl_render_state.h>
31
+ #include <pangolin/utils/simple_math.h>
32
+
33
+ namespace pangolin {
34
+
35
+ void Viewport::Activate() const
36
+ {
37
+ glViewport(l,b,w,h);
38
+ }
39
+
40
+ void Viewport::Scissor() const
41
+ {
42
+ glEnable(GL_SCISSOR_TEST);
43
+ glScissor(l,b,w,h);
44
+ }
45
+
46
+ void Viewport::ActivateAndScissor() const
47
+ {
48
+ glViewport(l,b,w,h);
49
+ glEnable(GL_SCISSOR_TEST);
50
+ glScissor(l,b,w,h);
51
+ }
52
+
53
+
54
+ void Viewport::DisableScissor()
55
+ {
56
+ glDisable(GL_SCISSOR_TEST);
57
+ }
58
+
59
+ bool Viewport::Contains(int x, int y) const
60
+ {
61
+ return l <= x && x < (l+w) && b <= y && y < (b+h);
62
+ }
63
+
64
+ void Viewport::ActivatePixelOrthographic() const
65
+ {
66
+ Activate();
67
+ glMatrixMode(GL_PROJECTION);
68
+ ProjectionMatrixOrthographic(-0.5, w-0.5, -0.5, h-0.5, -1.0, 1.0).Load();
69
+ glMatrixMode(GL_MODELVIEW);
70
+ glLoadIdentity();
71
+ }
72
+
73
+ void Viewport::ActivateIdentity() const
74
+ {
75
+ Activate();
76
+ glMatrixMode(GL_PROJECTION);
77
+ glLoadIdentity();
78
+ glMatrixMode(GL_MODELVIEW);
79
+ glLoadIdentity();
80
+ }
81
+
82
+
83
+ Viewport Viewport::Inset(int i) const
84
+ {
85
+ return Viewport(l+i, b+i, w-2*i, h-2*i);
86
+ }
87
+
88
+ Viewport Viewport::Inset(int horiz, int vert) const
89
+ {
90
+ return Viewport(l+horiz, b+vert, w-horiz, h-vert);
91
+ }
92
+
93
+ Viewport Viewport::Intersect(const Viewport& vp) const
94
+ {
95
+ GLint nl = std::max(l,vp.l);
96
+ GLint nr = std::min(r(),vp.r());
97
+ GLint nb = std::max(b,vp.b);
98
+ GLint nt = std::min(t(),vp.t());
99
+ return Viewport(nl,nb, nr-nl, nt-nb);
100
+ }
101
+
102
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/CMakeLists.txt ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ get_filename_component(COMPONENT ${CMAKE_CURRENT_LIST_DIR} NAME)
2
+
3
+ target_sources( ${COMPONENT}
4
+ PRIVATE
5
+ ${CMAKE_CURRENT_LIST_DIR}/src/packet.cpp
6
+ ${CMAKE_CURRENT_LIST_DIR}/src/packetstream.cpp
7
+ ${CMAKE_CURRENT_LIST_DIR}/src/packetstream_reader.cpp
8
+ ${CMAKE_CURRENT_LIST_DIR}/src/packetstream_writer.cpp
9
+ ${CMAKE_CURRENT_LIST_DIR}/src/playback_session.cpp
10
+ )
11
+
12
+ target_compile_definitions(${COMPONENT} PRIVATE "PANGOLIN_VERSION_STRING=\"${PANGOLIN_VERSION}\"")
13
+ target_link_libraries(${COMPONENT} PUBLIC pango_core)
14
+ target_include_directories(${COMPONENT} PUBLIC
15
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
16
+ $<INSTALL_INTERFACE:include>
17
+ )
18
+ install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/include"
19
+ DESTINATION ${CMAKE_INSTALL_PREFIX}
20
+ )
third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packet.h ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person
5
+ * obtaining a copy of this software and associated documentation
6
+ * files (the "Software"), to deal in the Software without
7
+ * restriction, including without limitation the rights to use,
8
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the
10
+ * Software is furnished to do so, subject to the following
11
+ * conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ * OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+ #pragma once
27
+
28
+ #include <mutex>
29
+
30
+ #include <pangolin/log/packetstream.h>
31
+ #include <pangolin/log/packetstream_source.h>
32
+
33
+ namespace pangolin {
34
+
35
+ // Encapsulate serialized reading of Packet from stream.
36
+ struct PANGOLIN_EXPORT Packet
37
+ {
38
+ Packet(PacketStream& s, std::unique_lock<std::recursive_mutex>&& mutex, std::vector<PacketStreamSource>& srcs);
39
+ Packet(const Packet&) = delete;
40
+ Packet(Packet&& o);
41
+ ~Packet();
42
+
43
+ size_t BytesRead() const;
44
+ int BytesRemaining() const;
45
+
46
+ PacketStream& Stream()
47
+ {
48
+ return _stream;
49
+ }
50
+
51
+ PacketStreamSourceId src;
52
+ int64_t time;
53
+ size_t size;
54
+ size_t sequence_num;
55
+ picojson::value meta;
56
+ std::streampos frame_streampos;
57
+
58
+ private:
59
+ void ParsePacketHeader(PacketStream& s, std::vector<PacketStreamSource>& srcs);
60
+ void ReadRemaining();
61
+
62
+ PacketStream& _stream;
63
+
64
+ std::unique_lock<std::recursive_mutex> lock;
65
+
66
+ std::streampos data_streampos;
67
+ size_t _data_len;
68
+ };
69
+
70
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream.h ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person
5
+ * obtaining a copy of this software and associated documentation
6
+ * files (the "Software"), to deal in the Software without
7
+ * restriction, including without limitation the rights to use,
8
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the
10
+ * Software is furnished to do so, subject to the following
11
+ * conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ * OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+ #pragma once
27
+
28
+ #include <fstream>
29
+
30
+ #include <pangolin/platform.h>
31
+
32
+ #include <pangolin/log/packetstream_tags.h>
33
+ #include <pangolin/utils/file_utils.h>
34
+
35
+ namespace pangolin
36
+ {
37
+
38
+ class PANGOLIN_EXPORT PacketStream: public std::ifstream
39
+ {
40
+ public:
41
+ PacketStream()
42
+ : _is_pipe(false)
43
+ {
44
+ cclear();
45
+ }
46
+
47
+ PacketStream(const std::string& filename)
48
+ : Base(filename.c_str(), std::ios::in | std::ios::binary),
49
+ _is_pipe(IsPipe(filename))
50
+ {
51
+ cclear();
52
+ }
53
+
54
+ bool seekable() const
55
+ {
56
+ return is_open() && !_is_pipe;
57
+ }
58
+
59
+ void open(const std::string& filename)
60
+ {
61
+ close();
62
+ _is_pipe = IsPipe(filename);
63
+ Base::open(filename.c_str(), std::ios::in | std::ios::binary);
64
+ }
65
+
66
+ void close()
67
+ {
68
+ cclear();
69
+ if (Base::is_open()) Base::close();
70
+ }
71
+
72
+ void seekg(std::streampos target);
73
+
74
+ void seekg(std::streamoff off, std::ios_base::seekdir way);
75
+
76
+ std::streampos tellg();
77
+
78
+ size_t read(char* target, size_t len);
79
+
80
+ char get();
81
+
82
+ size_t skip(size_t len);
83
+
84
+ size_t readUINT();
85
+
86
+ int64_t readTimestamp();
87
+
88
+ PangoTagType peekTag();
89
+
90
+ PangoTagType readTag();
91
+
92
+ PangoTagType readTag(PangoTagType);
93
+
94
+ PangoTagType syncToTag();
95
+
96
+ private:
97
+ using Base = std::ifstream;
98
+
99
+ bool _is_pipe;
100
+ PangoTagType _tag;
101
+
102
+ // Amount of frame data left to read. Tracks our position within a data block.
103
+
104
+
105
+ void cclear() {
106
+ _tag = 0;
107
+ }
108
+ };
109
+
110
+
111
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_reader.h ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person
5
+ * obtaining a copy of this software and associated documentation
6
+ * files (the "Software"), to deal in the Software without
7
+ * restriction, including without limitation the rights to use,
8
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the
10
+ * Software is furnished to do so, subject to the following
11
+ * conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ * OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+ #pragma once
27
+
28
+ #include <fstream>
29
+ #include <mutex>
30
+ #include <thread>
31
+
32
+ #include <pangolin/log/packet.h>
33
+
34
+ #include <pangolin/log/sync_time.h>
35
+ #include <pangolin/utils/file_utils.h>
36
+ #include <pangolin/utils/timer.h>
37
+
38
+ namespace pangolin
39
+ {
40
+
41
+ class PANGOLIN_EXPORT PacketStreamReader
42
+ {
43
+ public:
44
+ PacketStreamReader();
45
+
46
+ PacketStreamReader(const std::string& filename);
47
+
48
+ ~PacketStreamReader();
49
+
50
+ void Open(const std::string& filename);
51
+
52
+ void Close();
53
+
54
+ const std::vector<PacketStreamSource>&
55
+ Sources() const
56
+ {
57
+ return _sources;
58
+ }
59
+
60
+ // Grab Next available frame packetstream
61
+ Packet NextFrame();
62
+
63
+ // Grab Next available frame in packetstream from src, discarding other frames.
64
+ Packet NextFrame(PacketStreamSourceId src);
65
+
66
+ bool Good() const
67
+ {
68
+ return _stream.good();
69
+ }
70
+
71
+ // Jumps to a particular packet.
72
+ size_t Seek(PacketStreamSourceId src, size_t framenum);
73
+
74
+ // Jumps to the first packet with time >= time
75
+ size_t Seek(PacketStreamSourceId src, SyncTime::TimePoint time);
76
+
77
+ void FixFileIndex();
78
+
79
+ private:
80
+ bool GoodToRead();
81
+
82
+ bool SetupIndex();
83
+
84
+ void ParseHeader();
85
+
86
+ void ParseNewSource();
87
+
88
+ bool ParseIndex();
89
+
90
+ void RebuildIndex();
91
+
92
+ void AppendIndex();
93
+
94
+ std::streampos ParseFooter();
95
+
96
+ void SkipSync();
97
+
98
+ void ReSync() {
99
+ _stream.syncToTag();
100
+ }
101
+
102
+ std::string _filename;
103
+ std::vector<PacketStreamSource> _sources;
104
+ SyncTime::TimePoint packet_stream_start;
105
+
106
+ PacketStream _stream;
107
+ std::recursive_mutex _mutex;
108
+
109
+ bool _is_pipe;
110
+ int _pipe_fd;
111
+ };
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_source.h ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #pragma once
2
+
3
+ #include <iostream>
4
+ #include <pangolin/platform.h>
5
+ #include <pangolin/utils/picojson.h>
6
+
7
+ namespace pangolin {
8
+
9
+ using PacketStreamSourceId = size_t;
10
+
11
+ struct PANGOLIN_EXPORT PacketStreamSource
12
+ {
13
+ struct PacketInfo
14
+ {
15
+ std::streampos pos;
16
+ int64_t capture_time;
17
+ };
18
+
19
+ PacketStreamSource()
20
+ : id(static_cast<PacketStreamSourceId>(-1)),
21
+ version(0),
22
+ data_alignment_bytes(1),
23
+ data_size_bytes(0),
24
+ next_packet_id(0)
25
+ {
26
+ }
27
+
28
+ std::streampos FindSeekLocation(size_t packet_id)
29
+ {
30
+ if(packet_id < index.size()) {
31
+ return index[packet_id].pos;
32
+ }else{
33
+ return std::streampos(-1);
34
+ }
35
+
36
+ }
37
+
38
+ int64_t NextPacketTime() const
39
+ {
40
+ if(next_packet_id < index.size()) {
41
+ return index[next_packet_id].capture_time;
42
+ }else{
43
+ return 0;
44
+ }
45
+ }
46
+
47
+ std::string driver;
48
+ size_t id;
49
+ std::string uri;
50
+ picojson::value info;
51
+ int64_t version;
52
+ int64_t data_alignment_bytes;
53
+ std::string data_definitions;
54
+ int64_t data_size_bytes;
55
+
56
+ // Index keyed by packet_id
57
+ std::vector<PacketInfo> index;
58
+
59
+ // Based on current position in stream
60
+ size_t next_packet_id;
61
+ };
62
+
63
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_tags.h ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #pragma once
2
+
3
+ #include <string>
4
+
5
+ namespace pangolin {
6
+
7
+ using PangoTagType = uint32_t;
8
+
9
+ const static std::string PANGO_MAGIC = "PANGO";
10
+
11
+ const static std::string pss_src_driver = "driver";
12
+ const static std::string pss_src_id = "id";
13
+ const static std::string pss_src_info = "info";
14
+ const static std::string pss_src_uri = "uri";
15
+ const static std::string pss_src_packet = "packet";
16
+ const static std::string pss_src_version = "version";
17
+ const static std::string pss_pkt_alignment_bytes = "alignment_bytes";
18
+ const static std::string pss_pkt_definitions = "definitions";
19
+ const static std::string pss_pkt_size_bytes = "size_bytes";
20
+ const static std::string pss_pkt_format_written = "format_written";
21
+
22
+ const unsigned int TAG_LENGTH = 3;
23
+
24
+ #define PANGO_TAG(a,b,c) ( (c<<16) | (b<<8) | a)
25
+ const PangoTagType TAG_PANGO_HDR = PANGO_TAG('L', 'I', 'N');
26
+ const PangoTagType TAG_PANGO_MAGIC = PANGO_TAG('P', 'A', 'N');
27
+ const PangoTagType TAG_PANGO_SYNC = PANGO_TAG('S', 'Y', 'N');
28
+ const PangoTagType TAG_PANGO_STATS = PANGO_TAG('S', 'T', 'A');
29
+ const PangoTagType TAG_PANGO_FOOTER = PANGO_TAG('F', 'T', 'R');
30
+ const PangoTagType TAG_ADD_SOURCE = PANGO_TAG('S', 'R', 'C');
31
+ const PangoTagType TAG_SRC_JSON = PANGO_TAG('J', 'S', 'N');
32
+ const PangoTagType TAG_SRC_PACKET = PANGO_TAG('P', 'K', 'T');
33
+ const PangoTagType TAG_END = PANGO_TAG('E', 'N', 'D');
34
+ #undef PANGO_TAG
35
+
36
+ inline std::string tagName(int v)
37
+ {
38
+ char b[4];
39
+ b[0] = v&0xff;
40
+ b[1] = (v>>8)&0xff;
41
+ b[2] = (v>>16)&0xff;
42
+ b[3] = 0x00;
43
+ return std::string(b);
44
+ }
45
+
46
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_writer.h ADDED
@@ -0,0 +1,173 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person
5
+ * obtaining a copy of this software and associated documentation
6
+ * files (the "Software"), to deal in the Software without
7
+ * restriction, including without limitation the rights to use,
8
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the
10
+ * Software is furnished to do so, subject to the following
11
+ * conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ * OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+ #pragma once
27
+
28
+ #include <ostream>
29
+
30
+ #include <pangolin/log/packetstream.h>
31
+ #include <pangolin/log/packetstream_source.h>
32
+ #include <pangolin/utils/file_utils.h>
33
+ #include <pangolin/utils/threadedfilebuf.h>
34
+
35
+ namespace pangolin
36
+ {
37
+
38
+ class PANGOLIN_EXPORT PacketStreamWriter
39
+ {
40
+ public:
41
+ PacketStreamWriter()
42
+ : _stream(&_buffer), _indexable(false), _open(false), _bytes_written(0)
43
+ {
44
+ _stream.exceptions(std::ostream::badbit);
45
+ }
46
+
47
+ PacketStreamWriter(const std::string& filename, size_t buffer_size = 100*1024*1024)
48
+ : _buffer(pangolin::PathExpand(filename), buffer_size), _stream(&_buffer),
49
+ _indexable(!IsPipe(filename)), _open(_stream.good()), _bytes_written(0)
50
+ {
51
+ _stream.exceptions(std::ostream::badbit);
52
+ WriteHeader();
53
+ }
54
+
55
+ ~PacketStreamWriter() {
56
+ Close();
57
+ }
58
+
59
+ void Open(const std::string& filename, size_t buffer_size = 100 * 1024 * 1024)
60
+ {
61
+ Close();
62
+ _buffer.open(filename, buffer_size);
63
+ _open = _stream.good();
64
+ _bytes_written = 0;
65
+ _indexable = !IsPipe(filename);
66
+ WriteHeader();
67
+ }
68
+
69
+ void Close()
70
+ {
71
+ if (_open)
72
+ {
73
+ if (_indexable) {
74
+ WriteEnd();
75
+ }
76
+ _buffer.close();
77
+ _open = false;
78
+ }
79
+ }
80
+
81
+ // Does not write footer or index.
82
+ void ForceClose()
83
+ {
84
+ if (_open)
85
+ {
86
+ _buffer.force_close();
87
+ Close();
88
+ }
89
+ }
90
+
91
+
92
+ // Writes to the stream immediately upon add. Return source id # and writes
93
+ // source id # to argument struct
94
+ PacketStreamSourceId AddSource(PacketStreamSource& source);
95
+
96
+ // If constructor is called inline
97
+ PacketStreamSourceId AddSource(const PacketStreamSource& source);
98
+
99
+ void WriteSourcePacket(
100
+ PacketStreamSourceId src, const char* source,const int64_t receive_time_us,
101
+ size_t sourcelen, const picojson::value& meta = picojson::value()
102
+ );
103
+
104
+ // For stream read/write synchronization. Note that this is NOT the same as
105
+ // time synchronization on playback of iPacketStreams.
106
+ void WriteSync();
107
+
108
+ // Writes the end of the stream data, including the index. Does NOT close
109
+ // the underlying ostream.
110
+ void WriteEnd();
111
+
112
+ const std::vector<PacketStreamSource>& Sources() const {
113
+ return _sources;
114
+ }
115
+
116
+ bool IsOpen() const {
117
+ return _open;
118
+ }
119
+
120
+ private:
121
+ void WriteHeader();
122
+ void Write(const PacketStreamSource&);
123
+ void WriteMeta(PacketStreamSourceId src, const picojson::value& data);
124
+
125
+ threadedfilebuf _buffer;
126
+ std::ostream _stream;
127
+ bool _indexable, _open;
128
+
129
+ std::vector<PacketStreamSource> _sources;
130
+ size_t _bytes_written;
131
+ std::recursive_mutex _lock;
132
+ };
133
+
134
+ inline void writeCompressedUnsignedInt(std::ostream& writer, size_t n)
135
+ {
136
+ while (n >= 0x80)
137
+ {
138
+ writer.put(0x80 | (n & 0x7F));
139
+ n >>= 7;
140
+ }
141
+ writer.put(static_cast<unsigned char>(n));
142
+ }
143
+
144
+ inline void writeTimestamp(std::ostream& writer, int64_t time_us)
145
+ {
146
+ writer.write(reinterpret_cast<const char*>(&time_us), sizeof(decltype(time_us)));
147
+ }
148
+
149
+ inline void writeTag(std::ostream& writer, const PangoTagType tag)
150
+ {
151
+ writer.write(reinterpret_cast<const char*>(&tag), TAG_LENGTH);
152
+ }
153
+
154
+ inline picojson::value SourceStats(const std::vector<PacketStreamSource>& srcs)
155
+ {
156
+ picojson::value stat;
157
+ stat["num_sources"] = srcs.size();
158
+ stat["src_packet_index"] = picojson::array();
159
+ stat["src_packet_times"] = picojson::array();
160
+
161
+ for(auto& src : srcs) {
162
+ picojson::array pkt_index, pkt_times;
163
+ for (const PacketStreamSource::PacketInfo& frame : src.index) {
164
+ pkt_index.emplace_back(frame.pos);
165
+ pkt_times.emplace_back(frame.capture_time);
166
+ }
167
+ stat["src_packet_index"].push_back(std::move(pkt_index));
168
+ stat["src_packet_times"].push_back(std::move(pkt_times));
169
+ }
170
+ return stat;
171
+ }
172
+
173
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/playback_session.h ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #pragma once
2
+
3
+ #include <memory>
4
+ #include <vector>
5
+
6
+ #include <pangolin/log/packetstream_reader.h>
7
+ #include <pangolin/utils/file_utils.h>
8
+ #include <pangolin/utils/param_set.h>
9
+
10
+ namespace pangolin {
11
+
12
+ class Params;
13
+
14
+ class PlaybackSession
15
+ {
16
+ public:
17
+ // Singleton Instance
18
+ static std::shared_ptr<PlaybackSession> Default();
19
+
20
+ // Return thread-safe, shared instance of PacketStreamReader, providing
21
+ // serialised read for PacketStreamReader
22
+ std::shared_ptr<PacketStreamReader> Open(const std::string& filename)
23
+ {
24
+ const std::string path = SanitizePath(PathExpand(filename));
25
+
26
+ auto i = readers.find(path);
27
+ if(i == readers.end()) {
28
+ auto psr = std::make_shared<PacketStreamReader>(path);
29
+ readers[path] = psr;
30
+ return psr;
31
+ }else{
32
+ return i->second;
33
+ }
34
+ }
35
+
36
+ // Should only be called if there's no playbacks
37
+ // in flight
38
+ void Clear() {
39
+ readers.clear();
40
+ time.Reset();
41
+ }
42
+
43
+ SyncTime& Time()
44
+ {
45
+ return time;
46
+ }
47
+ static std::shared_ptr<PlaybackSession> ChooseFromParams(const ParamReader& reader);
48
+ static std::shared_ptr<PlaybackSession> ChooseFromParams(const Params& params);
49
+ private:
50
+ static std::shared_ptr<PlaybackSession> Choose(bool ordered_playback);
51
+ std::map<std::string,std::shared_ptr<PacketStreamReader>> readers;
52
+ SyncTime time;
53
+ };
54
+
55
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/sync_time.h ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person
5
+ * obtaining a copy of this software and associated documentation
6
+ * files (the "Software"), to deal in the Software without
7
+ * restriction, including without limitation the rights to use,
8
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the
10
+ * Software is furnished to do so, subject to the following
11
+ * conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ * OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+ #pragma once
27
+
28
+ #include <pangolin/platform.h>
29
+ #include <pangolin/utils/signal_slot.h>
30
+ #include <pangolin/utils/timer.h>
31
+
32
+ #include <atomic>
33
+ #include <condition_variable>
34
+ #include <mutex>
35
+ #include <queue>
36
+
37
+ namespace pangolin
38
+ {
39
+
40
+ // Lightweight timestamp class to allow synchronized playback from the same (or a different) stream.
41
+ // All playback functions called with the same SyncTime will be time-synchronized, and will remain synchronized on seek() if the SyncTime is passed in when seeking.
42
+ // Playback with multiple SyncTimes (on the same or different streams) should also be synced, even in different processes or systems (underlying clock sync is not required).
43
+ // However, playback with multiple SyncTimes will break on seek().
44
+ class PANGOLIN_EXPORT SyncTime
45
+ {
46
+ public:
47
+ using Clock = baseclock;
48
+ using Duration = Clock::duration;
49
+ using TimePoint = Clock::time_point;
50
+
51
+ struct SeekInterruption: std::runtime_error
52
+ {
53
+ SeekInterruption() : std::runtime_error("Time queue invalidated by seek"){}
54
+ };
55
+
56
+ SyncTime(Duration virtual_clock_offset = std::chrono::milliseconds(0))
57
+ : seeking(false)
58
+ {
59
+ SetOffset(virtual_clock_offset);
60
+ }
61
+
62
+ // Should only be called if no other callers are currently calling it
63
+ void Reset() {
64
+ seeking = false;
65
+ time_queue_us.clear();
66
+ SetOffset(std::chrono::milliseconds(0));
67
+ }
68
+
69
+ // No copy constructor
70
+ SyncTime(const SyncTime&) = delete;
71
+
72
+ void SetOffset(Duration virtual_clock_offset)
73
+ {
74
+ virtual_offset = virtual_clock_offset;
75
+ }
76
+
77
+ void SetClock(TimePoint virtual_now)
78
+ {
79
+ virtual_offset = virtual_now - Clock::now();
80
+ }
81
+
82
+ TimePoint TimeNow() const
83
+ {
84
+ return Clock::now() + virtual_offset;
85
+ }
86
+
87
+ TimePoint ToVirtual(TimePoint real) const
88
+ {
89
+ return real + virtual_offset;
90
+ }
91
+
92
+ TimePoint ToReal(TimePoint virt) const
93
+ {
94
+ return virt - virtual_offset;
95
+ }
96
+
97
+ void WaitUntil(TimePoint virtual_time) const
98
+ {
99
+ std::this_thread::sleep_until( ToReal(virtual_time) );
100
+ }
101
+
102
+ int64_t QueueEvent(int64_t new_event_time_us)
103
+ {
104
+ return WaitDequeueAndQueueEvent(0, new_event_time_us);
105
+ }
106
+
107
+ void DequeueEvent(int64_t event_time_us)
108
+ {
109
+ std::unique_lock<std::mutex> l(time_mutex);
110
+ auto i = std::find(time_queue_us.begin(), time_queue_us.end(), event_time_us);
111
+ PANGO_ENSURE(i != time_queue_us.end());
112
+ time_queue_us.erase(i);
113
+ queue_changed.notify_all();
114
+ }
115
+
116
+ int64_t WaitDequeueAndQueueEvent(int64_t event_time_us, int64_t new_event_time_us =0 )
117
+ {
118
+ std::unique_lock<std::mutex> l(time_mutex);
119
+
120
+ if(event_time_us) {
121
+ PANGO_ENSURE(time_queue_us.size());
122
+
123
+ // Wait until we're top the priority-queue
124
+ queue_changed.wait(l, [&](){
125
+ if(seeking) {
126
+ // Time queue will be invalidated on seek.
127
+ // Unblock without action
128
+ throw SeekInterruption();
129
+ }
130
+ return time_queue_us.back() == event_time_us;
131
+ });
132
+
133
+ // Dequeue
134
+ time_queue_us.pop_back();
135
+ }
136
+
137
+ if(new_event_time_us) {
138
+ // Add the new event whilst we still hold the lock, so that our
139
+ // event can't be missed
140
+ insert_sorted(time_queue_us, new_event_time_us, std::greater<int64_t>());
141
+
142
+ if(time_queue_us.back() == new_event_time_us) {
143
+ // Return to avoid yielding when we're next.
144
+ return new_event_time_us;
145
+ }
146
+ }
147
+
148
+ // Only yield if another device is next
149
+ queue_changed.notify_all();
150
+ return new_event_time_us;
151
+ }
152
+
153
+ void NotifyAll()
154
+ {
155
+ queue_changed.notify_all();
156
+ }
157
+
158
+ std::mutex& TimeMutex()
159
+ {
160
+ return time_mutex;
161
+ }
162
+
163
+ void Stop()
164
+ {
165
+ seeking = true;
166
+ OnTimeStop();
167
+ queue_changed.notify_all();
168
+ }
169
+
170
+ void Start()
171
+ {
172
+ OnTimeStart();
173
+ seeking=false;
174
+ }
175
+
176
+ void Seek(TimePoint t)
177
+ {
178
+ Stop();
179
+ OnSeek(t);
180
+ Start();
181
+ }
182
+
183
+ sigslot::signal<> OnTimeStart;
184
+
185
+ sigslot::signal<> OnTimeStop;
186
+
187
+ sigslot::signal<TimePoint> OnSeek;
188
+
189
+ private:
190
+ template< typename T, typename Pred >
191
+ static typename std::vector<T>::iterator
192
+ insert_sorted( std::vector<T> & vec, T const& item, Pred pred )
193
+ {
194
+ return vec.insert (
195
+ std::upper_bound( vec.begin(), vec.end(), item, pred ), item
196
+ );
197
+ }
198
+
199
+ std::vector<int64_t> time_queue_us;
200
+ Duration virtual_offset;
201
+ std::mutex time_mutex;
202
+ std::condition_variable queue_changed;
203
+ bool seeking;
204
+ };
205
+
206
+ struct SyncTimeEventPromise
207
+ {
208
+ SyncTimeEventPromise(SyncTime& sync, int64_t time_us = 0)
209
+ : sync(sync), time_us(time_us)
210
+ {
211
+ sync.QueueEvent(time_us);
212
+ }
213
+
214
+ ~SyncTimeEventPromise()
215
+ {
216
+ Cancel();
217
+ }
218
+
219
+ void Cancel()
220
+ {
221
+ if(time_us) {
222
+ sync.DequeueEvent(time_us);
223
+ time_us = 0;
224
+ }
225
+ }
226
+
227
+ void WaitAndRenew(int64_t new_time_us)
228
+ {
229
+ time_us = sync.WaitDequeueAndQueueEvent(time_us, new_time_us);
230
+ }
231
+
232
+ private:
233
+ SyncTime& sync;
234
+ int64_t time_us;
235
+ };
236
+
237
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/src/packet.cpp ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <pangolin/log/packet.h>
2
+
3
+ namespace pangolin {
4
+
5
+
6
+ Packet::Packet(PacketStream& s, std::unique_lock<std::recursive_mutex>&& lock, std::vector<PacketStreamSource>& srcs)
7
+ : _stream(s), lock(std::move(lock))
8
+ {
9
+ ParsePacketHeader(s, srcs);
10
+ }
11
+
12
+ Packet::Packet(Packet&& o)
13
+ : src(o.src), time(o.time), size(o.size), sequence_num(o.sequence_num),
14
+ meta(std::move(o.meta)), frame_streampos(o.frame_streampos), _stream(o._stream),
15
+ lock(std::move(o.lock)), data_streampos(o.data_streampos), _data_len(o._data_len)
16
+ {
17
+ o._data_len = 0;
18
+ }
19
+
20
+ Packet::~Packet()
21
+ {
22
+ ReadRemaining();
23
+ }
24
+
25
+ size_t Packet::BytesRead() const
26
+ {
27
+ return _stream.tellg() - data_streampos;
28
+ }
29
+
30
+ int Packet::BytesRemaining() const
31
+ {
32
+ if(_data_len) {
33
+ return (int)_data_len - (int)BytesRead();
34
+ }else{
35
+ return 0;
36
+ }
37
+ }
38
+
39
+ void Packet::ParsePacketHeader(PacketStream& s, std::vector<PacketStreamSource>& srcs)
40
+ {
41
+ size_t json_src = -1;
42
+
43
+ frame_streampos = s.tellg();
44
+ if (s.peekTag() == TAG_SRC_JSON)
45
+ {
46
+ s.readTag(TAG_SRC_JSON);
47
+ json_src = s.readUINT();
48
+ picojson::parse(meta, s);
49
+ }
50
+
51
+ s.readTag(TAG_SRC_PACKET);
52
+ time = s.readTimestamp();
53
+
54
+ src = s.readUINT();
55
+ PANGO_ENSURE(json_src == size_t(-1) || json_src == src, "Frame preceded by metadata for a mismatched source. Stream may be corrupt.");
56
+
57
+ PacketStreamSource& src_packet = srcs[src];
58
+
59
+ size = src_packet.data_size_bytes;
60
+ if (!size) {
61
+ size = s.readUINT();
62
+ }
63
+ sequence_num = src_packet.next_packet_id++;
64
+
65
+ _data_len = size;
66
+ data_streampos = s.tellg();
67
+ }
68
+
69
+ void Packet::ReadRemaining()
70
+ {
71
+ int bytes_left = BytesRemaining();
72
+
73
+ while(bytes_left > 0 && Stream().good()) {
74
+ Stream().skip(bytes_left);
75
+ bytes_left = BytesRemaining();
76
+ }
77
+ }
78
+
79
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/src/packetstream.cpp ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <pangolin/log/packetstream.h>
2
+ #include <stdexcept>
3
+
4
+ namespace pangolin {
5
+
6
+ size_t PacketStream::readUINT()
7
+ {
8
+ size_t n = 0;
9
+ size_t v = get();
10
+ uint32_t shift = 0;
11
+ while (good() && (v & 0x80))
12
+ {
13
+ n |= (v & 0x7F) << shift;
14
+ shift += 7;
15
+ v = get();
16
+ }
17
+ if (!good())
18
+ return static_cast<size_t>(-1);
19
+ return n | (v & 0x7F) << shift;
20
+ }
21
+
22
+ int64_t PacketStream::readTimestamp()
23
+ {
24
+ int64_t time_us;
25
+ read(reinterpret_cast<char*>(&time_us), sizeof(int64_t));
26
+ return time_us;
27
+ }
28
+
29
+ PangoTagType PacketStream::readTag()
30
+ {
31
+ auto r = peekTag();
32
+ _tag = 0;
33
+ return r;
34
+ }
35
+
36
+ PangoTagType PacketStream::readTag(PangoTagType x)
37
+ {
38
+ auto r = readTag();
39
+ if (r != x)
40
+ throw std::runtime_error(("Tag mismatch error: expected tag '" + tagName(r) + "' does not match found tag '" + tagName(x) + "'").c_str());
41
+ return r;
42
+ }
43
+
44
+ PangoTagType PacketStream::peekTag()
45
+ {
46
+ if (!_tag)
47
+ {
48
+ _tag = 0;
49
+ Base::read(reinterpret_cast<char*>(&_tag), TAG_LENGTH);
50
+ if (!good())
51
+ _tag = TAG_END;
52
+ }
53
+ return _tag;
54
+ }
55
+
56
+ char PacketStream::get()
57
+ {
58
+ _tag = 0;
59
+ return Base::get();
60
+ }
61
+
62
+ size_t PacketStream::read(char* target, size_t len)
63
+ {
64
+ _tag = 0;
65
+ Base::read(target, len);
66
+ return gcount();
67
+ }
68
+
69
+ size_t PacketStream::skip(size_t len)
70
+ {
71
+ if (seekable()) {
72
+ Base::seekg(len, std::ios_base::cur);
73
+ } else {
74
+ Base::ignore(len);
75
+ }
76
+ cclear();
77
+ return len;
78
+ }
79
+
80
+ std::streampos PacketStream::tellg()
81
+ {
82
+ if (_tag) {
83
+ return Base::tellg() - std::streamoff(TAG_LENGTH);
84
+ }else{
85
+ return Base::tellg();
86
+ }
87
+ }
88
+
89
+ void PacketStream::seekg(std::streampos target)
90
+ {
91
+ if (seekable()) {
92
+ cclear();
93
+ Base::seekg(target);
94
+ }
95
+ }
96
+
97
+ void PacketStream::seekg(std::streamoff off, std::ios_base::seekdir way)
98
+ {
99
+ if (seekable()) {
100
+ cclear();
101
+ Base::seekg(off, way);
102
+ }
103
+ }
104
+
105
+ static bool valid(PangoTagType t)
106
+ {
107
+ switch (t)
108
+ {
109
+ case TAG_PANGO_SYNC:
110
+ case TAG_ADD_SOURCE:
111
+ case TAG_SRC_JSON:
112
+ case TAG_SRC_PACKET:
113
+ case TAG_PANGO_STATS:
114
+ case TAG_PANGO_FOOTER:
115
+ case TAG_END:
116
+ case TAG_PANGO_HDR:
117
+ case TAG_PANGO_MAGIC:
118
+ return true;
119
+ default:
120
+ return false;
121
+ }
122
+ }
123
+
124
+ PangoTagType PacketStream::syncToTag() //scan through chars one by one until the last three look like a tag
125
+ {
126
+ peekTag();
127
+ char * buffer = reinterpret_cast<char*>(&_tag);
128
+
129
+ buffer[3] = 0;
130
+
131
+ do
132
+ {
133
+ buffer[0] = buffer[1];
134
+ buffer[1] = buffer[2];
135
+ buffer[2] = get();
136
+ }
137
+ while (good() && !valid(_tag));
138
+
139
+ if (!good())
140
+ _tag = TAG_END;
141
+
142
+ return _tag;
143
+
144
+ }
145
+
146
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/src/packetstream_reader.cpp ADDED
@@ -0,0 +1,428 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person
5
+ * obtaining a copy of this software and associated documentation
6
+ * files (the "Software"), to deal in the Software without
7
+ * restriction, including without limitation the rights to use,
8
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the
10
+ * Software is furnished to do so, subject to the following
11
+ * conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ * OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+ #include <pangolin/log/packetstream_reader.h>
27
+ #include <pangolin/log/packetstream_writer.h>
28
+
29
+ using std::string;
30
+ using std::istream;
31
+ using std::ios;
32
+ using std::lock_guard;
33
+ using std::runtime_error;
34
+ using std::ios_base;
35
+ using std::streampos;
36
+ using std::streamoff;
37
+
38
+ #include <thread>
39
+
40
+ #ifndef _WIN_
41
+ # include <unistd.h>
42
+ #endif
43
+
44
+ namespace pangolin
45
+ {
46
+
47
+ PacketStreamReader::PacketStreamReader()
48
+ : _pipe_fd(-1)
49
+ {
50
+ }
51
+
52
+ PacketStreamReader::PacketStreamReader(const std::string& filename)
53
+ : _pipe_fd(-1)
54
+ {
55
+ Open(filename);
56
+ }
57
+
58
+ PacketStreamReader::~PacketStreamReader()
59
+ {
60
+ Close();
61
+ }
62
+
63
+ void PacketStreamReader::Open(const std::string& filename)
64
+ {
65
+ std::lock_guard<std::recursive_mutex> lg(_mutex);
66
+
67
+ Close();
68
+
69
+ _filename = filename;
70
+ _is_pipe = IsPipe(filename);
71
+ _stream.open(filename);
72
+
73
+ if (!_stream.is_open())
74
+ throw runtime_error(
75
+ "Cannot open stream from " + filename +
76
+ "\nAre you sure the file exists?"
77
+ );
78
+
79
+ for (auto i : PANGO_MAGIC)
80
+ {
81
+ if (_stream.get() != i)
82
+ throw runtime_error("Unrecognised file header.");
83
+ if (!_stream.good())
84
+ throw runtime_error("Bad stream");
85
+ }
86
+
87
+
88
+ ParseHeader();
89
+
90
+ while (_stream.peekTag() == TAG_ADD_SOURCE) {
91
+ ParseNewSource();
92
+ }
93
+
94
+ if(!SetupIndex()) {
95
+ FixFileIndex();
96
+ }
97
+ }
98
+
99
+ void PacketStreamReader::Close() {
100
+ std::lock_guard<std::recursive_mutex> lg(_mutex);
101
+
102
+ _stream.close();
103
+ _sources.clear();
104
+
105
+ #ifndef _WIN_
106
+ if (_pipe_fd != -1) {
107
+ close(_pipe_fd);
108
+ }
109
+ #endif
110
+ }
111
+
112
+ void PacketStreamReader::ParseHeader()
113
+ {
114
+ _stream.readTag(TAG_PANGO_HDR);
115
+
116
+ picojson::value json_header;
117
+ picojson::parse(json_header, _stream);
118
+
119
+ // File timestamp
120
+ const int64_t start_us = json_header["time_us"].get<int64_t>();
121
+ packet_stream_start = SyncTime::TimePoint() + std::chrono::microseconds(start_us);
122
+
123
+ _stream.get(); // consume newline
124
+ }
125
+
126
+ void PacketStreamReader::ParseNewSource()
127
+ {
128
+ _stream.readTag(TAG_ADD_SOURCE);
129
+ picojson::value json;
130
+ picojson::parse(json, _stream);
131
+ _stream.get(); // consume newline
132
+
133
+
134
+ const size_t src_id = json[pss_src_id].get<int64_t>();
135
+
136
+ if(_sources.size() <= src_id) {
137
+ _sources.resize(src_id+1);
138
+ }
139
+
140
+ PacketStreamSource& pss = _sources[src_id];
141
+ pss.id = src_id;
142
+ pss.driver = json[pss_src_driver].get<string>();
143
+ pss.uri = json[pss_src_uri].get<string>();
144
+ pss.info = json[pss_src_info];
145
+ pss.version = json[pss_src_version].get<int64_t>();
146
+ pss.data_alignment_bytes = json[pss_src_packet][pss_pkt_alignment_bytes].get<int64_t>();
147
+ pss.data_definitions = json[pss_src_packet][pss_pkt_definitions].get<string>();
148
+ pss.data_size_bytes = json[pss_src_packet][pss_pkt_size_bytes].get<int64_t>();
149
+ }
150
+
151
+ bool PacketStreamReader::SetupIndex()
152
+ {
153
+ bool index_good = false;
154
+
155
+ if (_stream.seekable())
156
+ {
157
+ // Save current position
158
+ std::streampos pos = _stream.tellg();
159
+
160
+ // Look for footer at end of file (TAG_PANGO_FOOTER + index position).
161
+ _stream.seekg(-(static_cast<istream::off_type>(sizeof(uint64_t)) + TAG_LENGTH), ios_base::end);
162
+ if (_stream.peekTag() == TAG_PANGO_FOOTER)
163
+ {
164
+ //parsing the footer returns the index position
165
+ _stream.seekg(ParseFooter());
166
+ if (_stream.peekTag() == TAG_PANGO_STATS) {
167
+ // Read the pre-build index from the file
168
+ index_good = ParseIndex();
169
+ }
170
+ }
171
+
172
+ // Restore previous location
173
+ _stream.clear();
174
+ _stream.seekg(pos);
175
+ }
176
+
177
+ return index_good;
178
+ }
179
+
180
+ streampos PacketStreamReader::ParseFooter() //returns position of index.
181
+ {
182
+ _stream.readTag(TAG_PANGO_FOOTER);
183
+ uint64_t index=0;
184
+ size_t bytes_read = _stream.read(reinterpret_cast<char*>(&index), sizeof(index));
185
+ PANGO_ENSURE(bytes_read == sizeof(index));
186
+ return index;
187
+ }
188
+
189
+ bool PacketStreamReader::ParseIndex()
190
+ {
191
+ _stream.readTag(TAG_PANGO_STATS);
192
+ picojson::value json;
193
+ picojson::parse(json, _stream);
194
+
195
+ const bool index_good = json.contains("src_packet_index") && json.contains("src_packet_times");
196
+
197
+ if (index_good)
198
+ {
199
+ // This is a two-dimensional serialized array, [source id][sequence number] ---> packet position in stream
200
+ const auto& json_index = json["src_packet_index"].get<picojson::array>();
201
+ const auto& json_times = json["src_packet_times"].get<picojson::array>();
202
+
203
+ // We shouldn't have seen more sources than exist in the index
204
+ PANGO_ENSURE(_sources.size() <= json_index.size());
205
+ PANGO_ENSURE(json_index.size() == json_times.size());
206
+
207
+ _sources.resize(json_index.size());
208
+
209
+ // Populate index
210
+ for(size_t i=0; i < _sources.size(); ++i) {
211
+ PANGO_ENSURE(json_index[i].size() == json_times[i].size());
212
+ _sources[i].index.resize(json_index[i].size());
213
+ for(size_t f=0; f < json_index[i].size(); ++f) {
214
+ _sources[i].index[f].pos = json_index[i][f].get<int64_t>();
215
+ _sources[i].index[f].capture_time = json_times[i][f].get<int64_t>();
216
+ }
217
+ }
218
+ }
219
+
220
+ return index_good;
221
+ }
222
+
223
+ bool PacketStreamReader::GoodToRead()
224
+ {
225
+ if(!_stream.good()) {
226
+ #ifndef _WIN_
227
+ if (_is_pipe)
228
+ {
229
+ if (_pipe_fd == -1) {
230
+ _pipe_fd = ReadablePipeFileDescriptor(_filename);
231
+ }
232
+
233
+ if (_pipe_fd != -1) {
234
+ // Test whether the pipe has data to be read. If so, open the
235
+ // file stream and start reading. After this point, the file
236
+ // descriptor is owned by the reader.
237
+ if (PipeHasDataToRead(_pipe_fd))
238
+ {
239
+ close(_pipe_fd);
240
+ _pipe_fd = -1;
241
+ Open(_filename);
242
+ return _stream.good();
243
+ }
244
+ }
245
+ }
246
+ #endif
247
+
248
+ return false;
249
+ }
250
+
251
+ return true;
252
+
253
+ }
254
+
255
+ Packet PacketStreamReader::NextFrame()
256
+ {
257
+ std::unique_lock<std::recursive_mutex> lock(_mutex);
258
+
259
+ while (GoodToRead())
260
+ {
261
+ const PangoTagType t = _stream.peekTag();
262
+
263
+ switch (t)
264
+ {
265
+ case TAG_PANGO_SYNC:
266
+ SkipSync();
267
+ break;
268
+ case TAG_ADD_SOURCE:
269
+ ParseNewSource();
270
+ break;
271
+ case TAG_SRC_JSON: //frames are sometimes preceded by metadata, but metadata must ALWAYS be followed by a frame from the same source.
272
+ case TAG_SRC_PACKET:
273
+ return Packet(_stream, std::move(lock), _sources);
274
+ case TAG_PANGO_STATS:
275
+ ParseIndex();
276
+ break;
277
+ case TAG_PANGO_FOOTER: //end of frames
278
+ case TAG_END:
279
+ throw std::runtime_error("PacketStreamReader: end of stream");
280
+ case TAG_PANGO_HDR: //shoudln't encounter this
281
+ ParseHeader();
282
+ break;
283
+ case TAG_PANGO_MAGIC: //or this
284
+ SkipSync();
285
+ break;
286
+ default: //or anything else
287
+ pango_print_warn("Unexpected packet type: \"%s\". Resyncing()\n", tagName(t).c_str());
288
+ ReSync();
289
+ break;
290
+ }
291
+ }
292
+
293
+ // No frame
294
+ throw std::runtime_error("PacketStreamReader: no frame");
295
+ }
296
+
297
+ Packet PacketStreamReader::NextFrame(PacketStreamSourceId src)
298
+ {
299
+ while (1)
300
+ {
301
+ // This will throw if nothing is left.
302
+ auto fi = NextFrame();
303
+ if (fi.src == src) {
304
+ return fi;
305
+ }
306
+ }
307
+ }
308
+
309
+ void PacketStreamReader::RebuildIndex()
310
+ {
311
+ lock_guard<decltype(_mutex)> lg(_mutex);
312
+
313
+ if(_stream.seekable()) {
314
+ pango_print_warn("Index for '%s' bad / outdated. Rebuilding.\n", _filename.c_str());
315
+
316
+ // Save current position
317
+ std::streampos pos = _stream.tellg();
318
+
319
+ // Clear existing index
320
+ for(PacketStreamSource& s : _sources) {
321
+ s.index.clear();
322
+ s.next_packet_id = 0;
323
+ }
324
+
325
+ // Read through entire file, updating index
326
+ try{
327
+ while (1)
328
+ {
329
+ // This will throw if we've run out of frames
330
+ auto fi = NextFrame();
331
+ PacketStreamSource& s = _sources[fi.src];
332
+ PANGO_ENSURE(s.index.size() == fi.sequence_num);
333
+ s.index.push_back({fi.frame_streampos, fi.time});
334
+ }
335
+ }catch(...){
336
+ }
337
+
338
+ // Reset Packet id's
339
+ for(PacketStreamSource& s : _sources) {
340
+ s.next_packet_id = 0;
341
+ }
342
+
343
+ // Restore previous location
344
+ _stream.clear();
345
+ _stream.seekg(pos);
346
+ }
347
+ }
348
+
349
+ void PacketStreamReader::AppendIndex()
350
+ {
351
+ lock_guard<decltype(_mutex)> lg(_mutex);
352
+
353
+ if(_stream.seekable()) {
354
+ // Open file again for append
355
+ std::ofstream of(_filename, std::ios::app | std::ios::binary);
356
+ if(of.is_open()) {
357
+ pango_print_warn("Appending new index to '%s'.\n", _filename.c_str());
358
+ uint64_t indexpos = (uint64_t)of.tellp();
359
+ writeTag(of, TAG_PANGO_STATS);
360
+ SourceStats(_sources).serialize(std::ostream_iterator<char>(of), false);
361
+ writeTag(of, TAG_PANGO_FOOTER);
362
+ of.write(reinterpret_cast<char*>(&indexpos), sizeof(uint64_t));
363
+ }
364
+ }
365
+ }
366
+
367
+ void PacketStreamReader::FixFileIndex()
368
+ {
369
+ if(_stream.seekable())
370
+ {
371
+ RebuildIndex();
372
+ AppendIndex();
373
+ }
374
+ }
375
+
376
+ size_t PacketStreamReader::Seek(PacketStreamSourceId src, size_t framenum)
377
+ {
378
+ lock_guard<decltype(_mutex)> lg(_mutex);
379
+
380
+ PANGO_ASSERT(_stream.seekable());
381
+ PANGO_ASSERT(src < _sources.size());
382
+ PacketStreamSource& source = _sources[src];
383
+ PANGO_ASSERT(framenum < source.index.size());
384
+
385
+ if(source.index[framenum].pos > 0) {
386
+ _stream.clear();
387
+ _stream.seekg(source.index[framenum].pos);
388
+ source.next_packet_id = framenum;
389
+ }
390
+ return source.next_packet_id;
391
+ }
392
+
393
+ // Jumps to the first packet with time >= time
394
+ size_t PacketStreamReader::Seek(PacketStreamSourceId src, SyncTime::TimePoint time)
395
+ {
396
+ PacketStreamSource& source = _sources[src];
397
+
398
+ PacketStreamSource::PacketInfo v = {
399
+ 0, std::chrono::duration_cast<std::chrono::microseconds>(time.time_since_epoch()).count()
400
+ };
401
+
402
+ // Find time in indextime
403
+ auto lb = std::lower_bound(
404
+ source.index.begin(), source.index.end(), v,
405
+ [](const PacketStreamSource::PacketInfo& a, const PacketStreamSource::PacketInfo& b){
406
+ return a.capture_time < b.capture_time;
407
+ }
408
+ );
409
+
410
+ if(lb != source.index.end()) {
411
+ const size_t frame_num = lb - source.index.begin();
412
+ return Seek(src, frame_num);
413
+ }else{
414
+ return source.next_packet_id;
415
+ }
416
+ }
417
+
418
+ void PacketStreamReader::SkipSync()
419
+ {
420
+ //Assume we have just read PAN, read GO
421
+ if (_stream.get() != 'G' && _stream.get() != 'O')
422
+ throw std::runtime_error("Unknown packet type.");
423
+
424
+ while (_stream.peekTag() != TAG_SRC_PACKET && _stream.peekTag() != TAG_END)
425
+ _stream.readTag();
426
+ }
427
+
428
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/src/packetstream_writer.cpp ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person
5
+ * obtaining a copy of this software and associated documentation
6
+ * files (the "Software"), to deal in the Software without
7
+ * restriction, including without limitation the rights to use,
8
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ * copies of the Software, and to permit persons to whom the
10
+ * Software is furnished to do so, subject to the following
11
+ * conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be
14
+ * included in all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
+ * OTHER DEALINGS IN THE SOFTWARE.
24
+ */
25
+
26
+ #include <pangolin/log/packetstream_writer.h>
27
+ #include <pangolin/utils/file_utils.h>
28
+ #include <pangolin/utils/timer.h>
29
+
30
+ using std::ios;
31
+ using std::lock_guard;
32
+
33
+ #define SCOPED_LOCK lock_guard<decltype(_lock)> lg(_lock)
34
+
35
+ //#define SCOPED_LOCK
36
+
37
+ namespace pangolin
38
+ {
39
+
40
+ static inline const std::string CurrentTimeStr()
41
+ {
42
+ time_t time_now = time(0);
43
+ struct tm time_struct = *localtime(&time_now);
44
+ char buffer[80];
45
+ strftime(buffer, sizeof(buffer), "%Y-%m-%d %X", &time_struct);
46
+ return buffer;
47
+ }
48
+
49
+ void PacketStreamWriter::WriteHeader()
50
+ {
51
+ SCOPED_LOCK;
52
+ _stream.write(PANGO_MAGIC.c_str(), PANGO_MAGIC.size());
53
+ picojson::value pango;
54
+ pango["pangolin_version"] = PANGOLIN_VERSION_STRING;
55
+ pango["time_us"] = Time_us(TimeNow());
56
+ pango["date_created"] = CurrentTimeStr();
57
+ pango["endian"] = "little_endian";
58
+
59
+ writeTag(_stream, TAG_PANGO_HDR);
60
+ pango.serialize(std::ostream_iterator<char>(_stream), true);
61
+
62
+ for (const auto& source : _sources)
63
+ Write(source);
64
+ }
65
+
66
+ void PacketStreamWriter::Write(const PacketStreamSource& source)
67
+ {
68
+ SCOPED_LOCK;
69
+ picojson::value serialize;
70
+ serialize[pss_src_driver] = source.driver;
71
+ serialize[pss_src_id] = source.id;
72
+ serialize[pss_src_uri] = source.uri;
73
+ serialize[pss_src_info] = source.info;
74
+ serialize[pss_src_version] = source.version;
75
+ serialize[pss_src_packet][pss_pkt_alignment_bytes] = source.data_alignment_bytes;
76
+ serialize[pss_src_packet][pss_pkt_definitions] = source.data_definitions;
77
+ serialize[pss_src_packet][pss_pkt_size_bytes] = source.data_size_bytes;
78
+
79
+ writeTag(_stream, TAG_ADD_SOURCE);
80
+ serialize.serialize(std::ostream_iterator<char>(_stream), true);
81
+ }
82
+
83
+
84
+ PacketStreamSourceId PacketStreamWriter::AddSource(PacketStreamSource& source)
85
+ {
86
+ SCOPED_LOCK;
87
+ source.id = AddSource(const_cast<const PacketStreamSource&>(source));
88
+ return source.id;
89
+ }
90
+
91
+ PacketStreamSourceId PacketStreamWriter::AddSource(const PacketStreamSource& source)
92
+ {
93
+ SCOPED_LOCK;
94
+ PacketStreamSourceId r = _sources.size(); //source id is by vector position, so we must reassign.
95
+ _sources.push_back(source);
96
+ _sources.back().id = r;
97
+
98
+ if (_open) //we might be a pipe, in which case we may not be open
99
+ Write(_sources.back());
100
+
101
+ return _sources.back().id;
102
+ }
103
+
104
+ void PacketStreamWriter::WriteMeta(PacketStreamSourceId src, const picojson::value& data)
105
+ {
106
+ SCOPED_LOCK;
107
+ writeTag(_stream, TAG_SRC_JSON);
108
+ writeCompressedUnsignedInt(_stream, src);
109
+ data.serialize(std::ostream_iterator<char>(_stream), false);
110
+ }
111
+
112
+ void PacketStreamWriter::WriteSourcePacket(PacketStreamSourceId src, const char* source, const int64_t receive_time_us, size_t sourcelen, const picojson::value& meta)
113
+ {
114
+
115
+ SCOPED_LOCK;
116
+ _sources[src].index.push_back({_stream.tellp(), receive_time_us});
117
+
118
+ if (!meta.is<picojson::null>())
119
+ WriteMeta(src, meta);
120
+
121
+ writeTag(_stream, TAG_SRC_PACKET);
122
+ writeTimestamp(_stream, receive_time_us);
123
+ writeCompressedUnsignedInt(_stream, src);
124
+
125
+ if (_sources[src].data_size_bytes) {
126
+ if (sourcelen != static_cast<size_t>(_sources[src].data_size_bytes))
127
+ throw std::runtime_error("oPacketStream::writePacket --> Tried to write a fixed-size packet with bad size.");
128
+ } else {
129
+ writeCompressedUnsignedInt(_stream, sourcelen);
130
+ }
131
+
132
+ _stream.write(source, sourcelen);
133
+ _bytes_written += sourcelen;
134
+ }
135
+
136
+ void PacketStreamWriter::WriteSync()
137
+ {
138
+ SCOPED_LOCK;
139
+ for (unsigned i = 0; i < 10; ++i)
140
+ writeTag(_stream, TAG_PANGO_SYNC);
141
+ }
142
+
143
+ void PacketStreamWriter::WriteEnd()
144
+ {
145
+ SCOPED_LOCK;
146
+ if (!_indexable)
147
+ return;
148
+
149
+ auto indexpos = _stream.tellp();
150
+ writeTag(_stream, TAG_PANGO_STATS);
151
+ SourceStats(_sources).serialize(std::ostream_iterator<char>(_stream), false);
152
+ writeTag(_stream, TAG_PANGO_FOOTER);
153
+ _stream.write(reinterpret_cast<char*>(&indexpos), sizeof(uint64_t));
154
+ }
155
+
156
+ }
third-party/DPVO/Pangolin/components/pango_packetstream/src/playback_session.cpp ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <pangolin/log/playback_session.h>
2
+
3
+ namespace pangolin {
4
+
5
+ std::shared_ptr<PlaybackSession> PlaybackSession::Default()
6
+ {
7
+ static std::shared_ptr<PlaybackSession> instance = std::make_shared<PlaybackSession>();
8
+ return instance;
9
+ }
10
+
11
+ std::shared_ptr<PlaybackSession> PlaybackSession::ChooseFromParams(const ParamReader& reader)
12
+ {
13
+ return Choose(reader.Get<bool>("OrderedPlayback"));
14
+ }
15
+
16
+ std::shared_ptr<PlaybackSession> PlaybackSession::ChooseFromParams(const Params& params)
17
+ {
18
+ return Choose(params.Get<bool>("OrderedPlayback", false));
19
+ }
20
+
21
+ std::shared_ptr<PlaybackSession> PlaybackSession::Choose(bool use_ordered_playback)
22
+ {
23
+ if(use_ordered_playback)
24
+ {
25
+ return Default();
26
+ }
27
+ else
28
+ {
29
+ return std::make_shared<PlaybackSession>();
30
+ }
31
+ }
32
+ }
third-party/DPVO/Pangolin/components/pango_plot/CMakeLists.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ get_filename_component(COMPONENT ${CMAKE_CURRENT_LIST_DIR} NAME)
2
+
3
+ target_sources( ${COMPONENT}
4
+ PRIVATE
5
+ ${CMAKE_CURRENT_LIST_DIR}/src/datalog.cpp
6
+ ${CMAKE_CURRENT_LIST_DIR}/src/plotter.cpp
7
+ ${CMAKE_CURRENT_LIST_DIR}/src/loaders/csv_table_loader.cpp
8
+ )
9
+
10
+ target_link_libraries(${COMPONENT} pango_display)
11
+ target_include_directories(${COMPONENT} PUBLIC
12
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
13
+ $<INSTALL_INTERFACE:include>
14
+ )
15
+ install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/include"
16
+ DESTINATION ${CMAKE_INSTALL_PREFIX}
17
+ )
third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/datalog.h ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2011 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #pragma once
29
+
30
+ #include <pangolin/platform.h>
31
+
32
+ #include <algorithm> // std::min, std::max
33
+ #include <limits>
34
+ #include <memory>
35
+ #include <mutex>
36
+ #include <stdexcept>
37
+ #include <string>
38
+ #include <vector>
39
+
40
+ #if defined(HAVE_EIGEN) && !defined(__CUDACC__) //prevent including Eigen in cuda files
41
+ #define USE_EIGEN
42
+ #endif
43
+
44
+ #ifdef USE_EIGEN
45
+ #include <Eigen/Core>
46
+ #endif
47
+
48
+ namespace pangolin
49
+ {
50
+
51
+ /// Simple statistics recorded for a logged input dimension.
52
+ struct DimensionStats
53
+ {
54
+ DimensionStats()
55
+ {
56
+ Reset();
57
+ }
58
+
59
+ void Reset()
60
+ {
61
+ isMonotonic = true;
62
+ sum = 0.0f;
63
+ sum_sq = 0.0f;
64
+ min = std::numeric_limits<float>::max();
65
+ max = std::numeric_limits<float>::lowest();
66
+ }
67
+
68
+ void Add(const float v)
69
+ {
70
+ isMonotonic = isMonotonic && (v >= max);
71
+ sum += v;
72
+ sum_sq += v*v;
73
+ min = std::min(min, v);
74
+ max = std::max(max, v);
75
+ }
76
+
77
+ bool isMonotonic;
78
+ float sum;
79
+ float sum_sq;
80
+ float min;
81
+ float max;
82
+ };
83
+
84
+ class DataLogBlock
85
+ {
86
+ public:
87
+ /// @param dim: dimension of sample
88
+ /// @param max_samples: maximum number of samples this block can hold
89
+ /// @param start_id: index of first sample (from entire dataset) in this buffer
90
+ DataLogBlock(size_t dim, size_t max_samples, size_t start_id)
91
+ : dim(dim), max_samples(max_samples), samples(0),
92
+ start_id(start_id)
93
+ {
94
+ sample_buffer = std::unique_ptr<float[]>(new float[dim*max_samples]);
95
+ // stats = std::unique_ptr<DimensionStats[]>(new DimensionStats[dim]);
96
+ }
97
+
98
+ ~DataLogBlock()
99
+ {
100
+ }
101
+
102
+ size_t Samples() const
103
+ {
104
+ return samples;
105
+ }
106
+
107
+ size_t MaxSamples() const
108
+ {
109
+ return max_samples;
110
+ }
111
+
112
+ /// Return how many more samples can fit in this block
113
+ size_t SampleSpaceLeft() const
114
+ {
115
+ return MaxSamples()- Samples();
116
+ }
117
+
118
+ bool IsFull() const
119
+ {
120
+ return Samples() >= MaxSamples();
121
+ }
122
+
123
+ /// Add data to block
124
+ void AddSamples(size_t num_samples, size_t dimensions, const float* data_dim_major );
125
+
126
+ /// Delete all samples
127
+ void ClearLinked()
128
+ {
129
+ samples = 0;
130
+ nextBlock.reset();
131
+ }
132
+
133
+ DataLogBlock* NextBlock() const
134
+ {
135
+ return nextBlock.get();
136
+ }
137
+
138
+ size_t StartId() const
139
+ {
140
+ return start_id;
141
+ }
142
+
143
+ float* DimData(size_t d) const
144
+ {
145
+ return sample_buffer.get() + d;
146
+ }
147
+
148
+ size_t Dimensions() const
149
+ {
150
+ return dim;
151
+ }
152
+
153
+ const float* Sample(size_t n) const
154
+ {
155
+ const int id = (int)n - (int)start_id;
156
+
157
+ if( 0 <= id && id < (int)samples ) {
158
+ return sample_buffer.get() + dim*id;
159
+ }else{
160
+ if(nextBlock) {
161
+ return nextBlock->Sample(n);
162
+ }else{
163
+ throw std::out_of_range("Index out of range.");
164
+ }
165
+ }
166
+ }
167
+
168
+ protected:
169
+ size_t dim;
170
+ size_t max_samples;
171
+ size_t samples;
172
+ size_t start_id;
173
+ std::unique_ptr<float[]> sample_buffer;
174
+ // std::unique_ptr<DimensionStats[]> stats;
175
+ std::unique_ptr<DataLogBlock> nextBlock;
176
+ };
177
+
178
+ /// A DataLog can efficiently record floating point sample data of any size.
179
+ /// Memory is allocated in blocks is transparent to the user.
180
+ class PANGOLIN_EXPORT DataLog
181
+ {
182
+ public:
183
+ /// @param block_samples_alloc number of samples each memory block can hold.
184
+ DataLog(unsigned int block_samples_alloc = 10000 );
185
+
186
+ ~DataLog();
187
+
188
+ /// Provide textual labels corresponding to each dimension logged.
189
+ /// This information may be used by graphical interfaces to DataLog.
190
+ void SetLabels(const std::vector<std::string> & labels);
191
+ const std::vector<std::string>& Labels() const;
192
+
193
+ void Log(size_t dimension, const float * vals, unsigned int samples = 1);
194
+ void Log(float v);
195
+ void Log(float v1, float v2);
196
+ void Log(float v1, float v2, float v3);
197
+ void Log(float v1, float v2, float v3, float v4);
198
+ void Log(float v1, float v2, float v3, float v4, float v5);
199
+ void Log(float v1, float v2, float v3, float v4, float v5, float v6);
200
+ void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7);
201
+ void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8);
202
+ void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9);
203
+ void Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9, float v10);
204
+ void Log(const std::vector<float> & vals);
205
+
206
+ #ifdef USE_EIGEN
207
+ template<typename Derived>
208
+ void Log(const Eigen::MatrixBase<Derived>& M)
209
+ {
210
+ Log( M.rows() * M.cols(), M.template cast<float>().eval().data() );
211
+ }
212
+ #endif
213
+
214
+ void Clear();
215
+ void Save(std::string filename);
216
+
217
+ // Return first block of stored data
218
+ const DataLogBlock* FirstBlock() const;
219
+
220
+ // Return last block of stored data
221
+ const DataLogBlock* LastBlock() const;
222
+
223
+ // Return number of samples stored in this DataLog
224
+ size_t Samples() const;
225
+
226
+ // Return pointer to stored sample n
227
+ const float* Sample(int n) const;
228
+
229
+ // Return stats computed for each dimension if enabled.
230
+ const DimensionStats& Stats(size_t dim) const;
231
+
232
+ std::mutex access_mutex;
233
+
234
+ protected:
235
+ unsigned int block_samples_alloc;
236
+ std::vector<std::string> labels;
237
+ std::unique_ptr<DataLogBlock> block0;
238
+ DataLogBlock* blockn;
239
+ std::vector<DimensionStats> stats;
240
+ bool record_stats;
241
+ };
242
+
243
+ }
third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/loaders/csv_table_loader.h ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #pragma once
2
+
3
+ #include <fstream>
4
+ #include <memory>
5
+ #include "table_loader.h"
6
+
7
+ namespace pangolin {
8
+
9
+ class CsvTableLoader : public TableLoaderInterface
10
+ {
11
+ public:
12
+ /// Construct to read from the set of files \param csv_files such that
13
+ /// each row consists of the columns of each file in the provided order
14
+ ///
15
+ /// \param csv_files a list of CSV files to read from
16
+ /// \param delim the field delimiter between columns, normally ',' for CSV
17
+ CsvTableLoader(const std::vector<std::string>& csv_files, char delim = ',', char comment = '#');
18
+
19
+ bool SkipLines(const std::vector<size_t>& lines_per_input);
20
+
21
+ bool ReadRow(std::vector<std::string>& row) override;
22
+
23
+ private:
24
+ static bool AppendColumns(std::vector<std::string>& cols, std::istream& s, char delim, char comment);
25
+
26
+ char delim;
27
+ char comment;
28
+ std::vector<std::istream*> streams;
29
+ std::vector<std::unique_ptr<std::istream>> owned_streams;
30
+ };
31
+
32
+ }
third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/loaders/table_loader.h ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <pangolin/platform.h>
2
+ #include <vector>
3
+ #include <string>
4
+
5
+ namespace pangolin {
6
+
7
+ struct TableLoaderInterface
8
+ {
9
+ virtual bool ReadRow(std::vector<std::string>& row) = 0;
10
+ };
11
+
12
+ }
third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/plotter.h ADDED
@@ -0,0 +1,295 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2014 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #ifndef PLOTTER_H
29
+ #define PLOTTER_H
30
+
31
+ #include <limits>
32
+
33
+ #include <pangolin/display/view.h>
34
+ #include <pangolin/gl/colour.h>
35
+ #include <pangolin/gl/gl.h>
36
+ #include <pangolin/gl/glfont.h>
37
+ #include <pangolin/gl/glsl.h>
38
+ #include <pangolin/handler/handler.h>
39
+ #include <pangolin/utils/range.h>
40
+ #include <pangolin/plot/datalog.h>
41
+
42
+ #include <set>
43
+
44
+ namespace pangolin
45
+ {
46
+
47
+ enum DrawingMode
48
+ {
49
+ DrawingModePoints = GL_POINTS,
50
+ DrawingModeDashed = GL_LINES,
51
+ DrawingModeLine = GL_LINE_STRIP,
52
+ DrawingModeNone,
53
+ };
54
+
55
+ struct Marker
56
+ {
57
+ enum Direction
58
+ {
59
+ Horizontal,
60
+ Vertical
61
+ };
62
+
63
+ enum Equality
64
+ {
65
+ LessThan = -1,
66
+ Equal = 0,
67
+ GreaterThan = 1
68
+ };
69
+
70
+ Marker(Direction d, float value, Equality leg = Equal, Colour c = Colour() )
71
+ : colour(c)
72
+ {
73
+ if(d == Horizontal) {
74
+ range.x = Rangef::Open();
75
+ range.y = Rangef::Containing(value);
76
+ if(leg == LessThan) {
77
+ range.y.Insert(std::numeric_limits<float>::lowest() );
78
+ }else if(leg == GreaterThan) {
79
+ range.y.Insert(std::numeric_limits<float>::max() );
80
+ }
81
+ }else if(d == Vertical) {
82
+ range.x = Rangef::Containing(value);
83
+ range.y = Rangef::Open();
84
+ if(leg == LessThan) {
85
+ range.x.Insert(std::numeric_limits<float>::lowest() );
86
+ }else if(leg == GreaterThan) {
87
+ range.x.Insert(std::numeric_limits<float>::max() );
88
+ }
89
+ }
90
+ }
91
+
92
+ Marker(const XYRangef& range, const Colour& c = Colour() )
93
+ : range(range), colour(c)
94
+ {
95
+ }
96
+
97
+ XYRangef range;
98
+ Colour colour;
99
+ };
100
+
101
+ class PANGOLIN_EXPORT Plotter : public View, Handler
102
+ {
103
+ public:
104
+ Plotter(
105
+ DataLog* default_log,
106
+ float left=0, float right=600, float bottom=-1, float top=1,
107
+ float tickx=30, float ticky=0.5,
108
+ Plotter* linked_plotter_x = 0,
109
+ Plotter* linked_plotter_y = 0
110
+ );
111
+
112
+ virtual ~Plotter();
113
+
114
+ void Render();
115
+
116
+ XYRangef& GetSelection();
117
+
118
+ XYRangef& GetDefaultView();
119
+ void SetDefaultView(const XYRangef& range);
120
+
121
+ XYRangef& GetView();
122
+ void SetView(const XYRangef& range);
123
+ void SetViewSmooth(const XYRangef& range);
124
+
125
+ void ScrollView(float x, float y);
126
+ void ScrollViewSmooth(float x, float y);
127
+
128
+ void ScaleView(float x, float y, float cx, float cy);
129
+ void ScaleViewSmooth(float x, float y, float cx, float cy);
130
+
131
+ void ResetView();
132
+
133
+ void SetTicks(float tickx, float ticky);
134
+
135
+ void Track(const std::string& x="$i", const std::string& y = "");
136
+ void ToggleTracking();
137
+
138
+ void Trigger(const std::string& x="$0", int edge = -1, float value = 0.0f);
139
+ void ToggleTrigger();
140
+
141
+ void SetBackgroundColour(const Colour& col);
142
+ void SetAxisColour(const Colour& col);
143
+ void SetTickColour(const Colour& col);
144
+
145
+ void ScreenToPlot(int xpix, int ypix, float &xplot, float &yplot);
146
+ void Keyboard(View&, unsigned char key, int x, int y, bool pressed);
147
+ void Mouse(View&, MouseButton button, int x, int y, bool pressed, int mouse_state);
148
+ void MouseMotion(View&, int x, int y, int mouse_state);
149
+ void PassiveMouseMotion(View&, int x, int y, int button_state);
150
+ void Special(View&, InputSpecial inType, float x, float y, float p1, float p2, float p3, float p4, int button_state);
151
+
152
+ /// Remove all current series plots
153
+ void ClearSeries();
154
+
155
+ /// Add series X,Y plot from glsl compatible expressions x_expr, y_expr
156
+ /// $i refers to integral index of datum in log.
157
+ /// $0, $1, $2, ... refers to nth series in log.
158
+ /// e.g. x_expr = "$i", y_expr = "$0" // index - data[0] plot
159
+ /// e.g. x_expr = "$0", y_expr = "$1" // data[0], data[1] X-Y plot
160
+ /// e.g. x_exptr ="$i", y_expr = "sqrt($1)} // index - sqrt(data[0]) plot
161
+ void AddSeries(const std::string& x_expr, const std::string& y_expr,
162
+ DrawingMode drawing_mode = DrawingModeLine, Colour colour = Colour::Unspecified(),
163
+ const std::string &title = "$y", DataLog* log = nullptr
164
+ );
165
+
166
+ std::string PlotTitleFromExpr(const std::string& expr) const;
167
+
168
+ /// Remove all current markers
169
+ void ClearMarkers();
170
+
171
+ /// Add horizontal or vertical inequality marker; equal-to, less-than, or greater than.
172
+ /// This is useful for annotating a critical point or valid region.
173
+ Marker& AddMarker(
174
+ Marker::Direction d, float value,
175
+ Marker::Equality leg = Marker::Equal, Colour c = Colour()
176
+ );
177
+
178
+ Marker& AddMarker( const Marker& marker );
179
+
180
+ void ClearImplicitPlots();
181
+ void AddImplicitPlot();
182
+
183
+ /// Reset colour wheel to initial state. May be useful together with ClearSeries() / ClearMarkers()
184
+ void ResetColourWheel();
185
+
186
+ void ShowHoverLines(bool show)
187
+ {
188
+ showHoverLines = show;
189
+ }
190
+
191
+ void ShowTicks(bool show)
192
+ {
193
+ showTicks = show;
194
+ }
195
+
196
+ protected:
197
+ struct PANGOLIN_EXPORT Tick
198
+ {
199
+ float val;
200
+ float factor;
201
+ std::string symbol;
202
+ };
203
+
204
+ struct PANGOLIN_EXPORT PlotAttrib
205
+ {
206
+ PlotAttrib(std::string name, int plot_id, int location = -1)
207
+ : name(name), plot_id(plot_id), location(location) { }
208
+
209
+ std::string name;
210
+ int plot_id;
211
+ int location;
212
+ };
213
+
214
+ struct PANGOLIN_EXPORT PlotSeries
215
+ {
216
+ PlotSeries();
217
+ void CreatePlot(const std::string& x, const std::string& y, Colour c, std::string title);
218
+
219
+ GlSlProgram prog;
220
+ GlText title;
221
+ bool contains_id;
222
+ std::vector<PlotAttrib> attribs;
223
+ DataLog* log;
224
+ GLenum drawing_mode;
225
+ Colour colour;
226
+ bool used;
227
+ };
228
+
229
+ struct PANGOLIN_EXPORT PlotImplicit
230
+ {
231
+ // Assign to gl_FragColor
232
+ void CreatePlot(const std::string& code);
233
+
234
+ // Expression uses x,y and assignes colours [0,1] to r,g,b,a
235
+ void CreateColouredPlot(const std::string& code);
236
+
237
+ // Expression uses x,y and evaluates to true/false;
238
+ void CreateInequality(const std::string& ie, Colour c);
239
+
240
+ // Expression uses x,y and evaluates to a number
241
+ void CreateDistancePlot(const std::string& dist);
242
+
243
+ GlSlProgram prog;
244
+ };
245
+
246
+ void FixSelection();
247
+ void UpdateView();
248
+ Tick FindTickFactor(float tick);
249
+
250
+ DataLog* default_log;
251
+
252
+ ColourWheel colour_wheel;
253
+ Colour colour_bg;
254
+ Colour colour_tk;
255
+ Colour colour_ax;
256
+
257
+ GlSlProgram prog_lines;
258
+ GlSlProgram prog_text;
259
+
260
+ std::vector<PlotSeries> plotseries;
261
+ std::vector<Marker> plotmarkers;
262
+ std::vector<PlotImplicit> plotimplicits;
263
+
264
+ Tick tick[2];
265
+ XYRangef rview_default;
266
+ XYRangef rview;
267
+ XYRangef target;
268
+ XYRangef selection;
269
+
270
+ void ComputeTrackValue( float track_val[2] );
271
+ XYRangef ComputeAutoSelection();
272
+
273
+ bool track;
274
+ std::string track_x;
275
+ std::string track_y;
276
+ float last_track_val[2];
277
+
278
+ // -1: falling, -0:disable, 1: rising
279
+ int trigger_edge;
280
+ float trigger_value;
281
+ std::string trigger;
282
+
283
+ float hover[2];
284
+ int last_mouse_pos[2];
285
+
286
+ Plotter* linked_plotter_x;
287
+ Plotter* linked_plotter_y;
288
+
289
+ bool showTicks;
290
+ bool showHoverLines;
291
+ };
292
+
293
+ } // namespace pangolin
294
+
295
+ #endif // PLOTTER_H
third-party/DPVO/Pangolin/components/pango_plot/src/datalog.cpp ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2011 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <pangolin/plot/datalog.h>
29
+
30
+ #include <algorithm>
31
+ #include <fstream>
32
+ #include <limits>
33
+
34
+ namespace pangolin
35
+ {
36
+
37
+ void DataLogBlock::AddSamples(size_t num_samples, size_t dimensions, const float* data_dim_major )
38
+ {
39
+ if(nextBlock) {
40
+ // If next block exists, add to it instead
41
+ nextBlock->AddSamples(num_samples, dimensions, data_dim_major);
42
+ }else{
43
+ if(dimensions > dim) {
44
+ // If dimensions is too high for this block, start a new bigger one
45
+ nextBlock = std::unique_ptr<DataLogBlock>(new DataLogBlock(dimensions, max_samples, start_id + samples));
46
+ nextBlock->AddSamples(num_samples,dimensions,data_dim_major);
47
+ }else{
48
+ // Try to copy samples to this block
49
+ const size_t samples_to_copy = std::min(num_samples, SampleSpaceLeft());
50
+
51
+ if(dimensions == dim) {
52
+ // Copy entire block all together
53
+ std::copy(data_dim_major, data_dim_major + samples_to_copy*dim, sample_buffer.get()+samples*dim);
54
+ samples += samples_to_copy;
55
+ data_dim_major += samples_to_copy*dim;
56
+ }else{
57
+ // Copy sample at a time, filling with NaN's where needed.
58
+ float* dst = sample_buffer.get();
59
+ for(size_t i=0; i< samples_to_copy; ++i) {
60
+ std::copy(data_dim_major, data_dim_major + dimensions, dst);
61
+ for(size_t ii = dimensions; ii < dim; ++ii) {
62
+ dst[ii] = std::numeric_limits<float>::quiet_NaN();
63
+ }
64
+ dst += dimensions;
65
+ data_dim_major += dimensions;
66
+ }
67
+ samples += samples_to_copy;
68
+ }
69
+
70
+ // // Update Stats
71
+ // for(size_t s=0; s < samples_to_copy; ++s) {
72
+ // for(size_t d = 0; d < dimensions; ++d) {
73
+ // stats[d].Add(data_dim_major[s*dim + d]);
74
+ // }
75
+ // }
76
+
77
+ // Copy remaining data to next block (this one is full)
78
+ if(samples_to_copy < num_samples) {
79
+ nextBlock = std::unique_ptr<DataLogBlock>(new DataLogBlock(dim, max_samples, start_id + Samples()));
80
+ nextBlock->AddSamples(num_samples-samples_to_copy, dimensions, data_dim_major);
81
+ }
82
+ }
83
+ }
84
+ }
85
+
86
+ DataLog::DataLog(unsigned int buffer_size)
87
+ : block_samples_alloc(buffer_size), block0(nullptr), blockn(nullptr), record_stats(true)
88
+ {
89
+ }
90
+
91
+ DataLog::~DataLog()
92
+ {
93
+ Clear();
94
+ }
95
+
96
+ void DataLog::SetLabels(const std::vector<std::string> & new_labels)
97
+ {
98
+ std::lock_guard<std::mutex> l(access_mutex);
99
+
100
+ // Create new labels if needed
101
+ for( size_t i= labels.size(); i < new_labels.size(); ++i )
102
+ labels.push_back( std::string() );
103
+
104
+ // Add data to existing plots
105
+ for( unsigned int i=0; i<labels.size(); ++i )
106
+ labels[i] = new_labels[i];
107
+ }
108
+
109
+ const std::vector<std::string>& DataLog::Labels() const
110
+ {
111
+ return labels;
112
+ }
113
+
114
+ void DataLog::Log(size_t dimension, const float* vals, unsigned int samples )
115
+ {
116
+ if(!block0) {
117
+ // Create first block
118
+ block0 = std::unique_ptr<DataLogBlock>(new DataLogBlock(dimension, block_samples_alloc, 0));
119
+ blockn = block0.get();
120
+ }
121
+
122
+ if(record_stats) {
123
+ while(stats.size() < dimension) {
124
+ stats.push_back( DimensionStats() );
125
+ }
126
+ for(unsigned int d=0; d<dimension; ++d) {
127
+ DimensionStats& ds = stats[d];
128
+ for(unsigned int s=0; s<samples; ++s) {
129
+ ds.Add(vals[s*dimension+d]);
130
+ }
131
+ }
132
+ }
133
+
134
+ blockn->AddSamples(samples,dimension,vals);
135
+
136
+ // Update pointer to most recent block.
137
+ while(blockn->NextBlock()) {
138
+ blockn = blockn->NextBlock();
139
+ }
140
+ }
141
+
142
+ void DataLog::Log(float v)
143
+ {
144
+ const float vs[] = {v};
145
+ Log(1,vs);
146
+ }
147
+
148
+ void DataLog::Log(float v1, float v2)
149
+ {
150
+ const float vs[] = {v1,v2};
151
+ Log(2,vs);
152
+ }
153
+
154
+ void DataLog::Log(float v1, float v2, float v3)
155
+ {
156
+ const float vs[] = {v1,v2,v3};
157
+ Log(3,vs);
158
+ }
159
+ void DataLog::Log(float v1, float v2, float v3, float v4)
160
+ {
161
+ const float vs[] = {v1,v2,v3,v4};
162
+ Log(4,vs);
163
+ }
164
+ void DataLog::Log(float v1, float v2, float v3, float v4, float v5)
165
+ {
166
+ const float vs[] = {v1,v2,v3,v4,v5};
167
+ Log(5,vs);
168
+ }
169
+ void DataLog::Log(float v1, float v2, float v3, float v4, float v5, float v6)
170
+ {
171
+ const float vs[] = {v1,v2,v3,v4,v5,v6};
172
+ Log(6,vs);
173
+ }
174
+
175
+ void DataLog::Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7)
176
+ {
177
+ const float vs[] = {v1,v2,v3,v4,v5,v6,v7};
178
+ Log(7,vs);
179
+ }
180
+
181
+ void DataLog::Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8)
182
+ {
183
+ const float vs[] = {v1,v2,v3,v4,v5,v6,v7,v8};
184
+ Log(8,vs);
185
+ }
186
+
187
+ void DataLog::Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9)
188
+ {
189
+ const float vs[] = {v1,v2,v3,v4,v5,v6,v7,v8,v9};
190
+ Log(9,vs);
191
+ }
192
+
193
+ void DataLog::Log(float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9, float v10)
194
+ {
195
+ const float vs[] = {v1,v2,v3,v4,v5,v6,v7,v8,v9,v10};
196
+ Log(10,vs);
197
+ }
198
+
199
+ void DataLog::Log(const std::vector<float> & vals)
200
+ {
201
+ Log(vals.size(), &vals[0]);
202
+ }
203
+
204
+ void DataLog::Clear()
205
+ {
206
+ std::lock_guard<std::mutex> l(access_mutex);
207
+
208
+ blockn = nullptr;
209
+ block0 = nullptr;
210
+
211
+ stats.clear();
212
+ }
213
+
214
+ void DataLog::Save(std::string filename)
215
+ {
216
+ std::ofstream csvStream(filename);
217
+
218
+ if (!Labels().empty()) {
219
+ csvStream << Labels()[0];
220
+
221
+ for (size_t i = 1; i < Labels().size(); ++i) {
222
+ csvStream << "," << Labels()[i];
223
+ }
224
+
225
+ csvStream << std::endl;
226
+
227
+ }
228
+
229
+ const DataLogBlock * block = FirstBlock();
230
+
231
+ size_t i = 0;
232
+
233
+ while (block) {
234
+
235
+ const size_t blockEnd = i + block->Samples();
236
+
237
+ for (; i < blockEnd; ++i) {
238
+
239
+ csvStream << block->Sample(i)[0];
240
+
241
+ for (size_t d = 1; d < block->Dimensions(); ++d) {
242
+
243
+ csvStream << "," << block->Sample(i)[d];
244
+
245
+ }
246
+
247
+ csvStream << std::endl;
248
+
249
+ }
250
+
251
+ block = block->NextBlock();
252
+
253
+ }
254
+
255
+ }
256
+
257
+ const DataLogBlock* DataLog::FirstBlock() const
258
+ {
259
+ return block0.get();
260
+ }
261
+
262
+ const DataLogBlock* DataLog::LastBlock() const
263
+ {
264
+ return blockn;
265
+ }
266
+
267
+ const DimensionStats& DataLog::Stats(size_t dim) const
268
+ {
269
+ return stats[dim];
270
+ }
271
+
272
+ size_t DataLog::Samples() const
273
+ {
274
+ if(blockn) {
275
+ return blockn->StartId() + blockn->Samples();
276
+ }
277
+ return 0;
278
+ }
279
+
280
+ const float* DataLog::Sample(int n) const
281
+ {
282
+ if(block0) {
283
+ return block0->Sample(n);
284
+ }else{
285
+ return 0;
286
+ }
287
+ }
288
+
289
+ }
third-party/DPVO/Pangolin/components/pango_plot/src/loaders/csv_table_loader.cpp ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <pangolin/plot/loaders/csv_table_loader.h>
2
+ #include <fstream>
3
+ #include <memory>
4
+
5
+ namespace pangolin {
6
+
7
+ CsvTableLoader::CsvTableLoader(const std::vector<std::string>& csv_files, char delim, char comment)
8
+ : delim(delim), comment(comment)
9
+ {
10
+ for(const auto& f : csv_files) {
11
+ if(f == "-") {
12
+ streams.push_back(&std::cin);
13
+ }else{
14
+ std::ifstream* pFile = new std::ifstream(f);
15
+ owned_streams.emplace_back(pFile);
16
+ streams.push_back(pFile);
17
+ PANGO_ASSERT(pFile->is_open());
18
+ }
19
+ }
20
+ }
21
+
22
+ bool CsvTableLoader::SkipLines(const std::vector<size_t>& lines_per_input)
23
+ {
24
+ if(lines_per_input.size()) {
25
+ PANGO_ASSERT(lines_per_input.size() == streams.size());
26
+ std::vector<std::string> dummy_row;
27
+
28
+ for(size_t i=0; i < streams.size(); ++i) {
29
+ for(size_t r=0; r < lines_per_input[i]; ++r) {
30
+ if(!AppendColumns(dummy_row, *streams[i], delim, '\0')) {
31
+ return false;
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ return true;
38
+ }
39
+
40
+ bool CsvTableLoader::ReadRow(std::vector<std::string>& row)
41
+ {
42
+ row.clear();
43
+
44
+ for(auto& s : streams) {
45
+ if(!AppendColumns(row, *s, delim, comment)) {
46
+ return false;
47
+ }
48
+ }
49
+
50
+ return true;
51
+ }
52
+
53
+ bool CsvTableLoader::AppendColumns(std::vector<std::string>& cols, std::istream& s, char delim, char comment)
54
+ {
55
+ // Read line from stream
56
+ std::string row;
57
+ do {
58
+ std::getline(s,row);
59
+ }while(row.length() > 0 && row[0] == comment);
60
+
61
+
62
+ // Failure if no lines to read
63
+ if(!s.good()) return false;
64
+
65
+ std::stringstream row_stream(row);
66
+ std::string cell;
67
+
68
+ // Read cells
69
+ while(std::getline(row_stream, cell, delim)) {
70
+ cols.push_back(cell);
71
+ }
72
+
73
+ // Check for an empty trailing cell
74
+ if (!row_stream && cell.empty()) {
75
+ cols.push_back("");
76
+ }
77
+
78
+ return true;
79
+ }
80
+
81
+ }
third-party/DPVO/Pangolin/components/pango_plot/src/plotter.cpp ADDED
@@ -0,0 +1,1174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2014 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #include <pangolin/gl/gldraw.h>
29
+ #include <pangolin/plot/plotter.h>
30
+ #include <pangolin/display/default_font.h>
31
+
32
+ #include <cctype>
33
+ #include <iomanip>
34
+
35
+ namespace pangolin
36
+ {
37
+
38
+ std::string ReplaceChar(const std::string& str, char from, char to)
39
+ {
40
+ std::string ret = str;
41
+ for(size_t i=0; i<ret.length(); ++i) {
42
+ if(ret[i] == from) ret[i] = to;
43
+ }
44
+ return ret;
45
+ }
46
+
47
+ std::set<int> ConvertSequences(const std::string& str, char seq_char='$', char id_char='i')
48
+ {
49
+ std::set<int> sequences;
50
+
51
+ for(size_t i=0; i<str.length(); ++i) {
52
+ if(str[i] == seq_char) {
53
+ if(i+1 < str.length() && str[i+1] == id_char) {
54
+ sequences.insert(-1);
55
+ }else{
56
+ int v = 0;
57
+ for(size_t j=i+1; std::isdigit(str[j]) && j< str.length(); ++j) {
58
+ v = v*10 + (str[j] - '0');
59
+ }
60
+ sequences.insert(v);
61
+ }
62
+ }
63
+ }
64
+
65
+ return sequences;
66
+ }
67
+
68
+ Plotter::PlotSeries::PlotSeries()
69
+ : log(nullptr), drawing_mode(GL_LINE_STRIP)
70
+ {
71
+
72
+ }
73
+
74
+ // X-Y Plot given C-Code style (GLSL) expressions x and y.
75
+ void Plotter::PlotSeries::CreatePlot(const std::string &x, const std::string &y, Colour colour, std::string title)
76
+ {
77
+ static const std::string vs_header =
78
+ "uniform float u_id_offset;\n"
79
+ "uniform vec4 u_color;\n"
80
+ "uniform vec2 u_scale;\n"
81
+ "uniform vec2 u_offset;\n"
82
+ "varying vec4 v_color;\n"
83
+ "void main() {\n";
84
+
85
+ static const std::string vs_footer =
86
+ " vec2 pos = vec2(x, y);\n"
87
+ " gl_Position = vec4(u_scale * (pos + u_offset),0.0,1.0);\n"
88
+ " v_color = u_color;\n"
89
+ "}\n";
90
+
91
+ static const std::string fs =
92
+ #ifdef HAVE_GLES_2
93
+ "precision mediump float;\n"
94
+ #endif // HAVE_GLES_2
95
+ "varying vec4 v_color;\n"
96
+ "void main() {\n"
97
+ " gl_FragColor = v_color;\n"
98
+ "}\n";
99
+
100
+ attribs.clear();
101
+
102
+ this->colour = colour;
103
+ this->title = default_font().Text(title.c_str());
104
+ const std::set<int> ax = ConvertSequences(x);
105
+ const std::set<int> ay = ConvertSequences(y);
106
+ std::set<int> as;
107
+ as.insert(ax.begin(), ax.end());
108
+ as.insert(ay.begin(), ay.end());
109
+ contains_id = ( as.find(-1) != as.end() );
110
+
111
+ std::ostringstream oss_prog;
112
+
113
+ for(std::set<int>::const_iterator i=as.begin(); i != as.end(); ++i) {
114
+ std::ostringstream oss;
115
+ oss << "s" << *i;
116
+ const std::string name = *i >= 0 ? oss.str() : "sn";
117
+ attribs.push_back( PlotAttrib(name, *i) );
118
+ oss_prog << "attribute float " + name + ";\n";
119
+ }
120
+
121
+ oss_prog << vs_header;
122
+ if(contains_id) {
123
+ oss_prog << "float si = sn + u_id_offset;\n";
124
+ }
125
+ oss_prog << "float x = " + ReplaceChar(x,'$','s') + ";\n";
126
+ oss_prog << "float y = " + ReplaceChar(y,'$','s') + ";\n";
127
+ oss_prog << vs_footer;
128
+
129
+ prog.AddShader( GlSlVertexShader, oss_prog.str() );
130
+ prog.AddShader( GlSlFragmentShader, fs );
131
+ prog.Link();
132
+
133
+ // Lookup attribute locations in compiled shader
134
+ prog.SaveBind();
135
+ for(size_t i=0; i<attribs.size(); ++i) {
136
+ attribs[i].location = prog.GetAttributeHandle( attribs[i].name );
137
+ }
138
+ prog.Unbind();
139
+ }
140
+
141
+ void Plotter::PlotImplicit::CreatePlot(const std::string& code)
142
+ {
143
+ static const std::string vs =
144
+ "attribute vec2 a_position;\n"
145
+ "uniform vec2 u_scale;\n"
146
+ "uniform vec2 u_offset;\n"
147
+ "varying float x;\n"
148
+ "varying float y;\n"
149
+ "void main() {\n"
150
+ " gl_Position = vec4(u_scale * (a_position + u_offset),0,1);\n"
151
+ " x = a_position.x;"
152
+ " y = a_position.y;"
153
+ "}\n";
154
+
155
+ static const std::string fs1 =
156
+ #ifdef HAVE_GLES_2
157
+ "precision mediump float;\n"
158
+ #endif // HAVE_GLES_2
159
+ "varying float x;\n"
160
+ "varying float y;\n"
161
+ "void main() {\n";
162
+ static const std::string fs2 =
163
+ " gl_FragColor = z;\n"
164
+ "}\n";
165
+
166
+ prog.AddShader( GlSlVertexShader, vs );
167
+ prog.AddShader( GlSlFragmentShader, fs1 + code + fs2 );
168
+ prog.BindPangolinDefaultAttribLocationsAndLink();
169
+ }
170
+
171
+
172
+ void Plotter::PlotImplicit::CreateColouredPlot(const std::string& code)
173
+ {
174
+ CreatePlot(
175
+ " float r=1.0;\n"
176
+ " float g=1.0;\n"
177
+ " float b=1.0;\n"
178
+ " float a=0.5;\n" +
179
+ code +
180
+ " z = vec4(r,g,b,a);\n"
181
+ );
182
+ }
183
+
184
+ void Plotter::PlotImplicit::CreateInequality(const std::string& ie, Colour c)
185
+ {
186
+ std::ostringstream oss;
187
+ oss << std::fixed << std::setprecision(1);
188
+ oss << "if( !(" << ie << ") ) discard;\n";
189
+ oss << "z = vec4(" << c.r << "," << c.g << "," << c.b << "," << c.a << ");\n";
190
+
191
+ CreatePlot( oss.str() );
192
+ }
193
+
194
+ void Plotter::PlotImplicit::CreateDistancePlot(const std::string& /*dist*/)
195
+ {
196
+
197
+ }
198
+
199
+ Plotter::Plotter(
200
+ DataLog* log,
201
+ float left, float right, float bottom, float top,
202
+ float tickx, float ticky,
203
+ Plotter* linked_plotter_x,
204
+ Plotter* linked_plotter_y
205
+ ) : default_log(log),
206
+ colour_wheel(0.6f),
207
+ rview_default(left,right,bottom,top), rview(rview_default), target(rview),
208
+ selection(0,0,0,0),
209
+ track(false), track_x("$i"), track_y(""),
210
+ trigger_edge(0), trigger("$0"),
211
+ linked_plotter_x(linked_plotter_x),
212
+ linked_plotter_y(linked_plotter_y)
213
+ {
214
+ // Prevent links to ourselves - this could cause infinite recursion.
215
+ if(linked_plotter_x == this) this->linked_plotter_x = 0;
216
+ if(linked_plotter_y == this) this->linked_plotter_y = 0;
217
+
218
+ // Handle our own mouse / keyboard events
219
+ this->handler = this;
220
+ hover[0] = 0;
221
+ hover[1] = 0;
222
+
223
+ // Default colour scheme
224
+ colour_bg = Colour(0.0f, 0.0f, 0.0f);
225
+ colour_tk = Colour(0.2f, 0.2f, 0.2f);
226
+ colour_ax = Colour(0.5f, 0.5f, 0.5f);
227
+
228
+ SetTicks(tickx, ticky);
229
+
230
+ // Create shader for drawing simple primitives
231
+ prog_lines.AddShader( GlSlVertexShader,
232
+ "attribute vec2 a_position;\n"
233
+ "uniform vec4 u_color;\n"
234
+ "uniform vec2 u_scale;\n"
235
+ "uniform vec2 u_offset;\n"
236
+ "varying vec4 v_color;\n"
237
+ "void main() {\n"
238
+ " gl_Position = vec4(u_scale * (a_position + u_offset),0,1);\n"
239
+ " v_color = u_color;\n"
240
+ "}\n"
241
+ );
242
+ prog_lines.AddShader( GlSlFragmentShader,
243
+ #ifdef HAVE_GLES_2
244
+ "precision mediump float;\n"
245
+ #endif // HAVE_GLES_2
246
+ "varying vec4 v_color;\n"
247
+ "void main() {\n"
248
+ " gl_FragColor = v_color;\n"
249
+ "}\n"
250
+ );
251
+ prog_lines.BindPangolinDefaultAttribLocationsAndLink();
252
+
253
+ prog_text.AddShader( GlSlVertexShader,
254
+ "attribute vec2 a_position;\n"
255
+ "attribute vec2 a_texcoord;\n"
256
+ "uniform vec4 u_color;\n"
257
+ "uniform vec2 u_scale;\n"
258
+ "uniform vec2 u_offset;\n"
259
+ "varying vec4 v_color;\n"
260
+ "varying vec2 v_texcoord;\n"
261
+ "void main() {\n"
262
+ " gl_Position = vec4(u_scale * (a_position + u_offset),0,1);\n"
263
+ " v_color = u_color;\n"
264
+ " v_texcoord = a_texcoord;\n"
265
+ "}\n"
266
+ );
267
+ prog_text.AddShader( GlSlFragmentShader,
268
+ #ifdef HAVE_GLES_2
269
+ "precision mediump float;\n"
270
+ #endif // HAVE_GLES_2
271
+ "varying vec4 v_color;\n"
272
+ "varying vec2 v_texcoord;\n"
273
+ "uniform sampler2D u_texture;\n"
274
+ "void main() {\n"
275
+ " gl_FragColor = v_color;\n"
276
+ " gl_FragColor.a *= texture2D(u_texture, v_texcoord).a;\n"
277
+ "}\n"
278
+ );
279
+ prog_text.BindPangolinDefaultAttribLocationsAndLink();
280
+
281
+ const size_t RESERVED_SIZE = 100;
282
+
283
+ // Setup default PlotSeries
284
+ plotseries.reserve(RESERVED_SIZE);
285
+ for(unsigned int i=0; i< 10; ++i) {
286
+ std::ostringstream ss;
287
+ ss << "$" << i;
288
+ if(log) AddSeries("$i", ss.str());
289
+ }
290
+
291
+ // Setup test PlotMarkers
292
+ plotmarkers.reserve(RESERVED_SIZE);
293
+ // plotmarkers.push_back( Marker( Marker::Vertical, 10, Marker::GreaterThan, Colour(1,0,0,0.2)) );
294
+ // plotmarkers.push_back( Marker( Marker::Horizontal, 1, Marker::LessThan, Colour(0,1,0,0.2)) );
295
+
296
+ // Setup test implicit plots.
297
+ plotimplicits.reserve(RESERVED_SIZE);
298
+ // plotimplicits.push_back( PlotImplicit() );
299
+ // plotimplicits.back().CreateInequality("x+y <= 150.0", colour_wheel.GetUniqueColour().WithAlpha(0.2) );
300
+ // plotimplicits.push_back( PlotImplicit() );
301
+ // plotimplicits.back().CreateInequality("x+2.0*y <= 170.0", colour_wheel.GetUniqueColour().WithAlpha(0.2) );
302
+ // plotimplicits.push_back( PlotImplicit() );
303
+ // plotimplicits.back().CreateInequality("3.0*y <= 180.0", colour_wheel.GetUniqueColour().WithAlpha(0.2) );
304
+
305
+ // Setup texture spectogram style plots
306
+ // ...
307
+
308
+ showTicks = true;
309
+ showHoverLines = true;
310
+ }
311
+
312
+ Plotter::~Plotter()
313
+ {
314
+
315
+ }
316
+
317
+ template <typename T> int data_sgn(T val) {
318
+ return (T(0) < val) - (val < T(0));
319
+ }
320
+
321
+ void Plotter::ComputeTrackValue( float track_val[2] )
322
+ {
323
+ if(trigger_edge) {
324
+ // Track last edge transition matching trigger_edge
325
+ const DataLogBlock* block = default_log->LastBlock();
326
+ if(block) {
327
+ int s = (int)block->StartId() + (int)block->Samples() - 1;
328
+ const size_t dim = block->Dimensions();
329
+ const float* data = block->Sample(s);
330
+ int last_sgn = 0;
331
+ for(; s >= 0; --s, data -= dim )
332
+ {
333
+ const float val = data[0] - trigger_value;
334
+ const int sgn = data_sgn(val);
335
+ if(last_sgn * sgn == -1 && last_sgn == trigger_edge) {
336
+ track_val[0] = (float)s;
337
+ track_val[1] = 0.0f;
338
+ return;
339
+ }
340
+ last_sgn = sgn;
341
+ }
342
+ }
343
+ // Fall back to simple last value tracking
344
+ }
345
+
346
+ track_val[0] = (float)default_log->Samples();
347
+ track_val[1] = 0.0f;
348
+ }
349
+
350
+ XYRangef Plotter::ComputeAutoSelection()
351
+ {
352
+ XYRangef range;
353
+ range.x = target.x;
354
+
355
+ const DataLogBlock* block = default_log->FirstBlock();
356
+
357
+ if(block) {
358
+ for(size_t i=0; i < plotseries.size(); ++i)
359
+ {
360
+ if( plotseries[i].attribs.size() == 2 && plotseries[i].attribs[0].plot_id == -1) {
361
+ const int id = plotseries[i].attribs[1].plot_id;
362
+ if( 0<= id && id < (int)block->Dimensions()) {
363
+ range.y.Insert(default_log->Stats(id).min);
364
+ range.y.Insert(default_log->Stats(id).max);
365
+ }
366
+ }
367
+
368
+ }
369
+ }
370
+
371
+ return range;
372
+ }
373
+
374
+ void Plotter::Render()
375
+ {
376
+ // Animate scroll / zooming
377
+ UpdateView();
378
+
379
+ #ifndef HAVE_GLES
380
+ glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT);
381
+ #endif
382
+
383
+ glClearColor(colour_bg.r, colour_bg.g, colour_bg.b, colour_bg.a);
384
+ ActivateAndScissor();
385
+
386
+ if(std::isfinite(colour_bg.a)) {
387
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
388
+ }
389
+
390
+ if(extern_draw_function && show) {
391
+ glMatrixMode(GL_PROJECTION);
392
+ ProjectionMatrixOrthographic(rview.x.min, rview.x.max, rview.y.max, rview.y.min, -1.0f, 1.0f).Load();
393
+ glMatrixMode(GL_MODELVIEW);
394
+ glLoadIdentity();
395
+
396
+ extern_draw_function(*this);
397
+ }
398
+
399
+ // Try to create smooth lines
400
+ glDisable(GL_MULTISAMPLE);
401
+ glLineWidth(1.5);
402
+ glEnable(GL_LINE_SMOOTH);
403
+ glHint( GL_LINE_SMOOTH_HINT, GL_NICEST );
404
+ glEnable (GL_BLEND);
405
+ glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
406
+ glDisable(GL_LIGHTING);
407
+ glDisable( GL_DEPTH_TEST );
408
+
409
+ const float w = rview.x.AbsSize();
410
+ const float h = rview.y.AbsSize();
411
+ const float ox = -rview.x.Mid();
412
+ const float oy = -rview.y.Mid();
413
+ const float sx = 2.0f / w;
414
+ const float sy = 2.0f / h;
415
+
416
+ //////////////////////////////////////////////////////////////////////////
417
+ // Draw ticks
418
+ prog_lines.SaveBind();
419
+ prog_lines.SetUniform("u_scale", sx, sy);
420
+ prog_lines.SetUniform("u_offset", ox, oy);
421
+ prog_lines.SetUniform("u_color", colour_tk );
422
+
423
+ const float min_space = 80.0;
424
+ float ta[2] = {1,1};
425
+
426
+ while(true)
427
+ {
428
+ const float interval = v.w * tick[0].val / w;
429
+
430
+ if(ta[0] * interval < min_space)
431
+ ta[0] *=2;
432
+ if(ta[0] * interval < min_space)
433
+ ta[0] =(5*ta[0])/2;
434
+ if(ta[0] * interval < min_space)
435
+ ta[0] *=2;
436
+ else
437
+ break;
438
+ }
439
+ while(true)
440
+ {
441
+ const float interval = v.h * tick[1].val / h;
442
+
443
+ if(ta[1] * interval < min_space)
444
+ ta[1] *=2;
445
+ if(ta[1] * interval < min_space)
446
+ ta[1] =(5*ta[1])/2;
447
+ if(ta[1] * interval < min_space)
448
+ ta[1] *=2;
449
+ else
450
+ break;
451
+ }
452
+
453
+ const float tdelta[2] = {
454
+ tick[0].val * ta[0],
455
+ tick[1].val * ta[1]
456
+ };
457
+
458
+ const int tx[2] = {
459
+ (int)ceil(rview.x.min / tdelta[0]),
460
+ (int)ceil(rview.x.max / tdelta[0])
461
+ };
462
+
463
+ const int ty[2] = {
464
+ (int)ceil(rview.y.min / tdelta[1]),
465
+ (int)ceil(rview.y.max / tdelta[1])
466
+ };
467
+ if(showTicks)
468
+ {
469
+ for( int i=tx[0]; i<tx[1]; ++i ) {
470
+ glDrawLine((i)*tdelta[0], rview.y.min, (i)*tdelta[0], rview.y.max);
471
+ }
472
+
473
+ for( int i=ty[0]; i<ty[1]; ++i ) {
474
+ glDrawLine(rview.x.min, (i)*tdelta[1], rview.x.max, (i)*tdelta[1]);
475
+ }
476
+ }
477
+ prog_lines.Unbind();
478
+
479
+ //////////////////////////////////////////////////////////////////////////
480
+ // Draw axis
481
+
482
+ prog_lines.SaveBind();
483
+ prog_lines.SetUniform("u_color", colour_ax );
484
+ glDrawLine(0, rview.y.min, 0, rview.y.max );
485
+ glDrawLine(rview.x.min,0, rview.x.max,0 );
486
+ prog_lines.Unbind();
487
+
488
+ //////////////////////////////////////////////////////////////////////////
489
+ // Draw Implicits
490
+
491
+ for(size_t i=0; i < plotimplicits.size(); ++i) {
492
+ PlotImplicit& im = plotimplicits[i];
493
+ im.prog.SaveBind();
494
+
495
+ im.prog.SetUniform("u_scale", sx, sy);
496
+ im.prog.SetUniform("u_offset", ox, oy);
497
+
498
+ glDrawRect(rview.x.min,rview.y.min,rview.x.max,rview.y.max);
499
+
500
+ im.prog.Unbind();
501
+ }
502
+
503
+ //////////////////////////////////////////////////////////////////////////
504
+ // Draw series
505
+
506
+ static size_t id_size = 0;
507
+ static float* id_array = 0;
508
+
509
+ for(size_t i=0; i < plotseries.size(); ++i)
510
+ {
511
+ PlotSeries& ps = plotseries[i];
512
+
513
+ if(ps.drawing_mode != pangolin::DrawingModeNone)
514
+ {
515
+ GlSlProgram& prog = ps.prog;
516
+ ps.used = false;
517
+
518
+ prog.SaveBind();
519
+ prog.SetUniform("u_scale", sx, sy);
520
+ prog.SetUniform("u_offset", ox, oy);
521
+ prog.SetUniform("u_color", ps.colour );
522
+
523
+ // TODO: Try to skip drawing of blocks which aren't in view.
524
+ DataLog* log = ps.log ? ps.log : default_log;
525
+ std::lock_guard<std::mutex> l(log->access_mutex);
526
+
527
+ const DataLogBlock* block = log->FirstBlock();
528
+ while(block) {
529
+ if(ps.contains_id ) {
530
+ if(id_size < block->Samples() ) {
531
+ // Create index array that we can bind
532
+ delete[] id_array;
533
+ id_size = block->MaxSamples();
534
+ id_array = new float[id_size];
535
+ for(size_t k=0; k < id_size; ++k) {
536
+ id_array[k] = (float)k;
537
+ }
538
+ }
539
+ prog.SetUniform("u_id_offset", (float)block->StartId() );
540
+ }
541
+
542
+ // Enable appropriate attributes
543
+ bool shouldRender = true;
544
+ for(size_t i=0; i< ps.attribs.size(); ++i) {
545
+ if(0 <= ps.attribs[i].plot_id && ps.attribs[i].plot_id < (int)block->Dimensions() ) {
546
+ glVertexAttribPointer(ps.attribs[i].location, 1, GL_FLOAT, GL_FALSE, (GLsizei)(block->Dimensions()*sizeof(float)), block->DimData(ps.attribs[i].plot_id) );
547
+ glEnableVertexAttribArray(ps.attribs[i].location);
548
+ }else if( ps.attribs[i].plot_id == -1 ){
549
+ glVertexAttribPointer(ps.attribs[i].location, 1, GL_FLOAT, GL_FALSE, 0, id_array );
550
+ glEnableVertexAttribArray(ps.attribs[i].location);
551
+ }else{
552
+ // bad id: don't render
553
+ shouldRender = false;
554
+ break;
555
+ }
556
+ }
557
+
558
+ if(shouldRender) {
559
+ // Draw geometry
560
+ glDrawArrays(ps.drawing_mode, 0, (GLsizei)block->Samples());
561
+ ps.used = true;
562
+ }
563
+
564
+ // Disable enabled attributes
565
+ for(size_t i=0; i< ps.attribs.size(); ++i) {
566
+ glDisableVertexAttribArray(ps.attribs[i].location);
567
+ }
568
+
569
+ block = block->NextBlock();
570
+ }
571
+ prog.Unbind();
572
+ }
573
+ }
574
+
575
+ prog_lines.SaveBind();
576
+
577
+ //////////////////////////////////////////////////////////////////////////
578
+ // Draw markers
579
+ glLineWidth(2.5f);
580
+
581
+ for( size_t i=0; i < plotmarkers.size(); ++i) {
582
+ const Marker& m = plotmarkers[i];
583
+
584
+ XYRangef draw_range = m.range;
585
+ draw_range.Clamp(rview);
586
+
587
+ prog_lines.SetUniform("u_color", m.colour );
588
+ if(draw_range.x.Size() == 0.0 || draw_range.y.Size() == 0.0) {
589
+ // Horizontal or Vertical line
590
+ glDrawLine(draw_range.x.min, draw_range.y.min, draw_range.x.max, draw_range.y.max );
591
+ }else{
592
+ // Region
593
+ glDrawRect(draw_range.x.min, draw_range.y.min, draw_range.x.max, draw_range.y.max );
594
+ }
595
+ }
596
+
597
+ //////////////////////////////////////////////////////////////////////////
598
+ // Draw hover / selection
599
+ glLineWidth(1.5f);
600
+
601
+ if(showHoverLines)
602
+ {
603
+ // hover over
604
+ prog_lines.SetUniform("u_color", colour_ax.WithAlpha(0.3f) );
605
+ glDrawLine(hover[0], rview.y.min, hover[0], rview.y.max );
606
+ glDrawLine(rview.x.min, hover[1], rview.x.max, hover[1] );
607
+
608
+ // range
609
+ prog_lines.SetUniform("u_color", colour_ax.WithAlpha(0.5) );
610
+ glDrawLine(selection.x.min, rview.y.min, selection.x.min, rview.y.max );
611
+ glDrawLine(selection.x.max, rview.y.min, selection.x.max, rview.y.max );
612
+ glDrawLine(rview.x.min, selection.y.min, rview.x.max, selection.y.min );
613
+ glDrawLine(rview.x.min, selection.y.max, rview.x.max, selection.y.max );
614
+ glDrawRect(selection.x.min, selection.y.min, selection.x.max, selection.y.max);
615
+ }
616
+ prog_lines.Unbind();
617
+
618
+ prog_text.SaveBind();
619
+
620
+ //////////////////////////////////////////////////////////////////////////
621
+ // Draw Key
622
+
623
+ prog_text.SetUniform("u_scale", 2.0f / v.w, 2.0f / v.h);
624
+
625
+ int keyid = 0;
626
+ for(size_t i=0; i < plotseries.size(); ++i)
627
+ {
628
+ PlotSeries& ps = plotseries[i];
629
+ if(ps.used && ps.drawing_mode != pangolin::DrawingModeNone) {
630
+ prog_text.SetUniform("u_color", ps.colour );
631
+ prog_text.SetUniform("u_offset",
632
+ v.w-5-ps.title.Width() -(v.w/2.0f),
633
+ v.h-1.2*default_font().Height()*(++keyid) -(v.h/2.0f)
634
+ );
635
+ ps.title.DrawGlSl();
636
+ }
637
+ }
638
+
639
+ //////////////////////////////////////////////////////////////////////////
640
+ // Draw axis text
641
+
642
+ prog_text.SetUniform("u_scale", 2.0f / v.w, 2.0f / v.h);
643
+ prog_text.SetUniform("u_color", colour_ax );
644
+
645
+ for( int i=tx[0]; i<tx[1]; ++i ) {
646
+ std::ostringstream oss;
647
+ oss << i*tdelta[0]*tick[0].factor << tick[0].symbol;
648
+ GlText txt = default_font().Text(oss.str().c_str());
649
+ float sx = v.w*((i)*tdelta[0]-rview.x.Mid())/w - txt.Width()/2.0f;
650
+ prog_text.SetUniform("u_offset", sx, 15 -v.h/2.0f );
651
+ txt.DrawGlSl();
652
+ }
653
+
654
+ for( int i=ty[0]; i<ty[1]; ++i ) {
655
+ std::ostringstream oss;
656
+ oss << i*tdelta[1]*tick[1].factor << tick[1].symbol;
657
+ GlText txt = default_font().Text(oss.str().c_str());
658
+ float sy = v.h*((i)*tdelta[1]-rview.y.Mid())/h - txt.Height()/2.0f;
659
+ prog_text.SetUniform("u_offset", 15 -v.w/2.0f, sy );
660
+ txt.DrawGlSl();
661
+ }
662
+
663
+ prog_text.Unbind();
664
+
665
+
666
+ glLineWidth(1.0f);
667
+
668
+ #ifndef HAVE_GLES
669
+ glPopAttrib();
670
+ #endif
671
+
672
+ }
673
+
674
+ Plotter::Tick Plotter::FindTickFactor(float tick)
675
+ {
676
+ Plotter::Tick ret;
677
+ ret.val = tick;
678
+
679
+ const float eps = 1E-6f;
680
+
681
+ if( std::abs(tick/M_PI - floor(tick/M_PI)) < eps ) {
682
+ ret.factor = 1.0f / (float)M_PI;
683
+ ret.symbol = "pi";
684
+ }else if( std::abs(tick/M_PI_2 - floor(tick/M_PI_2)) < eps ) {
685
+ ret.factor = 1.0f / (float)M_PI;
686
+ ret.symbol = "pi";
687
+ }else if( std::abs(tick/M_PI_4 - floor(tick/M_PI_4)) < eps ) {
688
+ ret.factor = 1.0f / (float)M_PI;
689
+ ret.symbol = "pi";
690
+ }else if( std::abs(tick/M_SQRT2 - floor(tick/M_SQRT2)) < eps ) {
691
+ ret.factor = 1.0f / (float)M_SQRT2;
692
+ ret.symbol = "\251 2";
693
+ }else if( std::abs(tick/M_E - floor(tick/M_E)) < eps ) {
694
+ ret.factor = 1.0f / (float)M_E;
695
+ ret.symbol = "e";
696
+ }else{
697
+ ret.factor = 1.0f;
698
+ ret.symbol = "";
699
+ }
700
+ return ret;
701
+ }
702
+
703
+ void Plotter::SetTicks(float tickx, float ticky)
704
+ {
705
+ // Compute tick_factor, tick_label
706
+ tick[0] = FindTickFactor(tickx);
707
+ tick[1] = FindTickFactor(ticky);
708
+ }
709
+
710
+ void Plotter::Track(const std::string& x, const std::string& y)
711
+ {
712
+ Plotter& p = linked_plotter_x ? *linked_plotter_x :
713
+ (linked_plotter_y ? *linked_plotter_y : *this);
714
+
715
+ if( x != "$i" || y != "") {
716
+ throw std::runtime_error("Track option not fully implemented");
717
+ }
718
+
719
+ p.track_x = x;
720
+ p.track_y = y;
721
+ p.track = !p.track_x.empty() || !p.track_y.empty();
722
+ p.ComputeTrackValue(p.last_track_val);
723
+ }
724
+
725
+ void Plotter::ToggleTracking()
726
+ {
727
+ Plotter& p = linked_plotter_x ? *linked_plotter_x :
728
+ (linked_plotter_y ? *linked_plotter_y : *this);
729
+
730
+ p.track = !p.track;
731
+ p.ComputeTrackValue(p.last_track_val);
732
+ }
733
+
734
+ void Plotter::Trigger(const std::string& x, int edge, float value)
735
+ {
736
+ if( x != "$0") {
737
+ throw std::runtime_error("Trigger option not fully implemented");
738
+ }
739
+
740
+ trigger = x;
741
+ trigger_edge = edge;
742
+ trigger_value = value;
743
+ ComputeTrackValue(last_track_val);
744
+ }
745
+
746
+ void Plotter::ToggleTrigger()
747
+ {
748
+ trigger_edge = trigger_edge ? 0 : -1;
749
+ ComputeTrackValue(last_track_val);
750
+ }
751
+
752
+ void Plotter::SetBackgroundColour(const Colour& col)
753
+ {
754
+ colour_bg = col;
755
+ }
756
+
757
+ void Plotter::SetAxisColour(const Colour& col)
758
+ {
759
+ colour_ax = col;
760
+ }
761
+
762
+ void Plotter::SetTickColour(const Colour& col)
763
+ {
764
+ colour_tk = col;
765
+ }
766
+
767
+ XYRangef& Plotter::GetView()
768
+ {
769
+ return target;
770
+ }
771
+
772
+ XYRangef& Plotter::GetDefaultView()
773
+ {
774
+ return rview_default;
775
+ }
776
+
777
+ XYRangef& Plotter::GetSelection()
778
+ {
779
+ return selection;
780
+ }
781
+
782
+ void Plotter::FixSelection()
783
+ {
784
+ // Make sure selection matches sign of current viewport
785
+ if( (selection.x.min<selection.x.max) != (rview.x.min<rview.x.max) ) {
786
+ std::swap(selection.x.min, selection.x.max);
787
+ }
788
+ if( (selection.y.min<selection.y.max) != (rview.y.min<rview.y.max) ) {
789
+ std::swap(selection.y.min, selection.y.max);
790
+ }
791
+ }
792
+
793
+ void Plotter::UpdateView()
794
+ {
795
+ // Track value based on last log sample
796
+ if( (track || trigger_edge) && !(linked_plotter_x || linked_plotter_y) ) {
797
+ float newTrackVal[2];
798
+ ComputeTrackValue(newTrackVal);
799
+ if(target.x.max <= newTrackVal[0] ) {
800
+ ScrollView(newTrackVal[0]-last_track_val[0], newTrackVal[1]-last_track_val[1] );
801
+ }
802
+ last_track_val[0] = newTrackVal[0];
803
+ last_track_val[1] = newTrackVal[1];
804
+ }
805
+
806
+ const float sf = 1.0f / 20.0f;
807
+ // XYRange d = target - rview;
808
+ // rview += d * sf;
809
+
810
+ if( linked_plotter_x ) {
811
+ // Synchronise rview and target with linked plotter
812
+ rview.x = linked_plotter_x->rview.x;
813
+ target.x = linked_plotter_x->target.x;
814
+ }else{
815
+ // Animate view window toward target
816
+ Rangef d = target.x - rview.x;
817
+ rview.x += d * sf;
818
+ }
819
+
820
+ if( linked_plotter_y ) {
821
+ // Synchronise rview and target with linked plotter
822
+ rview.y = linked_plotter_y->rview.y;
823
+ target.y = linked_plotter_y->target.y;
824
+ }else{
825
+ // Animate view window toward target
826
+ Rangef d = target.y - rview.y;
827
+ rview.y += d * sf;
828
+ }
829
+ }
830
+
831
+ void Plotter::SetView(const XYRangef& range)
832
+ {
833
+ Plotter& px = linked_plotter_x ? *linked_plotter_x : *this;
834
+ Plotter& py = linked_plotter_y ? *linked_plotter_y : *this;
835
+
836
+ px.rview.x = range.x;
837
+ py.rview.y = range.y;
838
+ px.target.x = range.x;
839
+ py.target.y = range.y;
840
+ }
841
+
842
+ void Plotter::SetViewSmooth(const XYRangef &range)
843
+ {
844
+ Plotter& px = linked_plotter_x ? *linked_plotter_x : *this;
845
+ Plotter& py = linked_plotter_y ? *linked_plotter_y : *this;
846
+
847
+ px.target.x = range.x;
848
+ py.target.y = range.y;
849
+ }
850
+
851
+ void Plotter::SetDefaultView(const XYRangef &range)
852
+ {
853
+ Plotter& px = linked_plotter_x ? *linked_plotter_x : *this;
854
+ Plotter& py = linked_plotter_y ? *linked_plotter_y : *this;
855
+
856
+ px.rview_default.x = range.x;
857
+ py.rview_default.y = range.y;
858
+ }
859
+
860
+ void Plotter::ScrollView(float x, float y)
861
+ {
862
+ Plotter& px = linked_plotter_x ? *linked_plotter_x : *this;
863
+ Plotter& py = linked_plotter_y ? *linked_plotter_y : *this;
864
+
865
+ px.target.x += x;
866
+ py.target.y += y;
867
+ px.rview.x += x;
868
+ py.rview.y += y;
869
+ }
870
+
871
+ void Plotter::ScrollViewSmooth(float x, float y)
872
+ {
873
+ Plotter& px = linked_plotter_x ? *linked_plotter_x : *this;
874
+ Plotter& py = linked_plotter_y ? *linked_plotter_y : *this;
875
+
876
+ px.target.x += x;
877
+ py.target.y += y;
878
+ }
879
+
880
+ void Plotter::ScaleView(float x, float y, float cx, float cy)
881
+ {
882
+ Plotter& px = linked_plotter_x ? *linked_plotter_x : *this;
883
+ Plotter& py = linked_plotter_y ? *linked_plotter_y : *this;
884
+
885
+ px.target.x.Scale(x, cx);
886
+ py.target.y.Scale(y, cy);
887
+ px.rview.x.Scale(x, cx);
888
+ py.rview.y.Scale(y, cy);
889
+ }
890
+
891
+ void Plotter::ScaleViewSmooth(float x, float y, float cx, float cy)
892
+ {
893
+ Plotter& px = linked_plotter_x ? *linked_plotter_x : *this;
894
+ Plotter& py = linked_plotter_y ? *linked_plotter_y : *this;
895
+
896
+ px.target.x.Scale(x,cx);
897
+ py.target.y.Scale(y,cy);
898
+ }
899
+
900
+ void Plotter::ResetView()
901
+ {
902
+ Plotter& px = linked_plotter_x ? *linked_plotter_x : *this;
903
+ Plotter& py = linked_plotter_y ? *linked_plotter_y : *this;
904
+
905
+ px.target.x = px.rview_default.x;
906
+ py.target.y = py.rview_default.y;
907
+ }
908
+
909
+ void Plotter::Keyboard(View&, unsigned char key, int /*x*/, int /*y*/, bool pressed)
910
+ {
911
+ const float mvfactor = 1.0f / 10.0f;
912
+
913
+ const float c[2] = {
914
+ track || trigger_edge ? target.x.max : rview.x.Mid(),
915
+ rview.y.Mid()
916
+ };
917
+
918
+ if(pressed) {
919
+ if(key == ' ') {
920
+ if( selection.Area() <= 0.0f) {
921
+ // Work out Auto zoom selection bounds
922
+ selection = ComputeAutoSelection();
923
+ }
924
+
925
+ if( selection.Area() > 0.0f) {
926
+ // Set view to equal selection
927
+ SetViewSmooth(selection);
928
+
929
+ // Reset selection
930
+ selection.x.max = selection.x.min;
931
+ selection.y.max = selection.y.min;
932
+ }
933
+ }else if(key == PANGO_SPECIAL + PANGO_KEY_LEFT) {
934
+ const float w = rview.x.Size();
935
+ const float dx = mvfactor*w;
936
+ ScrollViewSmooth(-dx, 0);
937
+ }else if(key == PANGO_SPECIAL + PANGO_KEY_RIGHT) {
938
+ const float w = rview.x.Size();
939
+ const float dx = mvfactor*w;
940
+ ScrollViewSmooth(+dx, 0);
941
+ }else if(key == PANGO_SPECIAL + PANGO_KEY_DOWN) {
942
+ const float h = target.y.Size();
943
+ const float dy = mvfactor*h;
944
+ ScrollViewSmooth(0, -dy);
945
+ }else if(key == PANGO_SPECIAL + PANGO_KEY_UP) {
946
+ const float h = target.y.Size();
947
+ const float dy = mvfactor*h;
948
+ ScrollViewSmooth(0, +dy);
949
+ }else if(key == '=') {
950
+ ScaleViewSmooth(0.5, 0.5, c[0], c[1]);
951
+ }else if(key == '-') {
952
+ ScaleViewSmooth(2.0, 2.0, c[0], c[1]);
953
+ }else if(key == 'r') {
954
+ ResetView();
955
+ }else if(key == 't') {
956
+ ToggleTracking();
957
+ }else if(key == 'e') {
958
+ ToggleTrigger();
959
+ }else if('1' <= key && key <= '9') {
960
+ const size_t id = key - '1';
961
+ if(id < plotseries.size()) {
962
+ PlotSeries& s = plotseries[id];
963
+ if(s.drawing_mode == DrawingModeNone) {
964
+ s.drawing_mode = DrawingModePoints;
965
+ }else{
966
+ ++s.drawing_mode;
967
+ if(s.drawing_mode == GL_LINE_LOOP) {
968
+ ++s.drawing_mode;
969
+ }
970
+ }
971
+ }
972
+ }
973
+ }
974
+ }
975
+
976
+ void Plotter::ScreenToPlot(int xpix, int ypix, float& xplot, float& yplot)
977
+ {
978
+ xplot = rview.x.min + rview.x.Size() * (xpix - v.l) / (float)v.w;
979
+ yplot = rview.y.min + rview.y.Size() * (ypix - v.b) / (float)v.h;
980
+ }
981
+
982
+ void Plotter::Mouse(View& /*view*/, MouseButton button, int x, int y, bool pressed, int button_state)
983
+ {
984
+ // Update hover status (after potential resizing)
985
+ ScreenToPlot(x, y, hover[0], hover[1]);
986
+
987
+ const float scinc = 1.05f;
988
+ const float scdec = 1.0f/scinc;
989
+
990
+ const float c[2] = {
991
+ track || trigger_edge ? last_track_val[0] : hover[0],
992
+ hover[1]
993
+ };
994
+
995
+ if(button_state & KeyModifierShift) {
996
+ if(button == MouseWheelUp) {
997
+ ScaleViewSmooth(1.0f, scinc, c[0], c[1]);
998
+ }else if(button == MouseWheelDown) {
999
+ ScaleViewSmooth(1.0f, scdec, c[0], c[1]);
1000
+ }else if(button == MouseWheelLeft) {
1001
+ ScaleViewSmooth(scinc, 1.0f, c[0], c[1]);
1002
+ }else if(button == MouseWheelRight) {
1003
+ ScaleViewSmooth(scdec, 1.0f, c[0], c[1]);
1004
+ }
1005
+ }else if(button_state & KeyModifierCtrl) {
1006
+ if(button == MouseWheelUp) {
1007
+ ScaleViewSmooth(scinc, 1.0f, c[0], c[1]);
1008
+ }else if(button == MouseWheelDown) {
1009
+ ScaleViewSmooth(scdec, 1.0f, c[0], c[1]);
1010
+ }
1011
+ }else{
1012
+ const float mvfactor = 1.0f/20.0f;
1013
+
1014
+ if(button == MouseButtonLeft) {
1015
+ // Update selected range
1016
+ if(pressed) {
1017
+ selection.x.min = hover[0];
1018
+ selection.y.min = hover[1];
1019
+ trigger_value = selection.y.min;
1020
+ }
1021
+ selection.x.max = hover[0];
1022
+ selection.y.max = hover[1];
1023
+ }else if(button == MouseWheelUp) {
1024
+ ScrollViewSmooth(0.0f, +mvfactor*rview.y.Size() );
1025
+ }else if(button == MouseWheelDown) {
1026
+ ScrollViewSmooth(0.0f, -mvfactor*rview.y.Size() );
1027
+ }else if(button == MouseWheelLeft) {
1028
+ ScrollViewSmooth(+mvfactor*rview.x.Size(), 0.0f );
1029
+ }else if(button == MouseWheelRight) {
1030
+ ScrollViewSmooth(-mvfactor*rview.x.Size(), 0.0f );
1031
+ }
1032
+ }
1033
+
1034
+ FixSelection();
1035
+
1036
+ last_mouse_pos[0] = x;
1037
+ last_mouse_pos[1] = y;
1038
+ }
1039
+
1040
+ void Plotter::MouseMotion(View& view, int x, int y, int button_state)
1041
+ {
1042
+ const int d[2] = {x-last_mouse_pos[0], y-last_mouse_pos[1]};
1043
+ const float is[2] = {rview.x.Size(), rview.y.Size() };
1044
+ const float df[2] = {is[0]*d[0]/(float)v.w, is[1]*d[1]/(float)v.h};
1045
+
1046
+ // Update hover status (after potential resizing)
1047
+ ScreenToPlot(x, y, hover[0], hover[1]);
1048
+
1049
+ if( button_state == MouseButtonLeft )
1050
+ {
1051
+ // Update selected range
1052
+ selection.x.max = hover[0];
1053
+ selection.y.max = hover[1];
1054
+ }else if(button_state == MouseButtonMiddle )
1055
+ {
1056
+ Special(view, InputSpecialScroll, df[0], df[1], 0.0f, 0.0f, 0.0f, 0.0f, button_state);
1057
+ }else if(button_state == MouseButtonRight )
1058
+ {
1059
+ const float c[2] = {
1060
+ track || trigger_edge ? last_track_val[0] : hover[0],
1061
+ hover[1]
1062
+ };
1063
+
1064
+ const float scale[2] = {
1065
+ 1.0f + (float)d[0] / (float)v.w,
1066
+ 1.0f - (float)d[1] / (float)v.h,
1067
+ };
1068
+ ScaleView(scale[0], scale[1], c[0], c[1]);
1069
+ }
1070
+
1071
+ last_mouse_pos[0] = x;
1072
+ last_mouse_pos[1] = y;
1073
+ }
1074
+
1075
+ void Plotter::PassiveMouseMotion(View&, int x, int y, int /*button_state*/)
1076
+ {
1077
+ ScreenToPlot(x, y, hover[0], hover[1]);
1078
+ }
1079
+
1080
+ void Plotter::Special(View&, InputSpecial inType, float x, float y, float p1, float p2, float /*p3*/, float /*p4*/, int button_state)
1081
+ {
1082
+ if(inType == InputSpecialScroll) {
1083
+ const float d[2] = {p1,-p2};
1084
+ const float is[2] = {rview.x.Size(),rview.y.Size() };
1085
+ const float df[2] = {is[0]*d[0]/(float)v.w, is[1]*d[1]/(float)v.h};
1086
+
1087
+ ScrollView(-df[0], -df[1]);
1088
+ } else if(inType == InputSpecialZoom) {
1089
+ float scalex = 1.0f-p1;
1090
+ float scaley = 1.0f-p1;
1091
+
1092
+ if (button_state & (KeyModifierCmd | KeyModifierCtrl)) {
1093
+ scaley = 1.0f;
1094
+ }
1095
+ if (button_state & (KeyModifierShift)) {
1096
+ scalex = 1.0f;
1097
+ }
1098
+
1099
+ const float c[2] = {
1100
+ track || trigger_edge ? last_track_val[0] : hover[0],
1101
+ hover[1]
1102
+ };
1103
+
1104
+ ScaleView(scalex, scaley, c[0], c[1]);
1105
+ }
1106
+
1107
+ // Update hover status (after potential resizing)
1108
+ ScreenToPlot( (int)x, (int)y, hover[0], hover[1]);
1109
+ }
1110
+
1111
+ void Plotter::AddSeries(const std::string& x_expr, const std::string& y_expr,
1112
+ DrawingMode drawing_mode, Colour colour,
1113
+ const std::string& title, DataLog *log)
1114
+ {
1115
+ if( !std::isfinite(colour.r) ) {
1116
+ colour = colour_wheel.GetUniqueColour();
1117
+ }
1118
+ plotseries.push_back( PlotSeries() );
1119
+ plotseries.back().CreatePlot(x_expr, y_expr, colour, (title == "$y") ? PlotTitleFromExpr(y_expr) : title);
1120
+ plotseries.back().log = log;
1121
+ plotseries.back().drawing_mode = (GLenum)drawing_mode;
1122
+ }
1123
+
1124
+ std::string Plotter::PlotTitleFromExpr(const std::string& expr) const
1125
+ {
1126
+ const std::vector<std::string>& labels = default_log->Labels();
1127
+
1128
+ std::stringstream exp_in(expr);
1129
+ std::stringstream exp_out;
1130
+ while(!exp_in.eof()) {
1131
+ int c = exp_in.get();
1132
+ if(c=='$') {
1133
+ size_t id = -1;
1134
+ exp_in >> id;
1135
+ if(id < labels.size()) {
1136
+ exp_out << '\'' << labels[id] << '\'';
1137
+ }else{
1138
+ exp_out << '$' << id;
1139
+ }
1140
+ }else{
1141
+ exp_out << (char)c;
1142
+ }
1143
+ }
1144
+
1145
+ return exp_out.str();
1146
+ }
1147
+
1148
+ void Plotter::ClearSeries()
1149
+ {
1150
+ plotseries.clear();
1151
+ }
1152
+
1153
+ Marker& Plotter::AddMarker(Marker::Direction d, float value, Marker::Equality leg, Colour c )
1154
+ {
1155
+ return AddMarker(Marker(d,value,leg,c));
1156
+ }
1157
+
1158
+ Marker& Plotter::AddMarker( const Marker& marker )
1159
+ {
1160
+ plotmarkers.push_back( marker );
1161
+ return plotmarkers.back();
1162
+ }
1163
+
1164
+ void Plotter::ClearMarkers()
1165
+ {
1166
+ plotmarkers.clear();
1167
+ }
1168
+
1169
+ void Plotter::ResetColourWheel()
1170
+ {
1171
+ colour_wheel.Reset();
1172
+ }
1173
+
1174
+ }
third-party/DPVO/Pangolin/components/pango_python/CMakeLists.txt ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ get_filename_component(COMPONENT ${CMAKE_CURRENT_LIST_DIR} NAME)
2
+
3
+ option(BUILD_PANGOLIN_PYTHON "Build support for Pangolin Interactive Console" ON)
4
+
5
+ if(BUILD_PANGOLIN_PYTHON)
6
+ find_package(Python COMPONENTS Interpreter Development QUIET)
7
+ endif()
8
+
9
+ if(BUILD_PANGOLIN_PYTHON AND Python_FOUND)
10
+ # If we've inited the submodule, use that
11
+ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/pybind11/CMakeLists.txt")
12
+ add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/pybind11)
13
+ else()
14
+ find_package(pybind11 CONFIG QUIET)
15
+ endif()
16
+ endif()
17
+
18
+ if(BUILD_PANGOLIN_PYTHON AND Python_FOUND AND pybind11_FOUND)
19
+ set(SRC_BINDINGS
20
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/attach.cpp
21
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/colour.cpp
22
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/datalog.cpp
23
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/display.cpp
24
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/gl.cpp
25
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/gl_draw.cpp
26
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/glsl.cpp
27
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/glvbo.cpp
28
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/handler.cpp
29
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/image.cpp
30
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/image_view.cpp
31
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/opengl_render_state.cpp
32
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/params.cpp
33
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/pixel_format.cpp
34
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/plotter.cpp
35
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/pypangoio.cpp
36
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/var.cpp
37
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/video.cpp
38
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/view.cpp
39
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/viewport.cpp
40
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/widget.cpp
41
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin/window.cpp
42
+ )
43
+
44
+ target_sources(
45
+ ${COMPONENT} PRIVATE
46
+ ${CMAKE_CURRENT_LIST_DIR}/src/pyinterpreter.cpp
47
+ ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin_embed.cpp
48
+ ${SRC_BINDINGS}
49
+ )
50
+
51
+ target_compile_definitions(${COMPONENT} PUBLIC HAVE_PYTHON)
52
+ target_link_libraries(${COMPONENT} PUBLIC
53
+ pango_core pango_display pango_plot pango_video pango_vars
54
+ )
55
+ target_link_libraries(${COMPONENT} PRIVATE pybind11::embed )
56
+ target_include_directories(${COMPONENT} PUBLIC
57
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
58
+ $<INSTALL_INTERFACE:include>
59
+ )
60
+ install(DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/include"
61
+ DESTINATION ${CMAKE_INSTALL_PREFIX}
62
+ )
63
+
64
+ PangolinRegisterFactory( InterpreterInterface PyInterpreter )
65
+
66
+ # Add python module as another target. For some reason, it doesn't work to just link against ${COMPONENT}
67
+ pybind11_add_module(pypangolin ${CMAKE_CURRENT_LIST_DIR}/src/pypangolin_module.cpp ${SRC_BINDINGS})
68
+ target_link_libraries(pypangolin PRIVATE pango_core pango_display pango_plot pango_video pango_vars pybind11::module)
69
+ target_include_directories(pypangolin PUBLIC
70
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
71
+ $<INSTALL_INTERFACE:include>
72
+ )
73
+
74
+ # Create a target for generating a python wheel
75
+ include(MakePythonWheel)
76
+ MakeWheel( pypangolin
77
+ VERSION ${PANGOLIN_VERSION}
78
+ SUMMARY "Pangolin is a lightweight portable rapid development library for managing OpenGL display / interaction and abstracting video input."
79
+ HOMEPAGE "https://github.com/stevenlovegrove/Pangolin"
80
+ AUTHOR "Steven Lovegrove"
81
+ EMAIL "[email protected]"
82
+ LICENCE "MIT"
83
+ REQUIRES "pyopengl;pyopengl-accelerate;numpy;pillow;pybind11"
84
+ PRINT_HELP
85
+ )
86
+ else()
87
+ #TODO: with the following line uncommented and BUILD_PANGOLIN_PYTHON=OFF, `make install` fails b/c it tries to install a missing libpango_python.a
88
+ #set_target_properties(${COMPONENT} PROPERTIES EXCLUDE_FROM_ALL 1 EXCLUDE_FROM_DEFAULT_BUILD 1)
89
+ target_sources( ${COMPONENT} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/../pango_core/src/dummy.cpp )
90
+ endif()
third-party/DPVO/Pangolin/components/pango_python/include/pangolin/python/pyinterpreter.h ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* This file is part of the Pangolin Project.
2
+ * http://github.com/stevenlovegrove/Pangolin
3
+ *
4
+ * Copyright (c) 2011 Steven Lovegrove
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person
7
+ * obtaining a copy of this software and associated documentation
8
+ * files (the "Software"), to deal in the Software without
9
+ * restriction, including without limitation the rights to use,
10
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the
12
+ * Software is furnished to do so, subject to the following
13
+ * conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be
16
+ * included in all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25
+ * OTHER DEALINGS IN THE SOFTWARE.
26
+ */
27
+
28
+ #pragma once
29
+
30
+ #include <pybind11/embed.h>
31
+ #include <pangolin/var/varextra.h>
32
+ #include <pangolin/console/InterpreterInterface.h>
33
+ #include <queue>
34
+ #include <set>
35
+ #include <thread>
36
+
37
+ namespace pangolin
38
+ {
39
+
40
+ class PyInterpreter : public InterpreterInterface
41
+ {
42
+ public:
43
+ PyInterpreter();
44
+
45
+ ~PyInterpreter() override;
46
+
47
+ void PushCommand(const std::string &cmd) override;
48
+
49
+ bool PullLine(InterpreterLine& line) override;
50
+
51
+ std::vector<std::string> Complete(
52
+ const std::string& cmd, int max_options
53
+ ) override;
54
+
55
+ private:
56
+ void NewVarCallback(const pangolin::VarState::Event& e);
57
+
58
+ pybind11::scoped_interpreter guard;
59
+
60
+ pybind11::object pycompleter;
61
+ pybind11::object pycomplete;
62
+
63
+ std::string ToString(const pybind11::object& py);
64
+ pybind11::object EvalExec(const std::string& cmd);
65
+ void CheckPrintClearError();
66
+
67
+ std::queue<InterpreterLine> line_queue;
68
+ std::set<std::string> base_prefixes;
69
+ sigslot::scoped_connection var_added_connection;
70
+ };
71
+
72
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/.appveyor.yml ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: 1.0.{build}
2
+ image:
3
+ - Visual Studio 2015
4
+ test: off
5
+ skip_branch_with_pr: true
6
+ build:
7
+ parallel: true
8
+ platform:
9
+ - x86
10
+ environment:
11
+ matrix:
12
+ - PYTHON: 36
13
+ CONFIG: Debug
14
+ - PYTHON: 27
15
+ CONFIG: Debug
16
+ install:
17
+ - ps: |
18
+ $env:CMAKE_GENERATOR = "Visual Studio 14 2015"
19
+ if ($env:PLATFORM -eq "x64") { $env:PYTHON = "$env:PYTHON-x64" }
20
+ $env:PATH = "C:\Python$env:PYTHON\;C:\Python$env:PYTHON\Scripts\;$env:PATH"
21
+ python -W ignore -m pip install --upgrade pip wheel
22
+ python -W ignore -m pip install pytest numpy --no-warn-script-location pytest-timeout
23
+ - ps: |
24
+ Start-FileDownload 'https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.zip'
25
+ 7z x eigen-3.3.7.zip -y > $null
26
+ $env:CMAKE_INCLUDE_PATH = "eigen-3.3.7;$env:CMAKE_INCLUDE_PATH"
27
+ build_script:
28
+ - cmake -G "%CMAKE_GENERATOR%" -A "%CMAKE_ARCH%"
29
+ -DCMAKE_CXX_STANDARD=14
30
+ -DPYBIND11_WERROR=ON
31
+ -DDOWNLOAD_CATCH=ON
32
+ -DCMAKE_SUPPRESS_REGENERATION=1
33
+ .
34
+ - set MSBuildLogger="C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
35
+ - cmake --build . --config %CONFIG% --target pytest -- /m /v:m /logger:%MSBuildLogger%
36
+ - cmake --build . --config %CONFIG% --target cpptest -- /m /v:m /logger:%MSBuildLogger%
37
+ on_failure: if exist "tests\test_cmake_build" type tests\test_cmake_build\*.log*
third-party/DPVO/Pangolin/components/pango_python/pybind11/.clang-format ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ # See all possible options and defaults with:
3
+ # clang-format --style=llvm --dump-config
4
+ BasedOnStyle: LLVM
5
+ AccessModifierOffset: -4
6
+ AlwaysBreakTemplateDeclarations: Yes
7
+ BinPackArguments: false
8
+ BinPackParameters: false
9
+ BreakBeforeBinaryOperators: All
10
+ BreakConstructorInitializers: BeforeColon
11
+ ColumnLimit: 99
12
+ IndentCaseLabels: true
13
+ IndentPPDirectives: AfterHash
14
+ IndentWidth: 4
15
+ Language: Cpp
16
+ SpaceAfterCStyleCast: true
17
+ Standard: Cpp11
18
+ TabWidth: 4
19
+ ...
third-party/DPVO/Pangolin/components/pango_python/pybind11/.clang-tidy ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FormatStyle: file
2
+
3
+ Checks: '
4
+ cppcoreguidelines-init-variables,
5
+ clang-analyzer-optin.cplusplus.VirtualCall,
6
+ llvm-namespace-comment,
7
+ misc-misplaced-const,
8
+ misc-non-copyable-objects,
9
+ misc-static-assert,
10
+ misc-throw-by-value-catch-by-reference,
11
+ misc-uniqueptr-reset-release,
12
+ misc-unused-parameters,
13
+ modernize-avoid-bind,
14
+ modernize-make-shared,
15
+ modernize-redundant-void-arg,
16
+ modernize-replace-auto-ptr,
17
+ modernize-replace-disallow-copy-and-assign-macro,
18
+ modernize-replace-random-shuffle,
19
+ modernize-shrink-to-fit,
20
+ modernize-use-auto,
21
+ modernize-use-bool-literals,
22
+ modernize-use-equals-default,
23
+ modernize-use-equals-delete,
24
+ modernize-use-default-member-init,
25
+ modernize-use-noexcept,
26
+ modernize-use-emplace,
27
+ modernize-use-override,
28
+ modernize-use-using,
29
+ *performance*,
30
+ readability-avoid-const-params-in-decls,
31
+ readability-container-size-empty,
32
+ readability-else-after-return,
33
+ readability-delete-null-pointer,
34
+ readability-implicit-bool-conversion,
35
+ readability-make-member-function-const,
36
+ readability-misplaced-array-index,
37
+ readability-non-const-parameter,
38
+ readability-redundant-function-ptr-dereference,
39
+ readability-redundant-smartptr-get,
40
+ readability-redundant-string-cstr,
41
+ readability-simplify-subscript-expr,
42
+ readability-static-accessed-through-instance,
43
+ readability-static-definition-in-anonymous-namespace,
44
+ readability-string-compare,
45
+ readability-uniqueptr-delete-release,
46
+ '
47
+
48
+ CheckOptions:
49
+ - key: performance-for-range-copy.WarnOnAllAutoCopies
50
+ value: true
51
+ - key: performance-unnecessary-value-param.AllowedTypes
52
+ value: 'exception_ptr$;'
53
+ - key: readability-implicit-bool-conversion.AllowPointerConditions
54
+ value: true
55
+
56
+ HeaderFilterRegex: 'pybind11/.*h'
57
+
58
+ WarningsAsErrors: '*'
third-party/DPVO/Pangolin/components/pango_python/pybind11/.cmake-format.yaml ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ parse:
2
+ additional_commands:
3
+ pybind11_add_module:
4
+ flags:
5
+ - THIN_LTO
6
+ - MODULE
7
+ - SHARED
8
+ - NO_EXTRAS
9
+ - EXCLUDE_FROM_ALL
10
+ - SYSTEM
11
+
12
+ format:
13
+ line_width: 99
14
+ tab_size: 2
15
+
16
+ # If an argument group contains more than this many sub-groups
17
+ # (parg or kwarg groups) then force it to a vertical layout.
18
+ max_subgroups_hwrap: 2
19
+
20
+ # If a positional argument group contains more than this many
21
+ # arguments, then force it to a vertical layout.
22
+ max_pargs_hwrap: 6
23
+
24
+ # If a cmdline positional group consumes more than this many
25
+ # lines without nesting, then invalidate the layout (and nest)
26
+ max_rows_cmdline: 2
27
+ separate_ctrl_name_with_space: false
28
+ separate_fn_name_with_space: false
29
+ dangle_parens: false
30
+
31
+ # If the trailing parenthesis must be 'dangled' on its on
32
+ # 'line, then align it to this reference: `prefix`: the start'
33
+ # 'of the statement, `prefix-indent`: the start of the'
34
+ # 'statement, plus one indentation level, `child`: align to'
35
+ # the column of the arguments
36
+ dangle_align: prefix
37
+ # If the statement spelling length (including space and
38
+ # parenthesis) is smaller than this amount, then force reject
39
+ # nested layouts.
40
+ min_prefix_chars: 4
41
+
42
+ # If the statement spelling length (including space and
43
+ # parenthesis) is larger than the tab width by more than this
44
+ # amount, then force reject un-nested layouts.
45
+ max_prefix_chars: 10
46
+
47
+ # If a candidate layout is wrapped horizontally but it exceeds
48
+ # this many lines, then reject the layout.
49
+ max_lines_hwrap: 2
50
+
51
+ line_ending: unix
52
+
53
+ # Format command names consistently as 'lower' or 'upper' case
54
+ command_case: canonical
55
+
56
+ # Format keywords consistently as 'lower' or 'upper' case
57
+ # unchanged is valid too
58
+ keyword_case: 'upper'
59
+
60
+ # A list of command names which should always be wrapped
61
+ always_wrap: []
62
+
63
+ # If true, the argument lists which are known to be sortable
64
+ # will be sorted lexicographically
65
+ enable_sort: true
66
+
67
+ # If true, the parsers may infer whether or not an argument
68
+ # list is sortable (without annotation).
69
+ autosort: false
70
+
71
+ # Causes a few issues - can be solved later, possibly.
72
+ markup:
73
+ enable_markup: false
third-party/DPVO/Pangolin/components/pango_python/pybind11/.pre-commit-config.yaml ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # To use:
2
+ #
3
+ # pre-commit run -a
4
+ #
5
+ # Or:
6
+ #
7
+ # pre-commit install # (runs every time you commit in git)
8
+ #
9
+ # To update this file:
10
+ #
11
+ # pre-commit autoupdate
12
+ #
13
+ # See https://github.com/pre-commit/pre-commit
14
+
15
+ repos:
16
+ # Standard hooks
17
+ - repo: https://github.com/pre-commit/pre-commit-hooks
18
+ rev: v4.0.1
19
+ hooks:
20
+ - id: check-added-large-files
21
+ - id: check-case-conflict
22
+ - id: check-merge-conflict
23
+ - id: check-symlinks
24
+ - id: check-yaml
25
+ - id: debug-statements
26
+ - id: end-of-file-fixer
27
+ - id: mixed-line-ending
28
+ - id: requirements-txt-fixer
29
+ - id: trailing-whitespace
30
+ - id: fix-encoding-pragma
31
+ exclude: ^noxfile.py$
32
+
33
+ - repo: https://github.com/asottile/pyupgrade
34
+ rev: v2.23.1
35
+ hooks:
36
+ - id: pyupgrade
37
+
38
+ # Black, the code formatter, natively supports pre-commit
39
+ - repo: https://github.com/psf/black
40
+ rev: 21.7b0
41
+ hooks:
42
+ - id: black
43
+ # By default, this ignores pyi files, though black supports them
44
+ types: [text]
45
+ files: \.pyi?$
46
+
47
+ # Changes tabs to spaces
48
+ - repo: https://github.com/Lucas-C/pre-commit-hooks
49
+ rev: v1.1.10
50
+ hooks:
51
+ - id: remove-tabs
52
+
53
+ # Flake8 also supports pre-commit natively (same author)
54
+ - repo: https://github.com/PyCQA/flake8
55
+ rev: 3.9.2
56
+ hooks:
57
+ - id: flake8
58
+ additional_dependencies: [flake8-bugbear, pep8-naming]
59
+ exclude: ^(docs/.*|tools/.*)$
60
+
61
+ # CMake formatting
62
+ - repo: https://github.com/cheshirekow/cmake-format-precommit
63
+ rev: v0.6.13
64
+ hooks:
65
+ - id: cmake-format
66
+ additional_dependencies: [pyyaml]
67
+ types: [file]
68
+ files: (\.cmake|CMakeLists.txt)(.in)?$
69
+
70
+ # Check static types with mypy
71
+ - repo: https://github.com/pre-commit/mirrors-mypy
72
+ rev: v0.910
73
+ hooks:
74
+ - id: mypy
75
+ # The default Python type ignores .pyi files, so let's rerun if detected
76
+ types: [text]
77
+ files: ^pybind11.*\.pyi?$
78
+ # Running per-file misbehaves a bit, so just run on all files, it's fast
79
+ pass_filenames: false
80
+ additional_dependencies: [typed_ast]
81
+
82
+ # Checks the manifest for missing files (native support)
83
+ - repo: https://github.com/mgedmin/check-manifest
84
+ rev: "0.46"
85
+ hooks:
86
+ - id: check-manifest
87
+ # This is a slow hook, so only run this if --hook-stage manual is passed
88
+ stages: [manual]
89
+ additional_dependencies: [cmake, ninja]
90
+
91
+ - repo: https://github.com/codespell-project/codespell
92
+ rev: v2.1.0
93
+ hooks:
94
+ - id: codespell
95
+ exclude: ".supp$"
96
+ args: ["-L", "nd,ot,thist"]
97
+
98
+ - repo: https://github.com/shellcheck-py/shellcheck-py
99
+ rev: v0.7.2.1
100
+ hooks:
101
+ - id: shellcheck
102
+
103
+ # The original pybind11 checks for a few C++ style items
104
+ - repo: local
105
+ hooks:
106
+ - id: disallow-caps
107
+ name: Disallow improper capitalization
108
+ language: pygrep
109
+ entry: PyBind|Numpy|Cmake|CCache|PyTest
110
+ exclude: .pre-commit-config.yaml
111
+
112
+ - repo: local
113
+ hooks:
114
+ - id: check-style
115
+ name: Classic check-style
116
+ language: system
117
+ types:
118
+ - c++
119
+ entry: ./tools/check-style.sh
third-party/DPVO/Pangolin/components/pango_python/pybind11/.readthedocs.yml ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ python:
2
+ version: 3
3
+ requirements_file: docs/requirements.txt
third-party/DPVO/Pangolin/components/pango_python/pybind11/CMakeLists.txt ADDED
@@ -0,0 +1,290 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CMakeLists.txt -- Build system for the pybind11 modules
2
+ #
3
+ # Copyright (c) 2015 Wenzel Jakob <[email protected]>
4
+ #
5
+ # All rights reserved. Use of this source code is governed by a
6
+ # BSD-style license that can be found in the LICENSE file.
7
+
8
+ cmake_minimum_required(VERSION 3.4)
9
+
10
+ # The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with
11
+ # some versions of VS that have a patched CMake 3.11. This forces us to emulate
12
+ # the behavior using the following workaround:
13
+ if(${CMAKE_VERSION} VERSION_LESS 3.18)
14
+ cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
15
+ else()
16
+ cmake_policy(VERSION 3.18)
17
+ endif()
18
+
19
+ # Extract project version from source
20
+ file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/pybind11/detail/common.h"
21
+ pybind11_version_defines REGEX "#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) ")
22
+
23
+ foreach(ver ${pybind11_version_defines})
24
+ if(ver MATCHES [[#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$]])
25
+ set(PYBIND11_VERSION_${CMAKE_MATCH_1} "${CMAKE_MATCH_2}")
26
+ endif()
27
+ endforeach()
28
+
29
+ if(PYBIND11_VERSION_PATCH MATCHES [[\.([a-zA-Z0-9]+)$]])
30
+ set(pybind11_VERSION_TYPE "${CMAKE_MATCH_1}")
31
+ endif()
32
+ string(REGEX MATCH "^[0-9]+" PYBIND11_VERSION_PATCH "${PYBIND11_VERSION_PATCH}")
33
+
34
+ project(
35
+ pybind11
36
+ LANGUAGES CXX
37
+ VERSION "${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}")
38
+
39
+ # Standard includes
40
+ include(GNUInstallDirs)
41
+ include(CMakePackageConfigHelpers)
42
+ include(CMakeDependentOption)
43
+
44
+ if(NOT pybind11_FIND_QUIETLY)
45
+ message(STATUS "pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}")
46
+ endif()
47
+
48
+ # Avoid infinite recursion if tests include this as a subdirectory
49
+ if(DEFINED PYBIND11_MASTER_PROJECT)
50
+ set(PYBIND11_TEST OFF)
51
+ endif()
52
+
53
+ # Check if pybind11 is being used directly or via add_subdirectory
54
+ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR AND NOT DEFINED PYBIND11_MASTER_PROJECT)
55
+ ### Warn if not an out-of-source builds
56
+ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
57
+ set(lines
58
+ "You are building in-place. If that is not what you intended to "
59
+ "do, you can clean the source directory with:\n"
60
+ "rm -r CMakeCache.txt CMakeFiles/ cmake_uninstall.cmake pybind11Config.cmake "
61
+ "pybind11ConfigVersion.cmake tests/CMakeFiles/\n")
62
+ message(AUTHOR_WARNING ${lines})
63
+ endif()
64
+
65
+ set(PYBIND11_MASTER_PROJECT ON)
66
+
67
+ if(OSX AND CMAKE_VERSION VERSION_LESS 3.7)
68
+ # Bug in macOS CMake < 3.7 is unable to download catch
69
+ message(WARNING "CMAKE 3.7+ needed on macOS to download catch, and newer HIGHLY recommended")
70
+ elseif(WINDOWS AND CMAKE_VERSION VERSION_LESS 3.8)
71
+ # Only tested with 3.8+ in CI.
72
+ message(WARNING "CMAKE 3.8+ tested on Windows, previous versions untested")
73
+ endif()
74
+
75
+ message(STATUS "CMake ${CMAKE_VERSION}")
76
+
77
+ if(CMAKE_CXX_STANDARD)
78
+ set(CMAKE_CXX_EXTENSIONS OFF)
79
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
80
+ endif()
81
+
82
+ set(pybind11_system "")
83
+ else()
84
+ set(PYBIND11_MASTER_PROJECT OFF)
85
+ set(pybind11_system SYSTEM)
86
+ endif()
87
+
88
+ # Options
89
+ option(PYBIND11_INSTALL "Install pybind11 header files?" ${PYBIND11_MASTER_PROJECT})
90
+ option(PYBIND11_TEST "Build pybind11 test suite?" ${PYBIND11_MASTER_PROJECT})
91
+ option(PYBIND11_NOPYTHON "Disable search for Python" OFF)
92
+
93
+ cmake_dependent_option(
94
+ USE_PYTHON_INCLUDE_DIR
95
+ "Install pybind11 headers in Python include directory instead of default installation prefix"
96
+ OFF "PYBIND11_INSTALL" OFF)
97
+
98
+ cmake_dependent_option(PYBIND11_FINDPYTHON "Force new FindPython" OFF
99
+ "NOT CMAKE_VERSION VERSION_LESS 3.12" OFF)
100
+
101
+ # NB: when adding a header don't forget to also add it to setup.py
102
+ set(PYBIND11_HEADERS
103
+ include/pybind11/detail/class.h
104
+ include/pybind11/detail/common.h
105
+ include/pybind11/detail/descr.h
106
+ include/pybind11/detail/init.h
107
+ include/pybind11/detail/internals.h
108
+ include/pybind11/detail/type_caster_base.h
109
+ include/pybind11/detail/typeid.h
110
+ include/pybind11/attr.h
111
+ include/pybind11/buffer_info.h
112
+ include/pybind11/cast.h
113
+ include/pybind11/chrono.h
114
+ include/pybind11/common.h
115
+ include/pybind11/complex.h
116
+ include/pybind11/options.h
117
+ include/pybind11/eigen.h
118
+ include/pybind11/embed.h
119
+ include/pybind11/eval.h
120
+ include/pybind11/gil.h
121
+ include/pybind11/iostream.h
122
+ include/pybind11/functional.h
123
+ include/pybind11/numpy.h
124
+ include/pybind11/operators.h
125
+ include/pybind11/pybind11.h
126
+ include/pybind11/pytypes.h
127
+ include/pybind11/stl.h
128
+ include/pybind11/stl_bind.h
129
+ include/pybind11/stl/filesystem.h)
130
+
131
+ # Compare with grep and warn if mismatched
132
+ if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)
133
+ file(
134
+ GLOB_RECURSE _pybind11_header_check
135
+ LIST_DIRECTORIES false
136
+ RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
137
+ CONFIGURE_DEPENDS "include/pybind11/*.h")
138
+ set(_pybind11_here_only ${PYBIND11_HEADERS})
139
+ set(_pybind11_disk_only ${_pybind11_header_check})
140
+ list(REMOVE_ITEM _pybind11_here_only ${_pybind11_header_check})
141
+ list(REMOVE_ITEM _pybind11_disk_only ${PYBIND11_HEADERS})
142
+ if(_pybind11_here_only)
143
+ message(AUTHOR_WARNING "PYBIND11_HEADERS has extra files:" ${_pybind11_here_only})
144
+ endif()
145
+ if(_pybind11_disk_only)
146
+ message(AUTHOR_WARNING "PYBIND11_HEADERS is missing files:" ${_pybind11_disk_only})
147
+ endif()
148
+ endif()
149
+
150
+ # CMake 3.12 added list(TRANSFORM <list> PREPEND
151
+ # But we can't use it yet
152
+ string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/" PYBIND11_HEADERS
153
+ "${PYBIND11_HEADERS}")
154
+
155
+ # Cache variable so this can be used in parent projects
156
+ set(pybind11_INCLUDE_DIR
157
+ "${CMAKE_CURRENT_LIST_DIR}/include"
158
+ CACHE INTERNAL "Directory where pybind11 headers are located")
159
+
160
+ # Backward compatible variable for add_subdirectory mode
161
+ if(NOT PYBIND11_MASTER_PROJECT)
162
+ set(PYBIND11_INCLUDE_DIR
163
+ "${pybind11_INCLUDE_DIR}"
164
+ CACHE INTERNAL "")
165
+ endif()
166
+
167
+ # Note: when creating targets, you cannot use if statements at configure time -
168
+ # you need generator expressions, because those will be placed in the target file.
169
+ # You can also place ifs *in* the Config.in, but not here.
170
+
171
+ # This section builds targets, but does *not* touch Python
172
+ # Non-IMPORT targets cannot be defined twice
173
+ if(NOT TARGET pybind11_headers)
174
+ # Build the headers-only target (no Python included):
175
+ # (long name used here to keep this from clashing in subdirectory mode)
176
+ add_library(pybind11_headers INTERFACE)
177
+ add_library(pybind11::pybind11_headers ALIAS pybind11_headers) # to match exported target
178
+ add_library(pybind11::headers ALIAS pybind11_headers) # easier to use/remember
179
+
180
+ target_include_directories(
181
+ pybind11_headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${pybind11_INCLUDE_DIR}>
182
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
183
+
184
+ target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals
185
+ cxx_right_angle_brackets)
186
+ else()
187
+ # It is invalid to install a target twice, too.
188
+ set(PYBIND11_INSTALL OFF)
189
+ endif()
190
+
191
+ include("${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake")
192
+
193
+ # Relative directory setting
194
+ if(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)
195
+ file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${Python_INCLUDE_DIRS})
196
+ elseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)
197
+ file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})
198
+ endif()
199
+
200
+ if(PYBIND11_INSTALL)
201
+ install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
202
+ set(PYBIND11_CMAKECONFIG_INSTALL_DIR
203
+ "${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}"
204
+ CACHE STRING "install path for pybind11Config.cmake")
205
+
206
+ if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
207
+ set(pybind11_INCLUDEDIR "${CMAKE_INSTALL_FULL_INCLUDEDIR}")
208
+ else()
209
+ set(pybind11_INCLUDEDIR "\$\{PACKAGE_PREFIX_DIR\}/${CMAKE_INSTALL_INCLUDEDIR}")
210
+ endif()
211
+
212
+ configure_package_config_file(
213
+ tools/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
214
+ INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
215
+
216
+ if(CMAKE_VERSION VERSION_LESS 3.14)
217
+ # Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does
218
+ # not depend on architecture specific settings or libraries.
219
+ set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
220
+ unset(CMAKE_SIZEOF_VOID_P)
221
+
222
+ write_basic_package_version_file(
223
+ ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
224
+ VERSION ${PROJECT_VERSION}
225
+ COMPATIBILITY AnyNewerVersion)
226
+
227
+ set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P})
228
+ else()
229
+ # CMake 3.14+ natively supports header-only libraries
230
+ write_basic_package_version_file(
231
+ ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
232
+ VERSION ${PROJECT_VERSION}
233
+ COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)
234
+ endif()
235
+
236
+ install(
237
+ FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
238
+ ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
239
+ tools/FindPythonLibsNew.cmake
240
+ tools/pybind11Common.cmake
241
+ tools/pybind11Tools.cmake
242
+ tools/pybind11NewTools.cmake
243
+ DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
244
+
245
+ if(NOT PYBIND11_EXPORT_NAME)
246
+ set(PYBIND11_EXPORT_NAME "${PROJECT_NAME}Targets")
247
+ endif()
248
+
249
+ install(TARGETS pybind11_headers EXPORT "${PYBIND11_EXPORT_NAME}")
250
+
251
+ install(
252
+ EXPORT "${PYBIND11_EXPORT_NAME}"
253
+ NAMESPACE "pybind11::"
254
+ DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
255
+
256
+ # Uninstall target
257
+ if(PYBIND11_MASTER_PROJECT)
258
+ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in"
259
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
260
+
261
+ add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P
262
+ ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
263
+ endif()
264
+ endif()
265
+
266
+ # BUILD_TESTING takes priority, but only if this is the master project
267
+ if(PYBIND11_MASTER_PROJECT AND DEFINED BUILD_TESTING)
268
+ if(BUILD_TESTING)
269
+ if(_pybind11_nopython)
270
+ message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
271
+ else()
272
+ add_subdirectory(tests)
273
+ endif()
274
+ endif()
275
+ else()
276
+ if(PYBIND11_TEST)
277
+ if(_pybind11_nopython)
278
+ message(FATAL_ERROR "Cannot activate tests in NOPYTHON mode")
279
+ else()
280
+ add_subdirectory(tests)
281
+ endif()
282
+ endif()
283
+ endif()
284
+
285
+ # Better symmetry with find_package(pybind11 CONFIG) mode.
286
+ if(NOT PYBIND11_MASTER_PROJECT)
287
+ set(pybind11_FOUND
288
+ TRUE
289
+ CACHE INTERNAL "True if pybind11 and all required components found on the system")
290
+ endif()
third-party/DPVO/Pangolin/components/pango_python/pybind11/docs/_static/theme_overrides.css ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wy-table-responsive table td,
2
+ .wy-table-responsive table th {
3
+ white-space: initial !important;
4
+ }
5
+ .rst-content table.docutils td {
6
+ vertical-align: top !important;
7
+ }
8
+ div[class^='highlight'] pre {
9
+ white-space: pre;
10
+ white-space: pre-wrap;
11
+ }
third-party/DPVO/Pangolin/components/pango_python/pybind11/docs/advanced/cast/chrono.rst ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Chrono
2
+ ======
3
+
4
+ When including the additional header file :file:`pybind11/chrono.h` conversions
5
+ from C++11 chrono datatypes to python datetime objects are automatically enabled.
6
+ This header also enables conversions of python floats (often from sources such
7
+ as ``time.monotonic()``, ``time.perf_counter()`` and ``time.process_time()``)
8
+ into durations.
9
+
10
+ An overview of clocks in C++11
11
+ ------------------------------
12
+
13
+ A point of confusion when using these conversions is the differences between
14
+ clocks provided in C++11. There are three clock types defined by the C++11
15
+ standard and users can define their own if needed. Each of these clocks have
16
+ different properties and when converting to and from python will give different
17
+ results.
18
+
19
+ The first clock defined by the standard is ``std::chrono::system_clock``. This
20
+ clock measures the current date and time. However, this clock changes with to
21
+ updates to the operating system time. For example, if your time is synchronised
22
+ with a time server this clock will change. This makes this clock a poor choice
23
+ for timing purposes but good for measuring the wall time.
24
+
25
+ The second clock defined in the standard is ``std::chrono::steady_clock``.
26
+ This clock ticks at a steady rate and is never adjusted. This makes it excellent
27
+ for timing purposes, however the value in this clock does not correspond to the
28
+ current date and time. Often this clock will be the amount of time your system
29
+ has been on, although it does not have to be. This clock will never be the same
30
+ clock as the system clock as the system clock can change but steady clocks
31
+ cannot.
32
+
33
+ The third clock defined in the standard is ``std::chrono::high_resolution_clock``.
34
+ This clock is the clock that has the highest resolution out of the clocks in the
35
+ system. It is normally a typedef to either the system clock or the steady clock
36
+ but can be its own independent clock. This is important as when using these
37
+ conversions as the types you get in python for this clock might be different
38
+ depending on the system.
39
+ If it is a typedef of the system clock, python will get datetime objects, but if
40
+ it is a different clock they will be timedelta objects.
41
+
42
+ Provided conversions
43
+ --------------------
44
+
45
+ .. rubric:: C++ to Python
46
+
47
+ - ``std::chrono::system_clock::time_point`` β†’ ``datetime.datetime``
48
+ System clock times are converted to python datetime instances. They are
49
+ in the local timezone, but do not have any timezone information attached
50
+ to them (they are naive datetime objects).
51
+
52
+ - ``std::chrono::duration`` β†’ ``datetime.timedelta``
53
+ Durations are converted to timedeltas, any precision in the duration
54
+ greater than microseconds is lost by rounding towards zero.
55
+
56
+ - ``std::chrono::[other_clocks]::time_point`` β†’ ``datetime.timedelta``
57
+ Any clock time that is not the system clock is converted to a time delta.
58
+ This timedelta measures the time from the clocks epoch to now.
59
+
60
+ .. rubric:: Python to C++
61
+
62
+ - ``datetime.datetime`` or ``datetime.date`` or ``datetime.time`` β†’ ``std::chrono::system_clock::time_point``
63
+ Date/time objects are converted into system clock timepoints. Any
64
+ timezone information is ignored and the type is treated as a naive
65
+ object.
66
+
67
+ - ``datetime.timedelta`` β†’ ``std::chrono::duration``
68
+ Time delta are converted into durations with microsecond precision.
69
+
70
+ - ``datetime.timedelta`` β†’ ``std::chrono::[other_clocks]::time_point``
71
+ Time deltas that are converted into clock timepoints are treated as
72
+ the amount of time from the start of the clocks epoch.
73
+
74
+ - ``float`` β†’ ``std::chrono::duration``
75
+ Floats that are passed to C++ as durations be interpreted as a number of
76
+ seconds. These will be converted to the duration using ``duration_cast``
77
+ from the float.
78
+
79
+ - ``float`` β†’ ``std::chrono::[other_clocks]::time_point``
80
+ Floats that are passed to C++ as time points will be interpreted as the
81
+ number of seconds from the start of the clocks epoch.