*** empty log message ***
[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
62/**
526db675 63 * Create a segment
15c82487 64 * @param x1 x start point
65 * @param y1 y start point
66 * @param z1 z start point
67 * @param x2 x end point
68 * @param y2 y end point
69 * @param z2 z end point
70 */
526db675 71void Model::segment(double x1, double y1, double z1, double x2, double y2, double z2)
15c82487 72{
526db675 73 // find rotation vector and angle
15c82487 74
75 Vector initial(0.0, 1.0, 0.0); // initial rotation of cylinder
76 Vector desired(x2-x1, y2-y1, z2-z1); // desired rotation of cylinder
77 desired.normalize();
78
79 // rotation angle
526db675 80 double rotationAngle = initial.getAngle(desired);
15c82487 81
82 // rotation vector
526db675 83 Vector rotationVector = initial.getCrossProduct(desired);
84 rotationVector.normalize();
15c82487 85
86
87 // render the cylinder
88
526db675 89 static GLUquadric *quadric = gluNewQuadric();
15c82487 90
15c82487 91 glPushMatrix();
92 glTranslatef(x1, y1, z1);
526db675 93 glRotatef(rotationAngle, rotationVector.getX(), rotationVector.getY(), rotationVector.getZ());
15c82487 94 glRotatef(-90, 1, 0, 0);
95
526db675 96 gluCylinder(quadric, _diameter, _diameter, 1.0, 6, 6);
15c82487 97 glPopMatrix();
98}
99
100
101
102/**
526db675 103 * Specify a vertex
104 * @param x x-coordinate
105 * @param y y-coordinate
106 * @param z z-coordinate
107 */
108void Model::vertex(double x, double y, double z)
109{
110 glVertex3d(x, y, z);
111}
112
113
114
115/**
116 * Specify a normal
117 * @param x x-coordinate
118 * @param y y-coordinate
119 * @param z z-coordinate
120 */
121void Model::normal(double x, double y, double z)
122{
123 glNormal3f(x, y, z);
124}
125
126
127
128/**
129 * Render to screen
15c82487 130 */
131void Model::draw()
132{
133 glCallList(_displayList);
134}
135
136
137
138/**
139 * Clear the model
140 */
141void Model::clear()
142{
526db675 143 glDeleteLists(_displayList, 1);
144 _displayList = glGenLists(1);
145
146 setColorIndex(0);
147
148 _diameter = 0.1;
149 _diameterFactor = 0.8;
15c82487 150}
151
152
153
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/**
219 * Decrement diameter of segment
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/**
263 * Set current diameter of segment
264 * @param diameter the diameter
265 */
266void Model::setDiameter(double diameter)
267{
268 _diameter = diameter;
269}
270
271
272
273/**
274 * Set diameter factor
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/**
296 * Get current diameter of segment
297 * @return diameter of segment
298 */
299double Model::getDiameter()
300{
301 return _diameter;
15c82487 302}