// Copyright (C) 2006 Erik Dahlberg
//
-// This file is part of LSystem3d.
+// This file is part of LSystem3D.
//
// LSystem3D is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
+#include <vector>
+
#include "GL/gl.h"
#include "GL/glu.h"
+#include "color.h"
#include "model.h"
#include "vector.h"
+using namespace std;
+
/**
*/
Model::Model()
{
- _displayList = glGenLists(1);
+ // default color table
+ Color brown(0.5, 0.2, 0.0); _colorTable.push_back(brown);
+ Color white(1.0, 1.0, 1.0); _colorTable.push_back(white);
+ Color green(0.0, 0.5, 0.0); _colorTable.push_back(green);
+
+ _displayList = 0;
+
+ clear();
}
/**
- * Connect two points
- * @param diameter diameter of segment
+ * Clear the model
+ */
+void Model::clear()
+{
+ glDeleteLists(_displayList, 1);
+ _displayList = glGenLists(1);
+
+ setColorIndex(0);
+
+ _diameter = 0.1;
+ _diameterFactor = 0.8;
+}
+
+
+
+/**
+ * Render to screen
+ */
+void Model::draw()
+{
+ glCallList(_displayList);
+}
+
+
+
+/**
+ * Create a segment
* @param x1 x start point
* @param y1 y start point
* @param z1 z start point
* @param y2 y end point
* @param z2 z end point
*/
-void Model::segment(double diameter, double x1, double y1, double z1, double x2, double y2, double z2)
+void Model::segment(double x1, double y1, double z1, double x2, double y2, double z2)
{
- // wireframe
- //
- // glColor3f(1,1,1);
- // glBegin(GL_LINES);
- // glVertex3d(x1, y1, z1);
- // glVertex3d(x2, y2, z2);
- // glEnd();
-
-
-
- // solid
-
- // find rotation vector and angle of cylinder
+ // find rotation vector and angle
Vector initial(0.0, 1.0, 0.0); // initial rotation of cylinder
Vector desired(x2-x1, y2-y1, z2-z1); // desired rotation of cylinder
desired.normalize();
// rotation angle
- double angle = initial.getAngle(desired);
+ double rotationAngle = initial.getAngle(desired);
// rotation vector
- Vector crossProduct = initial.getCrossProduct(desired);
- crossProduct.normalize();
+ Vector rotationVector = initial.getCrossProduct(desired);
+ rotationVector.normalize();
// render the cylinder
- GLUquadric *quadric = gluNewQuadric();
+ static GLUquadric *quadric = gluNewQuadric();
- glColor3f(1.0, 0.5, 0.0);
-
glPushMatrix();
glTranslatef(x1, y1, z1);
- glRotatef(angle, crossProduct.getX(), crossProduct.getY(), crossProduct.getZ());
+ glRotatef(rotationAngle, rotationVector.getX(), rotationVector.getY(), rotationVector.getZ());
glRotatef(-90, 1, 0, 0);
- gluCylinder(quadric, diameter, diameter, 1.0, 6, 6);
+ gluCylinder(quadric, _diameter, _diameter, 1.0, 6, 6);
glPopMatrix();
}
/**
- * Draw model to screen
+ * Specify a vertex
+ * @param x x-coordinate
+ * @param y y-coordinate
+ * @param z z-coordinate
*/
-void Model::draw()
+void Model::vertex(double x, double y, double z)
{
- glCallList(_displayList);
+ glVertex3d(x, y, z);
}
/**
- * Clear the model
+ * Specify a normal
+ * @param x x-coordinate
+ * @param y y-coordinate
+ * @param z z-coordinate
*/
-void Model::clear()
+void Model::normal(double x, double y, double z)
{
- // TODO: not needed?
+ glNormal3f(x, y, z);
}
/**
- * Start recording of drawing operations
+ * Begin a modelling session
*/
void Model::begin()
{
/**
- * Stop recording of drawing operations
+ * End a modelling session
*/
void Model::end()
{
/**
- * Begin creation of a filled surface
+ * Begin creation of a filled polygon
*/
void Model::fillBegin()
{
- glColor3f(0.0, 0.5, 0.0);
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
+
glBegin(GL_POLYGON);
}
/**
- * End creation of a filled surface
+ * End creation of a filled polygon
*/
void Model::fillEnd()
{
glEnd();
+
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
}
/**
- * Create one vertex in the filled surface
- * @param x x-coordinate
- * @param y y-coordinate
- * @param z z-coordinate
+ * Increment current index to color table
*/
-void Model::point(double x, double y, double z)
+void Model::nextColor()
{
- glVertex3d(x, y, z);
+ setColorIndex(_colorIndex + 1);
+}
+
+
+
+/**
+ * Decrement current index to color table
+ */
+void Model::prevColor()
+{
+ setColorIndex(_colorIndex - 1);
+}
+
+
+
+/**
+ * Decrement segment diameter
+ */
+void Model::decrementDiameter()
+{
+ _diameter *= _diameterFactor;
+}
+
+
+
+/**
+ * Set current color index
+ * @param index the color index
+ */
+void Model::setColorIndex(int index)
+{
+ // keep in range
+
+ if (index < 0)
+ {
+ _colorIndex = _colorTable.size() - 1;
+ }
+ else if (index > (_colorTable.size() - 1))
+ {
+ _colorIndex = 0;
+ }
+ else
+ {
+ _colorIndex = index;
+ }
+
+
+ // set color
+
+ Color color = _colorTable[_colorIndex];
+ double r = color.getR();
+ double g = color.getG();
+ double b = color.getB();
+
+ glColor3f(r, g, b);
+}
+
+
+
+/**
+ * Set current segment diameter
+ * @param diameter the diameter
+ */
+void Model::setDiameter(double diameter)
+{
+ _diameter = diameter;
+}
+
+
+
+/**
+ * Set segment diameter factor
+ * @param diameter the diameter factor
+ */
+void Model::setDiameterFactor(double diameterFactor)
+{
+ _diameterFactor = diameterFactor;
+}
+
+
+
+/**
+ * Get current color index
+ * @return color index
+ */
+int Model::getColorIndex()
+{
+ return _colorIndex;
+}
+
+
+
+/**
+ * Get current segment diameter
+ * @return the diameter
+ */
+double Model::getDiameter()
+{
+ return _diameter;
+}
+
+
+
+/**
+ * Get segment diameter factor
+ * @return the diameter factor
+ */
+double Model::getDiameterFactor()
+{
+ return _diameterFactor;
}