*** empty log message ***
[lsystem3d.git] / src / model.cpp
1 // Copyright (C) 2006 Erik Dahlberg
2 //
3 // This file is part of LSystem3d.
4 //
5 // LSystem3D is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // LSystem3D is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with LSystem3D; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19
20
21
22 #include <vector>
23
24 #include "GL/gl.h"
25 #include "GL/glu.h"
26
27 #include "color.h"
28 #include "model.h"
29 #include "vector.h"
30
31
32
33 /**
34 * Constructor
35 */
36 Model::Model()
37 {
38 // default color table
39 Color brown(0.5, 0.2, 0.0); _colorTable.push_back(brown);
40 Color white(1.0, 1.0, 1.0); _colorTable.push_back(white);
41 Color green(0.0, 0.5, 0.0); _colorTable.push_back(green);
42
43 _displayList = 0;
44
45 clear();
46 }
47
48
49
50 /**
51 * Destructor
52 */
53 Model::~Model()
54 {
55 glDeleteLists(_displayList, 1);
56 }
57
58
59
60 /**
61 * Create a segment
62 * @param x1 x start point
63 * @param y1 y start point
64 * @param z1 z start point
65 * @param x2 x end point
66 * @param y2 y end point
67 * @param z2 z end point
68 */
69 void Model::segment(double x1, double y1, double z1, double x2, double y2, double z2)
70 {
71 // find rotation vector and angle
72
73 Vector initial(0.0, 1.0, 0.0); // initial rotation of cylinder
74 Vector desired(x2-x1, y2-y1, z2-z1); // desired rotation of cylinder
75 desired.normalize();
76
77 // rotation angle
78 double rotationAngle = initial.getAngle(desired);
79
80 // rotation vector
81 Vector rotationVector = initial.getCrossProduct(desired);
82 rotationVector.normalize();
83
84
85 // render the cylinder
86
87 static GLUquadric *quadric = gluNewQuadric();
88
89 glPushMatrix();
90 glTranslatef(x1, y1, z1);
91 glRotatef(rotationAngle, rotationVector.getX(), rotationVector.getY(), rotationVector.getZ());
92 glRotatef(-90, 1, 0, 0);
93
94 gluCylinder(quadric, _diameter, _diameter, 1.0, 6, 6);
95 glPopMatrix();
96 }
97
98
99
100 /**
101 * Specify a vertex
102 * @param x x-coordinate
103 * @param y y-coordinate
104 * @param z z-coordinate
105 */
106 void Model::vertex(double x, double y, double z)
107 {
108 glVertex3d(x, y, z);
109 }
110
111
112
113 /**
114 * Specify a normal
115 * @param x x-coordinate
116 * @param y y-coordinate
117 * @param z z-coordinate
118 */
119 void Model::normal(double x, double y, double z)
120 {
121 glNormal3f(x, y, z);
122 }
123
124
125
126 /**
127 * Render to screen
128 */
129 void Model::draw()
130 {
131 glCallList(_displayList);
132 }
133
134
135
136 /**
137 * Clear the model
138 */
139 void Model::clear()
140 {
141 glDeleteLists(_displayList, 1);
142 _displayList = glGenLists(1);
143
144 setColorIndex(0);
145
146 _diameter = 0.1;
147 _diameterFactor = 0.8;
148 }
149
150
151
152 /**
153 * Begin a modelling session
154 */
155 void Model::begin()
156 {
157 glNewList(_displayList, GL_COMPILE);
158 }
159
160
161
162 /**
163 * End a modelling session
164 */
165 void Model::end()
166 {
167 glEndList();
168 }
169
170
171
172 /**
173 * Begin creation of a filled polygon
174 */
175 void Model::fillBegin()
176 {
177 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
178
179 glBegin(GL_POLYGON);
180 }
181
182
183
184 /**
185 * End creation of a filled polygon
186 */
187 void Model::fillEnd()
188 {
189 glEnd();
190
191 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
192 }
193
194
195
196 /**
197 * Increment current index to color table
198 */
199 void Model::nextColor()
200 {
201 setColorIndex(_colorIndex + 1);
202 }
203
204
205
206 /**
207 * Decrement current index to color table
208 */
209 void Model::prevColor()
210 {
211 setColorIndex(_colorIndex - 1);
212 }
213
214
215
216 /**
217 * Decrement diameter of segment
218 */
219 void Model::decrementDiameter()
220 {
221 _diameter *= _diameterFactor;
222 }
223
224
225
226 /**
227 * Set current color index
228 * @param index the color index
229 */
230 void Model::setColorIndex(int index)
231 {
232 // keep in range
233
234 if (index < 0)
235 {
236 _colorIndex = _colorTable.size() - 1;
237 }
238 else if (index > (_colorTable.size() - 1))
239 {
240 _colorIndex = 0;
241 }
242 else
243 {
244 _colorIndex = index;
245 }
246
247
248 // set color
249
250 Color color = _colorTable[_colorIndex];
251 double r = color.getR();
252 double g = color.getG();
253 double b = color.getB();
254
255 glColor3f(r, g, b);
256 }
257
258
259
260 /**
261 * Set current diameter of segment
262 * @param diameter the diameter
263 */
264 void Model::setDiameter(double diameter)
265 {
266 _diameter = diameter;
267 }
268
269
270
271 /**
272 * Set diameter factor
273 * @param diameter the diameter factor
274 */
275 void Model::setDiameterFactor(double diameterFactor)
276 {
277 _diameterFactor = diameterFactor;
278 }
279
280
281
282 /**
283 * Get current color index
284 * @return color index
285 */
286 int Model::getColorIndex()
287 {
288 return _colorIndex;
289 }
290
291
292
293 /**
294 * Get current diameter of segment
295 * @return diameter of segment
296 */
297 double Model::getDiameter()
298 {
299 return _diameter;
300 }