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 
45 
46 
47 //=============================================================================
48 //
49 // CLASS ClippingNode - IMPLEMENTATION
50 //
51 //=============================================================================
52 
53 
54 //== INCLUDES =================================================================
55 
56 
57 #include "ClippingNode.hh"
58 
59 #include <ACG/GL/IRenderer.hh>
60 
61 #include <OpenMesh/Core/Utils/vector_cast.hh>
62 
63 #include <QImage>
64 
65 
66 //== NAMESPACES ===============================================================
67 
68 
69 namespace ACG {
70 namespace SceneGraph {
71 
72 
73 //== IMPLEMENTATION ==========================================================
74 
75 
76 void
77 ClippingNode::set_plane(const Vec3f& _position,
78  const Vec3f& _normal,
79  float _eps)
80 {
81  position_ = _position;
82  normal_ = _normal; normal_.normalize();
83  slice_width_ = _eps;
84 
85 
86  // one clipping plane
87  if (slice_width_ == 0.0)
88  {
89  plane0_[0] = normal_[0];
90  plane0_[1] = normal_[1];
91  plane0_[2] = normal_[2];
92  plane0_[3] = -(normal_|position_);
93  }
94 
95 
96  // two planes -> slice
97  else
98  {
99  float d = -(normal_|position_);
100  if (d > 0) { normal_ = -normal_; d = -d; }
101 
102  plane0_[0] = normal_[0];
103  plane0_[1] = normal_[1];
104  plane0_[2] = normal_[2];
105  plane0_[3] = d + 0.5f*slice_width_;
106 
107  plane1_[0] = -normal_[0];
108  plane1_[1] = -normal_[1];
109  plane1_[2] = -normal_[2];
110  plane1_[3] = -(d - 0.5f*slice_width_);
111  }
112 
113 
114  set_offset(offset_);
115 }
116 
117 
118 //----------------------------------------------------------------------------
119 
120 
121 void
123 {
124  offset_ = _offset;
125 
126  offset_plane0_[0] = plane0_[0];
127  offset_plane0_[1] = plane0_[1];
128  offset_plane0_[2] = plane0_[2];
129  offset_plane0_[3] = plane0_[3] - offset_;
130 
131  offset_plane1_[0] = plane1_[0];
132  offset_plane1_[1] = plane1_[1];
133  offset_plane1_[2] = plane1_[2];
134  offset_plane1_[3] = plane1_[3] + offset_;
135 }
136 
137 
138 //----------------------------------------------------------------------------
139 
140 
141 void ClippingNode::enter(GLState& /* _state */ , const DrawModes::DrawMode& /* _drawmode */ )
142 {
143  // one clipping plane
144  if (slice_width_ == 0.0)
145  {
146  glClipPlane(GL_CLIP_PLANE0, offset_plane0_);
147  ACG::GLState::enable(GL_CLIP_PLANE0);
148  }
149 
150  // two planes -> slice
151  else
152  {
153  glClipPlane(GL_CLIP_PLANE0, offset_plane0_);
154  ACG::GLState::enable(GL_CLIP_PLANE0);
155  glClipPlane(GL_CLIP_PLANE1, offset_plane1_);
156  ACG::GLState::enable(GL_CLIP_PLANE1);
157  }
158 }
159 
160 
161 //----------------------------------------------------------------------------
162 
163 
164 void ClippingNode::leave(GLState& /* _state */ , const DrawModes::DrawMode& /* _drawmode */ )
165 {
166  ACG::GLState::disable(GL_CLIP_PLANE0);
167  if (slice_width_ > 0.0)
168  ACG::GLState::disable(GL_CLIP_PLANE1);
169 }
170 
171 
172 //----------------------------------------------------------------------------
173 
174 
175 void ClippingNode::enter(IRenderer* _renderer, GLState& /* _state */, const DrawModes::DrawMode& /* _drawmode */)
176 {
177  _renderer->addRenderObjectModifier(&mod_);
178 }
179 
180 
181 //----------------------------------------------------------------------------
182 
183 
184 void ClippingNode::leave(IRenderer* _renderer, GLState& /* _state */, const DrawModes::DrawMode& /* _drawmode */)
185 {
186  _renderer->removeRenderObjectModifier(&mod_);
187 }
188 
189 //=============================================================================
190 
191 ClippingNode::ClippingShaderModifier ClippingNode::shaderMod1_(1);
192 ClippingNode::ClippingShaderModifier ClippingNode::shaderMod2_(2);
193 
194 ClippingNode::ClippingShaderModifier::ClippingShaderModifier(int _numClipPlanes)
195  : numClipPlanes_(_numClipPlanes)
196 {
198 }
199 
200 
202 {
203  for (int i = 0; i < numClipPlanes_; ++i)
204  _shader->addUniform(QString("vec4 g_SlicePlane%1").arg(i));
205 }
206 
207 
209 {
210  for (int i = 0; i < numClipPlanes_; ++i)
211  _code->push_back(QString("gl_ClipDistance[%1] = dot(SG_INPUT_POSOS, g_SlicePlane%1);").arg(i));
212 }
213 
214 //=============================================================================
215 
216 ClippingNode::ClippingObjectModifier::ClippingObjectModifier(const ClippingNode* _node)
217  : RenderObjectModifier("ClippingNode"), node_(_node)
218 {
219 }
220 
221 //=============================================================================
222 
224 {
225  // set clipping plane equation as uniform and set shader mod id to the object
226  Vec4f p0 = OpenMesh::vector_cast<Vec4f, Vec4d>(node_->plane0());
227 
228  _obj->setUniform("g_SlicePlane0", p0);
229  _obj->clipDistanceMask |= 0x1;
230 
231  unsigned int shaderModID = shaderMod1_.getID();
232 
233  if (node_->slice_width() > 0.0f)
234  {
235  Vec4f p1 = OpenMesh::vector_cast<Vec4f, Vec4d>(node_->plane1());
236  _obj->setUniform("g_SlicePlane1", p1);
237  _obj->clipDistanceMask |= 0x2;
238 
239  shaderModID = shaderMod2_.getID();
240  }
241 
242  // set shader modifier
243  _obj->shaderDesc.shaderMods.push_back(shaderModID);
244 
245  // enable clip distance pass through in geometry shader
246  _obj->shaderDesc.clipDistanceMask = _obj->clipDistanceMask;
247 }
248 
249 //=============================================================================
250 
251 
252 } // namespace SceneGraph
253 } // namespace ACG
254 //=============================================================================
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:81
Namespace providing different geometric functions concerning angles.
static unsigned int registerModifier(ShaderModifier *_modifier)
Shader modifiers have to be registered before they can be used. They also must remain allocated for t...
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:1198
virtual void removeRenderObjectModifier(RenderObjectModifier *_mod)
Callback for the scenegraph nodes, which removes a render object modifier from the renderer...
Definition: IRenderer.cc:1203
void addUniform(QString _uniform, QString _comment="")
Add one GLSL uniform specifier.
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
void modifyVertexIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the vertex shader.
void set_offset(float _dist)
sweep plane along normal by _dist
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:429
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
void apply(RenderObject *_obj)
apply the modifier
Interface class between scenegraph and renderer.
Definition: RenderObject.hh:98
Interface for modifying render objects.
unsigned int getID()
Returns the modifier ID.
void setUniform(const char *_name, GLint _value)
set values for int uniforms
void set_plane(const Vec3f &_position, const Vec3f &_normal, float _eps=0.0)
set position and normal of plane
Definition: ClippingNode.cc:77
void leave(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawmode)
disable clipping plane
void enter(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawmode)
enable clipping plane
ShaderGenDesc shaderDesc
Drawmode and other shader params.
void modifyVertexBeginCode(QStringList *_code)
Append code the the vertex shader.