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