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 SoVRMLCoordinate SoVRMLCoordinate.h Inventor/VRMLnodes/SoVRMLCoordinate.h
41   \brief The SoVRMLCoordinate class is used to define 3D coordinates for shapes.
42 
43   \ingroup VRMLnodes
44 
45   \WEB3DCOPYRIGHT
46 
47   \verbatim
48   Coordinate {
49     exposedField MFVec3f point  []      # (-inf, inf)
50   }
51   \endverbatim
52 
53   This node defines a set of 3D coordinates to be used in the coord
54   field of vertex-based geometry nodes including SoVRMLIndexedFaceSet,
55   SoVRMLIndexedLineSet, and SoVRMLPointSet.
56 
57 */
58 
59 /*!
60   \var SoMFVec3f SoVRMLCoordinate::point
61   The coordinates. Empty by default.
62 */
63 
64 #include <Inventor/VRMLnodes/SoVRMLCoordinate.h>
65 
66 #include <Inventor/actions/SoGLRenderAction.h>
67 #include <Inventor/VRMLnodes/SoVRMLMacros.h>
68 #include <Inventor/elements/SoCoordinateElement.h>
69 #include <Inventor/elements/SoGLVBOElement.h>
70 #include <Inventor/actions/SoAction.h>
71 
72 #include "nodes/SoSubNodeP.h"
73 #include "rendering/SoVBO.h"
74 
75 SO_NODE_SOURCE(SoVRMLCoordinate);
76 
77 #define PRIVATE(obj) obj->pimpl
78 
79 class SoVRMLCoordinateP {
80  public:
SoVRMLCoordinateP()81   SoVRMLCoordinateP() : vbo(NULL) { }
~SoVRMLCoordinateP()82   ~SoVRMLCoordinateP() { delete this->vbo; }
83   SoVBO * vbo;
84 };
85 
86 // Doc in parent
87 void
initClass(void)88 SoVRMLCoordinate::initClass(void) // static
89 {
90   SO_NODE_INTERNAL_INIT_CLASS(SoVRMLCoordinate, SO_VRML97_NODE_TYPE);
91 }
92 
93 /*!
94   Constructor.
95 */
SoVRMLCoordinate(void)96 SoVRMLCoordinate::SoVRMLCoordinate(void)
97 {
98   PRIVATE(this) = new SoVRMLCoordinateP;
99   SO_VRMLNODE_INTERNAL_CONSTRUCTOR(SoVRMLCoordinate);
100 
101   SO_VRMLNODE_ADD_EMPTY_EXPOSED_MFIELD(point);
102 }
103 
104 /*!
105   Destructor.
106 */
~SoVRMLCoordinate()107 SoVRMLCoordinate::~SoVRMLCoordinate()
108 {
109   delete PRIVATE(this);
110 }
111 
112 // Doc in parent
113 void
doAction(SoAction * action)114 SoVRMLCoordinate::doAction(SoAction * action)
115 {
116   SoCoordinateElement::set3(action->getState(), this,
117                             point.getNum(), point.getValues(0));
118 }
119 
120 // Doc in parent
121 void
GLRender(SoGLRenderAction * action)122 SoVRMLCoordinate::GLRender(SoGLRenderAction * action)
123 {
124   SoVRMLCoordinate::doAction((SoAction*) action);
125 
126   SoState * state = action->getState();
127   const int num = this->point.getNum();
128   SbBool setvbo = FALSE;
129   SoBase::staticDataLock();
130   if (SoGLVBOElement::shouldCreateVBO(state, num)) {
131     SbBool dirty = FALSE;
132     setvbo = TRUE;
133     if (PRIVATE(this)->vbo == NULL) {
134       PRIVATE(this)->vbo = new SoVBO(GL_ARRAY_BUFFER, GL_STATIC_DRAW);
135       dirty =  TRUE;
136     }
137     else if (PRIVATE(this)->vbo->getBufferDataId() != this->getNodeId()) {
138       dirty = TRUE;
139     }
140     if (dirty) {
141       PRIVATE(this)->vbo->setBufferData(this->point.getValues(0),
142                                         num*sizeof(SbVec3f),
143                                         this->getNodeId());
144     }
145   }
146   else if (PRIVATE(this)->vbo && PRIVATE(this)->vbo->getBufferDataId()) {
147     // clear buffers to deallocate VBO memory
148     PRIVATE(this)->vbo->setBufferData(NULL, 0, 0);
149   }
150   SoBase::staticDataUnlock();
151   if (setvbo) {
152     SoGLVBOElement::setVertexVBO(state, PRIVATE(this)->vbo);
153   }
154 
155 }
156 
157 // Doc in parent
158 void
getBoundingBox(SoGetBoundingBoxAction * action)159 SoVRMLCoordinate::getBoundingBox(SoGetBoundingBoxAction * action)
160 {
161   SoVRMLCoordinate::doAction((SoAction*) action);
162 }
163 
164 // Doc in parent
165 void
callback(SoCallbackAction * action)166 SoVRMLCoordinate::callback(SoCallbackAction * action)
167 {
168   SoVRMLCoordinate::doAction((SoAction*) action);
169 }
170 
171 // Doc in parent
172 void
pick(SoPickAction * action)173 SoVRMLCoordinate::pick(SoPickAction * action)
174 {
175   SoVRMLCoordinate::doAction((SoAction*) action);
176 }
177 
178 #undef PRIVATE
179 #endif // HAVE_VRML97
180