Spaces:
Sleeping
Sleeping
9f6ef56b47ab9a4a46bd6dcc26aaed5c1573071e90029486e391948c5a32e647
Browse files- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gltext.h +96 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/gltexturecache.h +116 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/glvbo.h +239 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/opengl_render_state.h +446 -0
- third-party/DPVO/Pangolin/components/pango_opengl/include/pangolin/gl/viewport.h +63 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/compat/gl2engine.cpp +39 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/fonts/AnonymousPro.ttf +0 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/fonts/AnonymousPro.txt +94 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/glchar.cpp +70 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/gldraw.cpp +55 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/glfont.cpp +207 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/glpangoglu.cpp +272 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/gltext.cpp +198 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/gltexturecache.cpp +38 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/opengl_render_state.cpp +707 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/stb_truetype.h +0 -0
- third-party/DPVO/Pangolin/components/pango_opengl/src/viewport.cpp +102 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/CMakeLists.txt +20 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packet.h +70 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream.h +111 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_reader.h +120 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_source.h +63 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_tags.h +46 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/packetstream_writer.h +173 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/playback_session.h +55 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/include/pangolin/log/sync_time.h +237 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/src/packet.cpp +79 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/src/packetstream.cpp +146 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/src/packetstream_reader.cpp +428 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/src/packetstream_writer.cpp +156 -0
- third-party/DPVO/Pangolin/components/pango_packetstream/src/playback_session.cpp +32 -0
- third-party/DPVO/Pangolin/components/pango_plot/CMakeLists.txt +17 -0
- third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/datalog.h +243 -0
- third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/loaders/csv_table_loader.h +32 -0
- third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/loaders/table_loader.h +12 -0
- third-party/DPVO/Pangolin/components/pango_plot/include/pangolin/plot/plotter.h +295 -0
- third-party/DPVO/Pangolin/components/pango_plot/src/datalog.cpp +289 -0
- third-party/DPVO/Pangolin/components/pango_plot/src/loaders/csv_table_loader.cpp +81 -0
- third-party/DPVO/Pangolin/components/pango_plot/src/plotter.cpp +1174 -0
- third-party/DPVO/Pangolin/components/pango_python/CMakeLists.txt +90 -0
- third-party/DPVO/Pangolin/components/pango_python/include/pangolin/python/pyinterpreter.h +72 -0
- third-party/DPVO/Pangolin/components/pango_python/pybind11/.appveyor.yml +37 -0
- third-party/DPVO/Pangolin/components/pango_python/pybind11/.clang-format +19 -0
- third-party/DPVO/Pangolin/components/pango_python/pybind11/.clang-tidy +58 -0
- third-party/DPVO/Pangolin/components/pango_python/pybind11/.cmake-format.yaml +73 -0
- third-party/DPVO/Pangolin/components/pango_python/pybind11/.pre-commit-config.yaml +119 -0
- third-party/DPVO/Pangolin/components/pango_python/pybind11/.readthedocs.yml +3 -0
- third-party/DPVO/Pangolin/components/pango_python/pybind11/CMakeLists.txt +290 -0
- third-party/DPVO/Pangolin/components/pango_python/pybind11/docs/_static/theme_overrides.css +11 -0
- 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.
|