q3dviewer 1.0.3__py3-none-any.whl → 1.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. q3dviewer/__init__.py +5 -0
  2. q3dviewer/base_glwidget.py +256 -0
  3. q3dviewer/base_item.py +57 -0
  4. q3dviewer/custom_items/__init__.py +9 -0
  5. q3dviewer/custom_items/axis_item.py +148 -0
  6. q3dviewer/custom_items/cloud_io_item.py +79 -0
  7. q3dviewer/custom_items/cloud_item.py +314 -0
  8. q3dviewer/custom_items/frame_item.py +194 -0
  9. q3dviewer/custom_items/gaussian_item.py +254 -0
  10. q3dviewer/custom_items/grid_item.py +88 -0
  11. q3dviewer/custom_items/image_item.py +172 -0
  12. q3dviewer/custom_items/line_item.py +120 -0
  13. q3dviewer/custom_items/text_item.py +63 -0
  14. q3dviewer/gau_io.py +0 -0
  15. q3dviewer/glwidget.py +131 -0
  16. q3dviewer/shaders/cloud_frag.glsl +28 -0
  17. q3dviewer/shaders/cloud_vert.glsl +72 -0
  18. q3dviewer/shaders/gau_frag.glsl +42 -0
  19. q3dviewer/shaders/gau_prep.glsl +249 -0
  20. q3dviewer/shaders/gau_vert.glsl +77 -0
  21. q3dviewer/shaders/sort_by_key.glsl +56 -0
  22. q3dviewer/tools/__init__.py +1 -0
  23. q3dviewer/tools/cloud_viewer.py +123 -0
  24. q3dviewer/tools/example_viewer.py +47 -0
  25. q3dviewer/tools/gaussian_viewer.py +60 -0
  26. q3dviewer/tools/lidar_calib.py +294 -0
  27. q3dviewer/tools/lidar_cam_calib.py +314 -0
  28. q3dviewer/tools/ros_viewer.py +85 -0
  29. q3dviewer/utils/__init__.py +4 -0
  30. q3dviewer/utils/cloud_io.py +323 -0
  31. q3dviewer/utils/convert_ros_msg.py +49 -0
  32. q3dviewer/utils/gl_helper.py +40 -0
  33. q3dviewer/utils/maths.py +168 -0
  34. q3dviewer/utils/range_slider.py +86 -0
  35. q3dviewer/viewer.py +58 -0
  36. q3dviewer-1.0.5.dist-info/LICENSE +21 -0
  37. {q3dviewer-1.0.3.dist-info → q3dviewer-1.0.5.dist-info}/METADATA +7 -4
  38. q3dviewer-1.0.5.dist-info/RECORD +41 -0
  39. q3dviewer-1.0.5.dist-info/top_level.txt +1 -0
  40. q3dviewer-1.0.3.dist-info/RECORD +0 -5
  41. q3dviewer-1.0.3.dist-info/top_level.txt +0 -1
  42. {q3dviewer-1.0.3.dist-info → q3dviewer-1.0.5.dist-info}/WHEEL +0 -0
  43. {q3dviewer-1.0.3.dist-info → q3dviewer-1.0.5.dist-info}/entry_points.txt +0 -0
