lsystem.cpp

A scenery demonstrating a quite complicated `retransformation'. In truth, there is only one object, namely a golden cylinder, but a retransformation function, which is built by a L-System algorithm, is applied to this cylinder, such that it appears multiple times in changing positions. The result is nearly botanical...

lsystem.jpg

#include <3D/main.hpp>
#include <3D/objects/Cylinder.hpp>
#include <3D/objects/planeobjs.hpp>
#include <wb/stack.hpp>
#include <ctype.h>
#include <stdio.h>
#include <fstream.h>

using namespace wb;
using namespace Lux;

char    lsystem1[2048];
char    lsystem2[16984];
char    lsystem3[128*1024];
const char*lsystem = lsystem3;


//nst   double  angle = M_PI/19.;
const   double  angle = M_PI/29.;
//const char lsystem0[] = "LZL(6y2zZL)(-4y(-2zZL)2zZL)(-4xZL)(4x2y2zZL)yL";
//const char lsystem0[] = "LZ(6y2zZ8SL)(-4y(-2zZ5SL)2zZL)(-4xZ5SL)(4x2y2zZ7SL)yL";

char lsystem0[1024] = 
"L40Z(11X5yL)(10Y-5Z9X5y5xL)(-14Y-5Z-7xL)(-12X-3Y-4Z-2x-6yL)S2X1yL";

//const char lsystem0[] = "L20Z1Y1yL";

int     maxLsystemlen = 0;
const char*lsys;

Stack<Transformation, 16> LSystemstack;

int     retransform(int t,Transformation&T,const ObjectBase&)
{
        if (t>maxLsystemlen) return 0;
        if (t==0)
        {
                LSystemstack.popall();
                lsys = lsystem;
        }

        while(*lsys)
        {
        int     sign = 1;
        int     mCount = 0;
                if (*lsys=='+' || *lsys=='-')
                {
                        for(;*lsys=='+';lsys++) sign=+1;
                        for(;*lsys=='-';lsys++) sign=-1;
                }

                while(isdigit(*lsys))
                {
                        mCount *= 10;
                        mCount += *lsys - '0';
                        lsys++;
                }
                mCount *= sign;

                switch(*lsys++)
                {
                case 'X':       T.Translation+=T.Obj_to_World*vector3(.05*mCount,0,0); break;
                case 'Y':       T.Translation+=T.Obj_to_World*vector3(0,.05*mCount,0); break;
                case 'Z':       T.Translation+=T.Obj_to_World*vector3(0,0,.05*mCount); break;

                case 'x':       T.Obj_to_World*=rotx(angle*mCount);
                                T.invertflag=1;
                                break;

                case 'y':       T.Obj_to_World*=roty(angle*mCount);
                                T.invertflag=1;
                                break;

                case 'z':       T.Obj_to_World*=rotz(angle*mCount);
                                T.invertflag=1;
                                break;

                //case 'S':     T.scale(.1*vector3(mCount,mCount,mCount));
                //case 'S':     T.scale(vector3(.6,.6,.6));
                case 'S':       T.scale(vector3(.9,.9,.9));
                                break;

                case '(':       LSystemstack.push(T);   break;
                case ')':       LSystemstack.pop(T);    break;

                case 'L':       return 1;
                }
        }

        return 0;
}


void    buildLsystem(char*to,const char*from,const char*const insert)
{
char    *o = to;
        while(*from) switch(*from)
        {
        case 'L':
                for(const char*cp=insert;*cp; *to++=*cp++)
                             ;
                from++;
                break;
        default:
                *to++ = *from++;
        }
        *to = '\0';
        printf("Lsystem: %d Bytes\n",to-o);
}

int     Lcount(const char*from)
{
int     L;
        for(L=0;*from;from++)
                if (*from=='L') L++;
        return L;
}


main(int argc,const char*argv[])
{
        {
        ifstream lif("lsystem.str");
                lif.getline(lsystem0,sizeof(lsystem0));
        }
        
Camera  Kamera(voption(argc,argv,"Standpunkt",vector3(-6,30,.3)),
               voption(argc,argv,"Blickpunkt",vector3( 6, 0, 7)) );

Standardobjektiv Lens(ioption(argc,argv,"angle",50));
        Kamera.use(Lens);

Scene   Welt;

Material        s = Material::gold;
Cylinder Kvirtual(s,.05, vector3(0,0,0), vector3(0,0,1.0) );

        Kvirtual.name="Virtueller Zylinder";

Material        bg(rgb_real(.4,0,.4));
        bg.transparency = rgb_real(0,0,0);
        bg.refract_indices = rgb_real(1,1,1);
        Welt.defBackground(bg);

        Welt.add(Kvirtual);

        Kvirtual.trans();
        Kvirtual.retransform = retransform;

        lsystem = lsystem0;
int     l = ioption(argc,argv,"level",1);
        
if (l>1) { buildLsystem(lsystem1,lsystem0,lsystem0); lsystem = lsystem1; }
if (l>2) { buildLsystem(lsystem2,lsystem1,lsystem0); lsystem = lsystem2; }
if (l>3) { buildLsystem(lsystem3,lsystem2,lsystem0); lsystem = lsystem3; }
        
        maxLsystemlen = Lcount(lsystem);

Material        Matt = Material::matt;
Plane   E1(Matt,vector3(0,0,-1),vector3(0,0,1));
        E1.name="Schiefe Ebene";
        Welt.add(E1);

InfiniteLight   Ls(rgb_real(1,1,1),vector3(-2,3,4));
        Ls.On(Welt);

        Kamera.autoexpose(Welt,argc,argv);

        return 0;
}


Generated on Wed Jun 17 20:00:14 2009 for Light++ by  doxygen 1.5.6