1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
// © 2004 Olivier Galizzi <olivier.galizzi@imag.fr>
// © 2008 Václav Šmilauer <eudoxos@arcig.cz>
#pragma once
#include <lib/multimethods/DynLibDispatcher.hpp>
#include <core/Body.hpp>
#include <core/Dispatcher.hpp>
#include <pkg/common/GLDrawFunctors.hpp>
namespace yade { // Cannot have #include directive inside.
struct GlExtraDrawer : public Serializable {
Scene* scene;
virtual void render();
// clang-format off
YADE_CLASS_BASE_DOC_ATTRS(GlExtraDrawer,Serializable,"Performing arbitrary OpenGL drawing commands; called from :yref:`OpenGLRenderer` (see :yref:`OpenGLRenderer.extraDrawers`) once regular rendering routines will have finished.\n\nThis class itself does not render anything, derived classes should override the *render* method.",
((bool,dead,false,,"Deactivate the object (on error/exception)."))
);
// clang-format on
};
REGISTER_SERIALIZABLE(GlExtraDrawer);
class OpenGLRenderer : public Serializable {
public:
static const int numClipPlanes = 3;
bool pointClipped(const Vector3r& p);
vector<Vector3r> clipPlaneNormals;
void setBodiesDispInfo();
static bool initDone;
Vector3r viewDirection; // updated from GLViewer regularly
GLViewInfo viewInfo; // update from GLView regularly
Vector3r highlightEmission0;
Vector3r highlightEmission1;
// normalized saw signal with given periodicity, with values ∈ 〈0,1〉 */
Real normSaw(Real t, Real period)
{
Real xi = (t - period * ((int)(t / period))) / period; /* normalized value, (0-1〉 */
return (xi < .5 ? 2 * xi : 2 - 2 * xi);
}
Real normSquare(Real t, Real period)
{
Real xi = (t - period * ((int)(t / period))) / period; /* normalized value, (0-1〉 */
return (xi < .5 ? 0 : 1);
}
void drawPeriodicCell();
void setBodiesRefSe3();
struct BodyDisp {
Vector3r pos;
Quaternionr ori;
bool isDisplayed;
bool hidden;
};
//! display data for individual bodies
vector<BodyDisp> bodyDisp;
void hide(Body::id_t id2)
{
if ((unsigned int)id2 < bodyDisp.size()) bodyDisp[id2].hidden = true;
}
void show(Body::id_t id2)
{
if ((unsigned int)id2 < bodyDisp.size()) bodyDisp[id2].hidden = false;
}
virtual ~OpenGLRenderer();
private:
void resetSpecularEmission();
GlBoundDispatcher boundDispatcher;
GlIGeomDispatcher geomDispatcher;
GlIPhysDispatcher physDispatcher;
GlShapeDispatcher shapeDispatcher;
// GlStateDispatcher stateDispatcher;
vector<string>
// stateFunctorNames,
boundFunctorNames, shapeFunctorNames, geomFunctorNames, physFunctorNames;
DECLARE_LOGGER;
public:
// updated after every call to render
shared_ptr<Scene> scene;
void init();
void initgl();
void render(const shared_ptr<Scene>& scene, Body::id_t selection = Body::id_t(-1));
void pyRender() { render(Omega::instance().getScene()); }
void renderDOF_ID();
void renderIPhys();
void renderIGeom();
void renderBound();
// called also to render selectable entitites;
void renderShape();
void renderAllInteractionsWire();
template <class FunctorType, class DispatcherT> void setupDispatcher(const vector<string>& names, DispatcherT& dispatcher);
enum class BlinkHighlight { NEVER, NORMAL, WEAK };
// clang-format off
YADE_CLASS_BASE_DOC_ATTRS_CTOR_PY(OpenGLRenderer,Serializable,"Class responsible for rendering scene on OpenGL devices.",
((Vector3r,dispScale,((void)"disable scaling",Vector3r::Ones()),,"Artificially enlarge (scale) dispalcements from bodies' :yref:`reference positions<State.refPos>` by this relative amount, so that they become better visible (independently in 3 dimensions). Disbled if (1,1,1)."))
((Real,rotScale,((void)"disable scaling",1.),,"Artificially enlarge (scale) rotations of bodies relative to their :yref:`reference orientation<State.refOri>`, so the they are better visible."))
((Vector3r,lightPos,Vector3r(75,130,0),,"Position of OpenGL light source in the scene."))
((Vector3r,light2Pos,Vector3r(-130,75,30),,"Position of secondary OpenGL light source in the scene."))
((Vector3r,lightColor,Vector3r(0.6,0.6,0.6),,"Per-color intensity of primary light (RGB)."))
((Vector3r,light2Color,Vector3r(0.5,0.5,0.1),,"Per-color intensity of secondary light (RGB)."))
((Vector3r,cellColor,Vector3r(1,1,0),,"Color of the periodic cell (RGB)."))
((Vector3r,bgColor,Vector3r(.2,.2,.2),,"Color of the background canvas (RGB)"))
((BlinkHighlight,blinkHighlight,BlinkHighlight::NORMAL,,"Adjust blinking of the body selected in the 'Simulation Inspection' window."))
((bool,wire,false,,"Render all bodies with wire only (faster)"))
((bool,light1,true,,"Turn light 1 on."))
((bool,light2,true,,"Turn light 2 on."))
((bool,dof,false,,"Show which degrees of freedom are blocked for each body"))
((bool,id,false,,"Show body id's"))
((bool,bound,false,,"Render body :yref:`Bound`"))
((bool,shape,true,,"Render body :yref:`Shape`"))
((bool,intrWire,false,,"If rendering interactions, use only wires to represent them."))
((bool,intrGeom,false,,"Render :yref:`Interaction::geom` objects."))
((bool,intrPhys,false,,"Render :yref:`Interaction::phys` objects"))
((bool,ghosts,true,,"Render objects crossing periodic cell edges by cloning them in multiple places (periodic simulations only)."))
((int,mask,((void)"draw everything",~0),,"Bitmask for showing only bodies where ((mask & :yref:`Body::mask`)!=0)"))
((Body::id_t,selId,Body::ID_NONE,,"Id of particle that was selected by the user."))
((vector<Se3r>,clipPlaneSe3,vector<Se3r>(numClipPlanes,Se3r(Vector3r::Zero(),Quaternionr::Identity())),,"Position and orientation of clipping planes"))
((vector<bool>,clipPlaneActive,vector<bool>(numClipPlanes,false),,"Activate/deactivate respective clipping planes"))
((vector<shared_ptr<GlExtraDrawer> >,extraDrawers,,,"Additional rendering components (:yref:`GlExtraDrawer`)."))
((bool,intrAllWire,false,,"Draw wire for all interactions, blue for potential and green for real ones (mostly for debugging)")),
/*ctor*/,
/*py*/
.def("setRefSe3",&OpenGLRenderer::setBodiesRefSe3,"Make current positions and orientation reference for scaleDisplacements and scaleRotations.")
.def("render",&OpenGLRenderer::pyRender,"Render the scene in the current OpenGL context.")
.def("hideBody",&OpenGLRenderer::hide,(boost::python::arg("id")),"Hide body from id (see :yref:`OpenGLRenderer::showBody`)")
.def("showBody",&OpenGLRenderer::show,(boost::python::arg("id")),"Make body visible (see :yref:`OpenGLRenderer::hideBody`)")
);
// clang-format on
};
REGISTER_SERIALIZABLE(OpenGLRenderer);
} // namespace yade
|