q3dviewer/glwidget.py ADDED
@@ -0,0 +1,131 @@
1
+ """
2
+ Copyright 2024 Panasonic Advanced Technology Development Co.,Ltd. (Liu Yang)
3
+ Distributed under MIT license. See LICENSE for more information.
4
+ """
5
+
6
+ from PySide6 import QtCore
7
+ from PySide6.QtWidgets import QWidget, QComboBox, QVBoxLayout, QHBoxLayout, QSizePolicy, QSpacerItem, QLabel, QLineEdit, QCheckBox
8
+ from PySide6.QtGui import QKeyEvent, QVector3D, QRegularExpressionValidator
9
+ from PySide6.QtCore import QRegularExpression
10
+ from OpenGL.GL import *
11
+ import numpy as np
12
+ from q3dviewer.base_glwidget import BaseGLWidget
13
+
14
+ class SettingWindow(QWidget):
15
+ def __init__(self):
16
+ super().__init__()
17
+ self.combo_items = QComboBox()
18
+ self.combo_items.currentIndexChanged.connect(self.on_combo_selection)
19
+ main_layout = QVBoxLayout()
20
+ self.stretch = QSpacerItem(
21
+ 10, 10, QSizePolicy.Minimum, QSizePolicy.Expanding)
22
+ main_layout.addWidget(self.combo_items)
23
+ self.layout = QVBoxLayout()
24
+ self.layout.addItem(self.stretch)
25
+ main_layout.addLayout(self.layout)
26
+ self.setLayout(main_layout)
27
+ self.setWindowTitle("Setting Window")
28
+ self.setGeometry(200, 200, 300, 200)
29
+ self.items = {}
30
+
31
+ def add_setting(self, name, item):
32
+ self.items.update({name: item})
33
+ self.combo_items.addItem("%s(%s)" % (name, item.__class__.__name__))
34
+
35
+ def clear_setting(self):
36
+ while self.layout.count():
37
+ child = self.layout.takeAt(0)
38
+ if child.widget():
39
+ child.widget().deleteLater()
40
+
41
+ def on_combo_selection(self, index):
42
+ self.layout.removeItem(self.stretch)
43
+ # remove all setting of previous widget
44
+ self.clear_setting()
45
+
46
+ key = list(self.items.keys())
47
+ item = self.items[key[index]]
48
+ if hasattr(item, "add_setting"):
49
+ item.add_setting(self.layout)
50
+ self.layout.addItem(self.stretch)
51
+ else:
52
+ print("%s: No setting." % (item.__class__.__name__))
53
+
54
+
55
+ class GLWidget(BaseGLWidget):
56
+ def __init__(self):
57
+ self.followed_name = 'none'
58
+ self.named_items = {}
59
+ self.color_str = '#000000'
60
+ self.followable_item_name = ['none']
61
+ self.setting_window = SettingWindow()
62
+ self.enable_show_center = True
63
+ super(GLWidget, self).__init__()
64
+
65
+ def keyPressEvent(self, ev: QKeyEvent):
66
+ if ev.key() == QtCore.Qt.Key_M: # setting meun
67
+ print("Open setting windows")
68
+ self.open_setting_window()
69
+ super().keyPressEvent(ev)
70
+
71
+ def on_followable_selection(self, index):
72
+ self.followed_name = self.followable_item_name[index]
73
+
74
+ def update(self):
75
+ if self.followed_name != 'none':
76
+ pos = self.named_items[self.followed_name].T[:3, 3]
77
+ self.opts['center'] = QVector3D(pos[0], pos[1], pos[2])
78
+ super().update()
79
+
80
+ def add_setting(self, layout):
81
+ label_color = QLabel("Set background color:")
82
+ layout.addWidget(label_color)
83
+ color_edit = QLineEdit()
84
+ color_edit.setToolTip("'using hex color, i.e. #FF4500")
85
+ color_edit.setText(self.color_str)
86
+ color_edit.textChanged.connect(self.set_bg_color)
87
+ regex = QRegularExpression(r"^#[0-9A-Fa-f]{6}$")
88
+ validator = QRegularExpressionValidator(regex)
89
+ color_edit.setValidator(validator)
90
+ layout.addWidget(color_edit)
91
+
92
+ label_focus = QLabel("Set Focus:")
93
+ combo_focus = QComboBox()
94
+ for name in self.followable_item_name:
95
+ combo_focus.addItem(name)
96
+ combo_focus.currentIndexChanged.connect(self.on_followable_selection)
97
+ layout.addWidget(label_focus)
98
+ layout.addWidget(combo_focus)
99
+
100
+ checkbox_show_center = QCheckBox("Show Center Point")
101
+ checkbox_show_center.setChecked(self.enable_show_center)
102
+ checkbox_show_center.stateChanged.connect(self.change_show_center)
103
+ layout.addWidget(checkbox_show_center)
104
+
105
+ def set_bg_color(self, color_str):
106
+ try:
107
+ color_flat = int(color_str[1:], 16)
108
+ red = (color_flat >> 16) & 0xFF
109
+ green = (color_flat >> 8) & 0xFF
110
+ blue = color_flat & 0xFF
111
+ self.color_str = color_str
112
+ self.set_color([red, green, blue, 0])
113
+ except ValueError:
114
+ return
115
+
116
+ def add_item_with_name(self, name, item):
117
+ self.named_items.update({name: item})
118
+ if (item.__class__.__name__ == 'AxisItem'):
119
+ self.followable_item_name.append(name)
120
+ self.setting_window.add_setting(name, item)
121
+ super().add_item(item)
122
+
123
+ def open_setting_window(self):
124
+ if self.setting_window.isVisible():
125
+ self.setting_window.raise_()
126
+
127
+ else:
128
+ self.setting_window.show()
129
+
130
+ def change_show_center(self, state):
131
+ self.enable_show_center = state
@@ -0,0 +1,28 @@
1
+ /*
2
+ Copyright 2024 Panasonic Advanced Technology Development Co.,Ltd. (Liu Yang)
3
+ Distributed under MIT license. See LICENSE for more information.
4
+ */
5
+
6
+ #version 330 core
7
+
8
+ uniform int point_type;
9
+
10
+ in vec4 color;
11
+
12
+ out vec4 finalColor;
13
+
14
+ void main()
15
+ {
16
+ // only do this when point_type is sphere
17
+ if (point_type == 2)
18
+ {
19
+ vec2 coord = gl_PointCoord * 2.0 - vec2(1.0); // Map [0,1] to [-1,1]
20
+ float distance = dot(coord, coord); // Squared distance
21
+
22
+ // Discard fragments outside the circle (radius = 1.0)
23
+ if (distance > 1.0)
24
+ discard;
25
+ }
26
+
27
+ finalColor = color;
28
+ }
@@ -0,0 +1,72 @@
1
+ /*
2
+ Copyright 2024 Panasonic Advanced Technology Development Co.,Ltd. (Liu Yang)
3
+ Distributed under MIT license. See LICENSE for more information.
4
+ */
5
+
6
+ #version 330 core
7
+
8
+ layout (location = 0) in vec3 position;
9
+ layout (location = 1) in uint value;
10
+
11
+ uniform mat4 view_matrix;
12
+ uniform mat4 projection_matrix;
13
+ uniform float alpha = 1;
14
+ uniform int color_mode = 0;
15
+ uniform int flat_rgb = 0;
16
+ uniform float vmin = 0;
17
+ uniform float vmax = 255;
18
+ uniform float focal = 1000;
19
+ uniform int point_type = 0; // 0 pixel, 1 flat square, 2 sphere
20
+ uniform float point_size = 0.01; // World size for each point (meter)
21
+ out vec4 color;
22
+
23
+ vec3 getRainbowColor(uint value_raw) {
24
+ float range = vmax - vmin;
25
+ float value = 1.0 - (float(value_raw) - vmin) / range;
26
+ value = clamp(value, 0.0, 1.0);
27
+ float hue = value * 5.0 + 1.0;
28
+ int i = int(floor(hue));
29
+ float f = hue - float(i);
30
+ if (mod(i, 2) == 0) f = 1.0 - f;
31
+ float n = 1.0 - f;
32
+
33
+ vec3 color;
34
+ if (i <= 1) color = vec3(n, 0.0, 1.0);
35
+ else if (i == 2) color = vec3(0.0, n, 1.0);
36
+ else if (i == 3) color = vec3(0.0, 1.0, n);
37
+ else if (i == 4) color = vec3(n, 1.0, 0.0);
38
+ else color = vec3(1.0, n, 0.0);
39
+ return color;
40
+ }
41
+
42
+ void main()
43
+ {
44
+ vec4 pw = vec4(position, 1.0);
45
+ vec4 pc = view_matrix * pw;
46
+ gl_Position = projection_matrix * pc;
47
+
48
+ // Calculate point size in pixels based on distance
49
+ if (point_type == 0)
50
+ gl_PointSize = int(point_size);
51
+ else
52
+ gl_PointSize = point_size / gl_Position.w * focal;
53
+ vec3 c = vec3(1.0, 1.0, 1.0);
54
+ if (color_mode == 1)
55
+ {
56
+ uint intensity = value >> 24;
57
+ c = getRainbowColor(intensity);
58
+ }
59
+ else if(color_mode == 2)
60
+ {
61
+ c.z = float(value & uint(0x000000FF))/255.;
62
+ c.y = float((value & uint(0x0000FF00)) >> 8)/255.;
63
+ c.x = float((value & uint(0x00FF0000)) >> 16)/255.;
64
+ }
65
+ else
66
+ {
67
+ c.z = float( uint(flat_rgb) & uint(0x000000FF))/255.;
68
+ c.y = float((uint(flat_rgb) & uint(0x0000FF00)) >> 8)/255.;
69
+ c.x = float((uint(flat_rgb) & uint(0x00FF0000)) >> 16)/255.;
70
+ }
71
+ color = vec4(c, alpha);
72
+ }
@@ -0,0 +1,42 @@
1
+ /*
2
+ this file is modified from GaussianSplattingViewer licensed under the MIT License.
3
+ see https://github.com/limacv/GaussianSplattingViewer/blob/main/shaders/gau_frag.glsl
4
+ */
5
+
6
+ #version 430 core
7
+
8
+ in vec3 color;
9
+ in float alpha;
10
+ in vec3 cinv2d;
11
+ in vec2 d_pix; // u - pix
12
+
13
+ uniform int render_mod = 1;
14
+
15
+ out vec4 final_color;
16
+
17
+ void main()
18
+ {
19
+ if (alpha < 0.001)
20
+ discard;
21
+ float maha_dist = cinv2d.x * d_pix.x * d_pix.x + cinv2d.z * d_pix.y * d_pix.y + 2 * cinv2d.y * d_pix.x * d_pix.y;
22
+ if (maha_dist < 0.f)
23
+ discard;
24
+
25
+ float g = exp(- 0.5 * maha_dist);
26
+ float alpha_prime = min(0.99f, alpha * g);
27
+ if (alpha_prime < 1.f / 255.f)
28
+ discard;
29
+ final_color = vec4(color, alpha_prime);
30
+
31
+ if (render_mod == 1)
32
+ {
33
+ final_color.a = final_color.a > 0.3 ? 1 : 0;
34
+ final_color.rgb = final_color.rgb * g;
35
+ }
36
+ else if (render_mod == 2)
37
+ {
38
+ final_color.a = final_color.a > 0.3 ? 1 - final_color.a: 0;
39
+ }
40
+
41
+
42
+ }
@@ -0,0 +1,249 @@
1
+ /*
2
+ We proprocess gaussian using compute shader.
3
+ this file is modified from GaussianSplattingViewer licensed under the MIT License.
4
+ see https://github.com/limacv/GaussianSplattingViewer/blob/main/shaders/gau_vert.glsl
5
+ */
6
+
7
+ #version 430 core
8
+
9
+ layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
10
+
11
+
12
+ //https://en.wikipedia.org/wiki/Table_of_spherical_harmonics
13
+ #define SH_C0_0 0.28209479177387814 // Y0,0: 1/2*sqrt(1/pi) plus
14
+ #define SH_C1_0 -0.4886025119029199 // Y1,-1: sqrt(3/(4*pi)) minus
15
+ #define SH_C1_1 0.4886025119029199 // Y1,0: sqrt(3/(4*pi)) plus
16
+ #define SH_C1_2 -0.4886025119029199 // Y1,1: sqrt(3/(4*pi)) minus
17
+ #define SH_C2_0 1.0925484305920792 // Y2,-2: 1/2 * sqrt(15/pi) plus
18
+ #define SH_C2_1 -1.0925484305920792 // Y2,-1: 1/2 * sqrt(15/pi) minus
19
+ #define SH_C2_2 0.31539156525252005 // Y2,0: 1/4*sqrt(5/pi) plus
20
+ #define SH_C2_3 -1.0925484305920792 // Y2,1: 1/2*sqrt(15/pi) minus
21
+ #define SH_C2_4 0.5462742152960396 // Y2,2: 1/4*sqrt(15/pi) plus
22
+ #define SH_C3_0 -0.5900435899266435 // Y3,-3: 1/4*sqrt(35/(2*pi)) minus
23
+ #define SH_C3_1 2.890611442640554 // Y3,-2: 1/2*sqrt(105/pi) plus
24
+ #define SH_C3_2 -0.4570457994644658 // Y3,-1: 1/4*sqrt(21/(2*pi)) minus
25
+ #define SH_C3_3 0.3731763325901154 // Y3,0: 1/4*sqrt(7/pi) plus
26
+ #define SH_C3_4 -0.4570457994644658 // Y3,1: 1/4*sqrt(21/(2*pi)) minus
27
+ #define SH_C3_5 1.445305721320277 // Y3,2: 1/4*sqrt(105/pi) plus
28
+ #define SH_C3_6 -0.5900435899266435 // Y3,3: 1/4*sqrt(35/(2*pi)) minus
29
+
30
+
31
+ #define OFFSET_DATA_POS 0
32
+ #define OFFSET_DATA_ROT 3
33
+ #define OFFSET_DATA_SCALE 7
34
+ #define OFFSET_DATA_ALPHA 10
35
+ #define OFFSET_DATA_SH 11
36
+
37
+ #define OFFSET_PREP_U 0
38
+ #define OFFSET_PREP_COVINV 3
39
+ #define OFFSET_PREP_COLOR 6
40
+ #define OFFSET_PREP_AREA 9
41
+ #define OFFSET_PREP_ALPHA 11
42
+ #define DIM_PREP 12
43
+
44
+ // 12 float
45
+
46
+ layout (std430, binding=0) buffer GaussianData {
47
+ float gs_data[];
48
+ };
49
+
50
+ layout (std430, binding=2) buffer GaussianDepth {
51
+ float depth[];
52
+ };
53
+
54
+ layout (std430, binding=3) buffer GaussianPrep {
55
+ float gs_prep[];
56
+ };
57
+
58
+ uniform mat4 view_matrix;
59
+ uniform mat4 projection_matrix;
60
+ uniform vec2 focal;
61
+ uniform int sh_dim;
62
+ uniform int gs_num;
63
+
64
+ mat3 computeCov3D(vec3 scale, vec4 q)
65
+ {
66
+ mat3 S = mat3(0.f);
67
+ S[0][0] = scale.x;
68
+ S[1][1] = scale.y;
69
+ S[2][2] = scale.z;
70
+ float w = q.x;
71
+ float x = q.y;
72
+ float y = q.z;
73
+ float z = q.w;
74
+
75
+ // In GLSL (OpenGL Shading Language), matrices are generally represented in column-major order
76
+ mat3 R = mat3(
77
+ 1.f - 2.f * (y * y + z * z), 2.f * (x * y + w * z), 2.f * (x * z - w * y),
78
+ 2.f * (x * y - w * z), 1.f - 2.f * (x * x + z * z), 2.f * (y * z + w * x),
79
+ 2.f * (x * z + w * y), 2.f * (y * z - w * x), 1.f - 2.f * (x * x + y * y)
80
+ );
81
+
82
+ mat3 M = R * S;
83
+ mat3 Sigma = M * transpose(M);
84
+ return Sigma;
85
+ }
86
+
87
+ vec3 computeCov2D(vec4 pc, float focal_x, float focal_y, mat3 cov3D, mat4 viewmatrix)
88
+ {
89
+ float z2 = pc.z * pc.z;
90
+ mat3 J = mat3(
91
+ focal_x/pc.z, 0.0f, 0,
92
+ 0.0f, focal_y / pc.z, 0,
93
+ -(focal_x*pc.x)/z2,-(focal_y * pc.y) / z2, 0);
94
+ mat3 W = mat3(viewmatrix);
95
+ mat3 T = J * W;
96
+
97
+ mat3 cov = T * cov3D * transpose(T);
98
+
99
+ cov[0][0] += 0.3f;
100
+ cov[1][1] += 0.3f;
101
+ return vec3(cov[0][0], cov[0][1], cov[1][1]);
102
+ }
103
+
104
+ vec3 get_vec3(int offset)
105
+ {
106
+ return vec3(gs_data[offset], gs_data[offset + 1], gs_data[offset + 2]);
107
+ }
108
+
109
+ vec4 get_vec4(int offset)
110
+ {
111
+ return vec4(gs_data[offset], gs_data[offset + 1], gs_data[offset + 2], gs_data[offset + 3]);
112
+ }
113
+
114
+ void set_prep_vec3(int offset, vec3 d)
115
+ {
116
+ gs_prep[offset] = d.x;
117
+ gs_prep[offset + 1] = d.y;
118
+ gs_prep[offset + 2] = d.z;
119
+ }
120
+
121
+ void set_prep_vec2(int offset, vec2 d)
122
+ {
123
+ gs_prep[offset] = d.x;
124
+ gs_prep[offset + 1] = d.y;
125
+ }
126
+
127
+ void set_prep_vec1(int offset, float d)
128
+ {
129
+ gs_prep[offset] = d.x;
130
+ }
131
+
132
+ vec3 computeColor(int sh_offset, vec3 ray_dir)
133
+ {
134
+ vec3 c = SH_C0_0 * get_vec3(sh_offset);
135
+
136
+ if (sh_dim > 3) // 1 * 3
137
+ {
138
+ float x = ray_dir.x;
139
+ float y = ray_dir.y;
140
+ float z = ray_dir.z;
141
+ c = c +
142
+ SH_C1_0 * y * get_vec3(sh_offset + 1 * 3) +
143
+ SH_C1_1 * z * get_vec3(sh_offset + 2 * 3) +
144
+ SH_C1_2 * x * get_vec3(sh_offset + 3 * 3);
145
+
146
+ if (sh_dim > 12) // (1 + 3) * 3
147
+ {
148
+ float xx = x * x, yy = y * y, zz = z * z;
149
+ float xy = x * y, yz = y * z, xz = x * z;
150
+ c = c +
151
+ SH_C2_0 * xy * get_vec3(sh_offset + 4 * 3) +
152
+ SH_C2_1 * yz * get_vec3(sh_offset + 5 * 3) +
153
+ SH_C2_2 * (2.0f * zz - xx - yy) * get_vec3(sh_offset + 6 * 3) +
154
+ SH_C2_3 * xz * get_vec3(sh_offset + 7 * 3) +
155
+ SH_C2_4 * (xx - yy) * get_vec3(sh_offset + 8 * 3);
156
+
157
+ if (sh_dim > 27) // (1 + 3 + 5) * 3
158
+ {
159
+ c = c +
160
+ SH_C3_0 * y * (3.0f * xx - yy) * get_vec3(sh_offset + 9 * 3) +
161
+ SH_C3_1 * xy * z * get_vec3(sh_offset + 10 * 3) +
162
+ SH_C3_2 * y * (4.0f * zz - xx - yy) * get_vec3(sh_offset + 11 * 3) +
163
+ SH_C3_3 * z * (2.0f * zz - 3.0f * xx - 3.0f * yy) * get_vec3(sh_offset + 12 * 3) +
164
+ SH_C3_4 * x * (4.0f * zz - xx - yy) * get_vec3(sh_offset + 13 * 3) +
165
+ SH_C3_5 * z * (xx - yy) * get_vec3(sh_offset + 14 * 3) +
166
+ SH_C3_6 * x * (xx - 3.0f * yy) * get_vec3(sh_offset + 15 * 3);
167
+ }
168
+ }
169
+ }
170
+ c += 0.5f;
171
+
172
+ return c;
173
+ }
174
+
175
+ void main()
176
+ {
177
+ int gs_id = int(gl_GlobalInvocationID.x);
178
+
179
+ if (gs_id > gs_num)
180
+ return;
181
+
182
+ int dim_gs = 3 + 4 + 3 + 1 + sh_dim;
183
+ int base_gs = gs_id * dim_gs;
184
+ int base_prep = DIM_PREP * gs_id;
185
+ vec4 pw = vec4(get_vec3(base_gs + OFFSET_DATA_POS), 1.f);
186
+ vec4 pc = view_matrix * pw;
187
+ vec4 u = projection_matrix * pc;
188
+
189
+ // set depth for sorter.
190
+ depth[gs_id] = pc.z;
191
+
192
+ u = u / u.w;
193
+
194
+ if (any(greaterThan(abs(u.xy), vec2(1.3))))
195
+ {
196
+ set_prep_vec3(base_prep + OFFSET_PREP_U, vec3(-100));
197
+ return;
198
+ }
199
+
200
+ // check the depth
201
+ if (abs(u.z) > 1.f)
202
+ {
203
+ set_prep_vec3(base_prep + OFFSET_PREP_U, vec3(-100));
204
+ return;
205
+ }
206
+
207
+
208
+ vec4 rot = get_vec4(base_gs + OFFSET_DATA_ROT);
209
+ vec3 scale = get_vec3(base_gs + OFFSET_DATA_SCALE);
210
+
211
+ mat3 cov3d = computeCov3D(scale, rot);
212
+ vec3 cov2d = computeCov2D(pc,
213
+ focal.x,
214
+ focal.y,
215
+ cov3d,
216
+ view_matrix);
217
+
218
+ // Invert covariance (EWA algorithm)
219
+ float det = (cov2d.x * cov2d.z - cov2d.y * cov2d.y);
220
+
221
+ if (det == 0.0f)
222
+ {
223
+ set_prep_vec3(DIM_PREP * gs_id + OFFSET_PREP_U, vec3(-100., -100., -100.));
224
+ return;
225
+ }
226
+
227
+ float det_inv = 1.f / det;
228
+ vec3 cinv2d = vec3(cov2d.z * det_inv, -cov2d.y * det_inv, cov2d.x * det_inv);
229
+
230
+ vec2 area = 3.f * sqrt(vec2(cov2d.x, cov2d.z)); // drawing area, 3 sigma of x and y
231
+
232
+ // Covert SH to color
233
+ vec3 cam_pos = inverse(view_matrix)[3].xyz;
234
+ int sh_offset = base_gs + OFFSET_DATA_SH;
235
+ vec3 ray_dir = pw.xyz - cam_pos;
236
+
237
+ ray_dir = normalize(ray_dir);
238
+ vec3 color = computeColor(sh_offset, ray_dir);
239
+ float alpha = gs_data[base_gs + OFFSET_DATA_ALPHA];
240
+
241
+ vec3 covinv = vec3(cov2d.z * det_inv, -cov2d.y * det_inv, cov2d.x * det_inv);
242
+
243
+ set_prep_vec3(base_prep + OFFSET_PREP_U, u.xyz); //set u
244
+ set_prep_vec3(base_prep + OFFSET_PREP_COVINV, covinv); //set cov_int
245
+ set_prep_vec3(base_prep + OFFSET_PREP_COLOR, color); //set color
246
+ set_prep_vec2(base_prep + OFFSET_PREP_AREA, area); //set area
247
+ set_prep_vec1(base_prep + OFFSET_PREP_ALPHA, alpha); //set area
248
+
249
+ }
@@ -0,0 +1,77 @@
1
+ /*
2
+ Copyright 2024 Panasonic Advanced Technology Development Co.,Ltd. (Liu Yang)
3
+ Distributed under MIT license. See LICENSE for more information.
4
+ */
5
+
6
+ //draw 2d gaussian using proprocess data.
7
+
8
+ #version 430 core
9
+
10
+ #define OFFSET_PREP_U 0
11
+ #define OFFSET_PREP_COVINV 3
12
+ #define OFFSET_PREP_COLOR 6
13
+ #define OFFSET_PREP_AREA 9
14
+ #define OFFSET_PREP_ALPHA 11
15
+ #define DIM_PREP 12
16
+
17
+ layout(location = 0) in vec2 vert;
18
+
19
+
20
+ layout (std430, binding=0) buffer GaussianData {
21
+ float gs_data[];
22
+ };
23
+ layout (std430, binding=1) buffer GaussianOrder {
24
+ int gs_index[];
25
+ };
26
+ layout (std430, binding=3) buffer GaussianPrep {
27
+ float gs_prep[];
28
+ };
29
+
30
+ uniform vec2 win_size;
31
+
32
+ out vec3 color;
33
+ out float alpha;
34
+ out vec3 cinv2d;
35
+ out vec2 d_pix; // local coordinate in quad, unit in pixel
36
+
37
+ vec3 get_prep_vec3(int offset)
38
+ {
39
+ return vec3(gs_prep[offset], gs_prep[offset + 1], gs_prep[offset + 2]);
40
+ }
41
+
42
+ vec2 get_prep_vec2(int offset)
43
+ {
44
+ return vec2(gs_prep[offset], gs_prep[offset + 1]);
45
+ }
46
+
47
+ float get_prep_vec1(int offset)
48
+ {
49
+ return float(gs_prep[offset]);
50
+ }
51
+
52
+ void main()
53
+ {
54
+ int gs_id = gs_index[gl_InstanceID];
55
+ int base_prep = gs_id * DIM_PREP;
56
+ gl_Position = vec4(-100);
57
+
58
+ vec3 u = get_prep_vec3(base_prep + OFFSET_PREP_U);
59
+
60
+ if (u == vec3(-100))
61
+ {
62
+ return;
63
+ }
64
+
65
+ vec2 area = get_prep_vec2(base_prep + OFFSET_PREP_AREA);
66
+
67
+ vec2 area_ndc = area / win_size * 2; // in ndc space
68
+ vec2 pix = u.xy + vert * area_ndc;
69
+ gl_Position = vec4(pix, u.z , 1.0f);
70
+
71
+ //color = computeColor(sh_offset, ray_dir);
72
+ color = get_prep_vec3(base_prep + OFFSET_PREP_COLOR);
73
+ alpha = get_prep_vec1(base_prep + OFFSET_PREP_ALPHA);
74
+ cinv2d = get_prep_vec3(base_prep + OFFSET_PREP_COVINV);
75
+ d_pix = vert * area;
76
+
77
+ }
@@ -0,0 +1,56 @@
1
+ /*
2
+ Copyright 2024 Panasonic Advanced Technology Development Co.,Ltd. (Liu Yang)
3
+ Distributed under MIT license. See LICENSE for more information.
4
+ */
5
+
6
+ /*
7
+ opengl compute shader.
8
+ sort guassian by depth using bitonic sorter
9
+ */
10
+
11
+ #version 430 core
12
+
13
+ layout(local_size_x = 256, local_size_y = 1, local_size_z = 1) in;
14
+
15
+
16
+ uniform int level;
17
+ uniform int stage;
18
+
19
+
20
+ layout(std430, binding = 1) buffer index_buffer {
21
+ uint index[];
22
+ };
23
+
24
+ layout(std430, binding = 2) buffer key_buffer {
25
+ float data[];
26
+ };
27
+
28
+
29
+ // bitonic sort
30
+ // https://en.wikipedia.org/wiki/Bitonic_sorter
31
+
32
+ void main() {
33
+ uint a = (gl_GlobalInvocationID.x / stage) * (stage * 2) + gl_GlobalInvocationID.x % stage;
34
+ uint b = a ^ stage;
35
+ uint idx_a = index[a];
36
+ uint idx_b = index[b];
37
+ float data_a = data[idx_a];
38
+ float data_b = data[idx_b];
39
+
40
+ if ((a & level) == 0)
41
+ {
42
+ if (data_a > data_b)
43
+ {
44
+ index[a] = idx_b;
45
+ index[b] = idx_a;
46
+ }
47
+ }
48
+ else
49
+ {
50
+ if(data_a < data_b)
51
+ {
52
+ index[a] = idx_b;
53
+ index[b] = idx_a;
54
+ }
55
+ }
56
+ }
@@ -0,0 +1 @@
1
+ # tools/__init__.py