Skip to content

Commit 9b2b147

Browse files
committed
Adds Field of View option
1 parent e37ba34 commit 9b2b147

10 files changed

Lines changed: 148 additions & 25 deletions

File tree

DOCUMENTATION.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ It is possible to write Lua scripts to manipulate visualisation in SFOAV. By sup
127127
| rotateCamera | dphi, the azimuthal increment | Rotate the camera |
128128
| zoomCamera | dr, move the camera to or from the focus | Zoom the camera |
129129
| inclineCamera | dtheta, the inclination increment | Incline the camera |
130+
| setCameraFieldOfView | fov, degrees | Set the field of view |
131+
| getCameraFieldOfView | | Get the field of view in degrees |
130132
| exit | | Exit sfoav |
131133

132134
E.g. the following script will set Atom 0 to a random colour every frame.

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ It is possible to write Lua scripts to manipulate visualisation in SFOAV. By sup
123123
| rotateCamera | dphi, the azimuthal increment | Rotate the camera |
124124
| zoomCamera | dr, move the camera to or from the focus | Zoom the camera |
125125
| inclineCamera | dtheta, the inclination increment | Incline the camera |
126+
| setCameraFieldOfView | fov, degrees | Set the field of view |
127+
| getCameraFieldOfView | | Get the field of view in degrees |
126128
| exit | | Exit sfoav |
127129

