Developer Documentation
Loading...
Searching...
No Matches
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
69namespace ACG {
70namespace SceneGraph {
71
72
73//== IMPLEMENTATION ==========================================================
74
75
76void
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
121void
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
141void 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
164void 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
175void ClippingNode::enter(IRenderer* _renderer, GLState& /* _state */, const DrawModes::DrawMode& /* _drawmode */)
176{
177 _renderer->addRenderObjectModifier(&mod_);
178}
179
180
181//----------------------------------------------------------------------------
182
183
184void ClippingNode::leave(IRenderer* _renderer, GLState& /* _state */, const DrawModes::DrawMode& /* _drawmode */)
185{
186 _renderer->removeRenderObjectModifier(&mod_);
187}
188
189//=============================================================================
190
191ClippingNode::ClippingShaderModifier ClippingNode::shaderMod1_(1);
192ClippingNode::ClippingShaderModifier ClippingNode::shaderMod2_(2);
193
194ClippingNode::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(inverse(g_mWV) * sg_vPosVS, g_SlicePlane%1);").arg(i));
212}
213
214//=============================================================================
215
216ClippingNode::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//=============================================================================
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition GLState.cc:1507
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition GLState.cc:1527
virtual void addRenderObjectModifier(RenderObjectModifier *_mod)
Callback for the scenegraph nodes, which adds a render object modifier to the renderer via this funct...
virtual void removeRenderObjectModifier(RenderObjectModifier *_mod)
Callback for the scenegraph nodes, which removes a render object modifier from the renderer.
Interface for modifying render objects.
void apply(RenderObject *_obj)
apply the modifier
void modifyVertexIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the vertex shader.
void modifyVertexEndCode(QStringList *_code)
Append code the the vertex shader.
void leave(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawmode) override
disable clipping plane
void set_plane(const Vec3f &_position, const Vec3f &_normal, float _eps=0.0)
set position and normal of plane
void enter(IRenderer *_renderer, GLState &_state, const DrawModes::DrawMode &_drawmode) override
enable clipping plane
void set_offset(float _dist)
sweep plane along normal by _dist
void addUniform(QString _uniform, QString _comment="")
Add one GLSL uniform specifier.
unsigned int getID()
Returns the modifier ID.
static unsigned int registerModifier(ShaderModifier *_modifier)
Shader modifiers have to be registered before they can be used. They also must remain allocated for t...
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM > >().norm())
Definition Vector11T.hh:454
Namespace providing different geometric functions concerning angles.
Interface class between scenegraph and renderer.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
void setUniform(const char *_name, GLint _value)
set values for int uniforms