Developer Documentation
ClippingNode.cc
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43  * *
44  * $Revision$ *
45  * $Author$ *
46  * $Date$ *
47  * *
48 \*===========================================================================*/
49 
50 
51 
52 
53 //=============================================================================
54 //
55 // CLASS ClippingNode - IMPLEMENTATION
56 //
57 //=============================================================================
58 
59 
60 //== INCLUDES =================================================================
61 
62 
63 #include "ClippingNode.hh"
64 
65 #include <ACG/GL/IRenderer.hh>
66 
67 #include <OpenMesh/Core/Utils/vector_cast.hh>
68 
69 #include <QImage>
70 
71 
72 //== NAMESPACES ===============================================================
73 
74 
75 namespace ACG {
76 namespace SceneGraph {
77 
78 
79 //== IMPLEMENTATION ==========================================================
80 
81 
82 void
83 ClippingNode::set_plane(const Vec3f& _position,
84  const Vec3f& _normal,
85  float _eps)
86 {
87  position_ = _position;
88  normal_ = _normal; normal_.normalize();
89  slice_width_ = _eps;
90 
91 
92  // one clipping plane
93  if (slice_width_ == 0.0)
94  {
95  plane0_[0] = normal_[0];
96  plane0_[1] = normal_[1];
97  plane0_[2] = normal_[2];
98  plane0_[3] = -(normal_|position_);
99  }
100 
101 
102  // two planes -> slice
103  else
104  {
105  float d = -(normal_|position_);
106  if (d > 0) { normal_ = -normal_; d = -d; }
107 
108  plane0_[0] = normal_[0];
109  plane0_[1] = normal_[1];
110  plane0_[2] = normal_[2];
111  plane0_[3] = d + 0.5f*slice_width_;
112 
113  plane1_[0] = -normal_[0];
114  plane1_[1] = -normal_[1];
115  plane1_[2] = -normal_[2];
116  plane1_[3] = -(d - 0.5f*slice_width_);
117  }
118 
119 
120  set_offset(offset_);
121 }
122 
123 
124 //----------------------------------------------------------------------------
125 
126 
127 void
129 {
130  offset_ = _offset;
131 
132  offset_plane0_[0] = plane0_[0];
133  offset_plane0_[1] = plane0_[1];
134  offset_plane0_[2] = plane0_[2];
135  offset_plane0_[3] = plane0_[3] - offset_;
136 
137  offset_plane1_[0] = plane1_[0];
138  offset_plane1_[1] = plane1_[1];
139  offset_plane1_[2] = plane1_[2];
140  offset_plane1_[3] = plane1_[3] + offset_;
141 }
142 
143 
144 //----------------------------------------------------------------------------
145 
146 
147 void ClippingNode::enter(GLState& /* _state */ , const DrawModes::DrawMode& /* _drawmode */ )
148 {
149  // one clipping plane
150  if (slice_width_ == 0.0)
151  {
152  glClipPlane(GL_CLIP_PLANE0, offset_plane0_);
153  ACG::GLState::enable(GL_CLIP_PLANE0);
154  }
155 
156  // two planes -> slice
157  else
158  {
159  glClipPlane(GL_CLIP_PLANE0, offset_plane0_);
160  ACG::GLState::enable(GL_CLIP_PLANE0);
161  glClipPlane(GL_CLIP_PLANE1, offset_plane1_);
162  ACG::GLState::enable(GL_CLIP_PLANE1);
163  }
164 }
165 
166 
167 //----------------------------------------------------------------------------
168 
169 
170 void ClippingNode::leave(GLState& /* _state */ , const DrawModes::DrawMode& /* _drawmode */ )
171 {
172  ACG::GLState::disable(GL_CLIP_PLANE0);
173  if (slice_width_ > 0.0)
174  ACG::GLState::disable(GL_CLIP_PLANE1);
175 }
176 
177 
178 //----------------------------------------------------------------------------
179 
180 
181 void ClippingNode::enter(IRenderer* _renderer, GLState& /* _state */, const DrawModes::DrawMode& /* _drawmode */)
182 {
183  _renderer->addRenderObjectModifier(&mod_);
184 }
185 
186 
187 //----------------------------------------------------------------------------
188 
189 
190 void ClippingNode::leave(IRenderer* _renderer, GLState& /* _state */, const DrawModes::DrawMode& /* _drawmode */)
191 {
192  _renderer->removeRenderObjectModifier(&mod_);
193 }
194 
195 //=============================================================================
196 
197 ClippingNode::ClippingShaderModifier ClippingNode::shaderMod1_(1);
198 ClippingNode::ClippingShaderModifier ClippingNode::shaderMod2_(2);
199 
200 ClippingNode::ClippingShaderModifier::ClippingShaderModifier(int _numClipPlanes)
201  : numClipPlanes_(_numClipPlanes)
202 {
204 }
205 
206 
207 void ClippingNode::ClippingShaderModifier::modifyVertexIO(ShaderGenerator* _shader)
208 {
209  for (int i = 0; i < numClipPlanes_; ++i)
210  _shader->addUniform(QString("vec4 g_SlicePlane%1").arg(i));
211 }
212 
213 
215 {
216  for (int i = 0; i < numClipPlanes_; ++i)
217  _code->push_back(QString("gl_ClipDistance[%1] = dot(SG_INPUT_POSOS, g_SlicePlane%1);").arg(i));
218 }
219 
220 //=============================================================================
221 
222 ClippingNode::ClippingObjectModifier::ClippingObjectModifier(const ClippingNode* _node)
223  : RenderObjectModifier("ClippingNode"), node_(_node)
224 {
225 }
226 
227 //=============================================================================
228 
229 void ClippingNode::ClippingObjectModifier::apply(RenderObject* _obj)
230 {
231  // set clipping plane equation as uniform and set shader mod id to the object
232  Vec4f p0 = OpenMesh::vector_cast<Vec4f, Vec4d>(node_->plane0());
233 
234  _obj->setUniform("g_SlicePlane0", p0);
235  _obj->clipDistanceMask |= 0x1;
236 
237  unsigned int shaderModID = shaderMod1_.getID();
238 
239  if (node_->slice_width() > 0.0f)
240  {
241  Vec4f p1 = OpenMesh::vector_cast<Vec4f, Vec4d>(node_->plane1());
242  _obj->setUniform("g_SlicePlane1", p1);
243  _obj->clipDistanceMask |= 0x2;
244 
245  shaderModID = shaderMod2_.getID();
246  }
247 
248  // set shader modifier
249  _obj->shaderDesc.shaderMods.push_back(shaderModID);
250 
251 }
252 
253 //=============================================================================
254 
255 
256 } // namespace SceneGraph
257 } // namespace ACG
258 //=============================================================================
void set_offset(float _dist)
sweep plane along normal by _dist
void vector_cast(const src_t &_src, dst_t &_dst, GenProg::Int2Type< n >)
Cast vector type to another vector type by copying the vector elements.
Definition: vector_cast.hh:86
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:144
void leave(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawmode)
disable clipping plane
Interface for modifying render objects.
void enter(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawmode)
enable clipping plane
static void enable(GLenum _cap)
replaces glEnable, but supports locking
virtual void removeRenderObjectModifier(RenderObjectModifier *_mod)
Callback for the scenegraph nodes, which removes a render object modifier from the renderer...
Definition: IRenderer.cc:1116
void setUniform(const char *_name, GLint _value)
set values for int uniforms
void modifyVertexBeginCode(QStringList *_code)
Append code the the vertex shader.
void set_plane(const Vec3f &_position, const Vec3f &_normal, float _eps=0.0)
set position and normal of plane
Definition: ClippingNode.cc:83
static void disable(GLenum _cap)
replaces glDisable, but supports locking
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
void addUniform(QString _uniform, QString _comment="")
Add one GLSL uniform specifier.
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:428
virtual void addRenderObjectModifier(RenderObjectModifier *_mod)
Callback for the scenegraph nodes, which adds a render object modifier to the renderer via this funct...
Definition: IRenderer.cc:1111
Interface class between scenegraph and renderer.
static unsigned int registerModifier(ShaderModifier *_modifier)
Shader modifiers have to be registered before they can be used. They also must remain allocated for t...
ShaderGenDesc shaderDesc
Drawmode and other shader params.
unsigned int getID()
Returns the modifier ID.
Definition: MeshNode2T.cc:1101