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 SoCoordinateElement Inventor/elements/SoCoordinateElement.h
35   \brief The SoCoordinateElement class is yet to be documented.
36 
37   \ingroup elements
38 
39   FIXME: write doc.
40 */
41 
42 #include <Inventor/elements/SoCoordinateElement.h>
43 
44 #include <cassert>
45 
46 #include <Inventor/errors/SoDebugError.h>
47 #include <Inventor/nodes/SoNode.h>
48 #include <Inventor/elements/SoGLVBOElement.h>
49 
50 #include "tidbitsp.h"
51 #include "SbBasicP.h"
52 
53 // static variables
54 SbVec3f * SoCoordinateElement::initialdefaultcoords = NULL;
55 
56 /*!
57   \fn SoCoordinateElement::numCoords
58 
59   FIXME: write doc.
60 */
61 
62 /*!
63   \fn SoCoordinateElement::coords3D
64 
65   FIXME: write doc.
66 */
67 
68 /*!
69   \fn SoCoordinateElement::coords4D
70 
71   FIXME: write doc.
72 */
73 
74 /*!
75   \fn SoCoordinateElement::areCoords3D
76 
77   FIXME: write doc.
78 */
79 
80 SO_ELEMENT_SOURCE(SoCoordinateElement);
81 
82 /*!
83   This static method initializes static data for the
84   SoCoordinateElement class.
85 */
86 
87 void
initClass(void)88 SoCoordinateElement::initClass(void)
89 {
90   SO_ELEMENT_INIT_CLASS(SoCoordinateElement, inherited);
91 
92   SoCoordinateElement::initialdefaultcoords = new SbVec3f(0.0f, 0.0f, 0.0f);
93 
94   coin_atexit(reinterpret_cast<coin_atexit_f *>(SoCoordinateElement::clean), CC_ATEXIT_NORMAL);
95 }
96 
97 // Clean up internal resource usage.
98 void
clean(void)99 SoCoordinateElement::clean(void)
100 {
101 #if COIN_DEBUG
102   delete SoCoordinateElement::initialdefaultcoords;
103 #endif // COIN_DEBUG
104 }
105 
106 /*!
107   The destructor.
108 */
109 
~SoCoordinateElement(void)110 SoCoordinateElement::~SoCoordinateElement(void)
111 {
112 }
113 
114 //! FIXME: write doc.
115 
116 void
init(SoState * state)117 SoCoordinateElement::init(SoState * state)
118 {
119   inherited::init(state);
120   this->numCoords = 1;
121   this->coords3D = SoCoordinateElement::initialdefaultcoords;
122   this->coords4D = NULL;
123   this->areCoords3D = TRUE;
124 }
125 
126 //! FIXME: write doc.
127 
128 void
set3(SoState * const state,SoNode * const node,const int32_t numCoords,const SbVec3f * const coords)129 SoCoordinateElement::set3(SoState * const state,
130                           SoNode * const node,
131                           const int32_t numCoords,
132                           const SbVec3f * const coords)
133 {
134   if (state->isElementEnabled(SoGLVBOElement::getClassStackIndex())) {
135     SoGLVBOElement::setVertexVBO(state, NULL);
136   }
137   SoCoordinateElement * elem =
138     coin_safe_cast<SoCoordinateElement *>
139     (
140      SoElement::getElement(state, classStackIndex)
141      );
142 
143   if (elem) {
144     elem->areCoords3D = TRUE;
145     elem->coords3D = coords;
146     elem->numCoords = numCoords;
147     elem->nodeId = node->getNodeId();
148   }
149 }
150 
151 //! FIXME: write doc.
152 
153 void
set4(SoState * const state,SoNode * const node,const int32_t numCoords,const SbVec4f * const coords)154 SoCoordinateElement::set4(SoState * const state,
155                           SoNode * const node,
156                           const int32_t numCoords,
157                           const SbVec4f * const coords)
158 {
159   if (state->isElementEnabled(SoGLVBOElement::getClassStackIndex())) {
160     SoGLVBOElement::setVertexVBO(state, NULL);
161   }
162   SoCoordinateElement * elem = coin_safe_cast<SoCoordinateElement *>
163     (
164      SoElement::getElement(state, classStackIndex)
165      );
166   if (elem) {
167     elem->areCoords3D = FALSE;
168     elem->coords4D = coords;
169     elem->numCoords = numCoords;
170     elem->nodeId = node->getNodeId();
171   }
172 }
173 
174 //! FIXME: write doc.
175 
176 const SbVec3f &
get3(const int index) const177 SoCoordinateElement::get3(const int index) const
178 {
179   assert(index >= 0 && index < this->numCoords);
180 
181   if (areCoords3D) return this->coords3D[index];
182   else {
183     // hack around const
184     SoCoordinateElement  * elem = const_cast<SoCoordinateElement *>(this);
185     this->coords4D[index].getReal(elem->dummy3D);
186     return this->dummy3D;
187   }
188 }
189 
190 //! FIXME: write doc.
191 
192 const SbVec4f &
get4(const int index) const193 SoCoordinateElement::get4(const int index) const
194 {
195   assert(index >= 0 && index < this->numCoords);
196 
197   if (!areCoords3D) return this->coords4D[index];
198   else {
199     // hack around const
200     SoCoordinateElement * elem = const_cast<SoCoordinateElement *>(this);
201     const SbVec3f &vec = this->coords3D[index];
202     elem->dummy4D[0] = vec[0];
203     elem->dummy4D[1] = vec[1];
204     elem->dummy4D[2] = vec[2];
205     elem->dummy4D[3] = 1.0f;
206     return this->dummy4D;
207   }
208 }
209 
210 //! FIXME: write doc.
211 
212 const SoCoordinateElement *
getInstance(SoState * const state)213 SoCoordinateElement::getInstance(SoState * const state)
214 {
215   return coin_assert_cast<const SoCoordinateElement * >
216     (
217      getConstElement(state, classStackIndex)
218      );
219 }
220 
221 //! FIXME: write doc.
222 
223 //$ EXPORT INLINE
224 int32_t
getNum(void) const225 SoCoordinateElement::getNum(void) const
226 {
227   return this->numCoords;
228 }
229 
230 //! FIXME: write doc.
231 
232 //$ EXPORT INLINE
233 SbBool
is3D() const234 SoCoordinateElement::is3D() const
235 {
236   return this->areCoords3D;
237 }
238 
239 /*!
240   Returns a pointer to the 3D coordinate array. Don't use this method
241   unless SoCoordinateElement::is3D() returns \c TRUE.
242 
243   This method is not part of the original SGI Open Inventor v2.1 API.
244 
245   \since Coin 1.0
246 */
247 const SbVec3f *
getArrayPtr3() const248 SoCoordinateElement::getArrayPtr3() const
249 {
250 #if COIN_DEBUG
251   if (!this->is3D()) {
252     SoDebugError::postWarning("SoDiffuseColorElement::getArrayPtr3",
253                               "coordinates are *not* 3D -- use "
254                               "getArrayPtr4() instead");
255   }
256 #endif // COIN_DEBUG
257 
258   return this->coords3D;
259 }
260 
261 /*!
262   Returns a pointer to the 4D coordinate array. Don't use this method
263   unless SoCoordinateElement::is3D() returns \c FALSE.
264 
265   This method is not part of the original SGI Open Inventor v2.1 API.
266 
267   \since Coin 1.0
268 */
269 const SbVec4f *
getArrayPtr4() const270 SoCoordinateElement::getArrayPtr4() const
271 {
272 #if COIN_DEBUG
273   if (this->is3D()) {
274     SoDebugError::postWarning("SoDiffuseColorElement::getArrayPtr4",
275                               "coordinates are *not* 4D -- use "
276                               "getArrayPtr3() instead");
277   }
278 #endif // COIN_DEBUG
279 
280   return this->coords4D;
281 }
282 
283 //! FIXME: write doc.
284 
285 //$ EXPORT INLINE
286 SbVec3f
getDefault3()287 SoCoordinateElement::getDefault3()
288 {
289   return SbVec3f(0, 0, 0);
290 }
291 
292 //! FIXME: write doc.
293 
294 //$ EXPORT INLINE
295 SbVec4f
getDefault4()296 SoCoordinateElement::getDefault4()
297 {
298   return SbVec4f(0, 0, 0, 1);
299 }
300 
301 //! FIXME: write doc.
302 
303 void
print(FILE *) const304 SoCoordinateElement::print(FILE * /* file */) const
305 {
306 }
307