*** empty log message ***
[lsystem3d.git] / src / model.cpp
index 48308a0cc39cc5d40c0a90796a58ce8e7fb7202b..9a8554b8dfa0494194c782cffcaf89a07e379c92 100644 (file)
 
 
 
+#include <vector>
+
 #include "GL/gl.h"
 #include "GL/glu.h"
 
+#include "color.h"
 #include "model.h"
 #include "vector.h"
 
  */
 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();
 }
 
 
@@ -48,8 +58,7 @@ Model::~Model()
 
 
 /**
- * Connect two points
- * @param diameter diameter of segment
+ * Create a segment
  * @param x1 x start point
  * @param y1 y start point
  * @param z1 z start point
@@ -57,53 +66,65 @@ Model::~Model()
  * @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::vertex(double x, double y, double z)
+{
+    glVertex3d(x, y, z);
+}
+
+
+
+/**
+ * Specify a normal
+ * @param x x-coordinate
+ * @param y y-coordinate
+ * @param z z-coordinate
+ */
+void Model::normal(double x, double y, double z)
+{
+    glNormal3f(x, y, z);
+}
+
+
+
+/**
+ * Render to screen
  */
 void Model::draw()
 {
@@ -117,13 +138,19 @@ void Model::draw()
  */
 void Model::clear()
 {
-    // TODO: not needed?
+    glDeleteLists(_displayList, 1);
+    _displayList = glGenLists(1);
+    
+    setColorIndex(0);
+    
+    _diameter = 0.1;
+    _diameterFactor = 0.8;
 }
 
 
 
 /**
- * Start recording of drawing operations
+ * Begin a modelling session
  */
 void Model::begin()
 {
@@ -133,7 +160,7 @@ void Model::begin()
 
 
 /**
- * Stop recording of drawing operations
+ * End a modelling session
  */
 void Model::end()
 {
@@ -143,33 +170,131 @@ 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 diameter of segment
+ */
+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 diameter of segment
+ * @param diameter the diameter
+ */
+void Model::setDiameter(double diameter)
+{
+    _diameter = diameter;
+}
+
+
+
+/**
+ * Set 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 diameter of segment
+ * @return diameter of segment
+ */
+double Model::getDiameter()
+{
+    return _diameter;
 }