X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fturtle.cpp;h=5ef84a5afb0e91efc8591401406399ab579a19d8;hb=68a7b857d7778c1a7b33d916d062de317fdd5069;hp=9847b5af8d8562e2f7f6a763a8f6694f8c774f31;hpb=15c82487a77555b040f3f4e03bc11da8b9bc5905;p=lsystem3d.git diff --git a/src/turtle.cpp b/src/turtle.cpp index 9847b5a..5ef84a5 100644 --- a/src/turtle.cpp +++ b/src/turtle.cpp @@ -1,6 +1,6 @@ // 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 @@ -28,21 +28,23 @@ #include "turtle.h" #include "vector.h" +using namespace std; + /** * Constructor - * @param model render this model + * @param model create this model */ Turtle::Turtle(Model *model) { + _model = model; + // initial position and orientation reset(); // 90 degrees _angle = M_PIl / 2.0; - - _model = model; } @@ -56,6 +58,31 @@ Turtle::~Turtle() +/** + * Reset to default state + */ +void Turtle::reset() +{ + // put turtle at (0,0,0), head upwards, back towards camera + + _position.setXYZ(0.0, 0.0, 0.0); + + _heading.setXYZ(0.0, 1.0, 0.0); + _left.setXYZ(1.0, 0.0, 0.0); + _up.setXYZ(0.0, 0.0, 1.0); + + + // empty the stacks + _positionStack = stack(); + _headingStack = stack(); + _leftStack = stack(); + _upStack = stack(); + _diameterStack = stack(); + _colorIndexStack = stack(); +} + + + /** * Turn left */ @@ -159,18 +186,31 @@ void Turtle::walk() // move turtle to new position _position.setXYZ(endX, endY, endZ); - if (!_fenceMode) - { - // connect the points - _model->segment(_diameter, - startX, startY, startZ, - endX, endY, endZ); - } - else - { - // part of a filled surface - _model->point(endX, endY, endZ); - } + // connect start and end point + _model->segment(startX, startY, startZ, + endX, endY, endZ); +} + + + +/** + * Walk forward, creating a filled surface + * TODO: merge with walk() ? + */ +void Turtle::fillWalk() +{ + // end point + double destinationX = _position.getX() + _heading.getX(); + double destinationY = _position.getY() + _heading.getY(); + double destinationZ = _position.getZ() + _heading.getZ(); + + _model->normal(_up.getX(), _up.getY(), _up.getZ()); + + // move turtle to new position + _position.setXYZ(destinationX, destinationY, destinationZ); + + // part of a filled polygon + _model->vertex(destinationX, destinationY, destinationZ); } @@ -189,7 +229,12 @@ void Turtle::push() _upStack.push(_up); // diameter - _diameterStack.push(_diameter); + double diameter = _model->getDiameter(); + _diameterStack.push(diameter); + + // color index + int colorIndex = _model->getColorIndex(); + _colorIndexStack.push(colorIndex); } @@ -200,72 +245,20 @@ void Turtle::push() void Turtle::pop() { // position - _position = _positionStack.top(); _positionStack.pop(); + _position = _positionStack.top(); _positionStack.pop(); // orientation - _heading = _headingStack.top(); _headingStack.pop(); - _left = _leftStack.top(); _leftStack.pop(); - _up = _upStack.top(); _upStack.pop(); + _heading = _headingStack.top(); _headingStack.pop(); + _left = _leftStack.top(); _leftStack.pop(); + _up = _upStack.top(); _upStack.pop(); // diameter - _diameter = _diameterStack.top(); _diameterStack.pop(); -} - - - -/** - * Reset to default state - */ -void Turtle::reset() -{ - _diameter = 0.1; - - _fenceMode = false; - - - // put turtle at (0,0,0), head upwards, back towards camera - - _position.setXYZ(0.0, 0.0, 0.0); - - _heading.setXYZ(0.0, 1.0, 0.0); - _left.setXYZ(1.0, 0.0, 0.0); - _up.setXYZ(0.0, 0.0, 1.0); -} - - - -/** - * Decrement diameter of segment - */ -void Turtle::decrementDiameter() -{ - // TODO: dynamic value... - _diameter *= 0.8; -} - - - -/** - * Begin creation of a filled surface - */ -void Turtle::fenceInBegin() -{ - _fenceMode = true; - - _model->fillBegin(); - _model->point(_position.getX(), _position.getY(), _position.getZ()); -} - - - -/** - * End creation of a filled surface - */ -void Turtle::fenceInEnd() -{ - _model->fillEnd(); + double diameter = _diameterStack.top(); _diameterStack.pop(); + _model->setDiameter(diameter); - _fenceMode = false; + // color index + int colorIndex = _colorIndexStack.top(); _colorIndexStack.pop(); + _model->setColorIndex(colorIndex); }