This was written by Nikkesa:
integer timer_on = 0;
list newPositions; //the list of positions to apply to the segments
list newRotations; //the list of rotations to apply to the segments
float curve_location_x = 360; //the position we are on the curve...
float distance_between_segments = 0.1; //the distance between each segment
vector segment_size = <0.01,0.1,0.1>;
//let's start setting this **bleep**...
//Note: may want to incorporate support for different types of segments, such as if we had 3 different cones per segment...
integer number_of_segments;
list command_list;
integer i;
float counter = 0;
//setup
vector position_offset;
//part 1
float myAngle1; //the new angle thingy... used later
//part 3
rotation rotation_between; //the rotation between two segments...
vector childPos1;
vector childPos2;
vector newValue;
////////////////////////////
list position_cache;
list rotation_cache;
integer toggle_building_setting = 0;
///////////////////////////
vector childPos(integer segment_id){
return llList2Vector( llGetLinkPrimitiveParams(segment_id, [PRIM_POSITION] ), 0 );
}
rotation childRot(integer segment_id){
return llList2Rot(llGetLinkPrimitiveParams(segment_id, [PRIM_ROT_LOCAL]), 0);
}
vector childPosLocal(integer segment_id){
return llList2Vector(llGetLinkPrimitiveParams(segment_id,[PRIM_POSITION]), 0) - llGetPos();
}
vector buildPositionOffset(rotation rotation_amount, vector current_position, vector axis_position, rotation base_rotation){
//builds the position offset relative to the rotation_amount relative to the base_rotation (which should be the root prims rotation)
return ((axis_position - current_position) - ((axis_position - current_position) * rotation_amount)) * base_rotation;
//this will return the amount we have to move Smiley Very Happy
}
list fix_position_offsets(list myList, float limit_distance){
//in here we want to basically scale the distance between segments so that it's always the same...
list newList = myList;
integer j=1;
vector segmentPos1;
vector segmentPos2;
vector vector_between;
float distance_between;
for (;j 0) return 1;
if (input ><0) return -1;
return 0;
}
/*
OKAY, NEW PLAN
--------------
We are going to pre-cache all of the positions and rotations for the animation sequence,
and apply them over the animation sequence!
so yeah, whatever.
*/
default
{
state_entry()
{
integer i = 2;
for (;i<=llGetNumberOfPrims();i++){
llSetLinkPrimitiveParamsFast(i,[PRIM_POS_LOCAL,<(float)(i-1) * distance_between_segments,0.0,0.0>,PRIM_ROT_LOCAL,ZERO_ROTATION, PRIM_SIZE, segment_size * i/(i+1)]);
}
number_of_segments = llGetNumberOfPrims() - 1;
//we want to ignore any avatars,especially in case of attachment and such...
if (number_of_segments > 1){
while (llGetAgentSize(llGetLinkKey(number_of_segments))){
--number_of_segments;
}
}
}
touch_start(integer total_number)
{
if (llDetectedKey(0) == llGetOwner()){
if (timer_on == 0){
timer_on = 1;
llSetTimerEvent(0.04);
} else {
timer_on = 0;
llSetTimerEvent(0.0);
llResetScript();
}
}
// let us start the building of the cache.
}
timer(){
i = 0;
counter++;
if (toggle_building_setting == 0)
{
curve_location_x = curve_location_x - 12;
if (curve_location_x ><= -1) {
curve_location_x = 360;
llOwnerSay("Done Caching... " + (string)counter);
counter = 0;
toggle_building_setting = 1;
}
command_list = [];
newPositions = [];
newRotations = [];
for (;i < number_of_segments;i++){
//part 1 - set up the new positions for each segment.
//use i+2
myAngle1 = llSin(( (float)(i+2) * (PI/2 / number_of_segments) )+( curve_location_x*TWO_PI/360 )) * 0.5;
newValue = (llGetPos() - childPos(i+2));
//llOwnerSay((string)myAngle1);
//newPositions += [<(float)(i+2)/(1 / distance_between_segments*0.9),0.0,0.0> + <0.0,llVecMag(newValue) * llSin(myAngle1),0.0>];
newPositions += [<(float)(i+2)/(1 / distance_between_segments),0.0,0.0> + ((newValue) - (newValue * llEuler2Rot( <0.0,0.0,myAngle1> ))) + 0><0.0,0.0,(llCos((TWO_PI * 3/4) * ((float)1 / (float)26) * (float)i) - 1)/2>];
//newPositions += [<(float)(i+2)/(distance_between_segments),0.0,0.0> + buildPositionOffset(llEuler2Rot( <0.0,myAngle1,myAngle1> ),childPos(i+2), llGetPos(),llGetRot())];
//newPositions += [<(1/distance_between_segments)*(curve_location_x/360)*i,0.0,0.0>];
//part 3 - set the rotations of the tail segments
/*
*/
//part 4 - build the command list for our setlinkprimparamsfast function
//
}
newPositions = fix_position_offsets(newPositions, distance_between_segments);
i = 0;
for (;i, childPos2 - childPos1);
newRotations += [rotation_between];
}
rotation_cache += newRotations;
} else {
if (counter == 30){
counter = 0;
}
i = 0;
command_list = [];
for (;i