Jump to content

An old query but hard to find a solution!


SerenaPufnstuf
 Share

You are about to reply to a thread that has been inactive for 1144 days.

Please take a moment to consider if this thread is worth bumping.

Recommended Posts

Look at llSetLinkPrimitiveParamsFast, and at PRIM_POS_LOCAL and PRIM_ROT_LOCAL as the two that you will be changing.

You'll want to use llGetLinkPrimitiveParams(lid, [PRIM_POS_LOCAL, PRM_ROT_LOCAL]) first to get the values for those two when the link number accessed by lid is closed, then again when it is moved to where you want it to be when open.

Link to comment
Share on other sites

There isn't much difference between scripting a linkset comprising just prims and one comprising just mesh, you have to work out the link number of the children and the sets of positions corresponding to open and closed.

 

Drop this in your linkset (warning, not tested inworld) and touch each child to see what the number and local values are.

// identify child prims and positions

key owner;

getChildDetails(integer which)
{
	list params = llGetLinkPrimitiveParams(which, [PRIM_POS_LOCAL, PRIM_ROT_LOCAL]);
	vector localPos = llList2Vector(params, 0);
	rotation localRot = llList2Rot(params,1);
	vector angle = llRot2Euler(localRot) * RAD_TO_DEG;

	llOwnerSay("Child " + (string) which + " pos " + (string) localPos + " rot " + (string) localRot + " degrees " + (string) angle);

}

default
{
	state_entry()
	{
		owner = llGetOwner();
	}
	touch_start(integer touches)
	{
		key toucher = llDetectedKey(touches - 1);
		integer whichChild = llDetectedLinkNumber(touches - 1);
		if( toucher == owner) getChildDetails(whichChild);
	}
}

 

Edited by Profaitchikenz Haiku
typos in script
  • Like 1
Link to comment
Share on other sites

you could use one of the many scripts in the pinned door post,  Door Scripts

or try this one... ( you can change the rotation vector to fit your needs )

/*
 * Smooth Rotating Linked Door With Hinge
 *
 * By: Lyn Mimistrobell
 * Version: 1.1
 * License: Do whatever you like with it, just don't blame me if you break it :)
 */
vector      ROTATION            = <0.0, 0.0, 80.0>;
vector      HINGE_POSITION      = <-0.8, 0.05, 0.0>; 
integer     gClosed = TRUE;     // Door state: TRUE = closed, FALSE = opened
rotation    gRotationClosed;    // Initial rotation of the door (closed)
vector      gPositionClosed;    // Initial position of the door (closed)

doOpenOrClose()
 {  integer linkNumber = llGetLinkNumber();
    if (gClosed)
     { gPositionClosed = llGetLocalPos();
       gRotationClosed = llGetLocalRot();
     } 
    vector hingePosition = gPositionClosed + HINGE_POSITION * gRotationClosed;    
    gClosed = !gClosed;
    if (gClosed)
    {   llSetLinkPrimitiveParamsFast(linkNumber,
          [PRIM_ROT_LOCAL, gRotationClosed, PRIM_POS_LOCAL, gPositionClosed]);       
    }
    else
    {   rotation rotationOpened = llEuler2Rot(ROTATION * DEG_TO_RAD) * gRotationClosed;
        vector positionOpened = hingePosition - HINGE_POSITION * rotationOpened;
        llSetLinkPrimitiveParamsFast(linkNumber,
          [PRIM_ROT_LOCAL, rotationOpened, PRIM_POS_LOCAL, positionOpened]);       
        llSetTimerEvent(5);
    }
}
default
 {
    state_entry() 
    { 
    }
    on_rez(integer param)
    {  llResetScript();
    }
    touch_start(integer agentCount) 
    {  doOpenOrClose();
    }
    timer() 
    {  llSetTimerEvent(0.0);
       if (! gClosed)
       doOpenOrClose();
    }
}

 

Edited by Xiija
Link to comment
Share on other sites

