Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Growable trees and seasonal coloration

Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
01-19-2005 08:10
Here's the first script of the DNT system, it goes in your main tree element along with additional elements:

CODE

// branch
// script for making growable trees

float symmetry = 3.2; // values around 3 are good for trees, use 4 for growable buildings, 6 is for hexagonal builds
vector direction = <0,0,1>; // orientation of your piece
vector branch_offset = <0,0,-1>; // offset at which branches grow
vector forkaxis = <0,1,0>; // axis around which new branches are rotated to, well, "branch" out

string decoration;
string buildelement = "platform";

vector correction_rotation = <0,0,135>; // rotation applied when piece is rezzed by another piece, in degrees
vector correction_offset;

// communication
integer listen_handle;
integer global_handle;
integer my_channel;
integer global_channel = 12345;

integer next_son = FALSE;

integer PermNeeded;

perm()
{
integer a=llGetPermissions();
if ((a&PermNeeded)!=PermNeeded)
llRequestPermissions(llGetOwner(),PermNeeded);
}

extend()
{
if (next_son)
{
return;
} else {
next_son = TRUE;
llRezObject(llGetObjectName(), ((llGetScale() * direction) * direction) * llGetRot() + llGetPos(), ZERO_VECTOR, llGetRot(), TRUE);
}
}

branch()
{
rotation rot;
vector offset;

rot = llEuler2Rot((PI/symmetry) * forkaxis); // use TWO_PI in non-tree growable objects
offset = (0.5 * llGetScale() * direction) * direction * rot + branch_offset;
offset = offset * llGetRot();

llRezObject(llGetObjectName(), offset + llGetPos(), ZERO_VECTOR, rot * llGetRot(), FALSE);
spin(2);
}

build(string obj)
{
llRezObject(obj, llGetPos(), ZERO_VECTOR, llGetRot(), TRUE);
spin(2);
}

spin(integer n)
{
llSetRot(llEuler2Rot( (PI/symmetry) * n * direction) * llGetRot());
}

change_channel()
{
llListenRemove(listen_handle);
my_channel = (integer)llFrand(10000000) + global_channel + 5;
listen_handle = llListen(my_channel, "", "", "");
}

default
{
state_entry()
{
PermNeeded = FALSE;
perm();
llSetTouchText("Menu");
global_handle = llListen(global_channel, "", "", "");
}

touch_start(integer counter)
{
change_channel();
llDialog(llDetectedKey(0),
"GROW=make it grow in length, BRANCH=make branch, BLOOM=make leaves, BUILD=make platform, CCW/CW=spin, FREEZE=remove all growth scripts of the tree, KILL=delete the tree",
["GROW", "BRANCH", "BLOOM", "BUILD", "CCW", "CW", "FREEZE", "KILL"],
my_channel);
llSetTimerEvent(20.0);
}

timer()
{
llListenRemove(listen_handle);
llSetTimerEvent(0.0);
}

listen(integer chan, string nom, key grower, string mesg)
{
llListenRemove(listen_handle);

if ((grower != llGetOwner()) && (llGetOwnerKey(grower) != llGetOwner()))
{
return;
}

if (mesg == "GROW")
{
extend();
} else if (mesg == "BRANCH")
{
branch();
} else if (mesg == "BLOOM")
{
build(decoration);
} else if (mesg == "BUILD")
{
build(buildelement);
} else if (mesg == "CCW")
{
spin(-1);
} else if (mesg == "CW")
{
spin(1);
} else if (mesg == "FREEZE")
{
if (chan != global_channel)
{
llListenRemove(global_channel);
llSay(global_channel, "FREEZE");
}
llRemoveInventory(llGetScriptName());
} else if (mesg == "KILL")
{
if (chan != global_channel)
{
llSleep(6.0);
llSay(global_channel, "KILL");
}
llDie();
}
}

run_time_permissions(integer a)
{
perm();
}

object_rez(key target)
{
if (next_son)
{
llSetPrimitiveParams([PRIM_TYPE, PRIM_TYPE_CYLINDER,
0, <0.0, 1.0, 0.0>, // holeshape, cut
0.0, <0.0, 0.0, 0.0>, // hollow, twist
<1.0, 1.0, 0.0>, <0.0, 0.0, 0.0>]); // topsize, topshear
}
llGiveInventory(target, llGetObjectName());
llGiveInventory(target, decoration);
llGiveInventory(target, buildelement);
}

on_rez(integer a)
{
rotation rot;
vector pos;
perm();

decoration = llGetObjectName() + "let";
next_son = FALSE;

if (a)
{
llSetRot(llEuler2Rot((llFrand(.5) + 1.0) * correction_rotation * DEG_TO_RAD) * llGetRot());
}
}
}


