Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions examples/hexgrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ int main()

// Make some dummy data (a sine wave) to make an interesting surface
std::vector<float> data(hg.num(), 0.0f);
for (unsigned int ri=0; ri<hg.num(); ++ri) {
data[ri] = 0.05f + 0.05f*std::sin(20.0f*hg.d_x[ri]) * std::sin(10.0f*hg.d_y[ri]) ; // Range 0->1
for (unsigned int ri = 0; ri < hg.num(); ++ri) {
data[ri] = 0.05f + 0.05f * std::sin (20.0f * hg.d_x[ri]) * std::sin (10.0f * hg.d_y[ri]) ; // Range 0->1
}

// Add a HexGridVisual to display the HexGrid within the sm::Visual scene
sm::vec<float, 3> offset = { 0.0f, -0.05f, 0.0f };
auto hgv = std::make_unique<mplot::HexGridVisual<float, mplot::gl::version_4_1>>(&hg, offset);
v.bindmodel (hgv);
hgv->wireframe (true);
hgv->cm.setType (mplot::ColourMapType::Ice);
hgv->setScalarData (&data);
hgv->hexVisMode = mplot::HexVisMode::HexInterp; // Or sm::HexVisMode::Triangles for a smoother surface plot
Expand Down
47 changes: 46 additions & 1 deletion mplot/VisualBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,17 @@ namespace mplot
* If true, then turn on the bounding box for the VM about which we are rotating and turn
* the others off (ignoring the value of 'showBoundingBoxes')
*/
highlightRotationVM
highlightRotationVM,
/*!
* If true, the view of the scene follows a model translation (one of the VisualModels in
* the scene has to be nominated as the 'model to follow'. Useful for top-down views. The
* selected model to follow is in a member attribute followedModel
*/
viewFollowsVMTranslations,
/*!
* The view 'camera' rotates with the selected VM (followedModel)
*/
viewFollowsVMRotations,
};

//! Whether to render with perspective or orthographic (or even a cylindrical projection)
Expand Down Expand Up @@ -270,6 +280,17 @@ namespace mplot
return rtn;
}

void setFollowedVM (const mplot::VisualModel<glver>* vm_to_follow)
{
for (unsigned int modelId = 0; modelId < this->vm.size(); ++modelId) {
if (this->vm[modelId].get() == vm_to_follow) {
this->followedVM = this->vm[modelId].get();
this->followedLastViewMatrix = this->followedVM->getViewMatrix();
break;
}
}
}

