*** empty log message ***
[lsystem3d.git] / src / model.cpp
CommitLineData
15c82487 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
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
31
32
33/**
34 * Constructor
35 */
36Model::Model()
37{
526db675 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();
15c82487 46}
47
48
49
50/**
51 * Destructor
52 */
53Model::~Model()
54{
55 glDeleteLists(_displayList, 1);
56}
57
58
59
60/**
526db675 61 * Create a segment
15c82487 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 */
526db675 69void Model::segment(double x1, double y1, double z1, double x2, double y2, double z2)
15c82487 70{
526db675 71 // find rotation vector and angle
15c82487 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
526db675 78 double rotationAngle = initial.getAngle(desired);
15c82487 79
80 // rotation vector
526db675 81 Vector rotationVector = initial.getCrossProduct(desired);
82 rotationVector.normalize();
15c82487 83
84
85 // render the cylinder
86
526db675 87 static GLUquadric *quadric = gluNewQuadric();
15c82487 88
15c82487 89 glPushMatrix();
90 glTranslatef(x1, y1, z1);
526db675 91 glRotatef(rotationAngle, rotationVector.getX(), rotationVector.getY(), rotationVector.getZ());
15c82487 92 glRotatef(-90, 1, 0, 0);
93
526db675 94 gluCylinder(quadric, _diameter, _diameter, 1.0, 6, 6);
15c82487 95 glPopMatrix();
96}
97
98
99
100/**
526db675 101 * Specify a vertex
102 * @param x x-coordinate
103 * @param y y-coordinate
104 * @param z z-coordinate
105 */
106void 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 */
119void Model::normal(double x, double y, double z)
120{
121 glNormal3f(x, y, z);
122}
123
124
125
126/**
127 * Render to screen
15c82487 128 */
129void Model::draw()
130{
131 glCallList(_displayList);
132}
133
134
135
136/**
137 * Clear the model
138 */
139void Model::clear()
140{
526db675 141 glDeleteLists(_displayList, 1);
142 _displayList = glGenLists(1);
143
144 setColorIndex(0);
145
146 _diameter = 0.1;
147 _diameterFactor = 0.8;
15c82487 148}
149
150
151
152/**
526db675 153 * Begin a modelling session
15c82487 154 */
155void Model::begin()
156{
157 glNewList(_displayList, GL_COMPILE);
158}
159
160
161
162/**
526db675 163 * End a modelling session
15c82487 164 */
165void Model::end()
166{
167 glEndList();
168}
169
170
171
172/**
526db675 173 * Begin creation of a filled polygon
15c82487 174 */
175void Model::fillBegin()
176{
526db675 177 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
178
15c82487 179 glBegin(GL_POLYGON);
180}
181
182
183
184/**
526db675 185 * End creation of a filled polygon
15c82487 186 */
187void Model::fillEnd()
188{
189 glEnd();
526db675 190
191 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
15c82487 192}
193
194
195
196/**
526db675 197 * Increment current index to color table
15c82487 198 */
526db675 199void Model::nextColor()
15c82487 200{
526db675 201 setColorIndex(_colorIndex + 1);
202}
203
204
205
206/**
207 * Decrement current index to color table
208 */
209void Model::prevColor()
210{
211 setColorIndex(_colorIndex - 1);
212}
213
214
215
216/**
217 * Decrement diameter of segment
218 */
219void Model::decrementDiameter()
220{
221 _diameter *= _diameterFactor;
222}
223
224
225
226/**
227 * Set current color index
228 * @param index the color index
229 */
230void 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 */
264void Model::setDiameter(double diameter)
265{
266 _diameter = diameter;
267}
268
269
270
271/**
272 * Set diameter factor
273 * @param diameter the diameter factor
274 */
275void Model::setDiameterFactor(double diameterFactor)
276{
277 _diameterFactor = diameterFactor;
278}
279
280
281
282/**
283 * Get current color index
284 * @return color index
285 */
286int Model::getColorIndex()
287{
288 return _colorIndex;
289}
290
291
292
293/**
294 * Get current diameter of segment
295 * @return diameter of segment
296 */
297double Model::getDiameter()
298{
299 return _diameter;
15c82487 300}