1 /*
2  * NodePointSet.cpp
3  *
4  * Copyright (C) 1999 Stephen F. White
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program (see the file "COPYING" for details); if
18  * not, write to the Free Software Foundation, Inc., 675 Mass Ave,
19  * Cambridge, MA 02139, USA.
20  */
21 
22 #include <stdio.h>
23 #include "stdafx.h"
24 
25 #include "NodePointSet.h"
26 #include "Proto.h"
27 #include "FieldValue.h"
28 #include "SFNode.h"
29 #include "NodeColor.h"
30 #include "NodeColorRGBA.h"
31 #include "NodeCoordinate.h"
32 #include "NodeGeoCoordinate.h"
33 #include "NodeFogCoordinate.h"
34 #include "DuneApp.h"
35 #include "Util.h"
36 
ProtoPointSet(Scene * scene)37 ProtoPointSet::ProtoPointSet(Scene *scene)
38   : GeometryProto(scene, "PointSet")
39 {
40     attrib.set(
41           addExposedField(MFNODE, "attrib", new MFNode(),
42                           VERTEX_ATTRIBUTE_NODE));
43     setFieldFlags(attrib, FF_X3D_ONLY);
44     color.set(
45           addExposedField(SFNODE, "color", new SFNode(NULL), COLOR_NODE));
46     coord.set(
47           addExposedField(SFNODE, "coord", new SFNode(NULL), COORDINATE_NODE));
48     fogCoord.set(
49           addExposedField(SFNODE, "fogCoord", new SFNode(NULL),
50                           X3D_FOG_COORDINATE));
51     setFieldFlags(fogCoord, FF_X3D_ONLY);
52 }
53 
54 Node *
create(Scene * scene)55 ProtoPointSet::create(Scene *scene)
56 {
57     return new NodePointSet(scene, this);
58 }
59 
NodePointSet(Scene * scene,Proto * def)60 NodePointSet::NodePointSet(Scene *scene, Proto *def)
61   : GeometryNode(scene, def)
62 {
63 }
64 
65 void
draw()66 NodePointSet::draw()
67 {
68     Node *ncoord = coord()->getValue();
69     if (ncoord != NULL) {
70         glPushName(coord_Field());       // field coord
71         glPushName(0);                   // index 0
72         if (ncoord->getType() == VRML_COORDINATE)
73             ((NodeCoordinate *)ncoord)->draw(this);
74         else if (ncoord->getType() == VRML_GEO_COORDINATE) {
75             ((NodeGeoCoordinate *)ncoord)->draw(this);
76         }
77         glPopName();
78         glPopName();
79     }
80 }
81 
82 void
pointDraw()83 NodePointSet::pointDraw()
84 {
85     Node *coord = ((SFNode *) getField(coord_Field()))->getValue();
86     MFFloat *colors = NULL;
87     int colorSize = 0;
88     float pointSize = TheApp->GetPointSetSize();
89 
90     glPushAttrib(GL_ENABLE_BIT | GL_LIGHTING);
91     glDisable(GL_LIGHTING);
92     glDisable(GL_TEXTURE_2D);
93     if (pointSize == 0.0) {
94         glEnable(GL_POINT_SMOOTH);
95         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
96         glEnable(GL_BLEND);
97         glPointSize(1.0);
98     } else {
99         glDisable(GL_POINT_SMOOTH);
100         glPointSize(pointSize);
101     }
102     int colorInc = 3;
103     if (color()->getValue()) {
104         if (color()->getValue()->getType() == VRML_COLOR) {
105             colors = ((NodeColor *)(color()->getValue()))->color();
106             colorSize = colors->getSFSize();
107         } else if (color()->getValue()->getType() == X3D_COLOR_RGBA) {
108             colors = ((NodeColorRGBA *)(color()->getValue()))->color();
109             colorSize = colors->getSFSize();
110             colorInc = 4;
111         }
112     }
113     if (colors == NULL) {
114         float c[4];
115         glGetMaterialfv(GL_FRONT, GL_EMISSION, c);
116         Util::myGlColor4fv(c);
117     }
118 
119     if (!coord)
120         return;
121 
122     MFVec3f *coords = NULL;
123     MFVec3d *coordsDouble = NULL;
124     int coordSize;
125     if (coord->getType() == VRML_COORDINATE) {
126         coords = ((NodeCoordinate *) coord)->point();
127         coordSize = coords->getSFSize();
128     } else {
129         coordsDouble = ((NodeGeoCoordinate *) coord)->pointX3D();
130         coordSize = coordsDouble->getSFSize();
131     }
132 
133     MFFloat *fogDepth = NULL;
134     if (fogCoord()->getValue())
135         if (fogCoord()->getValue()->getType() == X3D_FOG_COORDINATE)
136             fogDepth = ((NodeFogCoordinate *)
137                          (fogCoord()->getValue()))->depth();
138 
139     glBegin(GL_POINTS);
140     for (int i = 0; i < coordSize; i++) {
141         if (i < colorSize)
142             Util::myGlColor3fv(colors->getValues() + i * colorInc);
143         if (coords)
144             glVertex3fv(coords->getValue(i));
145         else
146             glVertex3dv(coordsDouble->getValue(i));
147 #ifdef HAVE_GLFOGCOORDF
148             if (fogDepth) {
149                 int fogIndex = fogDepth->getSize() - 1;
150                 if (i < fogDepth->getSize())
151                     fogIndex = i;
152                 if (fogIndex > -1)
153                     glFogCoordf(fogDepth->getValue(fogIndex));
154            }
155 #endif
156     }
157     glEnd();
158     glEnable(GL_LIGHTING);
159     glPopAttrib();
160 }
161 
162 
163 Vec3f
getMinBoundingBox(void)164 NodePointSet::getMinBoundingBox(void)
165 {
166     Vec3f ret(0, 0, 0);
167     Node *coord = ((SFNode *) getField(coord_Field()))->getValue();
168     if (coord != NULL) {
169         MFVec3f *coords = ((NodeCoordinate *)coord)->point();
170         if (coords != NULL)
171             ret = coords->getMinBoundingBox();
172    }
173    return ret;
174 }
175 
176 Vec3f
getMaxBoundingBox(void)177 NodePointSet::getMaxBoundingBox(void)
178 {
179     Vec3f ret(0, 0, 0);
180     Node *coord = ((SFNode *) getField(coord_Field()))->getValue();
181     if (coord != NULL) {
182         MFVec3f *coords = ((NodeCoordinate *)coord)->point();
183         if (coords != NULL)
184             ret = coords->getMaxBoundingBox();
185    }
186    return ret;
187 }
188 
189 void
flip(int index)190 NodePointSet::flip(int index)
191 {
192     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
193     if (ncoord)
194         if (ncoord->getType() == VRML_COORDINATE)
195             ncoord->flip(index);
196 }
197 
198 void
swap(int fromTo)199 NodePointSet::swap(int fromTo)
200 {
201     NodeCoordinate *ncoord = (NodeCoordinate *)coord()->getValue();
202     if (ncoord)
203         if (ncoord->getType() == VRML_COORDINATE)
204              ncoord->swap(fromTo);
205 }
206 
207