I have a suspicion that the lid of the trunk in question is not going to be one of the typical offset central axis ones, and so the majority of door solutions won't be immediately applicable.

The problem is more likely to become one of rotating a prim about a point that is not central to it.

My suggestion for this particular case is to get two particular sets of local pos and rot corresponding to the open and closed arrangements and simply throw those at the child in question. The brain will very conveniently supply the illusion of the lid having moved smoothly between the two positions. (This is one of those rare situations where Dennet is right and consciousness is indeed an illusion).

The OP has said that they are relatively now to scripting, and I suspect the plethora of door scripts and/or variation in coding styles is just going to add to the confusion.

What is going to make this much more interesting is if the OP returns to say that it isn't just a single child that needs to be adjusted, but several, say a lid, attached strap, and a handle.

Edited by Profaitchikenz Haiku
  • Like 1
Link to comment
Share on other sites

OK, as I suspected.

It would be easiest if the root prim was either the shadow or the body of the trunk, so that prims hinge & lid are both child prims and will therefore rotate relative to the root.  I suggest you unlink and then relink with the body or the shadow as root.

Put prims hinge and lid in the closed position, touch each of them, and you then have the local post and rots for them closed.

Then move both hinge & lid to the open position, touch each of them and again you then have the local pos and rots for them open.

Then, setting the lid and hinge to either open or closed is simply making two calls to llSetLinkPrimitiveParamsFast, as follows (replace lidNum, Hingenum, and the sets of vectors and rotation with the actual values you obtained in the previous two steps),

 

list open = [lidNum, <x,y,z>, <x,y,z,s>, hingenum, <x1,y1,z1>,<x1,y1,z1,s1>]; // substitute actual
 
list closed = [lidNum, <x,y,z>, <x,y,z,s>, hingenum, <x1,y1,z1>,<x1,y1,z1,s1>]; // numbers here
 
string position;
  
default
{
  state_entry()
  {
  	llSetLinkPrimitiveParamsFast(llList2Integer(closed, 0), [PRIM_POS_LOCAL, llList2Vector(closed, 1), PRIM_ROT_LOCAL, llList2Rot(closed, 2)]);
    llSetLinkPrimitiveParamsFast(llList2Integer(closed, 3), [PRIM_POS_LOCAL, llList2Vector(closed, 4), PRIM_ROT_LOCAL, llList2Rot(closed, 5)]);
    position = "closed";
  
  }
  touch_start(integer touches)
  {
  	if( position == "closed")
  	{
  		llSetLinkPrimitiveParamsFast(llList2Integer(open, 0), [PRIM_POS_LOCAL, llList2Vector(open, 1), PRIM_ROT_LOCAL, llList2Rot(open, 2)]);
    	llSetLinkPrimitiveParamsFast(llList2Integer(open, 3), [PRIM_POS_LOCAL, llList2Vector(open, 4), PRIM_ROT_LOCAL, llList2Rot(open, 5)]);
    	position = "open";  
  	}
  	else
  	{
  		llSetLinkPrimitiveParamsFast(llList2Integer(closed, 0), [PRIM_POS_LOCAL, llList2Vector(closed, 1), PRIM_ROT_LOCAL, llList2Rot(closed, 2)]);
    	llSetLinkPrimitiveParamsFast(llList2Integer(closed, 3), [PRIM_POS_LOCAL, llList2Vector(closed, 4), PRIM_ROT_LOCAL, llList2Rot(closed, 5)]);
    	position = "closed";  
  	}
  
  }
  
  
}

 

Notice how we are pulling out values from the lists in positions 0,1,2 and 3,4,5 to get the child number, local pos and local rot for each of them.

There is a shorter way of doing this that only requires one llSetLinkPrimitiveParamsFast call but it would add to the complexity of what you re going to have to try and understand. Get this working first and then have a look at PRIM_LINK_TARGET.

Edited by Profaitchikenz Haiku
typos in lists in script.
Link to comment
Share on other sites

Just to add to the confusion, I'll add my 2cents. Well, maybe more than 2:

