Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

How to make a smoothly wagging tail?

Nepenthes Ixchel
Broadly Offended.
Join date: 6 Dec 2005
Posts: 696
03-12-2006 02:38
How can I make an attached tail smoothly wag? llSetLocalRot() produces jerky movements, but llRotLookAt won't work on attachments. I've seen smotthly moving prim tails.. what rotation command is used to get the effect?
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
03-12-2006 04:43
There are a couple of other ways you can try: I've not tried either but they might work.

One would be flicking between multiple alphad out sets of tails, but that's probably not entirely smooth.

Another that might work would be similar to the cones with animated textures used for hair ribbons and things.

No promises mind, but they're alternatives that might work.
Exile Loudon
Aspiring Scripter
Join date: 10 Dec 2005
Posts: 122
03-12-2006 05:00
Well, I think you should wait until the havoc 2 engine is introduced to SL, or they just fully use all the potential of the havoc engine, and the physics will be possible. I saw another thread with a Linden who had a tail that moved freely with no lag or mess ups, and supposedly he was trying to show an example of the havoc 2 engine. If I tried making a tail, I wouldn't try wagging, I would just make a bunch of prims (around 20 or 30) and connect them through hinges, then have the prim follow me on a tight and quick sensor. This probably still wouldn't work very well, and would take forever to setup correctly.
AJ DaSilva
woz ere
Join date: 15 Jun 2005
Posts: 1,993
03-12-2006 06:06
Here's the flexible tail video: http://media.putfile.com/redtail

IIRC it's gonna be a property checkbox and it's all calculated client-side, so it's not part of the new Havok implimentation. Unfortunatly, nobody seems to know if/when it'll get implimented.

My best guess for a wagging animation would be to use llTargetOmega and switch between positive and negative values on a timer.
Dyne Talamasca
Noneuclidean Love Polygon
Join date: 9 Oct 2005
Posts: 436
03-12-2006 10:37
From: AJ DaSilva
My best guess for a wagging animation would be to use llTargetOmega and switch between positive and negative values on a timer.


That's essentially what I've seen in the one (1) example of a reasonably convincing tail in SL.

I think that you could use llSet(Local)Rot at the end of each direction to put the tail into a known position (because TargetOmega doesn't guarantee position), but I haven't tested it.
_____________________
Dyne Talamasca - I hate the word "bling".

Miscellany on MySLShop.com, SLB, and SLEx

Plonk
AJ DaSilva
woz ere
Join date: 15 Jun 2005
Posts: 1,993
03-12-2006 10:50
From: Dyne Talamasca
I think that you could use llSet(Local)Rot at the end of each direction to put the tail into a known position (because TargetOmega doesn't guarantee position), but I haven't tested it.
Just looked in the wiki and you'll definately have to do something like this since calling llTargetOmega resets the client side rotation.
Nepenthes Ixchel
Broadly Offended.
Join date: 6 Dec 2005
Posts: 696
03-12-2006 13:34
Well, if llTargetOmega is the only way to get smooth attachment movement I'll just have to make it work.

From: AJ DaSilva
Here's the flexible tail video: http://media.putfile.com/redtail

IIRC it's gonna be a property checkbox and it's all calculated client-side, so it's not part of the new Havok implimentation. Unfortunatly, nobody seems to know if/when it'll get implimented.


Does anyone have any more information on this? Is it like the Quicktime-on-faces thing from Silver Bells/Golden Spurs, a feature sitting in the Linden's cupboard that looks awesome but may never be implemented due to issues that aren't apparent by looking at the video sample?
Starchaser Webb
Artist / Builder
Join date: 23 Feb 2006
Posts: 30
03-13-2006 05:42
Ceera Murakami gave me a 'wag' script that someone gave her. As far as I know, it's free, and should work with a standard prim tail. Just drop this script into the tail.

I have seen this in use on Ceera's tail, and what it does is produce a fairly smooth back and forth wag a couple of times, then a pause, and repeats.

I haven't tried it on my own tail, because I use a Lost Furrest avatar that has a tail which actually has two positions, only one of which is visible at a time. I haven't wanted to interfere with its existing scripting.

CODE
vector start;
tailwag()
{
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <-20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <-20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <-20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <-20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <-20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <-20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <-20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <-20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <-20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <-20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <20, 0, 0>)));
llSetRot(llEuler2Rot(DEG_TO_RAD*(start)));
}
default
{
state_entry()
{
start = (RAD_TO_DEG*llRot2Euler(llGetLocalRot()));
llSetTimerEvent(10 + llFrand(10));
}
timer()
{
tailwag();
llSetTimerEvent(10 + llFrand(10));
}
}
Adman Drake
Registered User
Join date: 9 Feb 2006
Posts: 96
03-13-2006 13:09
From: Starchaser Webb

llSetRot(llEuler2Rot(DEG_TO_RAD*((RAD_TO_DEG*llRot2Euler(llGetLocalRot()))+ <-20, 0, 0>;)));


