Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Fractal Tree Open Source

Ming Chen
Here since 0.4.1!
Join date: 3 Sep 2003
Posts: 524
03-05-2005 06:07
Ok everyone, I usually never post Open Source code, but here is my first one in 2 years :P
This script lets you create realistic looking trees out of prims. The code removes itself at the end to prevent any script lag :)

Instructions
-------------
THE MAIN OBJECT
---------------------
1) Create a box or flower pot(or any build it will come out of) and call it "Fractal Tree"
2) Place the following Code inside

CODE

//////////////////////////////////////////////////////////
//Base Fractal Tree Code
//Created By Ming Chen
//You can sell this code as long as you leave this line, sell it with FULL permissions, and
//modify the code just a little to make it different :)
//
//By the way, these are the only comments you'll see mainly through the script (because
//usually im the only one to read my code)
////////////////////////////////////////////////////////

integer totalBranches = 4;
integer minAngle = 15;
integer maxAngle = 60;
float posOffset = 1;

float MIN_POS_OFFSET = 0;
float MAX_POS_OFFSET = 2;

integer MIN_TOTAL_BRACHES = 2;
integer MAX_TOTAL_BRACHES = 6;

integer MIN_MINIMUM_ANGLE = 5;
integer MAX_MINIMUM_ANGLE = 89;

integer MIN_MAXIMUM_ANGLE = 5;
integer MAX_MAXIMUM_ANGLE = 89;

integer checkLimits(float min, float max, float val){
if(val >= min && val <= max) return TRUE;
else return FALSE;
}

default
{
state_entry()
{
llSay(0, "Fractal Tree Generator online.");
llListen(0,"",llGetOwner(),"");
}

listen(integer chan, string name, key id, string message){
list parse = llParseString2List(llToLower(message),[" "],[]);
string command = llList2String(parse,0);
string data = llList2String(parse,1);

if(command == "!totalbranches")
{
if(checkLimits(MIN_TOTAL_BRACHES,MAX_TOTAL_BRACHES,(integer)data)){
totalBranches = (integer)data;
llSay(0,"Total Branches: " + (string)totalBranches);
}
}

if(command == "!branchminangle")
{
if(checkLimits(MIN_MINIMUM_ANGLE,MAX_MINIMUM_ANGLE,(integer)data)){
minAngle = (integer)data;
llSay(0,"Minimum Angle: " + (string)minAngle);
}
}

if(command == "!branchmaxangle")
{
if(checkLimits(MIN_MAXIMUM_ANGLE,MAX_MAXIMUM_ANGLE,(integer)data)){
maxAngle = (integer)data;
llSay(0,"Maximum Angle: " + (string)maxAngle);
}
}

if(command == "!posoffset")
{
if(checkLimits(MIN_POS_OFFSET,MAX_POS_OFFSET,(float)data)){
posOffset = (float)data;
llSay(0,"Pos Offset: " + (string)posOffset);
}
}



}

touch_start(integer total_number)
{
llRezObject("Tree",llGetPos(),<0,0,0>,ZERO_ROTATION,1);
llSleep(.5);
llSay(1, llDumpList2String([totalBranches,0,minAngle,maxAngle,posOffset],"|"));
}

object_rez(key id){
llGiveInventory(id,"Tree");
}
}


CODE

//////////////////////////////////////////////////////////
//Leaf Generator
//Created By Ming Chen
//You can sell this code as long as you leave this line, sell it with FULL permissions, and
//modify the code just a little to make it different :)
//
//By the way, these are the only comments you'll see mainly through the script (because
//usually im the only one to read my code)
////////////////////////////////////////////////////////

default
{
state_entry()
{
llListen(-1,"","","");
}
listen(integer chan, string name, key id, string message){
integer chan = llRound(llFrand(1000000));
llRezObject("Leaf",llGetPos(),<0,0,0>,ZERO_ROTATION,chan);
llWhisper(chan,message);
}
}


CREATING THE TREE OBJECT
----------------------------------
1)Create a cyclinder with the demensions <.2,.2,2> and a top size of .8
2)Call it "Tree" and set it to your favorite bark texture
3)Place the following code into the Tree Object

CODE

//////////////////////////////////////////////////////////
//Tree Object Code
//Created By Ming Chen
//You can sell this code as long as you leave this line, sell it with FULL permissions, and
//modify the code just a little to make it different :)
//
//By the way, these are the only comments you'll see mainly through the script (because
//usually im the only one to read my code)
////////////////////////////////////////////////////////


integer maxCreate;
integer curLevel;
integer angleMinRotate;
integer angleMaxRotate;
float posOffset;

integer rezTotal;
integer rezzed;
integer totalGive;

integer listenKey;

integer randInt(){
return (integer)((llFrand(2147483647) * -1) + llFrand(2147483647));
}

