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