- The first important thing to understand about rotation is that there are 2 major kinds: client side, and server side, although a rotation can often be a mix of the two, it's useful to keep the distinction in the back of your head. For situations where you need a very specific rotation, you will snap the objects to specific positions server-side, and the client will interpolate.

- The second important thing is that how easy/hard it is to get the rotation working will depend on if the mesh was conveniently prepared for rotation, and how slow you want the rotation; if the defined center (where the arrows/gimble are when you select the object in SL) of the thing you want to rotate (the lid) is along the axis of rotation (the hinge) it will be easier and smoother to rotate, because you will only have to rotate it, and not move it. keeping point one in mind, if you only need the rotation to be a short quick one, you can get away with snapping the object (lid) directly from its start position to its end position, and your client will interpolate that into a somewhat smooth looking rotation for you. if on the other hand you want the chest to open very slowly, the script needs to do some math to calculate the intermediate rotations, and move the object (lid) to each one in sequence after a delay.

In conclusion, your script will depend not only on what you want to do, but how you want to do it, and how well your build was designed for it.

Link to comment
Share on other sites

9 minutes ago, Quistessa said:

how well your build was designed for it.

You raise a good point there. I have in my collections of stuff various examples of sculpted doors and mesh where the creator has managed to get the necessary axis of rotation offset just as if it were a path-cut prim of the classic door type. I have yet to learn how to achieve this with my in-world sculpt and mesh tools. It's on my do-before-I-die list because as you say, it does make for so much better effects when the client does the interpolation between the two extremes.

In the OP's example it is tempting to say just ditch the hinge and puppeteer the lid alone, but I am trying to illustrate a general approach where you could additionally add things to the lid such as a handle, or the padlock flap, or even a luggage tag on a loop so that things could also flop around when opened or closed.

Edited by Profaitchikenz Haiku
Link to comment
Share on other sites

12 minutes ago, Profaitchikenz Haiku said:

In the OP's example it is tempting to say just ditch the hinge and puppeteer the lid alone, but I am trying to illustrate a general approach where you could additionally add things to the lid such as a handle, or the padlock flap, or even a luggage tag on a loop so that things could also flop around when opened or closed.

Funny you should say that, Prof.  I am coming into this thread late, having decided to eat breakfast and take a shower first, so one of my first suggestions was going to be getting rid of the hinge.  After all, it serves little purpose other than increasing the object's L.I.  You make a good point, though. Your approach -- hard-coding the positions and rotations of all links in an object in both its open and closed positions -- saves a lot of work and is universally applicable. It has the major disadvantage of being totally empirical, teaching nothing about how rotations work, but it will produce a working box lid.  There are times when the pressure to get a job done justifies a quick, one-off solution.  You and I do it occasionally. In the long run, though, I think it will serve the OP better to take some time to study the various approaches for scripting doors -- many of which are outlined in that sticky thread -- so that she has a better understanding of underlying principles. Unless, of course, this is the only box lid she will ever need to script.

Link to comment
Share on other sites

1 minute ago, Rolig Loon said:

Unless, of course, this is the only box lid she will ever need to script.

After this, it may well be :)

I think that rotations can be a major stumbling block for many of us because it makes what should be a simple concept become rather more complicated than a builder would really like it to be.

The next stage in the example, should it progress, would indeed be how to have a few intermediate positions so that the lid could open slowly with a Hammer House of Horror style effect, and maybe a slam shut once the sensation-seeker has jumped inside looking for Narnia, at which point we would be looking at how to use rotations to modify positions and other rotations to obtain intermediates, but at that point I'm probably going to bow out and hand things over to the rest of you. I can do it, but there are others who are far better at explaining it than I.

Link to comment
Share on other sites

6 minutes ago, Profaitchikenz Haiku said:

I think that rotations can be a major stumbling block for many of us because it makes what should be a simple concept become rather more complicated than a builder would really like it to be.

