Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Dash Particles for Hoverskates

Veigrn Potato
www.veigrn.com
Join date: 26 Mar 2006
Posts: 8
04-11-2006 00:04
Hello, I'm having a hard time aligning my blue dashing particles to my avatar while I run. It's completely horizonal and follows me around while I run, but instead of aligning to my hoverskate's local X axis, it aligns to the global X axis.

So I've posted here to see if anyone knows how to change the pushing for PSYS_SRC_ACCEL into a local axis instead of the global axis. I've attached screenshots so you can see what I mean. Both "axis_001.jpg" and "axis_002.jpg" have the blue dash particles aligned to the world's global X axis.

I need them to become local so that they align to whatever direction I'm facing's X axis. I have no problem with the fact that I don't need a PSYS_SRC_ACCEL preference for the smoke particles script (separate script) coming out of my hoverskates since they're spherical, but the dash particles are horizontal and do not look right without a set PSYS_SRC_ACCEL because otherwise they just spit out rambunctiously in every direction.

Here's the emitter script for the blue dashing particles:


CODE
key owner;
integer status;
// Particle Script 0.4j
// Created by Ama Omega 3-7-2004
// Updated by Jopsy Pendragon 5-11-2004
// For classes/tutorials/tricks, visit the Particle Labratory in Teal
// Values marked with (*) are defaults.

// SECTION ONE: APPEARANCE -- These settings affect how each particle LOOKS.
integer glow = TRUE; // TRUE or FALSE(*)
vector startColor = <1,1,1>; // RGB color, black<0,0,0> to white<1,1,1>(*)
vector endColor = <0.3,0.77,0.9>; //
float startAlpha = 1.0; // 0.0 to 1.0(*), lower = more transparent
float endAlpha = 1.0; //
vector startSize = <0.1,1,0.1>; // <0.04,0.04,0>(min) to <10,10,0>(max>, <1,1,0>(*)
vector endSize = <0.1,2,0.1>; // (Z part of vector is discarded)
string texture = ""; // Texture used for particles. Texture must be in prim's inventory.

// SECTION TWO: FLOW -- These settings affect how Many, how Quickly, and for how Long particles are created.
// Note,
integer count = 11; // Number of particles created per burst, 1(*) to 4096
float rate = 0.1; // Delay between bursts of new particles, 0.0 to 60, 0.1(*)
float age = 0.8; // How long each particle lives, 0.1 to 60, 10.0(*)
float life = 0.0; // When to stop creating new particles. never stops if 0.0(*)

// SECTION THREE: PLACEMENT -- Where are new particles created, and what direction are they facing?
float radius = 1.6; // 0.0(default) to 64? Distance from Emitter where new particles are created.
float innerAngle = PI; // "spread", for all ANGLE patterns, 0(default) to PI
float outerAngle = 0.0; // "tilt", for ANGLE patterns, 0(default) to TWO_PI, can use PI_BY_TWO or PI as well.
integer pattern = PSYS_SRC_PATTERN_ANGLE_CONE; // Choose one of the following:
// PSYS_SRC_PATTERN_EXPLODE (sends particles in all directions)
// PSYS_SRC_PATTERN_DROP (ignores minSpeed and maxSpeed. Don't bother with count>1 )
// PSYS_SRC_PATTERN_ANGLE_CONE (set innerangle/outerange to make rings/cones of particles)
// PSYS_SRC_PATTERN_ANGLE (set innerangle/outerangle to make flat fanshapes of particles)
vector omega = <0,0,0>; // How much to rotate the emitter around the <X,Y,Z> axises. <0,0,0>(*)
// Warning, there's no way to RESET the emitter direction once you use Omega!!
// You must attach the script to a new prim to clear the effect of omega.

// SECTION FOUR: MOVEMENT -- How do the particles move once they're created?
integer followSource = FALSE; // TRUE or FALSE(*), Particles move as the emitter moves, (TRUE disables radius!)
integer followVel = TRUE; // TRUE or FALSE(*), Particles rotate towards their direction
integer wind = FALSE; // TRUE or FALSE(*), Particles get blown away by wind in the sim
integer bounce = FALSE; // TRUE or FALSE(*), Make particles bounce on Z altitude of emitter
float minSpeed = 0.00; // 0.01 to ? Min speed each particle is spit out at, 1.0(*)
float maxSpeed = 0.00; // 0.01 to ? Max speed each particle is spit out at, 1.0(*)
vector push = <6,0,0>; // Continuous force pushed on particles, use small settings for long lived particles
key target = ""; // Select a target for particles to arrive at when they die
// can be "self" (emitter), "owner" (you), "" or any prim/persons KEY.

// SECTION FIVE: Ama's "Create Short Particle Settings List"
integer enableoutput = TRUE; // If this is TRUE, clicking on your emitter prim will cause it to speak
// very terse "shorthand" version of your particle settings. You can cut'n'paste
// this abbreviated version into a call to llParticleSystem([ ]); in another script.
// Pros: Takes up far less scripting space, letting you focus on the rest of your code.
// Cons: makes tune your settings afterwards rather awkward