My trees use one main branch element and one secondary, smaller element, this is the script for smaller element:
CODE

float symmetry = 3.0;
vector direction = <0,0,1>;

vector correction_offset = <0,0,1>;
vector correction_rotation = <60,0,0>;

// communication
integer listen_handle;
integer global_handle;
integer my_channel;
integer global_channel = 12345;

spin(integer n)
{
if (llGetLinkNumber() < 2)
{
llSetRot(llEuler2Rot( (PI/symmetry) * n * direction) * llGetRot());
} else {
llSetLocalRot(llEuler2Rot( (PI/symmetry) * n * direction) * llGetLocalRot());
}
}

change_channel()
{
llListenRemove(my_channel);
my_channel = (integer)llFrand(10000000) + global_channel + 5;
listen_handle = llListen(my_channel, "", "", "");
}

default
{
state_entry()
{
global_handle = llListen(global_channel, "", "", "");
}

touch_start(integer counter)
{
change_channel();
llDialog(llDetectedKey(0),
"CCW/CW=spin, FREEZE=end growth of tree, KILL=delete the tree",
["CCW", "CW", "FREEZE", "KILL"],
my_channel);
llSetTimerEvent(20.0);
}

timer()
{
llListenRemove(my_channel);
}

listen(integer chan, string nom, key grower, string mesg)
{
llListenRemove(listen_handle);

if ((grower != llGetOwner()) && (llGetOwnerKey(grower) != llGetOwner()))
{
return;
}

if (mesg == "CW")
{
spin(-1);
} else if (mesg == "CCW")
{
spin(1);
} else if (mesg == "FREEZE")
{
if (chan != global_channel)
{
llListenRemove(global_channel);
llSay(global_channel, "FREEZE");
}
llRemoveInventory(llGetScriptName());
} else if (mesg == "KILL")
{
if (chan != global_channel)
{
llListenRemove(global_channel);
llSay(global_channel, "KILL");
}
llDie();
}
}

on_rez(integer a)
{
rotation rot;
vector pos;

if (a)
{
if ((correction_offset != ZERO_VECTOR) || (correction_rotation != ZERO_VECTOR))
{
rot = llEuler2Rot(correction_rotation * DEG_TO_RAD);
pos = 0.5 * (llGetScale() * direction) * direction;

llSetPos( ((pos * rot) - pos + correction_offset) * llGetRot() + llGetPos());
llSetRot(rot * llGetRot());
}
}
}
}


Both scripts are set for cylinders.

Here's the script for making the leaves (a prim linked to other elements, big or small) change color with "season" (needs a dead leaves texture, the Faster and Slower commands only take effect at season change):
CODE

// seasons
// seasonal colors control
// Author: Jesrad Seraph
// Modify and redistribute freely

integer season = 1;
// 0 spring, 1 summer, 2 autumn, 3 winter

integer season_channel = 111333;
integer season_handle;

// colors are in rotation format so we can store alpha
rotation springcolor = <0,1,0,1>;
rotation summercolor = <1,1,1,1>;
rotation autumncolor = <1,.3,0,0.9>;
rotation wintercolor = <1,0.5,0,0>;