I concede the point, having lost sight of the difference between coming at the problem as a builder and approaching it as a scripter. I do that more often than I admit. As a scripter, I am drawn by the challenge of understanding what's involved in rotating parts of a randomly-oriented complex object.  As a builder, I would almost certainly be moved by the challenge of getting the damned lid to open and close properly. There's room for both perspectives.  I think you can see why I chose a career in the sciences rather than becoming an engineer, though.

Link to comment
Share on other sites

Rotations are strange, in that they seem impossible to grasp until one day they aren't, and you can't see what the fuss is about.

I think the stumbling block is that you need to stop thinking about multiplication, because that's not what you're doing.   The * sign means in this context, ""translate by this rotation" and doesn't mean "multiply by" anything.   The important questions are which objects you want to rotate,  and what frame of rotational reference you want to use (world ruler vs local ruler in the  edit window).

Once you appreciate that that the numbers don't really matter, because the simulator has to do all the heavy thinking about 3D geometry, and that, instead, you need to concentrate on being specific about what rotates around what, then it's all there on the wiki page, and it's easy.

Use the region map, or North/South/East/West == llGetRot();

Use the root prim's local map, or front/behind/left/right == *llGetRot()

In a linkset, then different rules apply (rotating around the root prim's axis or the child object's local axis) and in an attachment there are different rules still, but it's all easy enough to drop in.   

I don't need to know what the calculations are, any more than I need to know how the simulator arrives at a numerical value for PI_BY_TWO or what the integer value actually is of a listening channel I calculate from an object's uuid, so I don't worry about them.

 

 

Link to comment
Share on other sites

With the lid open and then closed here's what i get with the // identify child prims and positions script:

OPEN:

[11:06] Treasure Chest Lid: Child 3 pos <-0.00001, 0.41750, 0.33240> rot <0.13795, -0.69352, -0.13795, 0.69352> degrees <0.00000, -90.00000, -22.50001>
[11:06] 2: Child 4 pos <0.00000, 0.31613, 0.72003> rot <-0.55557, -0.00001, -0.00002, 0.83147> degrees <-67.50000, -0.00002, -0.00266>

CLOSED:

[11:05] Treasure Chest Lid: Child 3 pos <-0.00001, 0.42341, 0.33295> rot <0.50000, -0.50000, -0.50000, 0.50000> degrees <0.00000, -90.00000, -90.00000>
[11:05] 2: Child 4 pos <0.00000, 0.02650, 0.38763> rot <0.00000, 0.00000, -0.00002, 1.00000> degrees <0.00000, -0.00002, -0.00266>

Notice i get 4 co-ordinates for the rotation. Confusing!

Which wont fit in here:

list open = [lidNum, <x,y,z>, <x,y,z,s>, hingenum, <x1,y1,z1>,<x1,y1,z1,s1>]; // substitute actual
 
list closed = [lidNum, <x,y,z>, <x,y,z,s>, hingenum, <x1,y1,z1>,<x1,y1,z1,s1>]; // numbers here
Edited by SerenaPufnstuf
Link to comment
Share on other sites

9 minutes ago, SerenaPufnstuf said:

Notice i get 4 co-ordinates for the rotation. Confusing!

Yes, quaternion notation is a new concept for many people.  It takes new scripters a while to understand the difference between a vector and a quaternion. I suspect that most of us end up using llEuler2Rot and llRot2Euler much of the time rather than dealing directly with the math of a quaternion.  If you are truly interested, take a look at this very nice video lesson:

When it comes to using rotations, Innula is right that 

58 minutes ago, Innula Zenovka said:

I think the stumbling block is that you need to stop thinking about multiplication, because that's not what you're doing.   The * sign means in this context, ""translate by this rotation" and doesn't mean "multiply by" anything. 

although it's not quite correct to say that "*" means "translate by this rotation".  You really are multiplying, but not in the way that you normally think about multiplication. It's true that

1 hour ago, Innula Zenovka said:

I don't need to know what the calculations are

