1 /**************************************************************************\
2 * Copyright (c) Kongsberg Oil & Gas Technologies AS
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of the copyright holder nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 \**************************************************************************/
32
33 /*!
34 \class SoComplexity SoComplexity.h Inventor/nodes/SoComplexity.h
35 \brief The SoComplexity class is a node type which is used to set the tradeoff between quality and performance.
36
37 \ingroup nodes
38
39 By inserting SoComplexity nodes in the scene graph, you can control
40 the accuracy by which complex shapes are rendered and the quality of
41 the texture mapping used for geometry in the scene.
42
43 Shape nodes like SoCone, SoSphere, SoCylinder and others, will
44 render with fewer polygons and thereby improve performance, if the
45 complexity value of the traversal state is set to a lower value.
46
47 By using the SoComplexity::type field, you may also choose to render
48 the scene graph (or parts of it) just as wireframe bounding
49 boxes. This will improve rendering performance \e a \e lot, and can
50 sometimes be used in particular situations where responsiveness is
51 more important than appearance.
52
53 Texture mapping can be done in an expensive but attractive looking
54 manner, or in a quick way which doesn't look as appealing by
55 modifying the value of the SoComplexity::textureQuality field. By
56 setting the SoComplexity::textureQuality field to a value of 0.0,
57 you can also turn texturemapping completely off.
58
59 <b>FILE FORMAT/DEFAULTS:</b>
60 \code
61 Complexity {
62 type OBJECT_SPACE
63 value 0.5
64 textureQuality 0.5
65 }
66 \endcode
67 */
68
69 #include <Inventor/nodes/SoComplexity.h>
70
71 #include <Inventor/actions/SoCallbackAction.h>
72 #include <Inventor/actions/SoGLRenderAction.h>
73 #include <Inventor/actions/SoGetBoundingBoxAction.h>
74 #include <Inventor/actions/SoGetPrimitiveCountAction.h>
75 #include <Inventor/actions/SoPickAction.h>
76 #include <Inventor/elements/SoComplexityElement.h>
77 #include <Inventor/elements/SoOverrideElement.h>
78 #include <Inventor/elements/SoShapeStyleElement.h>
79 #include <Inventor/elements/SoTextureOverrideElement.h>
80 #include <Inventor/elements/SoTextureQualityElement.h>
81 #include <Inventor/errors/SoDebugError.h>
82
83 #include "nodes/SoSubNodeP.h"
84
85 /*!
86 \enum SoComplexity::Type
87
88 The available values for the SoComplexity::type field.
89 */
90 /*!
91 \var SoComplexity::Type SoComplexity::OBJECT_SPACE
92
93 Use the SoComplexity::value in calculations based on the geometry's
94 size in world-space 3D.
95 */
96 /*!
97 \var SoComplexity::Type SoComplexity::SCREEN_SPACE
98
99 Use the SoComplexity::value in calculations based on the geometry's
100 size when projected onto the rendering area. This is often a good
101 way to make sure that objects are rendered with as low complexity as
102 possible while still retaining their appearance for the user.
103 */
104 /*!
105 \var SoComplexity::Type SoComplexity::BOUNDING_BOX
106
107 Render further geometry in the scene graph as bounding boxes only
108 for superfast rendering.
109 */
110
111
112 /*!
113 \var SoSFEnum SoComplexity::type
114 Set rendering type. Default value is SoComplexity::OBJECT_SPACE.
115 */
116 /*!
117 \var SoSFFloat SoComplexity::value
118
119 Complexity value, valid settings range from 0.0 (worst appearance,
120 best performance) to 1.0 (optimal appearance, lowest rendering
121 speed). Default value for the field is 0.5.
122
123 Note that without any SoComplexity nodes in the scene graph,
124 geometry will render as if there was a SoComplexity node present
125 with SoComplexity::value set to 1.0.
126 */
127 /*!
128 \var SoSFFloat SoComplexity::textureQuality
129
130 Sets the quality value for texturemapping. Valid range is from 0.0
131 (texturemapping off, rendering will be much faster for most
132 platforms) to 1.0 (best quality, rendering might be slow).
133
134 The same value for this field on different platforms can yield
135 varying results, depending on the quality of the underlying
136 rendering hardware.
137
138 Note that this field influences the behavior of the SoTexture2 node,
139 \e not the shape nodes. There is an important consequence of this
140 that the application programmer need to know about: you need to
141 insert your SoComplexity node(s) \e before the SoTexture2 node(s) in
142 the scenegraph for them to have any influence on the textured
143 shapes.
144 */
145
146
147 // *************************************************************************
148
149 SO_NODE_SOURCE(SoComplexity);
150
151 /*!
152 Constructor.
153 */
SoComplexity(void)154 SoComplexity::SoComplexity(void)
155 {
156 SO_NODE_INTERNAL_CONSTRUCTOR(SoComplexity);
157
158 SO_NODE_ADD_FIELD(type, (SoComplexity::OBJECT_SPACE));
159 SO_NODE_ADD_FIELD(value, (0.5f));
160 SO_NODE_ADD_FIELD(textureQuality, (0.5f));
161
162 SO_NODE_DEFINE_ENUM_VALUE(Type, SCREEN_SPACE);
163 SO_NODE_DEFINE_ENUM_VALUE(Type, OBJECT_SPACE);
164 SO_NODE_DEFINE_ENUM_VALUE(Type, BOUNDING_BOX);
165 SO_NODE_SET_SF_ENUM_TYPE(type, Type);
166 }
167
168 /*!
169 Destructor.
170 */
~SoComplexity()171 SoComplexity::~SoComplexity()
172 {
173 }
174
175 // Doc from superclass.
176 void
initClass(void)177 SoComplexity::initClass(void)
178 {
179 SO_NODE_INTERNAL_INIT_CLASS(SoComplexity, SO_FROM_INVENTOR_1);
180
181 SO_ENABLE(SoGetBoundingBoxAction, SoComplexityElement);
182 SO_ENABLE(SoGetBoundingBoxAction, SoComplexityTypeElement);
183 SO_ENABLE(SoGetBoundingBoxAction, SoShapeStyleElement);
184
185 SO_ENABLE(SoGLRenderAction, SoComplexityElement);
186 SO_ENABLE(SoGLRenderAction, SoComplexityTypeElement);
187 SO_ENABLE(SoGLRenderAction, SoShapeStyleElement);
188 SO_ENABLE(SoGLRenderAction, SoTextureQualityElement);
189
190 SO_ENABLE(SoCallbackAction, SoComplexityElement);
191 SO_ENABLE(SoCallbackAction, SoComplexityTypeElement);
192 SO_ENABLE(SoCallbackAction, SoShapeStyleElement);
193 SO_ENABLE(SoCallbackAction, SoTextureQualityElement);
194
195 SO_ENABLE(SoPickAction, SoComplexityElement);
196 SO_ENABLE(SoPickAction, SoComplexityTypeElement);
197 SO_ENABLE(SoPickAction, SoShapeStyleElement);
198
199 SO_ENABLE(SoGetPrimitiveCountAction, SoComplexityElement);
200 SO_ENABLE(SoGetPrimitiveCountAction, SoComplexityTypeElement);
201 SO_ENABLE(SoGetPrimitiveCountAction, SoShapeStyleElement);
202 }
203
204 // Doc from superclass.
205 void
getBoundingBox(SoGetBoundingBoxAction * action)206 SoComplexity::getBoundingBox(SoGetBoundingBoxAction * action)
207 {
208 SoComplexity::doAction(action);
209 }
210
211 // Doc from superclass.
212 void
GLRender(SoGLRenderAction * action)213 SoComplexity::GLRender(SoGLRenderAction * action)
214 {
215 SoComplexity::doAction(action);
216
217 SoState * state = action->getState();
218 if (!this->textureQuality.isIgnored() &&
219 !SoTextureOverrideElement::getQualityOverride(state)) {
220 SoTextureQualityElement::set(state, this,
221 this->textureQuality.getValue());
222 if (this->isOverride()) {
223 SoTextureOverrideElement::setQualityOverride(state, TRUE);
224 }
225 }
226 }
227
228 // Doc from superclass.
229 void
doAction(SoAction * action)230 SoComplexity::doAction(SoAction * action)
231 {
232 SoState * state = action->getState();
233 if (!value.isIgnored() && !SoOverrideElement::getComplexityOverride(state)) {
234 SoComplexityElement::set(state, value.getValue());
235 if (this->isOverride()) {
236 SoOverrideElement::setComplexityOverride(state, this, TRUE);
237 }
238 }
239 if (!type.isIgnored() && !SoOverrideElement::getComplexityTypeOverride(state)) {
240 SoComplexityTypeElement::set(state, (SoComplexityTypeElement::Type)
241 type.getValue());
242 if (this->isOverride()) {
243 SoOverrideElement::setComplexityTypeOverride(state, this, TRUE);
244 }
245 }
246 }
247
248 // Doc from superclass.
249 void
callback(SoCallbackAction * action)250 SoComplexity::callback(SoCallbackAction * action)
251 {
252 SoComplexity::doAction((SoAction *)action);
253 if (!this->textureQuality.isIgnored()) {
254 SoTextureQualityElement::set(action->getState(), this,
255 this->textureQuality.getValue());
256 }
257 }
258
259 // Doc from superclass.
260 void
pick(SoPickAction * action)261 SoComplexity::pick(SoPickAction * action)
262 {
263 SoComplexity::doAction(action);
264 }
265
266 // Doc from superclass.
267 void
getPrimitiveCount(SoGetPrimitiveCountAction * action)268 SoComplexity::getPrimitiveCount(SoGetPrimitiveCountAction * action)
269 {
270 SoComplexity::doAction(action);
271 }
272