128130
```lua

include/axes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Axes
1515
public:
1616

1717
Axes(const Camera & camera)
18-
: camera({3.5, M_PI*0.5f, M_PI}, camera.getResX(), camera.getResY()),
18+
: camera({3.5, M_PI*0.5f, M_PI}, camera.getResX(), camera.getResY(), camera.getFieldOfView()),
1919
renderer(axes, axesPoints, axes.size())
2020
{
2121
renderer.setBondScale(0.33f);

include/camera.h

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ class Camera
3737
* @param resX the screen resolution width.
3838
* @param resY the screen resolution in height.
3939
*/
40-
Camera(const std::vector<Atom> & atoms, uint16_t resX, uint16_t resY)
41-
: resX(resX), resY(resY)
40+
Camera(const std::vector<Atom> & atoms, uint16_t resX, uint16_t resY, float fieldOfView)
41+
: resX(resX), resY(resY), fieldOfView(fieldOfView)
4242
{
4343
reset(atoms);
4444
}
@@ -50,8 +50,8 @@ class Camera
5050
* @param resX the screen resolution width.
5151
* @param resY the screen resolution in height.
5252
*/
53-
Camera(glm::vec3 positionSpherical, uint16_t resX, uint16_t resY)
54-
: resX(resX), resY(resY), positionSpherical(positionSpherical)
53+
Camera(glm::vec3 positionSpherical, uint16_t resX, uint16_t resY, float fieldOfView)
54+
: resX(resX), resY(resY), fieldOfView(fieldOfView), positionSpherical(positionSpherical)
5555
{
5656
reset();
5757
}
@@ -66,7 +66,7 @@ class Camera
6666

6767
projection = glm::perspective
6868
(
69-
glm::radians(45.0f), float(resX)/float(resY),
69+
glm::radians(fieldOfView), float(resX)/float(resY),
7070
0.1f,
7171
1000.0f
7272
);
@@ -180,6 +180,25 @@ class Camera
180180
*/
181181
float getUp() const { return up; }
182182

183+
/**
184+
* @brief Set the Field Of View
185+
*
186+
* @param degrees the field of view in degrees.
187+
* @remark clipped to [30, 90].
188+
*/
189+
void setFieldOfView(float degrees)
190+
{
191+
fieldOfView = std::min(std::max(30.0f, degrees), 90.0f);
192+
reset();
193+
}
194+
195+
/**
196+
* @brief Get the Field Of View
197+
*
198+
* @return float the field of view in degrees.
199+
*/
200+
float getFieldOfView() const { return fieldOfView; }
201+
183202
/**
184203
* @brief Get the Projection matrix.
185204
*
@@ -278,10 +297,31 @@ class Camera
278297
*/
279298
inline int lua_inclineCamera(lua_State * lua);
280299

300+
/**
301+
* @brief Set the field of view.
302+
*
303+
* @remark Lua arguments are:
304+
* 1. Field of view in degrees.
305+
* @param lua the Lua context.
306+
* @return int the return code.
307+
*/
308+
inline int lua_setCameraFieldOfView(lua_State * lua);
309+
310+
/**
311+
* @brief Set the field of view.
312+
*
313+
* @remark Lua arguments are:
314+
* 1. Field of view in degrees.
315+
* @param lua the Lua context.
316+
* @return int the return code.
317+
*/
318+
inline int lua_getCameraFieldOfView(lua_State * lua);
319+
281320
private:
282321

283322
uint16_t resX;
284323
uint16_t resY;
324+
float fieldOfView;
285325

286326
glm::vec3 positionSpherical;
287327
glm::vec3 focus;

include/commandLine.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ struct CommandLine
305305
extractArgument(deemphasisAlpha, arguments);
306306
extractArgument(atomClipCorrection, arguments);
307307
extractArgument(bondClipCorrection, arguments);
308+
extractArgument(fieldOfView, arguments);
308309
extractArgument(colourmap, arguments);
309310
extractArgument(atomColours, arguments);
310311
extractArgument(atomSize, arguments);
@@ -344,6 +345,7 @@ struct CommandLine
344345
Argument<float> deemphasisAlpha = {"deemphasisAlpha", "Alpha colour for deemphasised atoms.", "", 0.25f};
345346
Argument<float> atomClipCorrection = {"atomClipCorrection", "Correction for atom impostors.", "Increase if atoms clipped.", 1.5f};
346347
Argument<float> bondClipCorrection = {"bondClipCorrection", "Correction for bond impostors.", "Increase if atoms clipped.", 5.0f};
348+
Argument<float> fieldOfView = {"fieldOfView", "Field of view in degrees.", "", 60.0f};
347349
Argument<std::filesystem::path> colourmap = {"colourmap", "The colourmap path.", "", {}};
348350
Argument<std::filesystem::path> atomColours = {"atomColours", "Path for per-atom colour overrides.", "", {}};
349351
Argument<std::string> videoName = {"videoName", "Name of saved video.", "", ""};
@@ -464,10 +466,8 @@ struct CommandLine
464466
std::string * sval = stringFromName(s.characters);
465467
if (sval != nullptr)
466468
{
467-
std::cout << "yes\n";
468469
if (lua_isstring(lua, 2))
469470
{
470-
std::cout << "yes2\n";
471471
LuaString v; v.read(lua, 2);
472472
*sval = v.characters;
473473
return 0;
@@ -623,7 +623,7 @@ struct CommandLine
623623
<< "\n"
624624
<< sidebyside(argumentHelp(levelOfDetail), argumentHelp(hideInfoText), 42)
625625
<< "\n"
626-
<< argumentHelp(videoName)
626+
<< sidebyside(argumentHelp(videoName), argumentHelp(fieldOfView), 42)
627627
<< "\n"
628628
#ifdef WITH_FFMPEG
629629
<< "\n FFMPEG recording options:\n\n"
@@ -949,7 +949,7 @@ END OF TERMS AND CONDITIONS)";
949949
{globalBondAlpha.name, globalBondAlpha},
950950
{deemphasisAlpha.name, deemphasisAlpha},
951951
{atomClipCorrection.name, atomClipCorrection},
952-
{bondClipCorrection.name, bondClipCorrection},
952+
{bondClipCorrection.name, bondClipCorrection}
953953
};
954954

955955
if (values.find(name) != values.cend())

include/console.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ class Console
341341

342342
static int load_sfoavLib(lua_State * lua)
343343
{
344-
luaL_Reg sfoavLib[23] =
344+
luaL_Reg sfoavLib[25] =
345345
{
346346
{"setAtomColour", &dispatchVisualisationState<&VisualisationState::lua_setAtomColour>},
347347
{"getAtomColour", &dispatchVisualisationState<&VisualisationState::lua_getAtomColour>},
@@ -362,6 +362,8 @@ class Console
362362
{"rotateCamera", &dispatchCamera<&Camera::lua_rotateCamera>},
363363
{"zoomCamera", &dispatchCamera<&Camera::lua_zoomCamera>},
364364
{"inclineCamera", &dispatchCamera<&Camera::lua_inclineCamera>},
365+
{"setCameraFieldOfView", &dispatchCamera<&Camera::lua_setCameraFieldOfView>},
366+
{"getCameraFieldOfView", &dispatchCamera<&Camera::lua_getCameraFieldOfView>},
365367
{"exit", &lua_exit},
366368
{"getOption", &dispatchCommandLine<&CommandLine::lua_getOption>},
367369
{"setOption", &dispatchCommandLine<&CommandLine::lua_setOption>},

include/luaBindings/camera.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,43 @@ inline int Camera::lua_inclineCamera(lua_State * lua)
133133
return 0;
134134
}
135135

136+
/**
137+
* @brief Set the field of view.
138+
*
139+
* @remark Lua arguments are:
140+
* 1. Field of view in degrees.
141+
* @param lua the Lua context.
142+
* @return int the return code.
143+
*/
144+
inline int Camera::lua_setCameraFieldOfView(lua_State * lua)
145+
{
146+
int args = lua_gettop(lua);
147+
if (args != 1)
148+
{
149+
const std::string msg = "setCameraFieldOfView expects a number as argument.\n";
150+
lua_pushlstring(lua, msg.c_str(), msg.length());
151+
return lua_error(lua);
152+
}
153+
154+
LuaNumber fov;
155+
fov.read(lua, 1);
156+
fieldOfView = fov.n;
157+
reset();
158+
159+
return 0;
160+
}
161+
162+
/**
163+
* @brief Set the field of view.
164+
*
165+
* @remark Lua arguments are:
166+
* @param lua the Lua context.
167+
* @return int the return code.
168+
*/
169+
inline int Camera::lua_getCameraFieldOfView(lua_State * lua)
170+
{
171+
lua_pushnumber(lua, fieldOfView);
172+
return 1;
173+
}
174+
136175
#endif /* LUA_CAMERA_H */

src/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ int main(int argv, char ** argc)
7878

7979
structure->readFrame(0);
8080

81-
Camera loadingCamera {sfoavAtoms, resX, resY};
81+
Camera loadingCamera {sfoavAtoms, resX, resY, options.fieldOfView.value};
8282
loadingCamera.rotate(-M_PI/2.0);
8383

8484
AtomRenderer loadingAtoms
@@ -119,7 +119,7 @@ int main(int argv, char ** argc)
119119
if (options.focus.value < structure->atoms.size()) { centerOn(structure->atoms, options.focus.value); }
120120
com = getCenter(structure->atoms);
121121

122-
Camera camera {structure->atoms, resX, resY};
122+
Camera camera {structure->atoms, resX, resY, options.fieldOfView.value};
123123

124124
jLog::Log log;
125125
Console console(log, &visualisationState, &options, &camera);

tests/generate_lua_options_interop_tests.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,24 @@
1616
}
1717
"""
1818

19+
generate_string_test = """ WHEN("The script \\"v = sfoav.getOption(\\"meshes\\");\\"")
20+
{
21+
console.runString("v = sfoav.getOption(\\"meshes\\");");
22+
THEN("v is DEFAULT_INTERPOLATED")
23+
{
24+
REQUIRE(console.getGlobal<TYPE>("v").MEMBER == DEFAULT);
25+
}
26+
WHEN("The script \\"sfoav.setOption(\\"meshes\\", SET); v = sfoav.getOption(\\"meshes\\");\\"")
27+
{
28+
console.runString("sfoav.setOption(\\"meshes\\", SET); v = sfoav.getOption(\\"meshes\\");");
29+
THEN("v is SET")
30+
{
31+
CONDITION
32+
}
33+
}
34+
}
35+
"""
36+
1937
tests = """/*
2038
Tests are generated by tests/generate_lua_options_interop_tests.py
2139
*/
@@ -53,19 +71,21 @@
5371
tests += test+"\n"
5472

5573
for (option, default) in [("videoName", "\"\"")]:
56-
test = generate_test
57-
for (k, v) in [("meshes", option), ("DEFAULT", str(default)),
74+
test = generate_string_test
75+
for (k, v) in [("meshes", option), ("DEFAULT_INTERPOLATED", default.replace("\"","")),
76+
("DEFAULT", str(default)),
5877
("SET", "\\\"TEST\\\""), ("TYPE", "LuaString"),
5978
("MEMBER", "characters"),
6079
("CONDITION", "REQUIRE(\"TEST\" == console.getGlobal<LuaString>(\"v\").characters);")]:
6180
test = test.replace(k, v)
6281
tests += test+"\n"
6382

6483
tests += " #ifdef WITH_FFMPEG\n"
65-
for (option, default) in [("preset", "slow"), ("codec", "libx264"),
66-
("profile", "main")]:
67-
test = generate_test
68-
for (k, v) in [("meshes", option), ("DEFAULT", str(default)),
84+
for (option, default) in [("preset", "\"slow\""), ("codec", "\"libx264\""),
85+
("profile", "\"main\"")]:
86+
test = generate_string_test
87+
for (k, v) in [("meshes", option), ("DEFAULT_INTERPOLATED", default.replace("\"","")),
88+
("DEFAULT", default),
6989
("SET", "\\\"TEST\\\""), ("TYPE", "LuaString"),
7090
("MEMBER", "characters"),
7191
("CONDITION", "REQUIRE(\"TEST\" == console.getGlobal<LuaString>(\"v\").characters);")]:

tests/test_console/test_console.cpp

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ VisualisationState vs
1919
);
2020

2121
CommandLine options;
22-
Camera camera(testAtoms, 64, 64);
22+
Camera camera(testAtoms, 64, 64, 60.0);
2323

2424
SCENARIO("Lua atom interop")
2525
{
@@ -354,7 +354,7 @@ SCENARIO("Lua bond interop")
354354
SCENARIO("Lua camera interop")
355355
{
356356
jLog::Log l;
357-
GIVEN("A Lua console and a camera at spherical coordinates (1,3.14,1.57)")
357+
GIVEN("A Lua console and a camera at spherical coordinates (1,3.14,1.57) and 60 fov.")
358358
{
359359
Console console(l, &vs, &options, &camera);
360360
camera.setPosition({1,3.14,1.57});
@@ -423,6 +423,24 @@ SCENARIO("Lua camera interop")
423423
REQUIRE_THAT(z.n, WithinAbs(1.57, 0.01));
424424
}
425425
}
426+
WHEN("The script \"fov = sfoav.getCameraFieldOfView()\" is run")
427+
{
428+
console.runString("fov = sfoav.getCameraFieldOfView()");
429+
THEN("fov is 60.0")
430+
{
431+
auto fov = console.getGlobal<LuaNumber>("fov");
432+
REQUIRE_THAT(fov.n, WithinAbs(60.0, tol));
433+
}
434+
}
435+
WHEN("The script \"sfoav.setCameraFieldOfView(35.0); fov = sfoav.getCameraFieldOfView()\" is run")
436+
{
437+
console.runString("sfoav.setCameraFieldOfView(35.0); fov = sfoav.getCameraFieldOfView()");
438+
THEN("fov is 35.0")
439+
{
440+
auto fov = console.getGlobal<LuaNumber>("fov");
441+
REQUIRE_THAT(fov.n, WithinAbs(35.0, tol));
442+
}
443+
}
426444
}
427445
}
428446

@@ -762,7 +780,7 @@ SCENARIO("Lua options interop")
762780
WHEN("The script \"v = sfoav.getOption(\"videoName\");\"")
763781
{
764782
console.runString("v = sfoav.getOption(\"videoName\");");
765-
THEN("v is """)
783+
THEN("v is ")
766784
{
767785
REQUIRE(console.getGlobal<LuaString>("v").characters == "");
768786
}
@@ -782,7 +800,7 @@ SCENARIO("Lua options interop")
782800
console.runString("v = sfoav.getOption(\"preset\");");
783801
THEN("v is slow")
784802
{
785-
REQUIRE(console.getGlobal<LuaString>("v").characters == slow);
803+
REQUIRE(console.getGlobal<LuaString>("v").characters == "slow");
786804
}
787805
WHEN("The script \"sfoav.setOption(\"preset\", \"TEST\"); v = sfoav.getOption(\"preset\");\"")
788806
{
@@ -798,7 +816,7 @@ SCENARIO("Lua options interop")
798816
console.runString("v = sfoav.getOption(\"codec\");");
799817
THEN("v is libx264")
800818
{
801-
REQUIRE(console.getGlobal<LuaString>("v").characters == libx264);
819+
REQUIRE(console.getGlobal<LuaString>("v").characters == "libx264");
802820
}
803821
WHEN("The script \"sfoav.setOption(\"codec\", \"TEST\"); v = sfoav.getOption(\"codec\");\"")
804822
{
@@ -814,7 +832,7 @@ SCENARIO("Lua options interop")
814832
console.runString("v = sfoav.getOption(\"profile\");");
815833
THEN("v is main")
816834
{
817-
REQUIRE(console.getGlobal<LuaString>("v").characters == main);
835+
REQUIRE(console.getGlobal<LuaString>("v").characters == "main");
818836
}
819837
WHEN("The script \"sfoav.setOption(\"profile\", \"TEST\"); v = sfoav.getOption(\"profile\");\"")
820838
{

0 commit comments

Comments
 (0)