|
In this post, I'll show you how to script
a realistic splash when your whale enters and leaves the water.
First, you need to add add another prim. This prim will point the Z axis down. Particles come out of the Z-axis in a prim.
Add the following script to the new prim, and position it near the blow-hole of your whale. Click it first, then click the whale, and link them so you do not disturb the root prim. The box with the main scripts in it must be Yellow.
|
![]() |
This script has several functions. It has an on/off switch. It sprays a water particle in a circle. The circle spins rapidly so that you see a ring of water. The script decides how high the whale is above the water. It then adjusts the spray position so that a ring of water spray rises up from the center of the whale that is always at water level. As the whale rises, the spray gets less.
|
|
// particles constants float maxsysage = 0.0; // particles spray forever float maxspeed = 0.3; // max speed 0.3 meters a second float minspeed = 0.15; // and min is about half that. float burstrad = 0.0; // no radius at all integer burstcount = 20; // spray 20 of them float burstrate = 0.01; // really fast.. lets swamp the viewer with particles and spray. float outangle = 0.075; // make a wide cone float inangle = 0; vector omega = <0.0,0.0,0.0>; // no rotation float startalph = 0.75; // start semi-transparent float endalph = 0.015; // end almost invisible vector startscale = <2.0,2.0,2.0>; // start at 2 X the size of the texture vector endscale = <4.0,4.0,4.0>; // and end up twice that float maxage = 1.7; // last for 1.7 seconds vector accel = <0.0, 0.0, 1.0>; // push in the Z axis string texture = ""; // global constants vector pos; vector vel; vector up; float ground = 0.0; float water = 0.0; float height = 0.0; float oscillation = 1.25; float start_mult = 0.1; // when we start up, this makes the water 'rise' over time float rad; integer oscillate = TRUE; integer started = FALSE;
This next subroutine will calculate the height of the water, the spew, oscillation, and size of the particles.
Particles(integer part_on)
{
maxage = 0.001;
if (!part_on) jump particles;
vel = llGetVel() * 0.2;
ground = llGround(vel);
water = llWater(vel);
if (ground < water) {
maxspeed = 2.5;
minspeed = 1.25;
oscillation = 2.0;
endscale = <3.0,3.0,3.0>;
maxage = 2.0;
ground = water;
texture = "7f70a931-6300-8dbc-caca-8b09a9c2cf11";
} else {
maxspeed = 1.75;
minspeed = 0.875;
oscillation = 1.25;
endscale = <4.0,4.0,4.0>;
maxage = 1.75;
texture = "Water Particle - Mist";
}
pos = llGetPos() + vel;
up = llRot2Up(llGetRot());
height = pos.z - ground - 0.5;
height += (1.0 - up.z) * height;
if (height < 6.0 && height > -1.0) {
rad = 1.5 + (oscillate * oscillation);
outangle = PI - llAtan2(rad, height);
inangle = outangle + 0.15;
burstrad = rad / llSin(outangle);
startalph = ((llFabs(height) / -8.57) + 0.8 - (!oscillate * 0.15)) * start_mult;
endalph = ((llFabs(height) / -200.0) + 0.04) * start_mult;
maxsysage = 0.0;
part_on = TRUE;
} else {
maxsysage = 0.01;
part_on = FALSE;
}
@particles;
After the parameters have been calculated, we spray them from the Z-axis of the prim:
llParticleSystem([PSYS_PART_FLAGS,
PSYS_PART_INTERP_COLOR_MASK |
PSYS_PART_INTERP_SCALE_MASK |
//PSYS_PART_FOLLOW_VELOCITY_MASK |
PSYS_PART_WIND_MASK,
PSYS_SRC_PATTERN,
PSYS_SRC_PATTERN_ANGLE_CONE,
PSYS_PART_START_COLOR, <1.0, 1.0, 1.0>,
PSYS_PART_START_ALPHA, startalph,
PSYS_PART_END_COLOR, <1.0, 1.0, 1.0>,
PSYS_PART_END_ALPHA, endalph,
PSYS_PART_START_SCALE, startscale,
PSYS_PART_END_SCALE, endscale,
PSYS_PART_MAX_AGE, maxage,
PSYS_SRC_ACCEL, accel,
PSYS_SRC_TEXTURE, texture,
PSYS_SRC_BURST_RATE, burstrate,
PSYS_SRC_ANGLE_BEGIN, inangle,
PSYS_SRC_ANGLE_END, outangle,
PSYS_SRC_BURST_PART_COUNT, burstcount,
PSYS_SRC_BURST_RADIUS, burstrad,
PSYS_SRC_BURST_SPEED_MIN, minspeed,
PSYS_SRC_BURST_SPEED_MAX, maxspeed,
PSYS_SRC_MAX_AGE, maxsysage,
PSYS_SRC_OMEGA, omega
]);
if (!part_on)
{
llParticleSystem([]); // shut down, not on
} else {
if (started)
{
if (start_mult < 1.0)
start_mult += 0.075;
} else {
if (start_mult > 0.0)
start_mult -= 0.05;
else {
llSetTimerEvent(0.0);
llParticleSystem([]);
}
}
oscillate = !oscillate; // toggle this flag
}
}
The default function is called at start-up. Here we turn off all particles.
default
{
state_entry()
{
llSetTimerEvent(0.0); // turn off particles and timers on boot up
Particles(FALSE);
}
Touching the whale will start up the water spout for testing purposes ( and for fun! )
touch_start(integer n)
{
started = TRUE; // if touched, start up
start_mult = 0.1;
llSetTimerEvent(0.01); // rapidly jab the timer
}
A link message is a prim-to-prim message. They are generated by llMessageLinked commands in the main script. When the main script runs the following code:
llMessageLinked(LINK_SET,0,"on",NULL_KEY); // part of another script
The link_message will be executed in the child script, and the string 'msg' will become 'on'.
link_message(integer sender, integer num, string str, key id)
{
if (str == "on") {
started = TRUE;
start_mult = 0.1;
llSetTimerEvent(0.01);
} else if (str == "off") {
started = FALSE;
llParticleSystem([]);
Particles(FALSE);
}
}
timer()
{
Particles(TRUE);
}
}
Next - > Part 7 - Realistic movement script - make the tail and fins move
Back to the Best Free Tools in Second Life and OpenSim.