Skip to content

Instantly share code, notes, and snippets.

@alexesDev
Created September 22, 2012 14:04
Show Gist options
  • Select an option

  • Save alexesDev/3766258 to your computer and use it in GitHub Desktop.

Select an option

Save alexesDev/3766258 to your computer and use it in GitHub Desktop.
Simple L-System with Irrlicht render
#include <irrlicht.h>
#include <vector>
#include <iostream>
#include <stack>
#include <map>
#include <functional>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
struct State
{
vector3df rotate;
vector3df prevPoint;
State() : rotate(vector3df()) {}
State(const State& other) : rotate(other.rotate), prevPoint(other.prevPoint) { }
};
typedef std::vector<line3df> Lines;
typedef std::stack<State> States;
typedef std::map<char, std::string> Rules;
typedef std::function< void() > ActionFunction;
typedef std::map<char, ActionFunction> Actions;
int main()
{
IrrlichtDevice *device = createDevice(EDT_DIRECT3D9, dimension2d<u32>(1024, 576));
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
ISceneNode* root = smgr->addEmptySceneNode();
ILightSceneNode* light = smgr->addLightSceneNode();
light->setPosition(vector3df(100, 100, 100));
light->setRadius(1000);
camera->setPosition(vector3df(40, 40, 40));
camera->setTarget(vector3df(0, 0, 0));
//////
std::string command;
Lines lines;
Rules rules;
Actions actions;
// Start data
command = "F";
rules['F'] = "F[+F]F[-F][F]";
float angle = 20;
State currentState;
States states;
states.push(currentState);
vector3df point;
actions['F'] = [&states, &lines]()
{
vector3df point = states.top().prevPoint + vector3df(0, 10, 0);
point.rotateYZBy(states.top().rotate.X, states.top().prevPoint);
point.rotateXZBy(states.top().rotate.Y, states.top().prevPoint);
point.rotateXYBy(states.top().rotate.Z, states.top().prevPoint);
lines.push_back(line3df(point, states.top().prevPoint));
states.top().prevPoint = point;
};
actions['+'] = [&states, &angle](){ states.top().rotate.X += angle; };
actions['-'] = [&states, &angle](){ states.top().rotate.X -= angle; };
actions['&'] = [&states, &angle](){ states.top().rotate.Y += angle; };
actions['^'] = [&states, &angle](){ states.top().rotate.Y -= angle; };
actions['\\'] = [&states, &angle](){ states.top().rotate.Z += angle; };
actions['/'] = [&states, &angle](){ states.top().rotate.Z -= angle; };
actions['['] = [&states, &angle](){ states.push(State(states.top())); };
actions[']'] = [&states, &angle](){ states.pop(); };
for(int i = 0; i < 5; ++i)
{
std::string temp = "";
for(auto it = command.begin(); it != command.end(); ++it)
{
if(actions.find(*it) != actions.end())
actions[*it]();
if(rules.find(*it) != rules.end())
temp += rules[*it];
else
temp += *it;
}
command = temp;
}
for(auto it = command.begin(); it != command.end(); ++it)
{
if(actions.find(*it) != actions.end())
actions[*it]();
}
//////
while(device->run())
{
driver->beginScene();
smgr->drawAll();
SMaterial material;
material.Lighting = false;
driver->setMaterial(material);
for(auto it = lines.begin(); it != lines.end(); ++it)
{
driver->draw3DLine((*it).start, (*it).end);
}
driver->endScene();
}
device->closeDevice();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment