Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 setUniform(const char *_name, GLint _value)
set values for int uniforms
void set_offset(float _dist)
sweep plane along normal by _dist
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
static void enable(GLenum _cap)
replaces glEnable, but supports locking
static void disable(GLenum _cap)
replaces glDisable, but supports locking
void leave(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawmode)
disable clipping plane
void modifyVertexBeginCode(QStringList *_code)
Append code the the vertex shader.
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:1165
void enter(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawmode)
enable clipping plane
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
Interface for modifying render objects.
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:144
void set_plane(const Vec3f &_position, const Vec3f &_normal, float _eps=0.0)
set position and normal of plane
Definition: ClippingNode.cc:83
void addUniform(QString _uniform, QString _comment="")
Add one GLSL uniform specifier.
Interface class between scenegraph and renderer.
virtual void removeRenderObjectModifier(RenderObjectModifier *_mod)
Callback for the scenegraph nodes, which removes a render object modifier from the renderer...
Definition: IRenderer.cc:1170
unsigned int getID()
Returns the modifier ID.
Definition: MeshNode2T.cc:1101
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.