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 SoLocalBBoxMatrixElement Inventor/elements/SoLocalBBoxMatrixElement.h
35   \brief The SoLocalBBoxMatrixElement class is yet to be documented.
36 
37   \ingroup elements
38 
39   FIXME: write doc.
40 */
41 
42 #include "SbBasicP.h"
43 
44 #include <Inventor/elements/SoLocalBBoxMatrixElement.h>
45 #include <Inventor/misc/SoState.h>
46 
47 #if COIN_DEBUG
48 #include <Inventor/errors/SoDebugError.h>
49 #endif // COIN_DEBUG
50 
51 /*!
52   \fn SoLocalBBoxMatrixElement::localMatrix
53 
54   FIXME: write doc.
55 */
56 
57 SO_ELEMENT_SOURCE(SoLocalBBoxMatrixElement);
58 
59 /*!
60   This static method initializes static data for the
61   SoLocalBBoxMatrixElement class.
62 */
63 
64 void
initClass(void)65 SoLocalBBoxMatrixElement::initClass(void)
66 {
67   SO_ELEMENT_INIT_CLASS(SoLocalBBoxMatrixElement, inherited);
68 }
69 
70 /*!
71   The destructor.
72 */
73 
~SoLocalBBoxMatrixElement(void)74 SoLocalBBoxMatrixElement::~SoLocalBBoxMatrixElement(void)
75 {
76 }
77 
78 //! FIXME: write doc.
79 
80 void
init(SoState * state)81 SoLocalBBoxMatrixElement::init(SoState * state)
82 {
83   inherited::init(state);
84   this->localMatrix.makeIdentity();
85   this->modelInverseMatrix.makeIdentity();
86 }
87 
88 //! FIXME: write doc.
89 
90 void
push(SoState * state)91 SoLocalBBoxMatrixElement::push(SoState * state)
92 {
93   inherited::push(state);
94   SoLocalBBoxMatrixElement * prev =
95     coin_assert_cast<SoLocalBBoxMatrixElement*>(this->getNextInStack());
96   this->localMatrix = prev->localMatrix;
97 
98   // avoid cache dependencies by using the state getElement method
99   const SoModelMatrixElement * modelelem = coin_assert_cast<const SoModelMatrixElement*>
100     (
101      state->getConstElement(SoModelMatrixElement::getClassStackIndex())
102      );
103   // FIXME: is this really sensible caching? If push() is called more
104   // often than set() (the only place where it's actually used), I
105   // guess not. 20020905 mortene.
106   this->modelInverseMatrix = modelelem->getModelMatrix().inverse();
107 }
108 
109 //! FIXME: write doc.
110 
111 SbBool
matches(const SoElement *) const112 SoLocalBBoxMatrixElement::matches(const SoElement * /* element */) const
113 {
114 #if COIN_DEBUG
115   SoDebugError::postInfo("SoLocalBBoxMatrixElement::matches",
116                          "This method should never be called for this element.");
117 #endif // COIN_DEBUG
118   return TRUE;
119 }
120 
121 //! FIXME: write doc.
122 
123 SoElement *
copyMatchInfo(void) const124 SoLocalBBoxMatrixElement::copyMatchInfo(void) const
125 {
126 #if COIN_DEBUG
127   SoDebugError::postInfo("SoLocalBBoxMatrixElement::copyMatchInfo",
128                          "This method should never be called for this element.");
129 #endif // COIN_DEBUG
130   return NULL;
131 }
132 
133 //! FIXME: write doc.
134 
135 void
makeIdentity(SoState * const state)136 SoLocalBBoxMatrixElement::makeIdentity(SoState * const state)
137 {
138   SoLocalBBoxMatrixElement * element;
139   element = coin_safe_cast<SoLocalBBoxMatrixElement *>
140     (
141      SoElement::getElement(state, getClassStackIndex())
142      );
143   if (element) {
144     element->localMatrix.makeIdentity();
145     // inverse model matrix is set in push(), no need to set it here
146   }
147 }
148 
149 //! FIXME: write doc.
150 
151 void
set(SoState * const state,const SbMatrix & matrix)152 SoLocalBBoxMatrixElement::set(SoState * const state,
153                               const SbMatrix & matrix)
154 {
155   SoLocalBBoxMatrixElement * element = coin_safe_cast<SoLocalBBoxMatrixElement *>
156     (
157      SoElement::getElement(state, getClassStackIndex())
158      );
159   if (element) {
160     element->localMatrix = matrix * element->modelInverseMatrix;
161   }
162 }
163 
164 //! FIXME: write doc.
165 
166 void
mult(SoState * const state,const SbMatrix & matrix)167 SoLocalBBoxMatrixElement::mult(SoState * const state,
168                                const SbMatrix & matrix)
169 {
170   SoLocalBBoxMatrixElement * element = coin_safe_cast<SoLocalBBoxMatrixElement *>
171     (
172      SoElement::getElement(state, getClassStackIndex())
173      );
174 
175   if (element) {
176     element->localMatrix.multLeft(matrix);
177   }
178 }
179 
180 //! FIXME: write doc.
181 
182 void
translateBy(SoState * const state,const SbVec3f & translation)183 SoLocalBBoxMatrixElement::translateBy(SoState * const state,
184                                       const SbVec3f & translation)
185 {
186   SoLocalBBoxMatrixElement * element = coin_safe_cast<SoLocalBBoxMatrixElement *>
187     (
188      SoElement::getElement(state, getClassStackIndex())
189      );
190 
191   if (element) {
192     SbMatrix matrix;
193     matrix.setTranslate(translation);
194     element->localMatrix.multLeft(matrix);
195   }
196 }
197 
198 //! FIXME: write doc.
199 
200 void
rotateBy(SoState * const state,const SbRotation & rotation)201 SoLocalBBoxMatrixElement::rotateBy(SoState * const state,
202                                    const SbRotation & rotation)
203 {
204   SoLocalBBoxMatrixElement * element = coin_safe_cast<SoLocalBBoxMatrixElement *>
205     (
206      SoElement::getElement(state, getClassStackIndex())
207      );
208   if (element) {
209     SbMatrix matrix;
210     matrix.setRotate(rotation);
211     element->localMatrix.multLeft(matrix);
212   }
213 }
214 
215 //! FIXME: write doc.
216 
217 void
scaleBy(SoState * const state,const SbVec3f & scaleFactor)218 SoLocalBBoxMatrixElement::scaleBy(SoState * const state,
219                                   const SbVec3f & scaleFactor)
220 {
221   SoLocalBBoxMatrixElement * element = coin_safe_cast<SoLocalBBoxMatrixElement *>
222     (
223      SoElement::getElement(state, getClassStackIndex())
224      );
225 
226   if (element) {
227     SbMatrix matrix;
228     matrix.setScale(scaleFactor);
229     element->localMatrix.multLeft(matrix);
230   }
231 }
232 
233 //! FIXME: write doc.
234 
235 SbMatrix
pushMatrix(SoState * const state)236 SoLocalBBoxMatrixElement::pushMatrix(SoState * const state)
237 {
238   // use getElementNoPush to avoid element push
239   SoLocalBBoxMatrixElement * elem = coin_assert_cast<SoLocalBBoxMatrixElement *>
240     (
241      state->getElementNoPush(classStackIndex)
242      );
243   return elem->localMatrix;
244 }
245 
246 //! FIXME: write doc.
247 
248 void
popMatrix(SoState * const state,const SbMatrix & matrix)249 SoLocalBBoxMatrixElement::popMatrix(SoState * const state,
250                                     const SbMatrix & matrix)
251 {
252   // Important: use getElementNoPush to avoid a push on element
253   SoLocalBBoxMatrixElement *elem = coin_assert_cast<SoLocalBBoxMatrixElement*>
254     (
255      state->getElementNoPush(classStackIndex)
256     );
257   elem->localMatrix = matrix;
258 }
259 
260 //! FIXME: write doc.
261 
262 void
resetAll(SoState * const state)263 SoLocalBBoxMatrixElement::resetAll(SoState * const state)
264 {
265   SoLocalBBoxMatrixElement * element =
266     coin_safe_cast<SoLocalBBoxMatrixElement*>
267     (
268      state->getElement(getClassStackIndex())
269      );
270   while (element) {
271     element->localMatrix.makeIdentity();
272     element = coin_safe_cast<SoLocalBBoxMatrixElement*>(element->getNextInStack());
273   }
274 }
275 
276 //! FIXME: write doc.
277 
278 const SbMatrix &
get(SoState * const state)279 SoLocalBBoxMatrixElement::get(SoState * const state)
280 {
281   const SoLocalBBoxMatrixElement * element =
282     coin_assert_cast<const SoLocalBBoxMatrixElement *>
283     (
284      SoElement::getConstElement(state, getClassStackIndex())
285      );
286   return element->localMatrix;
287 }
288