I've seen someone post this mess before... it makes my eyes bleed.

Surely it can be rewritten...? Maybe:

llSetRot(llGetLocalRot() + llEuler2Rot(<-20 * DEG_TO_RAD, 0, 0>;));

?
Ceera Murakami
Texture Artist / Builder
Join date: 9 Sep 2005
Posts: 7,750
03-13-2006 13:53
Well, I wouldn't exactly call it efficient coding, but it works. What the heck, it's something someone gave me, almost off the cuff. If someone wants to code and post a more elegant wag script, I'd be glad to try it. :D
_____________________
Sorry, LL won't let me tell you where I sell my textures and where I offer my services as a sim builder. Ask me in-world.
Nepenthes Ixchel
Broadly Offended.
Join date: 6 Dec 2005
Posts: 696
03-15-2006 03:28
From: Ceera Murakami
If someone wants to code and post a more elegant wag script, I'd be glad to try it. :D


Done!

CODE

// SMooth Tail proof-of-concept
// Code by Nepenthes Ixchel
// Released under the GPL, so do what you like provided it remains copy/mod/trans with this notice in.
//
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.



//user variables, set manually
float MaxRot=30; //in degrees
float swingtime=2.0; //seconds for a swing from centre to MaxRot

//runtime variable
rotation gBaseRot=ZERO_ROTATION;

debugSay(string _str)
{
llSay(0,_str);
}

default
{
state_entry()
{
llListen(0,"",llGetOwner(),"wag");
}
listen (integer x, string n, key k, string m){
state wag;
}
}

state wag
{
state_entry()
{
gBaseRot=llGetLocalRot();
debugSay("starting wag sequence");
vector RotAxis=llRot2Up(llGetLocalRot()); // maybe.
float RotRate=(MaxRot*DEG_TO_RAD)/swingtime;
//Swing up
llTargetOmega(RotAxis,RotRate,1);
llSleep(-0.2+swingtime);
llSetLocalRot(gBaseRot*llAxisAngle2Rot(RotAxis,MaxRot*DEG_TO_RAD));

//swing to other side
llTargetOmega(RotAxis,-1*RotRate,1);
llSleep(-0.2+(swingtime*2));
llSetLocalRot(gBaseRot*llAxisAngle2Rot(RotAxis,-1*MaxRot*DEG_TO_RAD));

//And back to centre
llTargetOmega(RotAxis,RotRate,1);
llSleep(-0.2+swingtime);
llSetLocalRot(gBaseRot);

//stop rotation
llTargetOmega(RotAxis,0,0);
llSetRot(gBaseRot);
state default;
}
}


Put that in, say "wag" and watch the tail wag once, rotated around the root prims local Z-axis. And the really amazing thing? I got all the rotation stuff right first go! Normally I spend ages getting things to rotate correctly, but all the work I did with with my personal Rez-Foo alternative has really helped me manage geometry in a script.
Ceera Murakami
Texture Artist / Builder
Join date: 9 Sep 2005
Posts: 7,750
03-15-2006 04:56
From: Nepenthes Ixchel
Done!

{Code provided}

Put that in, say "wag" and watch the tail wag once, rotated around the root prims local Z-axis. And the really amazing thing? I got all the rotation stuff right first go! Normally I spend ages getting things to rotate correctly, but all the work I did with with my personal Rez-Foo alternative has really helped me manage geometry in a script.


Thank you!

OK, after the update for the client rolls out today, I'll give that a try. Maybe we can add the time delay from the other wag script, to make the tail sway on it's own occasionally, when you're not paying attention to it? Though I rather like the idea of a 'wag on command' as well, and that could be moved to a listen chanel in a final version, to reduce chat spamming.
_____________________
Sorry, LL won't let me tell you where I sell my textures and where I offer my services as a sim builder. Ask me in-world.
Nepenthes Ixchel
Broadly Offended.
Join date: 6 Dec 2005
Posts: 696
03-15-2006 05:07
From: Ceera Murakami
Thank you!

OK, after the update for the client rolls out today, I'll give that a try. Maybe we can add the time delay from the other wag script, to make the tail sway on it's own occasionally, when you're not paying attention to it? Though I rather like the idea of a 'wag on command' as well, and that could be moved to a listen chanel in a final version, to reduce chat spamming.


It's pretty easy to move from what I posted to one that moves continuously, and shows/hides prims as appropriate.

Hint: If the tail stops working, and you're really tired, you might forget that llTargetOmega() wont work when the object is select with the edit box. if this happens, do not try to debug the code, and do not enable physics and throw the tail out of your skybox window in anger.
Charlotta Broadbent
Registered User
Join date: 19 Jul 2006
Posts: 4
very nice script
07-23-2006 16:53
I used that tailwagging script to make curtains that move gently in a breeze. Just copied the scipt into the prim file and then fiddled with rotation/flexilibity settings to get what I wanted.

THANKS!!