but it might help to know how they work, if you're curious.  When we use the "*" operator on vectors and quaternions in LSL, we are looking for a product of two matrices.  We manipulate translations and rotations by using matrix algebra, therefore, in which there are a handful of basic operations. Rather than spell them all out here, I suggest taking a stroll through a primer like https://www.statisticshowto.com/matrices-and-matrix-algebra/. You'll never have to do the matrix algebra yourself in LSL because, as Innula says, the simulator does it all for you, but it's really not hard to understand once you know the rules and you might find it fun in a perverse sort of way.

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

1 hour ago, SerenaPufnstuf said:

Which wont fit in here:



list open = [lidNum, <x,y,z>, <x,y,z,s>, hingenum, <x1,y1,z1>,<x1,y1,z1,s1>]; // substitute actual
 
list closed = [lidNum, <x,y,z>, <x,y,z,s>, hingenum, <x1,y1,z1>,<x1,y1,z1,s1>]; // numbers here

Actually, they are exactly what you needed, and they do fit. Your local position vectors in each case are in the form <x,y,z> and the local rotation quaternions are in the form <x,y,z,s>, which is precisely the form that Prof's handy script spit out for you.  (Ignore the final value -- the "angle" -- in each case.  It's interesting but you don't really need it here.)  So just plug the vectors and quaternions that you just discovered into Prof's second script 

and you're done.

Link to comment
Share on other sites

Another confusing thing about quaternion rotations, is that like vectors, they can be thought about in (at least) two seemingly different ways: just like a vector can either intuitively represent a spot in 3d space (a place on your region) or a transformation of the origin to another location (a velocity and heading an object could be moving) , a quaternion can represent either a static orientation an object can be in (rather useful to think of the quaternion in its vector-angle formulation in that case https://eater.net/quaternions/) or a transformation from one orientation to another rotation (turn 90 degrees to the right with respect to your z axis).

  • Like 2
Link to comment
Share on other sites

11 minutes ago, Quistessa said:

they can be thought about in (at least) two seemingly different ways

Perhaps another way to think about vectors and rotations is to notice that we can never talk about where something is without also saying that its position is relative to something else. I can't tell you where my home is without also telling you implicitly that it is roughly 600 miles west of New York City or by giving you my home's longitude and latitude (which define a position relative to the north pole and the standard meridian).   The tree in my front yard is leaning, relative to the straight up and down orientation of any normal God-fearing tree.

In SL, we can define a regional position (relative to the southwest corner of the region) or a local position (relative to some other spot).  We can define a regional rotation relative to ZERO_ROTATION ( Z-axis pointing straight up and +X pointing due East) or a local rotation relative to something else. In any of the ways we use vectors and rotations, we are either thinking of where an object is and how it is rotated (relative to someplace else), or we are thinking of how much we would have to move it or rotate it to get somewhere else (relative to HERE).  Keeping your focus on the "relative to" part is the big key to success.

Link to comment
Share on other sites

Interestingly, if Hamilton had cut his formula into the stone of an English bridge he'd likely have been transported for life, at least, that's the dire warnings given of quite a few of the West Country bridges around me still say.

32 minutes ago, Rolig Loon said:

Ignore the final value -- the "angle" -- in each case

Yes, I'm sorry if I mislead people there, I had hoped that the sight of the angle expressed in degrees matching up (to an extent) with the edit-box display might make things look a bit more sensible here. It's what I do in these cases to just give myself a reference-point.  

Link to comment
Share on other sites

11 minutes ago, Profaitchikenz Haiku said:

I had hoped that the sight of the angle expressed in degrees matching up (to an extent) with the edit-box display might make things look a bit more sensible here. It's what I do in these cases to just give myself a reference-point.

Me too.  Brains don't work well in 4D quaternion space.  Angles make a whole lot more sense, especially if they are in degrees.  So, I didn't really mean "ignore" except in the sense that the script -- which does work well in 4D space -- doesn't need to know the "angle" information.

Link to comment
Share on other sites

You are about to reply to a thread that has been inactive for 1144 days.

Please take a moment to consider if this thread is worth bumping.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
 Share

×
×
  • Create New...