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 SoTexture3Transform SoTexture3Transform.h Inventor/nodes/SoTexture3Transform.h
35   \brief The SoTexture3Transform class is used to define 3D texture transformations.
36 
37   \ingroup nodes
38 
39   Textures applied to shapes in the scene can be transformed by
40   "prefixing" in the state with instances of this node
41   type. Translations, rotations and scaling in 3D can all be done.
42 
43   The default settings of this node's fields equals a "null
44   transform", ie no transformation.
45 
46   \COIN_CLASS_EXTENSION
47 
48   <b>FILE FORMAT/DEFAULTS:</b>
49   \code
50     Texture3Transform {
51         translation 0 0 0
52         rotation 0 0 1  0
53         scaleFactor 1 1 1
54         scaleOrientation 0 0 1  0
55         center 0 0 0
56     }
57   \endcode
58 
59   \sa SoTexture2Transform
60   \since Coin 2.0
61   \since TGS Inventor 2.6
62 */
63 
64 // *************************************************************************
65 
66 #include <Inventor/nodes/SoTexture3Transform.h>
67 
68 #include <Inventor/actions/SoGLRenderAction.h>
69 #include <Inventor/actions/SoPickAction.h>
70 #include <Inventor/actions/SoGetMatrixAction.h>
71 #include <Inventor/actions/SoCallbackAction.h>
72 #include <Inventor/elements/SoGLMultiTextureMatrixElement.h>
73 #include <Inventor/elements/SoTextureUnitElement.h>
74 #include <Inventor/elements/SoGLCacheContextElement.h>
75 #include <Inventor/C/glue/gl.h>
76 
77 #include "nodes/SoSubNodeP.h"
78 
79 // *************************************************************************
80 
81 /*!
82   \var SoSFVec3f SoTexture3Transform::translation
83 
84   Texture coordinate translation. Default value is [0, 0, 0].
85 */
86 /*!
87   \var SoSFRotation SoTexture3Transform::rotation
88 
89   Texture coordinate rotation (s is x-axis, t is y-axis and r is
90   z-axis).  Defaults to an identity rotation (ie zero rotation).
91 */
92 /*!
93   \var SoSFVec3f SoTexture3Transform::scaleFactor
94 
95   Texture coordinate scale factors. Default value is [1, 1, 1].
96 */
97 /*!
98   \var SoSFRotation SoTexture3Transform::scaleOrientation
99 
100   The orientation the texture is set to before scaling.  Defaults to
101   an identity rotation (ie zero rotation).
102 */
103 /*!
104   \var SoSFVec3f SoTexture3Transform::center
105 
106   Center for scale and rotation. Default value is [0, 0, 0].
107 */
108 
109 // *************************************************************************
110 
111 SO_NODE_SOURCE(SoTexture3Transform);
112 
113 /*!
114   Constructor.
115 */
SoTexture3Transform(void)116 SoTexture3Transform::SoTexture3Transform(void)
117 {
118   SO_NODE_INTERNAL_CONSTRUCTOR(SoTexture3Transform);
119 
120   SO_NODE_ADD_FIELD(translation, (0.0f, 0.0f, 0.0f));
121   SO_NODE_ADD_FIELD(rotation, (SbRotation(SbVec3f(0.0f, 0.0f, 1.0f), 0.0f)));
122   SO_NODE_ADD_FIELD(scaleFactor, (1.0f, 1.0f, 1.0f));
123   SO_NODE_ADD_FIELD(scaleOrientation, (SbRotation(SbVec3f(0.0f, 0.0f, 1.0f), 0.0f)));
124   SO_NODE_ADD_FIELD(center, (0.0f, 0.0f, 0.0f));
125 }
126 
127 /*!
128   Destructor.
129 */
~SoTexture3Transform()130 SoTexture3Transform::~SoTexture3Transform()
131 {
132 }
133 
134 // Documented in superclass.
135 void
initClass(void)136 SoTexture3Transform::initClass(void)
137 {
138   SO_NODE_INTERNAL_INIT_CLASS(SoTexture3Transform, SO_FROM_INVENTOR_1);
139 
140   SO_ENABLE(SoGLRenderAction, SoGLMultiTextureMatrixElement);
141   SO_ENABLE(SoCallbackAction, SoMultiTextureMatrixElement);
142   SO_ENABLE(SoPickAction, SoMultiTextureMatrixElement);
143 }
144 
145 
146 // Documented in superclass.
147 void
GLRender(SoGLRenderAction * action)148 SoTexture3Transform::GLRender(SoGLRenderAction * action)
149 {
150   SoState * state = action->getState();
151   int unit = SoTextureUnitElement::get(state);
152   const cc_glglue * glue =
153     cc_glglue_instance(SoGLCacheContextElement::get(state));
154   int maxunits = cc_glglue_max_texture_units(glue);
155 
156   if (unit < maxunits) {
157     SbMatrix mat;
158     mat.setTransform(this->translation.getValue(),
159                      this->rotation.getValue(),
160                      this->scaleFactor.getValue(),
161                      this->scaleOrientation.getValue(),
162                      this->center.getValue());
163     SoMultiTextureMatrixElement::mult(state, this, unit, mat);
164   }
165   else {
166     // we already warned in SoTextureUnit. I think it's best to just
167     // ignore the texture here so that all textures for non-supported
168     // units will be ignored. pederb, 2003-11-11
169   }
170 }
171 
172 // Documented in superclass.
173 void
doAction(SoAction * action)174 SoTexture3Transform::doAction(SoAction *action)
175 {
176   SoState * state = action->getState();
177   int unit = SoTextureUnitElement::get(state);
178   SbMatrix mat;
179   mat.setTransform(this->translation.getValue(),
180                    this->rotation.getValue(),
181                    this->scaleFactor.getValue(),
182                    this->scaleOrientation.getValue(),
183                    this->center.getValue());
184   SoMultiTextureMatrixElement::mult(action->getState(), this, unit, mat);
185 }
186 
187 // Documented in superclass.
188 void
callback(SoCallbackAction * action)189 SoTexture3Transform::callback(SoCallbackAction *action)
190 {
191   SoTexture3Transform::doAction(action);
192 }
193 
194 // Documented in superclass.
195 void
getMatrix(SoGetMatrixAction * action)196 SoTexture3Transform::getMatrix(SoGetMatrixAction * action)
197 {
198   int unit = SoTextureUnitElement::get(action->getState());
199   if (unit == 0) {
200     SbMatrix mat;
201     mat.setTransform(this->translation.getValue(),
202                      this->rotation.getValue(),
203                      this->scaleFactor.getValue(),
204                      this->scaleOrientation.getValue(),
205                      this->center.getValue());
206     action->getTextureMatrix().multLeft(mat);
207     action->getTextureInverse().multRight(mat.inverse());
208   }
209 }
210 
211 // Documented in superclass.
212 void
pick(SoPickAction * action)213 SoTexture3Transform::pick(SoPickAction * action)
214 {
215   SoTexture3Transform::doAction(action);
216 }
217