Kyrah Abattoir Posted April 18, 2019 Share Posted April 18, 2019 I know @Wulfie Reanimator it's just something that came to me when i was reading the topic so i dropped it here Link to comment Share on other sites More sharing options...
RozWright Posted June 15, 2019 Share Posted June 15, 2019 On 3/18/2017 at 12:48 PM, Innula Zenovka said: I think I'd look for a different door in that case, one that has its pivot point in the center, and then use llTargetOmega to move the door at the desired speed and, on a timer, llSetLocalRot or llSetLinkPPFast to snap it into place when llTargetOmega had done its stuff. Toy Wylie's script does this, and it works well in prim builds. But for mesh builds, I would not suggest llTargetOmega in a door script...it does bad things to your doorways. The non-scripting workaround is to "edit" your doorway...just the simple act of opening the edit window on the build fixes the problem (without leaving any evidence there was a problem in the first place). But who wants to left click a door and then right click the doorway to enter a building? Link to comment Share on other sites More sharing options...
Innula Zenovka Posted June 15, 2019 Share Posted June 15, 2019 2 hours ago, RozWright said: Toy Wylie's script does this, and it works well in prim builds. But for mesh builds, I would not suggest llTargetOmega in a door script...it does bad things to your doorways. The non-scripting workaround is to "edit" your doorway...just the simple act of opening the edit window on the build fixes the problem (without leaving any evidence there was a problem in the first place). But who wants to left click a door and then right click the doorway to enter a building? Sorry but I have to disagree with you there. There's nothing wrong with using llTargetOmega in doors in mesh builds -- I do it all the time, as do many other regulars here. the issues described in that post are to do with the specific build and the way the meshes are set. llTargetOmega, unless it's called in something which has been set as physics-enabled (so a car wheel rather than a house door) is entirely client side. Whether it's called in a prim or a mesh, the object doesn't actually move at all as far as the simulator is concerned. So you need to to call both llTargetOmega to make the door open and close smoothly and also call llSetRot actually to open and close it so people can or can't walk through the doorway. The only real issue with using llTargetOmega in doors is that you can't offset the centre of rotation, which is why you need either to pathcut regular prims or to offset it in a mesh door using the method described early in the thread, because you can't pathcut the mesh door. 1 Link to comment Share on other sites More sharing options...
Whirly Fizzle Posted June 15, 2019 Share Posted June 15, 2019 You do need to be careful of using llTargetOmega on mesh builds as Roz said above though. This bug explains why: BUG-225742 - Server side physics shape reverts to "Convex Hull" for un-analyzed meshes with "Prim Physics" connected to linksets with subcomponents animated with llTargetOmega / PRIM_OMEGA parameters upon server restart. 1 1 Link to comment Share on other sites More sharing options...
Innula Zenovka Posted June 15, 2019 Share Posted June 15, 2019 (edited) Thanks, @Whirly Fizzle. I'm not particularly familiar with the details of mesh modelling, and I'd not seen that bug report before. This is probably a very stupid question, but I note the title stresses that the bug affects "un-analysed meshes with 'Prim Physics'," and the fact that the mesh must be "un-analysed" is several times stressed in the description. Does this mean the problem is confined to meshes that have been uploaded with first having the viewer's uploader analyse them, and only then if they are physics enabled (that is, if you raise it off the ground with the edit tools and release it, it will fall to the ground or other solid surface rather than remain suspended in mid air) and is there any good reason for not analysing the mesh before uploading it? On the face of it, I can't see any reason why you'd want a house door to be physics enabled, since that's unnecessary and is simply asking for trouble, and even if you did, could you not remedy the problem by re-uploading the mesh only this time remembering first to ask the uploader to analyse it? All I can say is that I've worked with plenty of mesh houses and doors, and so have plenty of other experienced scripters, and never had this sort of problem -- though admittedly I've never thought to set a door to physics enabled, and I didn't make the meshes myself but I have every confidence in the skills of the mesh makers who did, so maybe they realised the importance of analysing the mesh before uploading it -- and I know for a fact (since the Mole who scripted them is a friend of mine) that many, if not all, of the houses and houseboats on Bellissaria have mesh doors that use llTargetOmega and llSetRot, and people seem to be able to use them without much difficulty, so it would appear that the issue is easily avoided. Edited June 15, 2019 by Innula Zenovka Link to comment Share on other sites More sharing options...
Ana Stubbs Posted June 15, 2019 Share Posted June 15, 2019 1 hour ago, Innula Zenovka said: Does this mean the problem is confined to meshes that have been uploaded with first having the viewer's uploader analyse them WITHOUT first having the viewer's uploader analyse them, yes. 1 hour ago, Innula Zenovka said: and only then if they are physics enabled (that is, if you raise it off the ground with the edit tools and release it, it will fall to the ground or other solid surface rather than remain suspended in mid air) and is there any good reason for not analysing the mesh before uploading it? No, Prim physics is nothing to do with being physics enabled. It means that the mesh is using the physics model that you uploaded, and not the "convex hull" (no holes) or "none" options. It mostly affects things like whether your avatar will collide with an object or walk through it, or whether you can walk on it, or if you can rez on it (you've probably met mesh floors that refuse to allow rezzing - that's usually a bad physics model). And, confusingly, "phantom" is a different thing again. 1 1 Link to comment Share on other sites More sharing options...
Innula Zenovka Posted June 15, 2019 Share Posted June 15, 2019 (edited) 36 minutes ago, Ana Stubbs said: WITHOUT first having the viewer's uploader analyse them, yes. No, Prim physics is nothing to do with being physics enabled. It means that the mesh is using the physics model that you uploaded, and not the "convex hull" (no holes) or "none" options. It mostly affects things like whether your avatar will collide with an object or walk through it, or whether you can walk on it, or if you can rez on it (you've probably met mesh floors that refuse to allow rezzing - that's usually a bad physics model). And, confusingly, "phantom" is a different thing again. Ah.. that makes a bit more sense. Thanks. Now I start to understand. I was thrown by the reference in the title to "un-analyzed meshes with "Prim Physics," which I took to mean PRIM_PHYSICS, but it presumably means PRIM_PHYSICS_SHAPE_TYPE, PHYSICS_SHAPE_TYPE_something. I'm not sure what the "something" is, though -- PRIM_PHYSICS_SHAPE_TYPE_PRIM presumably, since that's all that's left if it's neither convex hull or none. Now that I've read the repro more closely, the issue seems to be not with the door but with the root object. What happens if I make the root prim not the unanalysed mesh I've uploaded but, instead, a regular prim? How does the mesh object behave then after region restarts? Maybe it's just the mesh modellers I've worked with but my impression was that they tend to make things like houses with regular collision prims for the floors and walls and so on, link the house mesh to it and adjust things so that the collision prims are inside the floors and walls, set them to invisible, and then set the house mesh to PRIM_PHYSICS_SHAPE_TYPE_NONE. That seems to avoid most problems and also generally keeps the LI down. And if the whole thing is avoided simply by remembering to have the viewer's uploader analyse the mesh before you upload it, that's not much of a problem, I would have thought. Edited June 15, 2019 by Innula Zenovka Link to comment Share on other sites More sharing options...
Ana Stubbs Posted June 15, 2019 Share Posted June 15, 2019 19 minutes ago, Innula Zenovka said: my impression was that they tend to make things like houses with regular collision prims for the floors and walls and so on, link the house mesh to it and adjust things so that the collision prims are inside the floors and walls, set them to invisible, and then set the house mesh to PRIM_PHYSICS_SHAPE_TYPE_NONE. That seems to avoid most problems and also generally keeps the LI down. That's the lazy way to do it. I don't mean that as a perjorative description, i've done it that way myself plenty of times, but a proper physics model, done well, is the ideal. 22 minutes ago, Innula Zenovka said: And if the whole thing is avoided simply by remembering to have the viewer's uploader analyse the mesh before you upload it, that's not much of a problem, I would have thought. Some types of physics models are better as unanalysed. 1 Link to comment Share on other sites More sharing options...
RozWright Posted June 17, 2019 Share Posted June 17, 2019 (edited) On 6/15/2019 at 1:15 PM, Innula Zenovka said: All I can say is that I've worked with plenty of mesh houses and doors, and so have plenty of other experienced scripters, and never had this sort of problem With mesh came a lot of new door scripts that don't require that the "hinge" of the door also be its center (as it was with the cutpath prim), so those scripts wouldn't be using llTargetOmega. Someone graciously offered me a door script she'd created (that didn't use llTO) and the problem was solved. From my experience, the physics shape changed when llTargetOmega was called in the script (which was every time the door was opened or closed), not while it was in motion. So for things like ceiling fans it's not much of a problem, the build is already in edit mode when the rotation is set, and there's not much need for llTargetOmega to be called beyond that. There's no rational reason a client side effect would cause a problem like this, and yet it does, which makes troubleshooting it a mind melting experience. Edited June 17, 2019 by RozWright Link to comment Share on other sites More sharing options...
Innula Zenovka Posted June 17, 2019 Share Posted June 17, 2019 34 minutes ago, RozWright said: With mesh came a lot of new door scripts that don't require that the "hinge" of the door also be its center (as it was with the cutpath prim), so those scripts wouldn't be using llTargetOmega. Someone graciously offered me a door script she'd created (that didn't use llTO) and the problem was solved. I'm not quite sure I understand the example you're describing here -- I would need to see the door and the script to comment, and I must stress that while I do know something about doors and rotations, I don't know a great deal about making mesh. However, the basic scripting is quite simple, as are the constraints. By default, LSL rotations pivot round the centre of the object being rotated. The simplest workaround for when you need to pivot something on its edge -- a door, for example -- is to change the design of the object, by shifting its visual centre away from its actual centre, whether by path-cutting a prim or by manipulating a mesh door by adding a small hidden point offset from the edge of the door mesh, so it appears the centre of the resulting mesh object is, in fact, one edge of the visible area. If that's not possible (you didn't make the mesh) it's certainly possible, though rather fiddly, to offset the rotation by script, using a combination of llSetRot and llSetPos. That works for anything server-side, but not for llTargetOmega, since all its effects are client side. There's nothing you can do to fool llTargetOmega about where the centre of the object is. There's an added problem with llTargetOmega doors that, because that function is client-side, you also need to change the door's actual rotation, so the simulator knows what it is. Otherwise the door will seem open but you won't be able to pass through it because, while your CPU and GPU think the door should be drawn as open, the simulator thinks it's closed until the actual rotation is changed with llSetRot or similar. That can cause problems with scripted doors that use TargetOmega -- sometimes the way such doors are scripted mean that the door doesn't actually unblock or block the doorway until llTargetOmega has finished, which can be confusing. Typically I'll call llSetRot or llSetLocalRot several times on a timer while llTargetOmega is running, so the door's actual and represented rotations are always within 10° or 20° of each other, but not everyone bothers to do that, which can confuse users a lot. (I'm not saying that's the problem here.. just taking the opportunity to note it for future readers). 1 Link to comment Share on other sites More sharing options...
Ivanova Shostakovich Posted September 4, 2019 Share Posted September 4, 2019 (edited) I have a mesh house by a well known builder. All of its parts, doors and windows are a single linked object. The doors use the method of llTargetOmega() to make them appear to smoothly rotate, then setting the open or closed rotation after an appropriate delay. Because a door mesh was only actually rotated to the open position when that process completed, I was unable to walk through that doorway until it had. I wanted better realism. While the house is modifiable, the scripts in the doors (and windows) are not. I replaced them with a version using the aforementioned method, adding to the beginning and end of the door state change processes, respectively, llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_NONE]) and llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_PHYSICS_SHAPE_TYPE, PRIM_PHYSICS_SHAPE_PRIM]). This allows a much more realistic simulation, letting me gracefully make a grand entrance into my writing room, where my typewriter, sitting on a desk, balefully inquires of me "And where have you been?" Edited September 4, 2019 by Ivanova Shostakovich because too many to. Link to comment Share on other sites More sharing options...
Rayvn Evermore Posted September 14, 2019 Share Posted September 14, 2019 I have been trying to learn from this thread to solve a problem I have and so far I'm not getting there, yet, lol. Here is my issue. I have a roomba in my shop on a floating island. The roomba is physical, so that it can bump around the walls on the inside of the building. I have sliding double doors in the shop. The doors are mesh, they are linked to a frame that is separate from the building. If need be, I could unlink them from the frame and have them as separate objects if necessary. When all goes well, the sliding doors open and close to let people go in and out but the roomba stays in. Every so often, someone gets the doors to stick and stay open. The roomba goes out..... and then it's off vacuuming the sky..... So, I'd like to find a more reliable script for my door that would only let avatars go in and out. I would prefer the double doors to slide, but I tried Rollig's cafe doors. I thought they would do it until I watched the roomba open them and go out! I don't know a lot about scripting, can anyone guide me towards something that's not super complicated (or well explained) that would do a good job for what I want? Link to comment Share on other sites More sharing options...
Rolig Loon Posted September 14, 2019 Share Posted September 14, 2019 That's fortunately quite simple. Scripters don't usually need to worry about Roombas and such, so we don't bother to tell our scripts to obey only avatars. However, that's what the llDetectedType() function is designed for. All you need to do is include a simple test in whatever touch* or collision* event activates your door, as in: touch_start( integer num ) { if ( llDetectedType(0) & AGENT ) { //Go ahead and open the door } } Link to comment Share on other sites More sharing options...
Rolig Loon Posted November 28, 2020 Share Posted November 28, 2020 (edited) Scripters are often called upon to script double doors that will swing together when either one is touched. There are many ways to do that, depending on how the doors are constructed. Here's one. In this example, we have two identical doors ("Left Door" and "Right Door") that might be simple prims or mesh objects. They are parts of a linkset in which the root is the black prim below the doors. The doors might be linked to a building or a wall, in which case the root of that building or wall would take the place of the black prim in this image. The doors are named "Left Door" and "Right Door" and are designed so that their local X axes point toward each other. If you do that, the doors will hinge on their outer edges. In this example, I am starting with the simple door script posted by Innula Zenovka earlier in this thread >>> https://community.secondlife.com/forums/topic/338230-options-for-scripting-doors/?tab=comments#comment-1616538 . In state_entry, we first identify the link numbers of the two doors and save them in global integer variables, iLeftDoor and iRightDoor. The script assumes that because the doors are identical, I can use the dimensions of either one to determine where the hinge edges of both doors are. The value vOffset is determined in state_entry and saved as a global vector. The touch_start event, then, essentially blends two copies of Innula's touch_start event (one for each door) and then rotates both with a single llSetLinkPrimitiveParamsFast statement. The script is only activated if someone touches one of the two doors. With a little bit of thought, it should be possible to generalize this approach for use in a linkset with more than one set of double doors, or to construct a double door script that begins with a different approach than Innula's. integer intSwing = 90; // Door swing in degrees rotation rotSwing; vector vOffset; vector vOffsetR; integer iLeftDoor; integer iRightDoor; default{ state_entry() { //First, find the door prims .... integer len = llGetNumberOfPrims(); integer i; while ( i < len) { ++i; string name = llGetLinkName(i); if (name == "Left Door") { iLeftDoor = i; } else if (name == "Right Door") { iRightDoor = i; } } // Now, covert intSwing to a rotation in radians around the Z-axis rotSwing = llEuler2Rot(<0.0,0.0,(float)intSwing>*DEG_TO_RAD); // And calculate how far each door's hinge edge is from the centerline of the door vector size = (vector)llList2String(llGetLinkPrimitiveParams(iLeftDoor,[PRIM_SIZE]),0); vOffset = <(size.x*-0.5),(size.y*-0.5),0.0>; vOffsetR = <(size.x*-0.5),(size.y*0.5),0.0>; //Note the sign difference in the Y dimension's offset } touch_start(integer total_number) { if ( llDetectedLinkNumber(0) == iLeftDoor || llDetectedLinkNumber(0) == iRightDoor) { // Get the current local position and rotation of each door list lParamsL = llGetLinkPrimitiveParams(iLeftDoor,[PRIM_POS_LOCAL,PRIM_ROT_LOCAL]); vector vLeft = llList2Vector(lParamsL,0); rotation rLeft = llList2Rot(lParamsL,1); list lParamsR = llGetLinkPrimitiveParams(iRightDoor,[PRIM_POS_LOCAL,PRIM_ROT_LOCAL]); vector vRight = llList2Vector(lParamsR,0); rotation rRight = llList2Rot(lParamsR,1); rotation rotSwingRight = <rotSwing.x,rotSwing.y,rotSwing.z,-rotSwing.s>; //So, rotSwingRight rotates the door in the opposite direction // Now, swing both doors simlutaneously llSetLinkPrimitiveParams(LINK_SET,[34,iLeftDoor,PRIM_POS_LOCAL,vLeft+(vOffset - vOffset*rotSwing)*rLeft,PRIM_ROT_LOCAL,rotSwing*rLeft, 34,iRightDoor,PRIM_POS_LOCAL,vRight+(vOffsetR - vOffsetR*rotSwingRight)*rRight,PRIM_ROT_LOCAL,rotSwingRight*rRight]); // And finally, reverse the direction of swing, ready for the next touch rotSwing.s*=-1; } } } EDIT: Thank you to Mollymews for pointing out that because the left and right doors are mirrored, the arithmetic sign of the hinge offset in Y for the Right Door has to be the reverse of the sign for the Left Door. I have introduced vOffsetR to recognize that and have updated the script above to include it. It's a small correction -- most noticeable for a thick door -- but it assures that the two doors align correctly with a door jamb. Edited November 28, 2020 by Rolig Loon typos. as always. 2 Link to comment Share on other sites More sharing options...
Emma Krokus Posted November 28, 2020 Share Posted November 28, 2020 little typo in this line - vOffsetR = <(size.x*-0.5),(size.y*0.5),0.0); //Note the sign difference in the Y dimension's offset } i think should be... vOffsetR = <(size.x*-0.5),(size.y*0.5),0.0>; //Note the sign difference in the Y dimension's offset ? Emma Noob scripter Link to comment Share on other sites More sharing options...
Rolig Loon Posted November 28, 2020 Share Posted November 28, 2020 55 minutes ago, Emma Krokus said: i think should be... Yup. Don't you hate typos? I fixed it. Thanks. 1 Link to comment Share on other sites More sharing options...
Mollymews Posted December 2, 2020 Share Posted December 2, 2020 (edited) @siennasprout asked about sensor to open a linked double door set in other post i had a play with the above Rolig/Innula double door script and added a door sensor to it here is a pic. red and green are the doors. Orange is the sensor. Blue are the quadrants doors open when person is in either blue quadrant and is facing the doors example script // mod of Innula Zenovka / Rolig Loon double linked door script to add a sensor opener // this script goes in a sensor prim by the doors, the door frame is a good place to put it in integer intSwing = 90; // Door swing in degrees rotation rotSwing; vector vOffset; vector vOffsetR; integer iLeftDoor; integer iRightDoor; integer isOpen; swing() { // Get the current local position and rotation of each door list lParamsL = llGetLinkPrimitiveParams(iLeftDoor,[PRIM_POS_LOCAL,PRIM_ROT_LOCAL]); vector vLeft = llList2Vector(lParamsL,0); rotation rLeft = llList2Rot(lParamsL,1); list lParamsR = llGetLinkPrimitiveParams(iRightDoor,[PRIM_POS_LOCAL,PRIM_ROT_LOCAL]); vector vRight = llList2Vector(lParamsR,0); rotation rRight = llList2Rot(lParamsR,1); rotation rotSwingRight = <rotSwing.x,rotSwing.y,rotSwing.z,-rotSwing.s>; //So, rotSwingRight rotates the door in the opposite direction // Now, swing both doors simlutaneously llSetLinkPrimitiveParams(LINK_SET,[34,iLeftDoor,PRIM_POS_LOCAL,vLeft+(vOffset - vOffset*rotSwing)*rLeft,PRIM_ROT_LOCAL,rotSwing*rLeft, 34,iRightDoor,PRIM_POS_LOCAL,vRight+(vOffsetR - vOffsetR*rotSwingRight)*rRight,PRIM_ROT_LOCAL,rotSwingRight*rRight]); // And finally, reverse the direction of swing, ready for the next touch rotSwing.s*=-1; isOpen = !isOpen; } default{ state_entry() { //First, find the door prims .... integer len = llGetNumberOfPrims(); integer i; while ( i < len) { ++i; string name = llGetLinkName(i); if (name == "Left Door") { iLeftDoor = i; } else if (name == "Right Door") { iRightDoor = i; } } // Now, covert intSwing to a rotation in radians around the Z-axis rotSwing = llEuler2Rot(<0.0,0.0,(float)intSwing>*DEG_TO_RAD); // And calculate how far each door's hinge edge is from the centerline of the door vector size = (vector)llList2String(llGetLinkPrimitiveParams(iLeftDoor,[PRIM_SIZE]),0); vOffset = <(size.x*-0.5),(size.y*-0.5),0.0>; vOffsetR = <(size.x*-0.5),(size.y*0.5),0.0>; //Note the sign difference in the Y dimension's offset // goto state door_closed state door_closed; } } state door_closed { state_entry() { // start sensor llSensorRepeat("", NULL_KEY, AGENT, 5.0, PI, 1.0); } sensor(integer num) { while (!isOpen && ~--num) { // is agent within the diagonal quadrants in front of and behind the sensor ? // and when so is agent looking at the door ? vector bearing = llVecNorm(llDetectedPos(num) - llGetPos()); float quadrant = llFabs(llRot2Fwd(llGetRot()) * bearing); // quadrant range [0.0 .. 1.0]. 0.0 is wider float compass = -llRot2Fwd(llDetectedRot(num)) * bearing; // compass range[-1.0 .. 0.0 .. 1.0] 0.0 is wider if ((quadrant > 0.7) && (compass > 0.95)) { // when somebody found open the door and goto state door_open swing(); state door_open; } // caveat: as this is calculated using dot.product the conditions (as wrote) get screwy when reallly // close to the sensor. So agent has to move back away from the sensor sometimes // credit: the dot.product compass bearing method is credit Dora Gustafson. The quadrant bearing I derived from this } } } state door_open { state_entry() { // start sensor llSensorRepeat("", NULL_KEY, AGENT, 5.0, PI, 1.0); } no_sensor() { // when nobody found close the door and goto state door_closed swing(); state door_closed; } } Edited December 2, 2020 by Mollymews typs Link to comment Share on other sites More sharing options...
Mollymews Posted December 3, 2020 Share Posted December 3, 2020 (edited) i tidied up the compass bearing method so that the math is little bit more consistent with the use case main two things: 1) set pos.Z of agent and sensor to be the same Z. As when agent.Z and sensor.Z are on different levels, ie: sensor.Z is lower than agent.Z, the Z angle gets steeper as the agent gets closer to the sensor which affects the bearing calculation 2) scale by the magnitude of the bearing vector. This means that <0.5,0.5, 0> <1,1,0> <2,2,0>,<3,3,0>, etc return the same calculated bearing (give or take rounding errors) sensor(integer num) { vector sensorpos = llGetPos(); rotation sensorrot = llGetRot(); while (!isOpen && ~--num) { // is agent within the diagonal quadrants in front of and behind the sensor ? // and when so is agent looking at the door ? vector agentpos = llDetectedPos(num); rotation agentrot = llDetectedRot(num); agentpos.z = sensorpos.z; // set same Z to work in 2 dimensions XY vector bearing = llVecNorm(agentpos - sensorpos); float magnitude = llVecMag(bearing); // scale by magnitude so that bearing <1,1,0> = <2,2,0> = <3,3,0> etc float quadrant = llFabs(llRot2Fwd(sensorrot) * bearing / magnitude); // quadrant range [0.0 .. 1.0]. 0.0 is wider float compass = -llRot2Fwd(agentrot) * bearing / magnitude; // compass range[-1.0 .. 0.0 .. 1.0] 0.0 is wider if ((quadrant > 0.7) && (compass > 0.95)) { // when somebody found open the door and goto state door_open swing(); state door_open; } // credit: the dot.product compass bearing method is credit Dora Gustafson. The quadrant bearing I derived from this } } ps. while the tidy up can be used in the door case, I did it mostly because somebody asked me if could be used in a animesh kitten which stalks another animals or people. Like sneaks up behind them and if they turn around then the kitten goes still and pretends is asleep. Then when they turn away, kitten sneaks up a little bit more until close enough then goes raaaaar!!! Edited December 3, 2020 by Mollymews 1 Link to comment Share on other sites More sharing options...
Emma Krokus Posted December 3, 2020 Share Posted December 3, 2020 2 hours ago, Mollymews said: i tidied up the compass bearing method so that the math is little bit more consistent with the use case main two things: 1) set pos.Z of agent and sensor to be the same Z. As when agent.Z and sensor.Z are on different levels, ie: sensor.Z is lower than agent.Z, the Z angle gets steeper as the agent gets closer to the sensor which affects the bearing calculation 2) scale by the magnitude of the bearing vector. This means that <0.5,0.5, 0> <1,1,0> <2,2,0>,<3,3,0>, etc return the same calculated bearing (give or take rounding errors) sensor(integer num) { vector sensorpos = llGetPos(); rotation sensorrot = llGetRot(); while (!isOpen && ~--num) { // is agent within the diagonal quadrants in front of and behind the sensor ? // and when so is agent looking at the door ? vector agentpos = llDetectedPos(num); rotation agentrot = llDetectedRot(num); agentpos.z = sensorpos.z; // set same Z to work in 2 dimensions XY vector bearing = llVecNorm(agentpos - sensorpos); float magnitude = llVecMag(bearing); // scale by magnitude so that bearing <1,1,0> = <2,2,0> = <3,3,0> etc float quadrant = llFabs(llRot2Fwd(sensorrot) * bearing / magnitude); // quadrant range [0.0 .. 1.0]. 0.0 is wider float compass = -llRot2Fwd(agentrot) * bearing / magnitude; // compass range[-1.0 .. 0.0 .. 1.0] 0.0 is wider if ((quadrant > 0.7) && (compass > 0.95)) { // when somebody found open the door and goto state door_open swing(); state door_open; } // credit: the dot.product compass bearing method is credit Dora Gustafson. The quadrant bearing I derived from this } } ps. while the tidy up can be used in the door case, I did it mostly because somebody asked me if could be used in a animesh kitten which stalks another animals or people. Like sneaks up behind them and if they turn around then the kitten goes still and pretends is asleep. Then when they turn away, kitten sneaks up a little bit more until close enough then goes raaaaar!!! such a cute use case! BUT also, thanks so much for the door script(s) AND explanations ❤️ Emma 1 Link to comment Share on other sites More sharing options...
siennasprout Posted December 5, 2020 Share Posted December 5, 2020 On 12/3/2020 at 4:24 AM, Mollymews said: i tidied up the compass bearing method so that the math is little bit more consistent with the use case main two things: 1) set pos.Z of agent and sensor to be the same Z. As when agent.Z and sensor.Z are on different levels, ie: sensor.Z is lower than agent.Z, the Z angle gets steeper as the agent gets closer to the sensor which affects the bearing calculation 2) scale by the magnitude of the bearing vector. This means that <0.5,0.5, 0> <1,1,0> <2,2,0>,<3,3,0>, etc return the same calculated bearing (give or take rounding errors) sensor(integer num) { vector sensorpos = llGetPos(); rotation sensorrot = llGetRot(); while (!isOpen && ~--num) { // is agent within the diagonal quadrants in front of and behind the sensor ? // and when so is agent looking at the door ? vector agentpos = llDetectedPos(num); rotation agentrot = llDetectedRot(num); agentpos.z = sensorpos.z; // set same Z to work in 2 dimensions XY vector bearing = llVecNorm(agentpos - sensorpos); float magnitude = llVecMag(bearing); // scale by magnitude so that bearing <1,1,0> = <2,2,0> = <3,3,0> etc float quadrant = llFabs(llRot2Fwd(sensorrot) * bearing / magnitude); // quadrant range [0.0 .. 1.0]. 0.0 is wider float compass = -llRot2Fwd(agentrot) * bearing / magnitude; // compass range[-1.0 .. 0.0 .. 1.0] 0.0 is wider if ((quadrant > 0.7) && (compass > 0.95)) { // when somebody found open the door and goto state door_open swing(); state door_open; } // credit: the dot.product compass bearing method is credit Dora Gustafson. The quadrant bearing I derived from this } } ps. while the tidy up can be used in the door case, I did it mostly because somebody asked me if could be used in a animesh kitten which stalks another animals or people. Like sneaks up behind them and if they turn around then the kitten goes still and pretends is asleep. Then when they turn away, kitten sneaks up a little bit more until close enough then goes raaaaar!!! Thanks so much! I'll give this script a try next time I get a chance. 1 Link to comment Share on other sites More sharing options...
Mollymews Posted December 18, 2020 Share Posted December 18, 2020 not sure how long it has been available but I just noticed that Linden have added llSetClickAction(CLICK_ACTION_DISABLED) might have been them Belli building Moles who got it put thru. Is a real blessing for linked doors and windows which are linked to the building. The blessing is that can have just one script in the root prim to handle touches that open and close the doors/windows how to use: set all the prims (walls, floors, etc) other than the doors and windows to llSetClickAction(CLICK_ACTION_DISABLED) leaving only the doors/windows set to the default llSetClickAction(CLICK_ACTION_TOUCH) so only the doors/windows will accept a Touch and pass it thru to the script in the root prim even cooler is llSetClickAction() is a prim property. Once set the property is held by the prim and the script to set the property can be deleted. Example: // set the prim click action property to disabled // and then delete the script // stick this in every prim in a linked build that we don't want to // accept Touches and pass then thru to a root prim touch script default { state_entry() { llSetClickAction(CLICK_ACTION_DISABLED); llSleep(0.2); // give it a little time to take hold then llRemoveInventory(llGetScriptName()); // delete this script } } http://wiki.secondlife.com/wiki/LlSetClickAction Link to comment Share on other sites More sharing options...
Rolig Loon Posted February 16, 2021 Share Posted February 16, 2021 We've had a few entries about double doors, so here's a link to one method for scripting a pair of sliding double doors: Link to comment Share on other sites More sharing options...
Remi Alpha Posted April 7, 2021 Share Posted April 7, 2021 On 6/13/2018 at 10:45 PM, Rolig Loon said: touch_end( integer vIntNul ){ llSetLocalRot( (gRotSwing = (ZERO_ROTATION / gRotSwing)) * llGetLocalRot() ); } This compact method is great and works nicely for toggling a door open / closed with alternate touches. One thing I don't understand: llSetLocalRot appears to animate the hinge motion but I can't see any parameters associated with the time it takes to reach the final angle. I know there are keyframe-based methods to get more control over the animation – I’m not asking about that. I just want to understand this method specifically. Is there something about llSetLocalRot, or [the variable called here] gRotSwing (returned bv llEuler2Rot) that determines that it should animate? Or does llSetLocalRot simply rotate objects at some hard-coded rate that cannot be changed? Link to comment Share on other sites More sharing options...
Wulfie Reanimator Posted April 7, 2021 Share Posted April 7, 2021 7 minutes ago, Rem Voxel said: This compact method is great and works nicely for toggling a door open / closed with alternate touches. One thing I don't understand: llSetLocalRot appears to animate the hinge motion but I can't see any parameters associated with the time it takes to reach the final angle. I know there are keyframe-based methods to get more control over the animation – I’m not asking about that. I just want to understand this method specifically. Is there something about llSetLocalRot, or [the variable called here] gRotSwing (returned bv llEuler2Rot) that determines that it should animate? Or does llSetLocalRot simply rotate objects at some hard-coded rate that cannot be changed? The rotation change is instant, as far as the sim is concerned. What you've noticed is the client-side interpolation, and it's done for all rotation/position/scale changes (for both, objects and avatars). You definitely can't adjust it through scripts at all. 2 1 Link to comment Share on other sites More sharing options...
Remi Alpha Posted April 7, 2021 Share Posted April 7, 2021 1 hour ago, Wulfie Reanimator said: client-side interpolation Aha.... thank you. So it's a viewer thing, trying to smooth things I suppose. 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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