Minor cleanup.
[lsystem3d.git] / src / model.cpp
CommitLineData
15c82487 1// Copyright (C) 2006 Erik Dahlberg
2//
1a372e99 3// This file is part of LSystem3D.
15c82487 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
526db675 22#include <vector>
23
15c82487 24#include "GL/gl.h"
25#include "GL/glu.h"
26
526db675 27#include "color.h"
15c82487 28#include "model.h"
29#include "vector.h"
30
1a372e99 31using namespace std;
32
15c82487 33
34
35/**
36 * Constructor
37 */
38Model::Model()
39{
526db675 40 // default color table
41 Color brown(0.5, 0.2, 0.0); _colorTable.push_back(brown);
42 Color white(1.0, 1.0, 1.0); _colorTable.push_back(white);
43 Color green(0.0, 0.5, 0.0); _colorTable.push_back(green);
44
45 _displayList = 0;
46
47 clear();
15c82487 48}
49
50
51
52/**
53 * Destructor
54 */
55Model::~Model()
56{
57 glDeleteLists(_displayList, 1);
58}
59
60
61
68a7b857 62/**
63 * Clear the model
64 */
65void Model::clear()
66{
67 glDeleteLists(_displayList, 1);
68 _displayList = glGenLists(1);
69
70 setColorIndex(0);
71
72 _diameter = 0.1;
73 _diameterFactor = 0.8;
74}
75
76
77
78/**
79 * Render to screen
80 */
81void Model::draw()
82{
83 glCallList(_displayList);
84}
85
86
87
15c82487 88/**
526db675 89 * Create a segment
15c82487 90 * @param x1 x start point
91 * @param y1 y start point
92 * @param z1 z start point
93 * @param x2 x end point
94 * @param y2 y end point
95 * @param z2 z end point
96 */
526db675 97void Model::segment(double x1, double y1, double z1, double x2, double y2, double z2)
15c82487 98{
526db675 99 // find rotation vector and angle
15c82487 100
101 Vector initial(0.0, 1.0, 0.0); // initial rotation of cylinder
102 Vector desired(x2-x1, y2-y1, z2-z1); // desired rotation of cylinder
103 desired.normalize();
104
105 // rotation angle
526db675 106 double rotationAngle = initial.getAngle(desired);
15c82487 107
108 // rotation vector
526db675 109 Vector rotationVector = initial.getCrossProduct(desired);
110 rotationVector.normalize();
15c82487 111
112
113 // render the cylinder
114
526db675 115 static GLUquadric *quadric = gluNewQuadric();
15c82487 116
15c82487 117 glPushMatrix();
118 glTranslatef(x1, y1, z1);
526db675 119 glRotatef(rotationAngle, rotationVector.getX(), rotationVector.getY(), rotationVector.getZ());
15c82487 120 glRotatef(-90, 1, 0, 0);
121
526db675 122 gluCylinder(quadric, _diameter, _diameter, 1.0, 6, 6);
15c82487 123 glPopMatrix();
124}
125
126
127
128/**
526db675 129 * Specify a vertex
130 * @param x x-coordinate
131 * @param y y-coordinate
132 * @param z z-coordinate
133 */
134void Model::vertex(double x, double y, double z)
135{
136 glVertex3d(x, y, z);
137}
138
139
140
141/**
142 * Specify a normal
143 * @param x x-coordinate
144 * @param y y-coordinate
145 * @param z z-coordinate
146 */
147void Model::normal(double x, double y, double z)
148{
149 glNormal3f(x, y, z);
150}
151
152
153
15c82487 154/**
526db675 155 * Begin a modelling session
15c82487 156 */
157void Model::begin()
158{
159 glNewList(_displayList, GL_COMPILE);
160}
161
162
163
164/**
526db675 165 * End a modelling session
15c82487 166 */
167void Model::end()
168{
169 glEndList();
170}
171
172
173
174/**
526db675 175 * Begin creation of a filled polygon
15c82487 176 */
177void Model::fillBegin()
178{
526db675 179 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
180
15c82487 181 glBegin(GL_POLYGON);
182}
183
184
185
186/**
526db675 187 * End creation of a filled polygon
15c82487 188 */
189void Model::fillEnd()
190{
191 glEnd();
526db675 192
193 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
15c82487 194}
195
196
197
198/**
526db675 199 * Increment current index to color table
15c82487 200 */
526db675 201void Model::nextColor()
15c82487 202{
526db675 203 setColorIndex(_colorIndex + 1);
204}
205
206
207
208/**
209 * Decrement current index to color table
210 */
211void Model::prevColor()
212{
213 setColorIndex(_colorIndex - 1);
214}
215
216
217
218/**
68a7b857 219 * Decrement segment diameter
526db675 220 */
221void Model::decrementDiameter()
222{
223 _diameter *= _diameterFactor;
224}
225
226
227
228/**
229 * Set current color index
230 * @param index the color index
231 */
232void Model::setColorIndex(int index)
233{
234 // keep in range
235
236 if (index < 0)
237 {
238 _colorIndex = _colorTable.size() - 1;
239 }
240 else if (index > (_colorTable.size() - 1))
241 {
242 _colorIndex = 0;
243 }
244 else
245 {
246 _colorIndex = index;
247 }
248
249
250 // set color
251
252 Color color = _colorTable[_colorIndex];
253 double r = color.getR();
254 double g = color.getG();
255 double b = color.getB();
256
257 glColor3f(r, g, b);
258}
259
260
261
262/**
68a7b857 263 * Set current segment diameter
526db675 264 * @param diameter the diameter
265 */
266void Model::setDiameter(double diameter)
267{
268 _diameter = diameter;
269}
270
271
272
273/**
68a7b857 274 * Set segment diameter factor
526db675 275 * @param diameter the diameter factor
276 */
277void Model::setDiameterFactor(double diameterFactor)
278{
279 _diameterFactor = diameterFactor;
280}
281
282
283
284/**
285 * Get current color index
286 * @return color index
287 */
288int Model::getColorIndex()
289{
290 return _colorIndex;
291}
292
293
294
295/**
68a7b857 296 * Get current segment diameter
297 * @return the diameter
526db675 298 */
299double Model::getDiameter()
300{
301 return _diameter;
15c82487 302}
68a7b857 303
304
305
306/**
307 * Get segment diameter factor
308 * @return the diameter factor
309 */
310double Model::getDiameterFactor()
311{
312 return _diameterFactor;
313}