// === Don't muck about below this line unless you're comfortable with the LSL scripting language ====

// Script variables
integer pre = 2; //Adjust the precision of the generated list.
integer flags;
list sys;
integer type;
vector tempVector;
rotation tempRot;
string tempString;
integer i;

string float2String(float in)
{
return llGetSubString((string)in,0,pre - 7);
}

updateParticles()
{
flags = 0;
if (target == "owner") target = llGetOwner();
if (target == "self") target = llGetKey();
if (glow) flags = flags | PSYS_PART_EMISSIVE_MASK;
if (bounce) flags = flags | PSYS_PART_BOUNCE_MASK;
if (startColor != endColor) flags = flags | PSYS_PART_INTERP_COLOR_MASK;
if (startSize != endSize) flags = flags | PSYS_PART_INTERP_SCALE_MASK;
if (wind) flags = flags | PSYS_PART_WIND_MASK;
if (followSource) flags = flags | PSYS_PART_FOLLOW_SRC_MASK;
if (followVel) flags = flags | PSYS_PART_FOLLOW_VELOCITY_MASK;
if (target != "") flags = flags | PSYS_PART_TARGET_POS_MASK;
sys = [ PSYS_PART_MAX_AGE,age,
PSYS_PART_FLAGS,flags,
PSYS_PART_START_COLOR, startColor,
PSYS_PART_END_COLOR, endColor,
PSYS_PART_START_SCALE,startSize,
PSYS_PART_END_SCALE,endSize,
PSYS_SRC_PATTERN, pattern,
PSYS_SRC_BURST_RATE,rate,
PSYS_SRC_ACCEL, push,
PSYS_SRC_BURST_PART_COUNT,count,
PSYS_SRC_BURST_RADIUS,radius,
PSYS_SRC_BURST_SPEED_MIN,minSpeed,
PSYS_SRC_BURST_SPEED_MAX,maxSpeed,
PSYS_SRC_TARGET_KEY,target,
PSYS_SRC_INNERANGLE,innerAngle,
PSYS_SRC_OUTERANGLE,outerAngle,
PSYS_SRC_OMEGA, omega,
PSYS_SRC_MAX_AGE, life,
PSYS_SRC_TEXTURE, texture,
PSYS_PART_START_ALPHA, startAlpha,
PSYS_PART_END_ALPHA, endAlpha
];
float newrate = rate;
if (newrate == 0.0) newrate=.01;
}



initialize()
{
llSetAlpha(0.0, 2);
llSetTimerEvent(.00001); //honestly you could make this shorter, but what would be the point? .5 seems to work nice.
owner = llGetOwner();
llInstantMessage(llGetOwner(),"Hoverskates operational");
status = 0;

}



default
{
// state_entry() is an event handler, it executes
// whenever a state is entered.
state_entry()
{
if(llGetOwner() != owner) //checks to see if we have changed owner
{
initialize();
}

updateParticles();

}


on_rez(integer total_number)
{
if(llGetOwner() != owner)
{
initialize();
}
}




timer()
{
updateParticles();

if (llGetAgentInfo(owner) & AGENT_WALKING) //status changed since last checked?
{ llParticleSystem(sys);
}
else
{ llParticleSystem( [ ] );
}

}


}



Jopsy Pendragon
Perpetual Outsider
Join date: 15 Jan 2004
Posts: 1,906
04-11-2006 01:43
Hi Veigrn -

ACCEL is always based on the global axis unfortunately. With the approach you're trying I'm not sure if there's really a good solution.

I don't like being critical, but there are three things you *really* should do to this script... (without which you'll be creating unnecessary lag):

1) Slow that llSetTimerEvent(0.0001) back down to (0.5)

2) remove the updateparticles(); from inside the timer() { } block of code. It should only ever need to be called once, and you've done that state_entry() section.

3) The way it looks now... your code will constantly be turning the particles ON ON ON ON ON while the player is running and constantly be turning the particles OFF OFF OFF OFF OFF when they aren't. I haven't experimented with the llGetAgentInfo() function... but that's my take on how you have it now. I'd recommend searching the wiki for examples of this function that detect "changing from walking to running" or "changing from running to walking" rather than only checking if they're running or walking.

Wish I could suggest something to help you tune the particles as you want them... but even making this script more efficient, the way I would recommend setting this up would still result in a lag-creating-monster. :o

Anyway Good Luck to you!
_____________________
* The Particle Laboratory * - One of SecondLife's Oldest Learning Resources.
Free particle, control and targetting scripts. Numerous in-depth visual demonstrations, and multiple sandbox areas.
-
Stop by and try out Jopsy's new "Porgan 1800" an advanced steampunk styled 'particle organ' and the new particle texture store!