vector leavescolor = <0.9,0.2,0>;
string leavestexture = "dead leaves";
vector leavessize = <0.08,0.16,0.0>;

float delay = 1.6;
float steps = 21.0;

float n;
rotation a;
rotation b;
integer target_season;

fade()
{
vector trans;
vector col;
float ratio;
float opacity;

ratio = n / steps;
col.x = (1.0 - ratio) * a.x + ratio * b.x;
col.y = (1.0 - ratio) * a.y + ratio * b.y;
col.z = (1.0 - ratio) * a.z + ratio * b.z;
llSetColor(col, ALL_SIDES);
llSetAlpha( ( (1.0 - ratio) * a.s + ratio * b.s), ALL_SIDES);
}

next_colors()
{
if (season == 0)
{
a = springcolor;
b = summercolor;
} else if (season == 1)
{
a = summercolor;
b = autumncolor;
} else if (season == 2)
{
llParticleSystem([PSYS_PART_FLAGS, PSYS_PART_WIND_MASK | PSYS_PART_FOLLOW_VELOCITY_MASK,
PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE_CONE,
PSYS_PART_START_COLOR, leavescolor,
PSYS_PART_START_SCALE, leavessize,
PSYS_PART_END_SCALE, leavessize,
PSYS_SRC_ANGLE_BEGIN, 0.0,
PSYS_SRC_ANGLE_END, PI,
PSYS_PART_MAX_AGE, (steps*delay/2.0),
PSYS_SRC_ACCEL, <0,0,-0.4>,
PSYS_SRC_BURST_RATE, delay/steps,
PSYS_SRC_BURST_PART_COUNT, 2,
PSYS_SRC_TEXTURE, leavestexture
]);
a = autumncolor;
b = wintercolor;
} else if (season == 3)
{
llParticleSystem([]);
a = wintercolor;
b = springcolor;
}
}

default
{
timer()
{

++n;

if (n <= steps)
{
fade();
} else {
n = 0.0;
++season;
if (season > 3)
season = 0;
next_colors();
if (season == target_season)
{
llSetTimerEvent(0.0);
}
}
}

state_entry()
{
n = 0.0;
a = summercolor;
b = autumncolor;
llListenRemove(season_handle);
season_handle = llListen(season_channel, "", "", "");
}

on_rez(integer startparam)
{
n = 0.0;
a = summercolor;
b = autumncolor;
llListenRemove(season_handle);
season_handle = llListen(season_channel, "", "", "");
}

touch_start(integer a)
{
season_handle = llListen(season_channel, "", "", "");
llDialog(llDetectedKey(0),
"Season:",
["Spring", "Summer", "Autumn", "Winter"],
season_channel);
}

listen(integer chan, string nom, key grower, string mesg)
{
if ((grower != llGetOwner()) && (llGetOwnerKey(grower) != llGetOwner()))
{
return;
}

if (mesg == "Spring")
{
target_season = 0;

} else if (mesg == "Summer")
{
target_season = 1;

} else if (mesg == "Autumn")
{
target_season = 2;

} else if (mesg == "Winter")
{
target_season = 3;

} else if (mesg == "Faster")
{
delay /= 2.0;
if (delay < 0.5)
delay = 0.5;
} else if (mesg == "Slower")
{
delay *= 2.0;
}

if (season != target_season)
llSetTimerEvent(delay);
}
}


The scripts auto-adjust for size of elements they're in so you should be able to slap the season one on an alpha-textured prim, link it to a cylinder, put the second script in that cylinder, then put the first in a bigger (for looks) cylinder, copy this cylinder, then add the small element and the big element to the copy of the big element = new tree.
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
RacerX Gullwing
Magic Rabbit
Join date: 18 Jun 2004
Posts: 371
01-22-2005 21:57
interesting little set of scripts having a little trouble compiling it the first one went ok the second one gets stuck at this part
CODE
}

