55#include <ACG/GL/acg_glew.hh>
56#include "ArrowNode.hh"
57#include <ACG/GL/IRenderer.hh>
58#include <OpenMesh/Core/Utils/vector_cast.hh>
71 localArrowMin_(0.0f, 0.0f, 0.0f),
72 localArrowMax_(0.0f, 0.0f, 0.0f),
73 invalidateInstanceData_(true),
74 invalidateInstanceBuffer_(true),
75 supportsInstancing_(-1)
90 float radius = std::max(localArrowMax_[1] - localArrowMin_[1], localArrowMax_[2] - localArrowMin_[2]) * 0.5f;
92 size_t n = arrows_.size();
93 for (
size_t i = 0; i < n; ++i)
95 const Arrow* a = &arrows_[i];
99 Vec3f e = a->start + a->dir * a->scale[1];
102 Vec3d sd = OpenMesh::vector_cast<Vec3d>(s);
103 Vec3d ed = OpenMesh::vector_cast<Vec3d>(e);
106 Vec3d volEnlargeOffset = OpenMesh::vector_cast<Vec3d>(radius * a->scale);
108 _bbMin.
minimize(sd - volEnlargeOffset);
109 _bbMin.
minimize(ed - volEnlargeOffset);
111 _bbMax.
maximize(sd + volEnlargeOffset);
112 _bbMax.
maximize(ed + volEnlargeOffset);
126void ArrowNode::createArrowMesh()
134 0.681818f, -0.034091f, -0.068182f, 0.000000f, -1.000000f, 0.000000f,
135 0.681818f, -0.034091f, 0.068182f, 0.000000f, -1.000000f, 0.000000f,
136 0.000000f, -0.034091f, 0.000000f, 0.000000f, -1.000000f, 0.000000f,
137 1.000000f, -0.034091f, 0.000000f, 0.000000f, -1.000000f, 0.000000f,
138 0.681818f, -0.034091f, -0.227273f, 0.000000f, -1.000000f, 0.000000f,
139 0.681818f, -0.034091f, 0.227273f, 0.000000f, -1.000000f, 0.000000f,
140 0.681818f, 0.034091f, -0.068182f, 0.000000f, 1.000000f, -0.000000f,
141 1.000000f, 0.034091f, 0.000000f, 0.000000f, 1.000000f, 0.000000f,
142 0.681818f, 0.034091f, -0.227273f, -0.000000f, 1.000000f, 0.000000f,
143 0.681818f, 0.034091f, 0.068182f, 0.000000f, 1.000000f, -0.000000f,
144 0.000000f, 0.034091f, 0.000000f, 0.000000f, 1.000000f, -0.000000f,
145 0.681818f, 0.034091f, 0.227273f, 0.000000f, 1.000000f, 0.000000f,
146 1.000000f, -0.034091f, 0.000000f, 0.581238f, 0.000000f, -0.813734f,
147 0.681818f, 0.034091f, -0.227273f, 0.581238f, 0.000000f, -0.813734f,
148 1.000000f, 0.034091f, 0.000000f, 0.581238f, 0.000000f, -0.813734f,
149 0.681818f, -0.034091f, -0.227273f, 0.581238f, 0.000000f, -0.813734f,
150 0.681818f, -0.034091f, 0.227273f, 0.581238f, 0.000000f, 0.813734f,
151 1.000000f, 0.034091f, 0.000000f, 0.581238f, 0.000000f, 0.813734f,
152 0.681818f, 0.034091f, 0.227273f, 0.581238f, -0.000000f, 0.813734f,
153 1.000000f, -0.034091f, 0.000000f, 0.581238f, 0.000000f, 0.813734f,
154 0.681818f, -0.034091f, 0.068182f, -1.000000f, -0.000000f, 0.000000f,
155 0.681818f, 0.034091f, 0.227273f, -1.000000f, -0.000000f, 0.000000f,
156 0.681818f, 0.034091f, 0.068182f, -1.000000f, 0.000000f, 0.000000f,
157 0.681818f, -0.034091f, 0.227273f, -1.000000f, -0.000000f, 0.000000f,
158 0.681818f, -0.034091f, -0.227273f, -1.000000f, -0.000000f, 0.000000f,
159 0.681818f, 0.034091f, -0.068182f, -1.000000f, -0.000000f, 0.000000f,
160 0.681818f, 0.034091f, -0.227273f, -1.000000f, 0.000000f, 0.000000f,
161 0.681818f, -0.034091f, -0.068182f, -1.000000f, -0.000000f, 0.000000f,
162 0.000000f, -0.034091f, 0.000000f, -0.099504f, 0.000000f, 0.995037f,
163 0.681818f, 0.034091f, 0.068182f, -0.099504f, 0.000000f, 0.995037f,
164 0.000000f, 0.034091f, 0.000000f, -0.099504f, 0.000000f, 0.995037f,
165 0.681818f, -0.034091f, 0.068182f, -0.099504f, 0.000000f, 0.995037f,
166 0.681818f, -0.034091f, -0.068182f, -0.099504f, -0.000000f, -0.995037f,
167 0.000000f, 0.034091f, 0.000000f, -0.099504f, -0.000000f, -0.995037f,
168 0.681818f, 0.034091f, -0.068182f, -0.099504f, 0.000000f, -0.995037f,
169 0.000000f, -0.034091f, 0.000000f, -0.099504f, -0.000000f, -0.995037f,
205 numIndices_ =
sizeof(idata) /
sizeof(idata[0]);
208 vertexBuffer_.upload(
sizeof(vdata), vdata, GL_STATIC_DRAW);
209 indexBuffer_.upload(
sizeof(idata), idata, GL_STATIC_DRAW);
212 localArrowMin_ =
Vec3f(vdata[0], vdata[1], vdata[2]);
213 localArrowMax_ = localArrowMin_;
215 for (
int i = 1; i < numVertices_; ++i)
217 Vec3f v =
Vec3f(vdata[i * 6], vdata[i * 6 + 1], vdata[i * 6 + 2]);
229 updateInstanceData();
231 vertexBuffer_.bind();
238 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)&viewMatrix);
242 glEnable(GL_COLOR_MATERIAL);
243 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
245 for (
size_t i = 0; i < arrows_.size(); ++i)
248 GLMatrixf worldView = viewMatrix * readWorldMatrix(i);
249 glLoadMatrixf(worldView.data());
251 Vec4uc c = arrows_[i].color;
252 glColor4ub(c[0], c[1], c[2], c[3]);
254 glDrawElements(GL_TRIANGLES, numIndices_, GL_UNSIGNED_INT, 0);
258 glLoadMatrixf(viewMatrix.data());
260 glDisable(GL_COLOR_MATERIAL);
272 updateInstanceBuffer();
277 obj.depthTest =
true;
284 if (supportsInstancing_ < 0)
290 if (supportsInstancing_)
294 obj.
shaderDesc.vertexTemplateFile =
"ArrowNode/instancing_vs.glsl";
296 obj.glDrawElementsInstanced(GL_TRIANGLES, numIndices_, GL_UNSIGNED_INT, 0, arrows_.size());
310 for (
size_t i = 0; i < arrows_.size(); ++i)
312 const Arrow* a = &arrows_[i];
314 obj.
modelview = viewMatrix * readWorldMatrix(i);
315 obj.
diffuse =
Vec3f(a->color[0] / 255.0f, a->color[1] / 255.0f, a->color[2] / 255.0f);
316 obj.alpha = a->color[3] / 255.0f;
318 obj.glDrawElements(GL_TRIANGLES, numIndices_, GL_UNSIGNED_INT, 0);
342 return int(arrows_.size());
347GLMatrixf ArrowNode::computeWorldMatrix(
int _arrow)
const
349 const Arrow* a = &arrows_[_arrow];
358 Vec3f binormal = a->dir % a->normal;
359 for (
int i = 0; i < 3; ++i)
361 align(i, 0) = a->dir[i];
362 align(i, 1) = a->normal[i];
363 align(i, 2) = binormal[i];
367 align.
scale(a->scale[1], a->scale[2], a->scale[0]);
385 arrows_.push_back(a);
387 invalidateInstanceData_ =
true;
388 invalidateInstanceBuffer_ =
true;
390 return int(arrows_.size()) - 1;
398 for (
int i = 0; i < 4; ++i)
399 c[i] = std::min(std::max(
int(_color[i] * 255.0f), 0), 255);
400 return addArrow(_start, _dir, _normal, _scale, c);
405void ArrowNode::Arrow::orthonormalize()
411 normal =
Vec3f(0.0f, 1.0f, 0.0f);
415 while (std::fabs(dir | normal) > 0.99f || normal.
sqrnorm() < 0.01f)
417 for (
int i = 0; i < 3; ++i)
418 normal[i] =
float(rand()) / float(RAND_MAX) * 2.0f - 1.0f;
422 Vec3f binormal = dir % normal;
423 normal = (binormal % dir).normalized();
430 return addArrow(OpenMesh::vector_cast<Vec3f>(_start), OpenMesh::vector_cast<Vec3f>(_dir), OpenMesh::vector_cast<Vec3f>(_normal), OpenMesh::vector_cast<Vec3f>(_scale), _color);
438 for (
int i = 0; i < 4; ++i)
439 c[i] = std::min(std::max(
int(_color[i] * 255.0f), 0), 255);
440 return addArrow(_start, _dir, _normal, _scale, c);
445void ArrowNode::updateInstanceData()
447 if (invalidateInstanceData_)
449 const int numArrows = arrows_.size();
452 const int instanceSize = instanceDataSize();
454 instanceData_.resize(numArrows * instanceSize);
456 for (
int i = 0; i < numArrows; ++i)
460 int offset = instanceDataOffset(i);
463 for (
int r = 0; r < 3; ++r)
464 for (
int c = 0; c < 4; ++c)
465 instanceData_[offset + r*4 + c] = m(r,c);
469 for (
int r = 0; r < 3; ++r)
470 for (
int c = 0; c < 3; ++c)
471 instanceData_[offset + 4 * 3 + r * 3 + c] = m(c, r);
475 memcpy(&instanceData_[offset + 4*3 + 3*3], arrows_[i].color.data(), 4);
480 invalidateInstanceData_ =
false;
488 int offset = instanceDataOffset(_arrow);
491 for (
int r = 0; r < 3; ++r)
492 for (
int c = 0; c < 4; ++c)
493 m(r,c) = instanceData_[offset + r*4 + c];
496 m(3,0) = 0.0f; m(3,1) = 0.0f; m(3,2) = 0.0f; m(3,3) = 1.0f;
503void ArrowNode::updateInstanceBuffer()
505 if (invalidateInstanceBuffer_ || invalidateInstanceData_)
507 updateInstanceData();
509 if (!instanceData_.empty())
510 instanceBuffer_.upload(4 * instanceData_.size(), &instanceData_[0], GL_STATIC_DRAW);
528 invalidateInstanceBuffer_ =
false;
536 return arrows_[_arrowID].start;
541 arrows_[_arrowID].start = _start;
542 invalidateInstanceData_ =
true;
547 return arrows_[_arrowID].dir;
552 arrows_[_arrowID].dir = _dir;
553 arrows_[_arrowID].orthonormalize();
554 invalidateInstanceData_ =
true;
559 return arrows_[_arrowID].normal;
564 arrows_[_arrowID].normal = _normal;
565 arrows_[_arrowID].orthonormalize();
566 invalidateInstanceData_ =
true;
571 return arrows_[_arrowID].scale;
576 arrows_[_arrowID].scale = _scale;
577 invalidateInstanceData_ =
true;
582 return arrows_[_arrowID].color;
587 arrows_[_arrowID].color = _color;
588 invalidateInstanceData_ =
true;
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
void identity()
setup an identity matrix
bool invert()
matrix inversion (returns true on success)
void draw(GLState &_state, const DrawModes::DrawMode &_drawMode) override
draw arrows
Vec3f arrowDir(int _arrowID) const
Return the direction of an arrow.
void boundingBox(Vec3d &_bbMin, Vec3d &_bbMax) override
update bounding box
Vec3f arrowStart(int _arrowID) const
Return the start position of an arrow.
Vec3f arrowScale(int _arrowID) const
Return the scale of an arrow.
int n_arrows() const
number of arrows
int addArrow(const Vec3f &_start, const Vec3f &_dir, const Vec3f &_normal=Vec3f(0.0f, 1.0f, 0.0f), const Vec3f &_scale=Vec3f(1.0f, 1.0f, 1.0f), const Vec4uc &_color=Vec4uc(82, 82, 82, 255))
Add an arrow to the node.
void getRenderObjects(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawMode, const ACG::SceneGraph::Material *_mat) override
Add the objects to the given renderer.
Vec3f arrowNormal(int _arrowID) const
Return the normal of an arrow.
ArrowNode(BaseNode *_parent=0, std::string _name="<ArrowNode>")
default constructor
DrawModes::DrawMode availableDrawModes() const override
return available draw modes
void reserve(int _n)
reserve mem for _n arrows
Vec4uc arrowColor(int _arrowID) const
Return the color of an arrow.
DrawModes::DrawMode drawMode() const
Return the own draw modes of this node.
void addElement(const VertexElement *_pElement)
unsigned int getNumElements() const
void deactivateFixedFunction() const
unsigned int getVertexStride(unsigned int i=0) const
void activateFixedFunction() const
decltype(std::declval< S >() *std::declval< S >()) sqrnorm() const
compute squared euclidean norm
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM > >().norm())
DrawMode SOLID_FLAT_SHADED
draw flat shaded faces (requires face normals)
Namespace providing different geometric functions concerning angles.
GLMatrixT< float > GLMatrixf
typedef
bool checkExtensionSupported(const std::string &_extension)
VectorT< float, 3 > Vec3f
@ VERTEX_USAGE_NORMAL
"inNormal"
@ VERTEX_USAGE_COLOR
"inColor"
@ VERTEX_USAGE_POSITION
"inPosition"
@ VERTEX_USAGE_SHADER_INPUT
defined by user via VertexElement::shaderInputName_
Interface class between scenegraph and renderer.
Vec3f diffuse
material definitions
ShaderGenDesc shaderDesc
Drawmode and other shader params.
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
GLuint indexBuffer
Use vertex array object.
GLMatrixd modelview
Modelview transform.
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
void initFromState(GLState *_glState)
Initializes a RenderObject instance.