default
{
state_entry(){
llAllowInventoryDrop(TRUE);
}
on_rez(integer param)
{
if(param != 0){
listenKey = llListen(param,"","","");
}
}

listen(integer chan, string name, key id, string message)
{
llListenRemove(listenKey);
list vals = llParseString2List(message,["|"],[]);

maxCreate = (integer)llList2String(vals,0);
curLevel = (integer)llList2Integer(vals,1);

angleMinRotate = (integer)llList2Integer(vals,2);
angleMaxRotate = (integer)llList2Integer(vals,3);

posOffset = (float)llList2Integer(vals,4);

rezzed = TRUE;

vector scale = llGetScale();
scale *= llPow(.8,curLevel);
posOffset *= .8;
llSetScale(scale);
scale = llGetScale();
llSetPos(llGetPos() + (llRot2Up(llGetRot()) * (scale.z / 2)));

}

changed(integer p){
if(p == CHANGED_INVENTORY && rezzed){
if(curLevel < maxCreate)
{

curLevel++;
rotation rotate1 = llGetRot() * llEuler2Rot(<(llFrand(angleMaxRotate - angleMinRotate) + angleMinRotate),0,0> * DEG_TO_RAD);
rotation rotate2 = llGetRot() * llEuler2Rot(<-(llFrand(angleMaxRotate - angleMinRotate) + angleMinRotate),0,0> * DEG_TO_RAD);
rotation rotate3 = llGetRot() * llEuler2Rot(<0,(llFrand(angleMaxRotate - angleMinRotate) + angleMinRotate),0> * DEG_TO_RAD);
rotation rotate4 = llGetRot() * llEuler2Rot(<0,-(llFrand(angleMaxRotate - angleMinRotate) + angleMinRotate),0> * DEG_TO_RAD);

vector scale = llGetScale();
vector rezPos;


integer curChan;
string vals = llDumpList2String([maxCreate,curLevel,angleMinRotate, angleMaxRotate,posOffset],"|");

curChan = randInt();
rezPos = llGetPos() + ( llRot2Up(llGetRot()) * ((scale.z / 2) - llFrand(posOffset)) );
llRezObject("Tree",rezPos,<0,0,0>,rotate1,curChan);
llSay(curChan,vals);


curChan = randInt();
rezPos = llGetPos() + ( llRot2Up(llGetRot()) * ((scale.z / 2) - llFrand(posOffset)) );
llRezObject("Tree",rezPos,<0,0,0>,rotate2,curChan);
llSay(curChan,vals);


curChan = randInt();
rezPos = llGetPos() + ( llRot2Up(llGetRot()) * ((scale.z / 2) - llFrand(posOffset)) );
llRezObject("Tree",rezPos,<0,0,0>,rotate3,curChan);
llSay(curChan,vals);


curChan = randInt();
rezPos = llGetPos() + ( llRot2Up(llGetRot()) * ((scale.z / 2) - llFrand(posOffset)) );
llRezObject("Tree",rezPos,<0,0,0>,rotate4,curChan);
llSay(curChan,vals);

}
else{
vector scale = llGetScale();
llShout(-1,(string)(llGetPos() + ( llRot2Up(llGetRot()) * ((scale.z / 2)))) + "|" + (string)llGetRot());
llRemoveInventory("Tree");
llRemoveInventory(llGetScriptName());
}
}
}


object_rez(key id){
totalGive++;
llGiveInventory(id,"Tree");
if(totalGive == 4){
llRemoveInventory("Tree");
llRemoveInventory(llGetScriptName());
}

}
}


4)Place the tree object in the main object you created earlier

CREATING THE LEAF OBJECT
---------------------------------
1)Creatre a sphere with the demensions <1,1,.4>
2)Name it "Leaf" and set its texture to any leafy texture or color
3)Place the following code inside of it

CODE

//////////////////////////////////////////////////////////
//Fractal Tree Leaf Code
//Created By Ming Chen
//You can sell this code as long as you leave this line, sell it with FULL permissions, and
//modify the code just a little to make it different :)
//
//By the way, these are the only comments you'll see mainly through the script (because
//usually im the only one to read my code)
////////////////////////////////////////////////////////

integer listener;

default
{
on_rez(integer p){
llSetAlpha(0,-1);
listener = llListen(p,"","","");
}
listen(integer chan, string name, key id, string message){
llListenRemove(listener);
list parse = llParseString2List(message,["|"],[]);
llSetRot((rotation)llList2String(parse,1));
vector moveTo = (vector)llList2String(parse,0);
while(llGetPos() != moveTo){
llSetPos(moveTo);
}
llSetAlpha(1,-1);
llRemoveInventory(llGetScriptName());
}
}


4)Place the leaf object in the main object you made earlier

ALL DONE!

Recap:

The Main Object should contain the following
-Tree Object
-Leaf Object
-Leaf Generator
-Fract Tree Base Code

How to use:
"!totalbranches <x>" = replace x with a number wetween 1 and 5, this is the number of 'families' the tree will have. NOTE the number of tree objects rezzed will be 4^x so try to keep the number below 5!

"!branchminangle <x>" = Sets the minimum angle for each branch to be at, the angle of each branch will be between min and max

"!branchmaxangle <x>" = Sets the maximum angle for each branch to be at, the angle of each branch will be between min and max

"!posoffset <x>" = Sets the maximum offset from its default position on the trunk, to keep the tre truly fractal, set this value to 0 and min & max angles to the same

When your settings are done, click the main object and your tree will generate!

I would REALLY like to see some of the trees everyone generates, so a snap of your favorite tree would be nice :)

--Ming Out
_____________________
McWheelie Baldwin
Registered User
Join date: 9 Apr 2004
Posts: 154
03-06-2005 05:46
Ming, I gave your tree code a shot. I think it's missing a give inventory somewhere. After rezzing the first 'Tree' object section, it moves into place, then I get an error message saying "Unable to create requested object. Object is missing from database." I notice in the Tree script you allow for inventory drop, but I don't see the Fractal Tree script actually giving the inventory to the new section. Just thought I would let you know.

McW
_____________________


SS Sakai
Registered User
Join date: 16 Oct 2006
Posts: 1
Doesn't work anymore...?
01-11-2007 20:01
I get an error saying Grey goo - recursive fence...

This apparently prevents it from completing... Kewl Idea though ;)

So is there the infamous world destroying Grey Goo in SL?