Join us in Outworldz at www.outworldz.com:9000 or follow us:

Teaching a fish to swim in Second Life™

Now that you have recorded all the motions of the whale flippers, and have a working whale that runs around in circles, sprays, and spouts, it is time to make it all play together!

This next script will animate the whale flippers.   Put this script into the root prim.  It is a stripped down recorder script.  It does not have all the extra stuff to record motion.  It has a timer that will make  the flipper move every second or so.

Download


// User settable parameters:
float FLIPTIME = 1.5;  // how often the tail moves, floating point.
string NOTECARD = "Movement";   // the notecard name, you can add any number of Note cards 


// global variables below - no need to modify

// These are for notecard reading
integer iIndexLines;
integer i = 0;
integer iMove;               // N movements rea from the notecard
key kNoteCardLines;        		// the key of the notecard
key kGetIndexLines;        		// the key of the current line

// misc
list masterlist; // the list of coords, filled in by a notecard reader
integer tailcounter = 0; // this counter flips the tail up and down
integer STRIDE = 6;	// the list we record contains  6 pieces of info

// subroutine to remove any white space before or after a string
string strip(string str)
{
	return llStringTrim(str, STRING_TRIM);
}

// subroutine to get a line at index 'line' from list Input, and strip white space b4 or after
string Getline(list Input, integer line)
{
	return strip(llList2String(Input, line));
}

// subroutine to Play Back a named animation
PlayBack (string name)
{
	integer i;
	integer iMax = llGetListLength(masterlist);		
	// how many are in the list? we need this to know when to stop
	// scan the entire array for the named animation
	for (i = 0; i < iMax; i+= STRIDE)
	{
		string aniname2 = llList2String(masterlist,i);
		if (aniname2 == name)
		{
			// convert each list element into a loal variable
			float fPrimnum = llList2Float(masterlist,i+1);
			vector  vPrimpos  = llList2Vector(masterlist,i+2);
			rotation rPrimrot = llList2Rot(masterlist,i+3) ;
			string  sMsg = llList2String(masterlist,i+4);
			string sUUID = llList2String(masterlist,i+5);

			if (llStringLength(sMsg) > 0)
				llSay(0,sMsg);		// chat any text we find
			if (llStringLength(sUUID) > 0)
				llPlaySound(sUUID,1.0);	// play any sound we find

			if (fPrimnum < 0)
			{
				llSleep(-fPrimnum); // sleep the interval in the notecard
			}
			else
			{
				rPrimrot /=  llGetRot();       // Add in the local rot

				if (fPrimnum != 0)
					llSetLinkPrimitiveParamsFast((integer) fPrimnum,
					[PRIM_POSITION,vPrimpos,PRIM_ROTATION,rPrimrot]);
			}
		}
	}
}


default
{
	state_entry()
	{
		kNoteCardLines = llGetNumberOfNotecardLines(NOTECARD);
		kGetIndexLines = llGetNotecardLine(NOTECARD,0);
	}

	// read notecard on reset, once.  We store this in RAM and never reset again
	dataserver(key kQueryid, string sData)
	{
		if (kQueryid == kNoteCardLines)
			iIndexLines = (integer) sData;

		if (kQueryid == kGetIndexLines)
		{
			if (sData != EOF)
			{
				// read and parse the notecard line into a list of items
				kQueryid = llGetNotecardLine(NOTECARD, i);
				list lLine = (llParseString2List(sData, ["|"], []));

				// pull each element from the notecard list so we can store it in the proper format
				string junk = llList2String(lLine,0); // this is the time/date field 
				and object name that was chatted into the notecard
				string sAniname = llList2String(lLine,1);		// the name of the animation
				integer iNum = (integer)Getline(lLine,2);		// the prim link number
				vector vPos = (vector) Getline(lLine,3);			// the position
				rotation rRot = (rotation) Getline(lLine,4);		// the rotation
				string sMsg = llList2String(lLine,5);			// optional chat string
				string sUUID = llList2String(lLine,6);			// option sound name or UUID

				if(iNum > 1)	// skip the root prim! we don't want to move it
				{
					if (llStringLength(sMsg) > 0)
						llSay(0,sMsg);		// chat any text in this notecard
					if (llStringLength(sUUID) > 0)
						llPlaySound(sUUID,1.0);	// play any sound we find in the notecard

					masterlist += [sAniname];
					masterlist += [iNum];
					masterlist += [vPos];
					masterlist += [rRot];
					masterlist += [sMsg];
					masterlist += [sUUID];
					rRot /= llGetRot();		// remove our current rotation, by subtracting.. 
						yes, a divide is a subtract in vector math

					llSetLinkPrimitiveParamsFast(Num,[PRIM_POSITION,Pos,PRIM_ROTATION,Rot]);
					iMove++;			// count the real movement
				}
				i++;
				integer     iInitPerCent = (integer) llRound(( (i+1) / (float) iIndexLines) * 100);
				llSetText("Initialising... \n" + (string) iInitPerCent + "%" , <1,1,1>, 1.0);
				if (iInitPerCent == 100)
					llSetText(""  , <1,1,1>, 1.0);
				kGetIndexLines = llGetNotecardLine(NOTECARD,i);
			}
			else
			{
				llOwnerSay("initialized with " + (string) iMove + " movements");
				llSetText(""  , <1,1,1>, 1.0);
				// start the whale flipping the tail every so often
				llSetTimerEvent(FLIPTIME);
			}
		}
	}


	// The timer code moves the prim up and down
	timer()
	{
		if (tailcounter ++ %2 == 0)
			PlayBack("up");
		else
			PlayBack("down");

	}
			

I hope your pet is swimming away for years and years like ours has!

Back to the Best Free Tools in Second Life and OpenSim.