/*!
* VisualModel Getter
*
Expand Down Expand Up @@ -787,6 +808,7 @@ namespace mplot
this->sceneview_tr = sv_tr * this->savedSceneview_tr;
}

// This is called every time render() is called
void computeSceneview()
{
if (std::abs(this->scenetrans_delta.sum()) > 0.0f || this->rotation_delta.is_zero_rotation() == false) {
Expand All @@ -798,12 +820,35 @@ namespace mplot
this->scenetrans_delta.zero();
this->state.reset (visual_state::scrolling);
}

if (this->options.test (visual_options::viewFollowsVMTranslations)
&& this->followedVM != nullptr
&& this->followedLastViewMatrix != this->followedVM->getViewMatrix()) {

// Move camera the difference between followedLastViewMatrix and
// followedVM->getViewMatrix() in the screen frame of reference.
sm::vec<float> fol_screenframe = (this->sceneview * followedLastViewMatrix.translation()
- this->sceneview * followedVM->getViewMatrix().translation()).less_one_dim();

this->sceneview.pretranslate (fol_screenframe);
this->sceneview_tr.pretranslate (fol_screenframe);
this->savedSceneview.pretranslate (fol_screenframe);
this->savedSceneview_tr.pretranslate (fol_screenframe);

this->followedLastViewMatrix = this->followedVM->getViewMatrix();
}
}

//! A vector of pointers to all the mplot::VisualModels (HexGridVisual,
//! ScatterVisual, etc) which are going to be rendered in the scene.
std::vector<std::unique_ptr<mplot::VisualModel<glver>>> vm;

//! If the view should follow a model (options viewFollowsVMTranslations and ...Rotations), this is the one.
mplot::VisualModel<glver>* followedVM = nullptr;

//! Holds the viewmatrix of the followedVM the last time we called render
sm::mat44<float> followedLastViewMatrix;

// Initialize OpenGL shaders, set some flags (Alpha, Anti-aliasing), read in any external
// state from json, and set up the coordinate arrows and any VisualTextModels that will be
// required to render the Visual.
Expand Down
5 changes: 5 additions & 0 deletions mplot/VisualModelBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ namespace mplot
postVertexInitRequired,
twodimensional, // If true, then this VisualModel should always be viewed in a plane - it's a 2D model
hide, // If true, then calls to VisualModel::render should return
wireframe, // If true, draw in GL's polygon mode
show_bb, // If true, draw vertices/indices for the bounding box frame
compute_bb // For some models, it's not useful to compute the bounding box (e.g. coordinate arrows)
};
Expand Down Expand Up @@ -746,6 +747,7 @@ namespace mplot
_flags.set (vm_bools::postVertexInitRequired, false);
_flags.set (vm_bools::twodimensional, false);
_flags.set (vm_bools::hide, false);
_flags.set (vm_bools::wireframe, false);
_flags.set (vm_bools::show_bb, false);
_flags.set (vm_bools::compute_bb, true);
return _flags;
Expand All @@ -765,6 +767,9 @@ namespace mplot
void twodimensional (const bool val) { this->flags.set (vm_bools::twodimensional, val); }
bool twodimensional() const { return this->flags.test (vm_bools::twodimensional); }

void wireframe (const bool val) { this->flags.set (vm_bools::wireframe, val); }
bool wireframe() const { return this->flags.test (vm_bools::wireframe); }

//! Getter for vertex positions (for mplot::NormalsVisual)
std::vector<float> getVertexPositions() { return this->vertexPositions; }
//! Getter for vertex normals (for mplot::NormalsVisual)
Expand Down
9 changes: 9 additions & 0 deletions mplot/VisualModelImplMX.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,14 @@ namespace mplot
_glfn->UseProgram (this->get_gprog(this->parentVis));

if (!this->indices.empty()) {

// Enable/disable wireframe mode per-model on each render call
if (this->flags.test (vm_bools::wireframe)) {
_glfn->PolygonMode (GL_FRONT_AND_BACK, GL_LINE);
} else {
_glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL);
}

// It is only necessary to bind the vertex array object before rendering
// (not the vertex buffer objects)
_glfn->BindVertexArray (this->vao);
Expand Down Expand Up @@ -252,6 +260,7 @@ namespace mplot
mplot::gl::Util::checkError (__FILE__, __LINE__, _glfn);

// Now render any VisualTextModels
_glfn->PolygonMode (GL_FRONT_AND_BACK, GL_FILL);
auto ti = this->texts.begin();
while (ti != this->texts.end()) { (*ti)->render(); ti++; }

Expand Down
9 changes: 9 additions & 0 deletions mplot/VisualModelImplNoMX.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ namespace mplot
glUseProgram (this->get_gprog(this->parentVis));

if (!this->indices.empty()) {

// Enable/disable wireframe mode per-model on each render call
if (this->flags.test (vm_bools::wireframe)) {
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
} else {
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
}

// It is only necessary to bind the vertex array object before rendering
// (not the vertex buffer objects)
glBindVertexArray (this->vao);
Expand Down Expand Up @@ -241,6 +249,7 @@ namespace mplot
mplot::gl::Util::checkError (__FILE__, __LINE__);

// Now render any VisualTextModels
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
auto ti = this->texts.begin();
while (ti != this->texts.end()) { (*ti)->render(); ti++; }

Expand Down