PDA

View Full Version : Sample of recursive scene graph



ToolTech
03-27-2003, 12:03 PM
I just wanted to share an example of my new research. It is a technique to define fractal and recursive contents in a scene graph.

My example shows a mathematical tree affected by a smooth wind. Look at http://www.tooltech-software.com

Julien Cayzac
03-27-2003, 12:05 PM
Any doc/sample for us on non-win32 platforms?

Julien.

ToolTech
03-27-2003, 12:21 PM
I can compile it for Linux, Irix, Mac OS X and Linux. What would you prefer ?

You can find the source code in the source directory..

ToolTech
03-27-2003, 01:52 PM
Here is the source code for the tree demo that builds the actual tree




// A displacement function for a branch segment
gzRealXY xyfunk1(gzReal in)
{
return gzRealXY(in*(1-in)*sin(in*GZ_PI*3)*5,in*(1-in)*sin(3*in*GZ_PI)*5);
}

// A second displacement function for a branch segment
gzRealXY xyfunk2(gzReal in)
{
return gzRealXY(in*(1-in)*sin(2*in*GZ_PI)*5,in*(1-in)*sin(5*in*GZ_PI));
}

// A method that creates a leaf geometry ( A quad texture )
gzGeometry *leaf()
{
gzGeometry *leaf=new gzGeometry;

gzArray<gzVec3> &amp;coordinates=leaf->getCoordinateArray();
gzArray<gzVec2> &amp;tex=leaf->getTexCoordinateArray();
gzArray<gzVec3> &amp;norm=leaf->getNormalArray();


coordinates+= gzVec3(-80,0,0);
coordinates+= gzVec3(80,0,0);
coordinates+= gzVec3(80,160,0);
coordinates+= gzVec3(-80,160,0);

tex+= gzVec2(0,0);
tex+= gzVec2(1,0);
tex+= gzVec2(1,1);
tex+= gzVec2(0,1);

norm+=gzVec3(0,0,1);

leaf->setTexBind(GZ_BIND_ON);
leaf->setNormalBind(GZ_BIND_PER_PRIM);
leaf->setGeoPrimType(GZ_PRIM_QUADS);


// Fix state on leaf

gzMaterial *material=new gzMaterial;
gzState *state=new gzState;

state->setMaterial(material);
//state->setBackMaterial(material);
state->setMode(GZ_STATE_MATERIAL,GZ_STATE_ON);

gzTexture *texture=new gzTexture;

texture->setImage(gzImageManager::loadImage("leaf.png"));
texture->setComponents(4);
texture->setWrapS(GZ_REPEAT);
texture->setWrapT(GZ_REPEAT);
texture->useMipMaps(TRUE);
texture->setMagFilter(GZ_LINEAR);
texture->setMinFilter(GZ_LINEAR_MIPMAP_LINEAR);

// Make the leaf texture transparent ourside leaf
state->setMode(GZ_STATE_ALPHA_FUNC,GZ_STATE_ON);
state->setAlphaFunc(GZ_ALPHA_FUNC_GREATER,0.5f);


state->setTexture(texture);
state->setMode(GZ_STATE_TEXTURE,GZ_STATE_ON);

state->setMode(GZ_STATE_POLYGON_MODE,GZ_STATE_ON);
state->setBackPolygonMode(GZ_POLYGON_MODE_FILL);
state->setFrontPolygonMode(GZ_POLYGON_MODE_FILL);

leaf->setState(state);

return leaf;
}