on_rez(integer*a)
{
rotation rot;

and the third one went ok.
the multiply integer by a , I thought maybe a typo
and removed the * that made it compileable and it does stuff but I think it must be able to do more than add a branches that can be spun the grow doesn' t seem to do anything and I'm guessing there sposed to be connected since you refer to some parts as child to each other that doesn't seem to be happening also I get a lot of unable to locate . And It doesn't say what it can't find, the times it did say what it couldn't find I named stuff those names and put them inside the branch like branchlet and platform should there be a branch inside of branch? what exactly goes in the trunk and what should the trunk be named? does branch get a branchlet inside it and a leaf ? does branchlet get a leaf in it?
well looking forward to seeing a tree grow was thinking of making a pet grow myself. Was hoping I'd find what I needed in here.
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
01-24-2005 23:33
1) make cylinder
2) put the first script in this cylinder
3) copy this cylinder
4) put copy inside the original cylinder so that it can rez a copy of itself
5) make smaller cylinder
6) give this cylinder the same name as the main cylinder, with "let" added at the end. If your bigger cyllinder is called "Oak" it will have to be called "Oaklet".
7) put second script in this cylinderlet
8) put cylinderlet in the main cylinder

There, you have a new growable tree :)

Next you can attach additional prims to your cylinders, give them a transparent foliage texture and the third script to make the leaves. Caveat: keep these foliage prims centered on the Z axis of the cylinder you attach them to.
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
RacerX Gullwing
Magic Rabbit
Join date: 18 Jun 2004
Posts: 371
02-10-2005 03:43
OK but on the second script the (let) it wont save. It stops and gives an error message See my earlier post from before hope to see this work someday sounds like fun
but until it can be saved I can't see that happening try copying it yourself the second script wont work. A typo? a space somewhere added because of the way it shows in the forum I don't know?

CODE

on_rez(integer*a)
{
rotation rot;


gives this message
(85, 18) : ERROR :Syntacs error
Jesrad Seraph
Nonsense
Join date: 11 Dec 2004
Posts: 1,463
02-11-2005 10:44
This is strange, there isn't a * in my code in SL... I'm fixing it in the post.
_____________________
Either Man can enjoy universal freedom, or Man cannot. If it is possible then everyone can act freely if they don't stop anyone else from doing same. If it is not possible, then conflict will arise anyway so punch those that try to stop you. In conclusion the only strategy that wins in all cases is that of doing what you want against all adversity, as long as you respect that right in others.
Heratiki Turnbull
Juggalo Ninja Master
Join date: 2 Mar 2005
Posts: 81
05-16-2005 20:35
I did what you said and keep getting the error couldn't find object platform...
Ravenis Black
Registered User
Join date: 8 Apr 2005
Posts: 90
07-05-2005 10:04
This is an ok script to start with but I suggest keeping the updates coming.. I don't understand how you get the leaves to grow and also a suggestion for the script would be randomizing the branches more.. All of the branches sprout off one another only from the base of the parent branch, if it is possible try and modify it so that the branches will sprout randomly throughout the entire length of the branch not just at the base.
Wheel Fizz
Registered User
Join date: 26 May 2005
Posts: 36
07-09-2005 06:24
Im playing with it at the mo and its great fun...to get the leaves to grow you have to select Bloom from the menu....or say "/12345 BLOOM" which makes all the branches and branchlets Bloom leaves...so watch out if its a big tree...:)
OddSight Andric
Registered User
Join date: 15 Sep 2005
Posts: 1
10-01-2005 14:09
ooooo and you could have a particle script that makes dead leaf sprite fall as it loses leaves!!

...and it might be over kill (or just super detailed) but you could put a sound clip of leaves on the tree rustling in the wind for when there are leaves on the tree...

I think that would be kind of cool :P