Miranda Umino
-
Posts
411 -
Joined
-
Last visited
Content Type
Forums
Blogs
Knowledge Base
Posts posted by Miranda Umino
-
-
Ok , now with this version , you finish your movement where you want .
Nevertheless , your version has again a problem .
What does exactly your prim :
- it rotates around the center of the prim
- it moves the center of the prim from A to B with a straight line
Nevertheless , when you look a door , the center of the door doesn t a movement in a straight line but in a arc of circle .
If you are looking carefully your prim when it rotates, near the axis of rotation , your prim goes in the back while it rotates the half of the rotation . In the real your door is sticked to the axis of rotation.
For instance let s guess your prim goes from < 1,0,0> to <0,1,0> . At the half , your prim is at <0.5,0.5,0>.
A real door should be at <0.707,0.707,0>. So your movement is wrong.
Problem : there are no commands in llsetkeyframedmotion to tell to my prim "do a circle"
Problem 2 : there are no interpolation of curves in llSetKeyframedmotion . And we NEED it
So , you need to create a motion with several keyframes . Each one of translations do an approximation of an arc of circle .
For instance with two steps . you go from <1,0,0> to <0.707,0.707,0> ( first keyframe) and from <0.707,0.707,0> to <0,1,0>
But you can repeat with several steps .
Nevertheless :
1) in every keys , because your translation has a slope different , you will have the feeling it s "jerky" when you go from one key to an another key .
2) more you do some keys , more the movement is realistic . It fits better the movement of rotation between the two points
3) more you do some keys , less the "jerky" effect will be visible , because the difference of slopes between the translations will be smaller
4) unfortunately , you can t repeat this at infinity as in mathematics . Because linden impose 0.1 seconds between every keys . So the soltion of door with llsetkeyframedmotion will have always a "jerky" effect
5) you need to be careful of the time in every keys to be multiple of the time of one frame .
6) more you add keys , more you will have approximations of llsetkeyframedmotion , and more you will have drift . Don t think it s an important drift . It s very light , and for your door , with 2 seconds of rotation you will be limited to 18 keys max , so it won t be important .
But there are some animations who could be more important with sveral thousand of keys .Particulary when the movement does many curves . In this cas , you could have signifant errors
7) May it creates some lag with more keys ? While you build your list of keys certainly , but it s done once time . While the animation is played , i don t know . Maybe yes , maybe no , as the interpolation on the sim is done frame per frame , it has maybe no effects
Finally , the old trick to rotate doors in cutting them by half to have the center of rotation on one side of the prim will be always useful
This is the code to fix the movement of the center of the prim
integer open=FALSE;float angle=PI_BY_TWO; // angle to turn [radians]turn( float ang, float time){ list FrameList; integer maxsteps=(integer)(time * 9); float newtime = maxsteps / 9.0; integer i ; vector v1; rotation deltaRot = llAxisAngle2Rot(llRot2Up(llGetRot()), ang/(float)maxsteps); for ( i = 0; i < maxsteps ; i++) { v1 = 0.5*llGetScale() * llEuler2Rot(< 0,0,i * ang/(float)maxsteps>) * llGetRot(); FrameList += [ v1 * deltaRot - v1 , llEuler2Rot(< 0,0,ang/(float)maxsteps>), newtime/(float)maxsteps ]; } llSetTimerEvent(newtime); llSetKeyframedMotion( FrameList, []); if ( TRUE ) state turning; }default{ state_entry() { llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]); // make client mesh-aware } touch_end(integer total_number) { turn( angle, PI); }}state turning{ timer() { state waitingTouch; }}state waitingTouch{ touch_end(integer t) { llOwnerSay((string)llGetPos()+" "+(string)llGetRot()); angle = - angle; turn( angle, PI); } }
Just for information , i display the rotations and positions to every touchs
I have , for instance
[10:15] Object: <80.78793, 144.08410, 56.51097> <0.18346, 0.01934, 0.57035, 0.80042>
[10:15] Object: <98.93296, 105.77510, 40.66754> <0.11606, 0.14340, -0.16267, 0.96928>
[10:15] Object: <80.78656, 144.08310, 56.51110> <0.18346, 0.01934, 0.57035, 0.80042>
[10:15] Object: <98.93204, 105.77430, 40.66765> <0.11606, 0.14340, -0.16267, 0.96928>
[10:15] Object: <80.78549, 144.08220, 56.51120> <0.18346, 0.01934, 0.57035, 0.80042>
[10:15] Object: <98.93098, 105.77340, 40.66775> <0.11606, 0.14340, -0.16268, 0.96928>
[10:16] Object: <80.78500, 144.08190, 56.51123> <0.18346, 0.01934, 0.57035, 0.80042>As you can see the drift is low but i don t knwow any solutions actually to fix it
-
In fact , in your llsetpos code ,
you do the transformation
llGetRot() * deltaRot so the result is a global rotation in the world. It s normal because llSetRot waits a global rotation
llSetKeyframedMotion seems to do the inverse :
deltaRot * llGetRot() so the result is a local rotation
For instance with an initial rotation of 30 degrees on X-Axis
llGetRot, <0.258819, 0.000000, 0.000000, 0.965926>,
, llRotup, <0.000000, -0.500000, 0.866025>,
, deltaRot, <0.000000, -0.353553, 0.612372, 0.707107>,
, llGetRot*deltarot, <0.183013, -0.183013, 0.683013, 0.683013>,
, deltaror*llGetRot, <0.183013, -0.500000, 0.500000, 0.683013>,after motion<0.18302, -0.49997, 0.49997, 0.68305>
turn( float ang, float time){ llOwnerSay( llList2CSV( [ "llGetRot", llGetRot(), "\n", "llRotup",llRot2Up(llGetRot()), "\n", "deltaRot",llAxisAngle2Rot(llRot2Up(llGetRot()), ang),"\n", "llGetRot*deltarot",llGetRot()*llAxisAngle2Rot(llRot2Up(llGetRot()), ang),"\n", "deltaror*llGetRot",llAxisAngle2Rot(llRot2Up(llGetRot()), ang)*llGetRot(),"\n" ] )); vector v1 = 0.5*llGetScale()*llGetRot(); rotation deltaRot = llAxisAngle2Rot(llRot2Up(llGetRot()), ang); llSetKeyframedMotion([v1*deltaRot-v1, deltaRot, time], []); llSleep(time+1.0); llOwnerSay("after motion"+(string)llGetRot());}
Taken from the wiki http://wiki.secondlife.com/wiki/Rotation
In LSL, the difference between doing a local or global rotation is the order the rotations are evaluated in the statement.
This does a local 30 degree rotation by putting the constant 30 degree rotation to the left of the object's starting rotation (myRot). It is like the first operation in the first example above, just twisting the dart 30 degrees around its own long axis.
rotation localRot = rot30X * myRot; // do a local rotation by multiplying a constant rotation by a world rotation To do a global rotation, use the same rotation values, but in the opposite order. This is like the second operation in the second example, the dart rotating up and to the right around the world X axis. In this case, the existing rotation (myRot) is rotated 30 degrees around the global X axis.
rotation globalRot = myRot * rot30X; // do a global rotation by multiplying a world rotation by a constant rotation Let s guess you want to do the same rotation as in your llsetpos code .You have llGetRot * deltarot = unknownRot * llGetRotDivide per llGetRotllGetRot * deltarot / llGetRot = unknownRot * llGetRot / llGetrot = unknownRotSo you should give as parameter to llSetKeyframedMotion: llGetRot * deltarot / llGetRot for the rotation -
integer open=FALSE;float angle=PI_BY_TWO; // angle to turn [radians]vector T ;rotation R;turn( vector v1, rotation deltaRot , float time){ llSetKeyframedMotion([v1, deltaRot, time], []); llSetTimerEvent(time); if ( TRUE) state turning; }default{ state_entry() { llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]); // make client mesh-aware vector v1 = 0.5*llGetScale()*llGetRot(); rotation deltaRot = llAxisAngle2Rot(llRot2Up(llGetRot()), angle); R = llEuler2Rot(< 0,0,angle>); T = v1*deltaRot-v1; } touch_end(integer total_number) { turn( T, R, 2.0); }}state turning{ timer() { state waiting; }}state waiting{ touch_end(integer t) { T = -T; R = ZERO_ROTATION / R; turn( T, R, 2.0); } }
Avoid to be touched while turning , because it can launch a second animation with wrong initial relative values. If you care , use KFM_COMMAND : the commands KFM_PLAY andKFM_STOP
-
In relative, you need to send
Keyframe 1 : vector T for translation , rotation R , time t1
KeyFrame 2 : Vector -T for translation, ZERO_ROTATION / R, time t2
So Keyframe1 +Keyframe2 = T - T = ZERO_VECTOR for translation, so invariant
R * ZERO_ROTATION / R = ZERO_ROTATION , so invariant
-
No , The third click , in your instance , should have exactly the same inputs that the first click . See my code at teh last post
You compute in using llGetRot , but rotations in llsetkeyframedmotion rotates always relatively with its actual rotation . You don t need llgetrot
-
Not broken in this cas .
Just debug in displayind llOwnerSay(llList2CSV(yourlistofmotions));
You don t send the same informations between the different clicks
For instance with an inital RotX = 30 degrees
list=, <-0.500000, 0.000000, 0.000000>, <0.000000, -0.353553, 0.612372, 0.707107>, 2.000000, 1.570796
[15:01] Object: list=, <0.433013, -0.216531, 0.124957>, <0.353554, 0.530310, -0.306221, 0.707107>, 2.000000, 1.570796
[15:01] Object: list=, <-0.266800, -0.412352, 0.093720>, <0.438756, -0.163451, 0.529884, 0.707107>, 2.000000, 1.570796
[15:01] Object: list=, <0.114807, 0.406020, -0.268267>, <-0.657138, 0.245159, 0.089818, 0.707107>, 2.000000, 1.570796
[15:01] Object: list=, <0.068671, -0.362525, -0.337431>, <-0.100604, -0.486981, 0.502721, 0.707107>, 2.000000, 1.570796
[15:01] Object: list=, <0.145453, 0.005032, 0.478349>, <-0.266578, 0.650714, 0.074215, 0.707107>, 2.000000, 1.570796
[15:01] Object: list=, <0.208265, -0.415030, -0.185406>, <-0.642050, -0.254229, -0.152117, 0.707107>, 2.000000, 1.570796
[15:01] Object: list=, <-0.267259, -0.401657, -0.131317>, <-0.050111, -0.188837, 0.679581, 0.707107>, 2.000000, 1.570796I think you want more something like this
integer open=FALSE;float angle=PI_BY_TWO; // angle to turn [radians]turn( vector v1, float ang, float time){ rotation deltaRot = llEuler2Rot(<0, 0 , ang>); llSetKeyframedMotion([v1, deltaRot, time], []); llOwnerSay(llList2CSV(["list=",v1, deltaRot, time, llRot2Angle(deltaRot)]));}default{ state_entry() { llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]); // make client mesh-aware } touch_end(integer total_number) { open=!open; if (open) turn( 0.5* llGetScale(), angle, 2.0); else turn( -0.5* llGetScale(), -angle, 2.0); }}
Don t forget that your input to llSKFM are relatives , not absolutes
or something like this
integer open=FALSE;float angle=PI_BY_TWO; // angle to turn [radians]vector T ;turn( vector v1, float ang, float time){ rotation deltaRot = llEuler2Rot(<0, 0 , ang>); llSetKeyframedMotion([v1, deltaRot, time], []); llOwnerSay(llList2CSV(["list=",v1, deltaRot, time, llRot2Angle(deltaRot)]));}default{ state_entry() { llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_CONVEX]); // make client mesh-aware T = 0.5* llGetScale() * llGetRot(); } touch_end(integer total_number) { open=!open; if (open) turn( T, angle, 2.0); else turn( -T, -angle, 2.0); }}
-
if you paste a part of your code , we could help you .
if i understand , you have a light drift ? There is one drift who is caused when your framekey is not a multiple of the time of one frame .
For instance :
The sim is ruled with 45 Frames per seconds theorically ( your frame/per seconds of the viewer is not important . The variable frames per seconds of the sim is not important neither. Only the FPS theoric is important . On the grids of secondlife its always 45 FPS .But there are some grids with OpenSim where the theoric FPS is 50 FPS . Nevertheless , llSetKeyFramedMotion is not implemented yet in these grids ).
You anime 10 meters in one axis in 2 seconds and 10 meters in the opposite axis in 0.7 seconds. Theorically at the end of the animation you should have kept the same position.
But 0.7 seconds = 31.5 frame . 31.5 is not integer , so the decimal part of 31.5 is not played . So you loose the information of movement of 0.5 frame .
The velocity of your prim is 10 m / 0.7 seconds = 14.2857 m/sec
0.5 frame at this velocity = (14.2857 * 0.5 ) / 45 = 0.1587 m. It explains your drift
To fix it , change 0.5 seconds by 22.0/45.0 or 23.0/45.0. It s very near of 0.5 seconds , but it will fix your main shift .
Now after to have fixed this , you should see again a shift . But very low for a cube 0.5 m with a motion of 10 m . Something like 0.001 meters . It exists too a shift about rotations . Sometimes it can reach 0.02 degrees per keyframe ..
Now i ve readen you move only of 0.1 meters .. Maybe you could watch again a drift important . I guess , but i am not sure that , it s because the sim doesn t handle positions with full precisions but with a gap .
when the items are small or keymotion are small, every frame , the position is rounded to stick at the grid of the sim .
And finally after several frames there is a drift important .
It s just an intuition . I need to prove it mathematically
The third drift who can exist is because your velocity is too low . For instance your animmation goes 0.1 meter on X axis in 4 seconds and -0.1 meter in the opposed axis X quicly below the second . And you loop your animation .. In reality , only some frames are played in the first part of the loop and it does 0. 022 meter on the X positive axis and 0.1 meter on the X negative axis /
The fourth drift i know is to touch your prim when it moves . There is no BLOCK_GRAB status . There are no llTouchFilter as it exists llCollisionFilter, and your motion is altered
Well .. It does many problems . And there are other things not explained
-
Well .. if your script was what you have wanted , its perfect.
I ve just said that because your script does 75 degrees in 20 seconds .
With 5 steps it should do 15 degrees in 4 seconds per step.
But when i run your script it does 5-6 degrees and stops , wait the rest of the time until 5 seconds,
resumes and oes 5-6 degrees again and stops , wait the rest of the time until 5 seconds etc ...
.. And this 5 fimes ..
and finally the rotation is repositionned with llsetpos in doing more than45 degres in one call .
I tell you just what i have in my screen ..You may check your llGetRot each 4 seconds to verify .
In fact i see each keyframe has been stopped . But of course a keyframe stopped doesn t stop the whole list of keyframes . So , no : low velocities don t work in several keyframes. Rotation of PI radians in 19 seconds is not halted . Rotation of PI/12 radians in 2 seconds is halted
-
llTargetOmega(ZERO_VECTOR,0.0,0.0);
-
Thank for your script cerise .
If you allow me some remarks :
- probably your script could be simpler and easier if you didn t use llSetKeyFramedMotion but if you play with Omega
- your rotation is slow, jerky and halted in every steps . You are doing several steps , but every step is halted before its end . Be aware , because llSetKeyFramedMotion is bugged for rotation with angular velocity below 0.16 rad/seconds (around 9-10 degrees /seconds). The rotation is stopped when it s below.
see https://jira.secondlife.com/browse/SVC-7471
note the bug is related by the angular velocity of the frame , not directly the angle or the time of the frame
- if you right click when your motion is paused , it will continue its movement , and your initial rotation of the bridge is lost. Use KMD_CMD_STOP in replacement
-
It should be proved that llSetLinkPrimitiveParamsFast will be lighter in THIS paticular case
Firstly , the prim doesn t need the collisions . So it s possible to filter out all collisions out with llColisionFilter.
Secondly, there are several ways to move vertically :
- llSetBuoyancy with llMoveToTarget
- llSetHoverHeight and llStopHover
- llGroundRepel
- and the last llSetPhysicsMaterial( integer material_bits, float gravity_multiplier, float restitution, float friction, float density ) with a very low gravity , sometimes = 0 sometimes negative . You may change the density to change the mass of the object too ( sorry, the wiki page doesn t exist )
Each physical function has not the same weight to loead in the server . Probably i would avoid llMoveToTarget.
llSetPhysicsMaterial is great : it consumes very few Energy even with a 64*64*64 prim
If we just want the effect of levitation but we don t care with exactitude the final height , physics are great . It doesn t a linear movement with constant velocity and so it can be nicer to watch . To add , to have a smooth movement will llSetLinkPrimitiveParams you need to spam and to grow up the number of events per seconds .
-
I remember an old bug when you change states inside the touch_start event , you loose one click .
Replace touch_starrt by touch_end and try again
- 1
-
I guess you meet this actual bug ( an old bug)
https://jira.secondlife.com/browse/SVC-4143
Your furnitures are maybe no-modify and when their scripts are disabled by the estate menu , thay can t be renabled
-
llGetMass and llGetMassMKS return a 32 bit float not a 32 bit integer .
You can have some floats superior to 2^32.
I ve done a quick test with a cube 64 * 64 *64 with the max density ( max density is actually at 22587.000 kg / m3 .
llGetMass returns 59210464.000000 and llGetMassMKS 5921046528.000000
I ve done a second test with a cube 64 * 64 *64 with a density not mutiple of kg/m3 .
For instance , for density = 1.235 , the theoric value is 323747,84
llGetMass returns 3237.478271 and llGetMassMKS 323747.843750
Well , the both are wrong ...
Now , do a shear of 0.5 on X ;
if you remember your geometry courses, the number of m3 doesn t change : llGetMass returns 3 3237.480225 and llGetMassMKS 323748.031250
It s bugged ..
-
The both .. It s a market ..
Let stake a simple instance :
you have a friend who has 1012 m² and he pays fees . Fees are 8 $ for 1012 m²
you want a parcel of 512 m² . Fees are 5 $ for 512 m² .
But your friend doesn t need anymore 1024 , and 512 are enough for him .
If he offers you to rent 512 m² for a price-equivalent-lindens-to-dollars superior to 5$ on his parcel , you won t be interested . Because you pay more with him than buying .
If he offers you to rent 512 m² for a price-equivalent-lindens-to-dollars inferior to 3$ on his parcel , he won t be interested . Because he will have only 512 m$ , pays 8$ fees , and has less 3$ income , so a balance superior to 5$ . It s more advantageous for him to give up his 1024 m² and buy a 512 m².
If he offers you to rent 512m² for a price-equivalent-lindens-to-dollars between the two limits 3$ and 5$ , for instance 4 .5 $ : You will pay with renting less with him than buying . You spend 0.5 $ less.
And on his side , he will pay 8$ fees but will earn 4.5$ for renting from you . So the 512 m² he has kept he would spend only 8-4.5= 3.5 $
This instance is showing than the both , the one who is renting and the one who is buying , spend less money together .
Of course , the one who is buying can have a little advantage because he can spend less money than the one who is renting . But he has some risks too ( for instance you dissolve your contract )
An another point :
You have said
"Someone else said to me that renting is so much easier and cheaper?"
I m not convinced by "it s easier" . Of course you don t need to manage your land when you rent . Nevertheless it s a lack of rights that you give up to the one one you rent . You are less free to do everything you want to do on your land if you rent it . It s more , in my opinion a disadvantage
-
You don t need thread for what you want to do .
If I ve understood , you want a synchrone execution and not an asynchrone execution .
So for this , you need to trigger the next event inside the current event itself . Imagine to program recursively.
In your instance , inside sensor/no_sensor event , you call a function who will move to the next position and who will call llSensor
This is an instance of coe
movingSynchrone(vector dest){ while ( llGetPos() != dest ) llSetPos(dest); llSensor("","",PASSIVE,5.0,PI); }vector nextIter(){ if ( iteratorCurrent.x >= iteratorEnd.x ) { if ( iteratorCurrent.y < iteratorEnd.y ) { iteratorCurrent.x = iteratorBegin.x; iteratorCurrent.y += iteratorStep.y; } else { } } else { iteratorCurrent.x += iteratorStep.x; } return iteratorCurrent; }doJob(vector v){ llOwnerSay("i m working on "+ (string)v);}doJobAndNext(vector v){ doJob(v); vector v = nextIter(); if ( v != iteratorEnd ) movingSynchrone( v ); else endProgram(); }endProgram(){ iteratorBegin = ZERO_VECTOR; llOwnerSay("Program has finished ");}vector iteratorBegin = ZERO_VECTOR;vector iteratorStep = <2,1.5,0>;vector iteratorEnd = iteratorBegin ;vector iteratorCurrent;default{ touch_start(integer total_number) { iteratorBegin += llGetPos(); iteratorEnd = iteratorBegin ; iteratorEnd.x += 5 * iteratorStep.x ; iteratorEnd.y += 8 * iteratorStep.y ; iteratorCurrent = iteratorBegin; doJobAndNext( iteratorCurrent); } sensor(integer n) { doJobAndNext( iteratorCurrent); } no_sensor() { doJobAndNext( iteratorCurrent); } }
Note : for physical moves , you should inside the sensor event call a function who will move your prim. and it s at the moving_end or at_target event who you will call llsensor event
-
Hi Kaluura,
would you have better precision in replacing your function by this one :
I ve changed the loop
uuMakeCurve(rotation rot, integer dir, float angle, float radius, float steps, float time){ // dir: 1 = left, -1 = right // angle: in degrees // time = total time // vector offset = <-radius, 0.0, 0.0> * (llEuler2Rot(<0.0, 0.0, dir * PI_BY_TWO>) * rot); // Offset from relative center of the arc of circle time = 10.0/45.0; // Time for each step //angle = (angle * DEG_TO_RAD * dir) / steps; // Arc of circle for each step angle = (angle * DEG_TO_RAD ) * (float)dir / steps; // Arc of circle for each step rot = llEuler2Rot(<0.0, 0.0, angle>); // Relative rotation for each step FrameList = []; integer i = 1; // Don't re-do step 0! for (; i <= (integer)steps; ++i) { // the offset is now defined as the precedent rotated vector vector move = offset ; offset = offset * llEuler2Rot(<0.0, 0.0, angle >) ; move = offset - move; // Original Code // vector move = (offset * llEuler2Rot(<0.0, 0.0, angle * (float)i>)) // - (offset * llEuler2Rot(<0.0, 0.0, angle * (float)(i - 1)>)); // Relative movement from previous pos to current one. FrameList += [move, rot, time]; } }
This one avoids some compute of rotations . It keeps the old vector rotated , compute the new vector rotated and does the difference
-
Hi marilyn , have you changed PRIM_POSITION by PRIM_POS_LOCAL ?
Convert after to region ccordinates withe the pos of the root
-
It s not a rotation .
It s just a polygon you are drawing .
I am stupefied to see there are not curves interpolation .
I can t believe that Havok 7 has no function to deal with this . And i don t understand why Linden have not given this feature .
Why should it be the scripter to compute ( and compute badly ) the movements .....
failed ...
-
With SL3 , put the attributes of gravity to 0 .
So , it will move only on the XY plane
And on LSL use PRIM_PHYSICS_MATERIAL inside llSetLinkPrimitiveParamsFast
PRIM_PHYSICS_MATERIAL 31 Sets the prim's physics material properties. [ PRIM_PHYSICS_MATERIAL, integer material_bits, float gravity_multiplier, float restitution, float friction, float density ] -
Other idea :
string MSG_1 = "get lost";string QUESTION_1 = "You seriously want me to get lost?";string MSG_2 = "Ok then..";string MSG_3 = "Then why did you tell me t- >.< nvm...";string MSG_4 = "go away";string QUESTION_2 = "You really want me to go away?";string MSG_5 = "Ok";string MSG_6 = "Jeez, such a dolt, make up your mind already!";string YES ="yes";string NO ="no";default{ state_entry() { llOwnerSay( (string)llGetUsedMemory()); llListen(0,"", llGetOwner(), MSG_1); llListen(0,"", llGetOwner(), MSG_4); } listen(integer channel, string name, key id, string message) { if ( message == MSG_1) state getLost; else state goAway; }}state getLost{ state_entry() { llSay(0, QUESTION_1); llListen(0,"", llGetOwner(), YES); llListen(0,"", llGetOwner(), NO); } listen(integer channel, string name, key id, string message) { if (message == YES ) llSay(0, MSG_2); else llSay(0, MSG_3); state default; }}state goAway{ state_entry() { llSay(0, QUESTION_2); llListen(0,"", llGetOwner(), YES); llListen(0,"", llGetOwner(), NO); } listen(integer channel, string name, key id, string message) { if (message == YES ) llSay(0, MSG_5); else llSay(0, MSG_6); state default; } }
-
Other idea :
string MSG_1 = "get lost";string QUESTION_1 = "You seriously want me to get lost?";string MSG_2 = "Ok then..";string MSG_3 = "Then why did you tell me t- >.< nvm...";string MSG_4 = "go away";string QUESTION_2 = "You really want me to go away?";string MSG_5 = "Ok";string MSG_6 = "Jeez, such a dolt, make up your mind already!";string YES ="yes";string NO ="no";default{ state_entry() { llOwnerSay( (string)llGetUsedMemory()); llListen(0,"", llGetOwner(), MSG_1); llListen(0,"", llGetOwner(), MSG_4); } listen(integer channel, string name, key id, string message) { if ( message == MSG_1) state getLost; else state goAway; }}state getLost{ state_entry() { llSay(0, QUESTION_1); llListen(0,"", llGetOwner(), YES); llListen(0,"", llGetOwner(), NO); } listen(integer channel, string name, key id, string message) { if (message == YES ) llSay(0, MSG_2); else llSay(0, MSG_3); state default; }}state goAway{ state_entry() { llSay(0, QUESTION_2); llListen(0,"", llGetOwner(), YES); llListen(0,"", llGetOwner(), NO); } listen(integer channel, string name, key id, string message) { if (message == YES ) llSay(0, MSG_5); else llSay(0, MSG_6); state default; } }
-
I m not sure :
some people may be offline when you give their acces code , and the IMs are sent to the box mail if people authorize them
By default , it s authorized , and probably few people will tell you they didn t receive your access code , but it can happen . Be aware about this .
There is too the email solution , but it s not in-world .
And there is the new possibilty to send messages via https://my.secondlife.com ; but , people may accept the messages only from their friends .
-
I m not sure :
some people may be offline when you give their acces code , and the IMs are sent to the box mail if people authorize them
By default , it s authorized , and probably few people will tell you they didn t receive your access code , but it can happen . Be aware about this .
There is too the email solution , but it s not in-world .
And there is the new possibilty to send messages via https://my.secondlife.com ; but , people may accept the messages only from their friends .
LlSetKeyframedMotion for Linked prim
in LSL Scripting
Posted
You write
iv= llCeil(time*45)/45
But , 45 is an integer typed . So the result of the division will be an integer ( even if the result is stored in a float)
Fot time = 0.5 , iv = 0.0000 with this formula .
You need to force the division in float
either by
iv= llCeil(time*45)/45.0
either by
iv= llCeil(time*45)/(float)45