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 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif // HAVE_CONFIG_H
36 
37 #ifdef HAVE_VRML97
38 
39 /*!
40   \class SoVRMLBox SoVRMLBox.h Inventor/VRMLnodes/SoVRMLBox.h
41   \brief The SoVRMLBox class is used for representing a 3D box.
42 
43   \ingroup VRMLnodes
44 
45   \WEB3DCOPYRIGHT
46 
47   \verbatim
48   Box {
49     field    SFVec3f size  2 2 2        # (0, inf)
50   }
51   \endverbatim
52 
53   The Box node specifies a rectangular parallelepiped box centred at (0, 0, 0)
54   in the local coordinate system and aligned with the local coordinate axes.
55   By default, the box measures 2 units in each dimension, from -1 to +1. The
56   size field specifies the extents of the box along the X-, Y-, and
57   Z-axes respectively and each component value shall be greater than zero.
58   Figure 6.2 illustrates the Box node.
59 
60   <center>
61   <img src="http://www.web3d.org/documents/specifications/14772/V2.0/Images/box.gif">
62   Figure 6.2
63   </center>
64 
65   Textures are applied individually to each face of the box. On the
66   front (+Z), back (-Z), right (+X), and left (-X) faces of the box,
67   when viewed from the outside with the +Y-axis up, the texture is
68   mapped onto each face with the same orientation as if the image were
69   displayed normally in 2D.  On the top face of the box (+Y), when
70   viewed from above and looking down the Y-axis toward the origin with
71   the -Z-axis as the view up direction, the texture is mapped onto the
72   face with the same orientation as if the image were displayed
73   normally in 2D. On the bottom face of the box (-Y), when viewed from
74   below looking up the Y-axis toward the origin with the +Z-axis as
75   the view up direction, the texture is mapped onto the face with the
76   same orientation as if the image were displayed normally in
77   2D. SoVRMLTextureTransform affects the texture coordinates of the
78   Box.  The Box node's geometry requires outside faces only. When
79   viewed from the inside the results are undefined.
80 
81 */
82 
83 /*!
84   \var SoVRMLBox::size
85 
86   Box size vector. Default value is (2,2,2).
87 */
88 
89 #include <Inventor/VRMLnodes/SoVRMLBox.h>
90 #include "coindefs.h"
91 
92 #include <Inventor/VRMLnodes/SoVRMLMacros.h>
93 #include <Inventor/elements/SoGLMultiTextureEnabledElement.h>
94 #include <Inventor/elements/SoMultiTextureCoordinateElement.h>
95 #include <Inventor/actions/SoGLRenderAction.h>
96 #include <Inventor/actions/SoGetPrimitiveCountAction.h>
97 #include <Inventor/actions/SoRayPickAction.h>
98 #include <Inventor/bundles/SoMaterialBundle.h>
99 #include <Inventor/misc/SoState.h>
100 
101 #include "nodes/SoSubNodeP.h"
102 #include "rendering/SoGL.h"
103 #include "misc/SoGenerate.h"
104 #include "misc/SoPick.h"
105 
106 SO_NODE_SOURCE(SoVRMLBox);
107 
108 // Doc in parent
109 void
initClass(void)110 SoVRMLBox::initClass(void) // static
111 {
112   SO_NODE_INTERNAL_INIT_CLASS(SoVRMLBox, SO_VRML97_NODE_TYPE);
113 }
114 
115 /*!
116   Constructor.
117 */
SoVRMLBox(void)118 SoVRMLBox::SoVRMLBox(void)
119 {
120   SO_VRMLNODE_INTERNAL_CONSTRUCTOR(SoVRMLBox);
121 
122   SO_VRMLNODE_ADD_FIELD(size, (2.0f, 2.0f, 2.0f));
123 }
124 
125 /*!
126   Destructor.
127 */
~SoVRMLBox()128 SoVRMLBox::~SoVRMLBox()
129 {
130 }
131 
132 // Doc in parent
133 void
GLRender(SoGLRenderAction * action)134 SoVRMLBox::GLRender(SoGLRenderAction * action)
135 {
136  if (!this->shouldGLRender(action)) return;
137   SoState * state = action->getState();
138 
139   SbBool doTextures = SoGLMultiTextureEnabledElement::get(state);
140 
141   SoMaterialBundle mb(action);
142   mb.sendFirst();
143 
144   SbBool sendNormals = !mb.isColorOnly() ||
145     (SoMultiTextureCoordinateElement::getType(state) == SoMultiTextureCoordinateElement::FUNCTION);
146 
147   unsigned int flags = 0;
148   if (doTextures) flags |= SOGL_NEED_TEXCOORDS;
149   if (sendNormals) flags |= SOGL_NEED_NORMALS;
150 
151   SbVec3f s = this->size.getValue();
152 
153   sogl_render_cube(s[0],
154                    s[1],
155                    s[2],
156                    &mb,
157                    flags, state);
158 }
159 
160 // Doc in parent
161 void
rayPick(SoRayPickAction * action)162 SoVRMLBox::rayPick(SoRayPickAction * action)
163 {
164   if (!shouldRayPick(action)) return;
165 
166   SbVec3f s = this->size.getValue();
167   sopick_pick_cube(s[0],
168                    s[1],
169                    s[2],
170                    0,
171                    this, action);
172 }
173 
174 // Doc in parent
175 void
getPrimitiveCount(SoGetPrimitiveCountAction * action)176 SoVRMLBox::getPrimitiveCount(SoGetPrimitiveCountAction * action)
177 {
178   if (!this->shouldPrimitiveCount(action)) return;
179   action->addNumTriangles(12);
180 }
181 
182 // Doc in parent
183 void
generatePrimitives(SoAction * action)184 SoVRMLBox::generatePrimitives(SoAction * action)
185 {
186   SbVec3f s = this->size.getValue();
187   sogen_generate_cube(s[0],
188                       s[1],
189                       s[2],
190                       0,
191                       this,
192                       action);
193 }
194 
195 // Doc in parent
196 void
computeBBox(SoAction * action,SbBox3f & COIN_UNUSED_ARG (box),SbVec3f & center)197 SoVRMLBox::computeBBox(SoAction * action,
198                        SbBox3f & COIN_UNUSED_ARG(box),
199                        SbVec3f & center)
200 {
201   center.setValue(0.0f, 0.0f, 0.0f);
202   SbVec3f s = this->size.getValue();
203   float w = s[0] * 0.5f;
204   float h = s[1] * 0.5f;
205   float d = s[2] * 0.5f;
206 
207   // Allow negative values.
208   if (w < 0.0f) w = -w;
209   if (h < 0.0f) h = -h;
210   if (d < 0.0f) d = -d;
211 
212   box.setBounds(-w, -h, -d, w, h, d);
213 }
214 
215 #endif // HAVE_VRML97
216