SimpleFastOpenAtomicVisualiser
Loading...
Searching...
No Matches
main.h
Go to the documentation of this file.
1#ifndef MAIN_H
2#define MAIN_H
3
4#include <sstream>
5#include <chrono>
6#include <exception>
7#include <algorithm>
8
9#define STB_IMAGE_WRITE_IMPLEMENTATION
10#include <stb_image_write.h>
11
12#include <jGL/jGL.h>
13#include <jGL/OpenGL/openGLInstance.h>
14#include <jGL/Display/desktopDisplay.h>
15#include <jGL/orthoCam.h>
16
17#include <icon.h>
18
19#include <jLog/jLog.h>
20
21#include <atom.h>
22#include <atomRenderer.h>
23#include <bondRenderer.h>
24#include <axes.h>
25#include <util.h>
26#include <glUtils.h>
27#include <structureUtils.h>
28#include <commandLine.h>
29#include <xyz.h>
30#include <config.h>
31#include <camera.h>
32#include <cell.h>
33#include <console.h>
34#include <visualisationState.h>
35#include <neighbours.h>
36
37const float dr = (1.0)*0.5;
38const float dtheta = (3.14)*0.025;
39const float dphi = (2.0*3.14)*0.05;
40
41const float emphasisedAlpha = 1.0f;
42
43bool closing = false;
44
45std::unique_ptr<jGL::jGLInstance> jGLInstance;
46
53void screenshot(glm::ivec2 resolution)
54{
55 std::vector<uint8_t> pixels(resolution.x*resolution.y*4, 0);
57 (
58 0,
59 0,
60 resolution.x,
61 resolution.y,
62 GL_RGBA,
64 pixels.data()
65 );
67 std::string name = timeStamp()+".png";
68 stbi_write_png(name.c_str(), resolution.x, resolution.y, 4, pixels.data(), 4*resolution.x);
69}
70
82(
84 int key,
85 int scancode,
86 int action,
87 int mods
88)
89{
91 {
92 closing = true;
93 }
94 jGL::parseAction(window, key, action);
95}
96
101struct Theme
102{
103 glm::vec4 background;
104 glm::vec4 text;
105};
106
113{
114 return
115 {
116 glm::vec4(5.0, 5.0, 5.0, 255.0)/255.0f,
117 glm::vec4(250.0, 250.0, 250.0, 255.0)/255.0f
118 };
119}
120
127{
128 return
129 {
130 glm::vec4(250.0, 250.0, 250.0, 255.0)/255.0f,
131 glm::vec4(5.0, 5.0, 5.0, 255.0)/255.0f
132 };
133}
134
147(
148 jGL::DesktopDisplay & display,
149 Camera & camera,
150 float zoomSpeed,
151 float rotateSpeed,
152 float inclineSpeed
153)
154{
155 bool moved = false;
156 if (display.keyHasAnyEvents(GLFW_KEY_W, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
157 {
158 camera.zoom(-dr*zoomSpeed);
159 moved = true;
160 }
161 if (display.keyHasAnyEvents(GLFW_KEY_S, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
162 {
163 camera.zoom(dr*zoomSpeed);
164 moved = true;
165 }
166 if (display.keyHasAnyEvents(GLFW_KEY_Q, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
167 {
169 moved = true;
170 }
171 if (display.keyHasAnyEvents(GLFW_KEY_E, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
172 {
173 camera.incline(-dtheta*inclineSpeed);
174 moved = true;
175 }
176 if (display.keyHasAnyEvents(GLFW_KEY_A, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
177 {
178 camera.rotate(-dphi*rotateSpeed);
179 moved = true;
180 }
181 if (display.keyHasAnyEvents(GLFW_KEY_D, {jGL::EventType::PRESS, jGL::EventType::HOLD}))
182 {
183 camera.rotate(dphi*rotateSpeed);
184 moved = true;
185 }
186 return moved;
187}
188
204(
205 jGL::DesktopDisplay & display,
206 std::vector<Atom> & atoms,
207 std::map<int, Element> & emphasisControls,
208 std::multimap<Element, uint64_t> & elementMap,
209 std::vector<float> & alphaOverrides,
210 float deemphasisAlpha,
211 float translateSpeed
212)
213{
214 bool elementsNeedUpdate = false;
215 if (display.keyHasEvent(GLFW_KEY_LEFT, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_LEFT, jGL::EventType::HOLD))
216 {
217 translate(atoms, {-dr*translateSpeed, 0.0, 0.0});
218 elementsNeedUpdate = true;
219 }
220 if (display.keyHasEvent(GLFW_KEY_RIGHT, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_RIGHT, jGL::EventType::HOLD))
221 {
222 translate(atoms, {dr*translateSpeed, 0.0, 0.0});
223 elementsNeedUpdate = true;
224 }
225 if (display.keyHasEvent(GLFW_KEY_PERIOD, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_PERIOD, jGL::EventType::HOLD))
226 {
227 translate(atoms, {0.0, -dr*translateSpeed, 0.0});
228 elementsNeedUpdate = true;
229 }
230 if (display.keyHasEvent(GLFW_KEY_SLASH, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_SLASH, jGL::EventType::HOLD))
231 {
232 translate(atoms, {0.0, dr*translateSpeed, 0.0});
233 elementsNeedUpdate = true;
234 }
235 if (display.keyHasEvent(GLFW_KEY_DOWN, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_DOWN, jGL::EventType::HOLD))
236 {
237 translate(atoms, {0.0, 0.0, -dr*translateSpeed});
238 elementsNeedUpdate = true;
239 }
240 if (display.keyHasEvent(GLFW_KEY_UP, jGL::EventType::PRESS) || display.keyHasEvent(GLFW_KEY_UP, jGL::EventType::HOLD))
241 {
242 translate(atoms, {0.0, 0.0, dr*translateSpeed});
243 elementsNeedUpdate = true;
244 }
245
246 for (const auto & control : emphasisControls)
247 {
248 if (display.keyHasEvent(control.first, jGL::EventType::PRESS))
249 {
250 auto iter = elementMap.equal_range(control.second);
251 while (iter.first != iter.second)
252 {
253 float & alpha = alphaOverrides[iter.first->second];
254 alpha = (alpha == emphasisedAlpha ? deemphasisAlpha : emphasisedAlpha);
255 atoms[iter.first->second].colour.a = alpha;
256 iter.first++;
257 }
258 elementsNeedUpdate = true;
259 }
260 }
261
262 return elementsNeedUpdate;
263}
264
271void setAlpha(std::vector<Atom> & atoms, std::vector<float> alphas)
272{
273 for (uint64_t i = 0; i < atoms.size(); i++) { atoms[i].colour.a = alphas[i]; }
274}
275
285(
286 jGL::DesktopDisplay & display,
287 Camera & camera,
289 std::string progressMessage,
290 Theme theme,
291 const unsigned int resX,
292 const unsigned int resY,
293 bool hideInfo = false
294)
295{
296 double deltas[60];
297 double delta = 0;
298 unsigned frameId = 0;
299 auto tic = std::chrono::high_resolution_clock::now();
300
301 jGLInstance->beginFrame();
302 jGLInstance->setClear(theme.background);
303 jGLInstance->clear();
304
305 cameraControls(display, camera, 1.0f, 1.0f, 1.0f);
306
307 loadingAtoms.updateCamera(camera);
308 loadingAtoms.draw(true);
309
310 std::stringstream debugText;
311
312 if (!hideInfo)
313 {
314 jGLInstance->text(
316 glm::vec2(64.0f, resY-64.0f),
317 0.5f,
318 theme.text
319 );
320 }
321
322 jGLInstance->endFrame();
323 display.loop();
324
325 delta = 0.0;
326 for (int n = 0; n < 60; n++)
327 {
328 delta += deltas[n];
329 }
330 delta /= 60.0;
331 auto toc = std::chrono::high_resolution_clock::now();
332 deltas[frameId] = std::chrono::duration_cast<std::chrono::milliseconds>(toc-tic).count();
333 frameId = (frameId+1) % 60;
334}
335
341void backward(std::unique_ptr<Structure> & structure)
342{
343 uint64_t f = structure->framePosition();
344 if (f > 2) { f -= 2; }
345 else { f = structure->frameCount()-2+f;}
346 structure->readFrame(f);
347}
348
357(
358 const std::vector<Atom> & atoms,
361)
362{
363 for (const auto & atom : atoms)
364 {
365 if (atom.colour.a != 0.0 && atom.colour.a != 1.0)
366 {
367 atomRenderer.setTransparencySorting(true);
368 bondRenderer.setTransparencySorting(true);
369 return;
370 }
371 }
372 atomRenderer.setTransparencySorting(false);
373 bondRenderer.setTransparencySorting(false);
374}
375
376#endif /* MAIN_H */
void translate(std::vector< Atom > &atoms, glm::vec3 r)
Definition atom.h:146
Render atoms as sphere meshes.
Definition atomRenderer.h:27
Render Bonds as ray-traced cylinders.
Definition bondRenderer.h:18
A 3D projective camera centered on a focus moving on a sphere.
Definition camera.h:30
void rotate(float increment)
Rotate about the y OpenGL axis.
Definition camera.h:136
void zoom(float increment)
Increment the zoom.
Definition camera.h:110
void incline(float increment)
Incline about the y OpenGL axis.
Definition camera.h:117
glm::vec< L, float, glm::qualifier::highp > vec
Definition commandLine.h:214
bool closing
Definition main.h:43
void keyEventCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
Override jGL default event callback.
Definition main.h:82
const float dr
Definition main.h:37
bool atomControls(jGL::DesktopDisplay &display, std::vector< Atom > &atoms, std::map< int, Element > &emphasisControls, std::multimap< Element, uint64_t > &elementMap, std::vector< float > &alphaOverrides, float deemphasisAlpha, float translateSpeed)
Controls for the Atoms position's.
Definition main.h:204
void loadingScreenFrame(jGL::DesktopDisplay &display, Camera &camera, AtomRenderer &loadingAtoms, std::string progressMessage, Theme theme, const unsigned int resX, const unsigned int resY, bool hideInfo=false)
Display a frame of the loading screen.
Definition main.h:285
void setAlpha(std::vector< Atom > &atoms, std::vector< float > alphas)
Set the alpha channel of Atom colours.
Definition main.h:271
void setTransparencySorting(const std::vector< Atom > &atoms, AtomRenderer &atomRenderer, BondRenderer &bondRenderer)
Enable of disable transparency sorting if there are transparent elements.
Definition main.h:357
const float dphi
Definition main.h:39
Theme lightTheme()
A light colour theme.
Definition main.h:126
const float dtheta
Definition main.h:38
std::unique_ptr< jGL::jGLInstance > jGLInstance
Definition main.h:45
bool cameraControls(jGL::DesktopDisplay &display, Camera &camera, float zoomSpeed, float rotateSpeed, float inclineSpeed)
Controls for the camera.
Definition main.h:147
void backward(std::unique_ptr< Structure > &structure)
Move back one frame.
Definition main.h:341
void screenshot(glm::ivec2 resolution)
Obtain screen pixels and write to a png.
Definition main.h:53
const float emphasisedAlpha
Definition main.h:41
Theme darkTheme()
A dark colour theme.
Definition main.h:112
A background and text colour theme.
Definition main.h:102
glm::vec4 background
Definition main.h:103
glm::vec4 text
Definition main.h:104
std::string timeStamp()
Current timestamp.
Definition util.h:179