Let's create a simple set of slides to demonstrate the common use, and good practices, of the library.
Simple template
A simple & clean template for a project could be like this:
#include "slope.h"
using namespace slope;
Slideshow show;
void init () {
Latex::UsePackage("libertine"); // set font
LatexLoader::Init("text.json"); // set latex source
}
int main(int argc,char** argv) {
show.init("A simple project",argc,argv);
init();
show.run();
return 0;
}
Latex::UsePackage to append before all latex files the libertine package to set the font for the text and formulas and LatexLoader::Init("text.json) to indicate the file for the hot reloading of the text. Even for simple text, assume that you will have to edit the text many times so using the hot-reloading is always a good idea.
Note that a good idea to reduce compilation time would be to generate each group of slides in different cpp files to avoid recompiling everything at each edits, but let's do everything in one block for the sake of clarity.
Titles
Titles are essential in a presentation and in slope they allow to label each group of slides to enable jumping back and forth between slide groups. They appear larger than standard text and are unique to a slide. Let's make it appear at the center first, and then make it move to the top at the next slide.
Note that only adding TOP will refer automatically to the last primitive inserted. Here it is equivalent to:
auto title = Title("The moon and the tides");
show << title->at(CENTER);
show << inNextFrame << title->at(TOP);
Primitives and camera
The core objects in slope are the primitives, that are either screen ones (purely in 2D space in the screen), or Polyscope ones, we can start by adding a sphere:
// adding a mesh
auto planet = Mesh::Add("sphere.obj");
show << planet;
planet->pc->setSurfaceColor(glm::vec3(0.5,0.6,1));
At this point, you should get this:
We first adapt the camera to the scene by changing it as usual with polyscope and you can save the view by pressing c and here we save it under view1 and add it to the scene:
Text and hot-reloading
We can also start adding text, do it by modifing the latex souce file, here test.json:
We can hot-reload the text (and its width) in the json file, and we can move (and scale) the text as we loaded it with a (persistent) anchor.
Animations and screen space tracking
We can add a point that follows a simple trajectory:
auto moon = Point::Add([] (TimeObject t) -> vec {
float angle = t.inner_time;
scalar r = 1.3;
return r*vec(cos(angle), sin(angle), 0);
});
show << moon;
Polyscope quantities
We can also make a scalar field appear at a different moment than the mesh itself, and access to its own polyscope attributes:
Vec tide = Vec::Zero(planet->getVertices().size());
auto q = planet->pc->addVertexScalarQuantity("tide",tide);
auto tide_plot = PolyscopeQuantity<polyscope::SurfaceVertexScalarQuantity>::Add(q);
tide_plot->q->setColorMap("blues");
A simple yet powerful animation idea is to update the scalar values and the mesh itself in a single updater:
auto verts = planet->getVertices();
tide_plot->updater = [verts,planet,q,tide,moon](TimeObject t){
Vec values = tide;
vec m = moon->getCurrentPos();
auto new_pos = verts;
for (size_t i = 0; i < planet->getVertices().size(); i++) {
values(i) = 1/(verts[i] - m).squaredNorm();
new_pos[i] += 0.01*values(i)*verts[i];// offset sphere in normal direction
}
q->updateData(values);
q->setMapRange({values.minCoeff(),values.maxCoeff()}); //required for polyscope to update
planet->updateMesh(new_pos);
};
show << tide_plot;
Overall pretty simple right?
Full code
#include "slope.h"
using namespace slope;
Slideshow show;
void init () {
Latex::UsePackage("libertine"); // set font
LatexLoader::Init("test.json"); // set latex source
show << Title("The moon and the tides")->at(CENTER);
show << inNextFrame << TOP;
auto planet = Mesh::Add("sphere.obj");
show << planet;
planet->pc->setSurfaceColor(glm::vec3(0.5,0.6,1));
show << CameraView::Add("base");
show << LatexLoader::LoadWithAnchor("moon1");
show << inNextFrame;
auto moon = Point::Add([] (TimeObject t) -> vec {
float angle = t.inner_time;
scalar r = 1.3;
return r*vec(cos(angle), sin(angle), 0);
});
show << moon;
show << Latex::Add("The moon")->track([moon] () {return moon->getCurrentPos();}, vec2(0,-0.05));
Vec tide = Vec::Random(planet->getVertices().size());
auto q = planet->pc->addVertexScalarQuantity("tide",tide);
auto tide_plot = AddPolyscopeQuantity(q);
auto verts = planet->getVertices();
tide_plot->q->setColorMap("blues");
tide_plot->updater = [verts,planet,q,tide,moon](TimeObject t){
Vec values = tide;
vec m = moon->getCurrentPos();
auto new_pos = verts;
for (size_t i = 0; i < planet->getVertices().size(); i++) {
values(i) = 1/(verts[i] - m).squaredNorm();
new_pos[i] += 0.01*values(i)*verts[i];// offset sphere in normal direction
}
q->updateData(values);
q->setMapRange({values.minCoeff(),values.maxCoeff()}); // required for polyscope to update
planet->updateMesh(new_pos);
};
show << tide_plot;
show << newFrame;
// make more slides here!
}
int main(int argc,char** argv) {
show.init("A simple project",argc,argv);
init();
show.run();
return 0;
}