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