// Builds the recursive tree geometry
gzNode *buildTree()
{

// Create two potential selections of a branch
gzGeometry *base_1=new gzGeometryTube(50,5,11,6,GZ_TUBE_CONE,xyfunk1,5,5) ;

gzGeometry *base_2=new gzGeometryTube(50,5,11,6,GZ_TUBE_CONE,xyfunk2,5,5) ;


// Base branch

gzSeedSwitch *base=new gzSeedSwitch;

base->addNode(base_1);
base->addNode(base_2);


// The max recursion depth
gzULong depth=13;

// Build tree

gzRecursive *tree=new gzRecursive;

tree->setMaxDepth(depth);

// Experimental stuff
//tree->useDistanceDepth(TRUE);
//tree->setDistanceDepthEquation(1000,1);


// The recusrsive tree algo
// tree=(base+T1*R1*S1*tree+T2*R2*S2*tree))

// tree=base
tree->addNode(base);

// When max recusrion is reached, use this coupling to next set
tree->setMaxDepthNode(leaf());

// Some paramenters
gzFloat rotation=180;
gzFloat balance=0.6;
gzFloat spread=50;
gzFloat offset=0;
gzFloat add_rotation=108;

// TRS1 - top striving high
gzSeedTransform *pSeedTransform_1=new gzSeedTransform();
pSeedTransform_1->setTranslation(0,48.5,0);
pSeedTransform_1->setScale(0.85,balance*1.5,0.85);
pSeedTransform_1->setHPRSeedValue(TRUE,gzVec3(rotation+add_rotation, (1-balance)*spread,0),gzVec3(rotation+add_rotation,(1-balance)*spread,0));

pSeedTransform_1->setStriveDirection(gzVec3(1,0,0));
pSeedTransform_1->setStriveFactors(0.1,0.1,2);

pSeedTransform_1->addNode(tree);
pSeedTransform_1->setRecursiveDepthScaleFactor(1);

// tree=base+T1*R1*S1*tree
tree->addNode(pSeedTransform_1);


// TRS2 - side winder
gzSeedTransform *pSeedTransform_2=new gzSeedTransform();
pSeedTransform_2->setTranslation(0,48,0);
pSeedTransform_2->setScale((1-balance)*1.7,(1-balance)*1.7,(1-balance)*1.7);
pSeedTransform_2->setHPRSeedValue(TRUE,gzVec3(rotation+add_rotation,-(offset+balance*spread),0),gzVec3(rotation+add_rot ation,-(offset+balance*spread),0));

pSeedTransform_2->setStriveDirection(gzVec3(1,-1,0));
pSeedTransform_2->setStriveFactors(0.5);

pSeedTransform_2->addNode(tree);
pSeedTransform_2->setRecursiveDepthScaleFactor(1.1);


tree->addNode(pSeedTransform_2);


// Fix state on overall tree

gzMaterial *material=new gzMaterial;
gzState *state=new gzState;

state->setMaterial(material);
state->setMode(GZ_STATE_MATERIAL,GZ_STATE_ON);

gzTexture *tex=new gzTexture;

tex->setImage(gzImageManager::loadImage("bark.png"));
tex->setWrapS(GZ_REPEAT);
tex->setWrapT(GZ_REPEAT);
tex->useMipMaps(TRUE);
tex->setMagFilter(GZ_LINEAR);
tex->setMinFilter(GZ_LINEAR_MIPMAP_LINEAR);


state->setTexture(tex);
state->setMode(GZ_STATE_TEXTURE,GZ_STATE_ON);

// Seed starter
gzSeedControl *topNode=new gzSeedControl;
//topNode->setSeedControlType(GZ_SEED_FROM_TIME);

base->setState(state);

// Add recursive tree

topNode->addNode(tree);

return topNode;
}

BlackSoftware
03-27-2003, 02:35 PM
wow this is really cool. I'm really impressed I've been planning on doing somthing similar to this for a couple months but school has had me all tied up.

does your algorithm use Hofmeisters rules?

is there a higher-level interface for defining different types of plants?

can you grow the tree from a seed?

which variables determine the shape of the tree?

ToolTech
03-27-2003, 02:52 PM
The system can be used to implement hoffmeister rules. The demo is just one simple rule. More complex rule can be cascaded.

I am planning to add some kind of language that can build the scene structure, but for know I am working on performance on the implementation. The demo is about 160.000 polys each frame and thats too much..

I can grow the plant from a seed. The gzSeedControl can take a position or time etc to start a new sequence.

The shapes are really determined by the scaling and rotation. Right now I am experimenting with classes that adds/removes contents based on weights so e.g. I can design a library of 10 branch types and let the algo select beteen them...