Jump to content

Quistess Alpha

Resident
  • Posts

    3,999
  • Joined

  • Last visited

Everything posted by Quistess Alpha

  1. I think the closest thing is CTS wardrobe, but from my limited experience with it, it's not easy to use at all. (tried it for 10 minutes couldn't get it to work, moved on to something else)
  2. @Jenna Huntsman I got around to it! My converter works on the few test cases I tried (mostly bvh animations from open-collar) although it's not 1:1 with the viewer's conversion (it doesn't cull minute changes or 0-data, and I'm not sure why the bvh examples I have explicitly tell the avatar to go 46 inches upwards.) It turns out the math for the conversion is pretty straight-forward, but file-IO is a bit of a nightmare. If you're comfortable compiling from source, feel free to send me a message. There's still a bit of cleanup to do before I release it publicly* though. *if I release it publicly.. . on the one hand, was a decent amount of work, on the other, I'm not really interested in trying to add usability features like a file selection interface, and I don't really want to be obliged to explain to people how to use a command-line or compile from source. . .
  3. Sounds like fun! Currently only one person has actually filled out the form, so it looks like my get together will probably be on the weekend, evening US-time. (I'll be more specific tomorrow; stay tuned!)
  4. If anyone feels like modifying the wiki page posted in the OP, I'd recommend sending the rezzed HUD the hash of the person to attach to via its rez parameter, then having it sensor for them: default { state_entry() { llVolumeDetect(TRUE); } collision_start(integer NumberOfCollisions) { integer i = 0; for(; i < NumberOfCollisions; i++) { key give_to = llDetectedKey(i); llSay(0, "Rezzing HUD for " + (string)give_to); llRezObject(llGetInventoryName(INVENTORY_OBJECT, 0), llGetPos(), ZERO_VECTOR, ZERO_ROTATION, llHash(give_to) ); } } } // Example script for LSL Experience Tools attachment // This script runs on an object that is rezzed in-world which gets // an Experience permissions and then attaches to an AV. integer target_hash; integer log_spam_channel = 0; // Change this or remove llSay() commands default { on_rez(integer start_parameter) { // Start listening for a message from rezzer target_hash = start_parameter; llSensor("","",AGENT,5.0,PI); llSay(log_spam_channel, "Test HUD has been rezzed"); } sensor(integer n) { // Listen for the message from the rezzer with the target agent key llSetTimerEvent(0.1); // if no-one detected; time-out quickly. while(~--n) { if(llHash(llDetectedKey(n))==target_hash) { // Ask for the experience permission llSay(log_spam_channel, "Trying experience permissions request."); llRequestExperiencePermissions(llDetectedKey(n), ""); llSetTimerEvent(60.0); } } } experience_permissions(key target_id) { // Permissions granted, so attach to the AV llSay(log_spam_channel, "Trying llAttachToAvatarTemp()"); llAttachToAvatarTemp(ATTACH_HUD_CENTER_1); llSay(log_spam_channel, "After llAttachToAvatarTemp() with llGetAttached() returning " + (string)llGetAttached()); llSetTimerEvent(0.0); if (llGetAttached() == 0) { // Attaching failed llDie(); } } experience_permissions_denied( key agent_id, integer reason ) { // Permissions denied, so go away llSay(log_spam_channel, "Denied experience permissions for " + (string)agent_id + " due to reason #" + (string) reason); llDie(); } attach( key id ) { // Attached or detached from the avatar if (id) { llSetTimerEvent(0.0); llSay(log_spam_channel, "Now attached with a key " + (string)id + " and llGetAttached() returning " + (string)llGetAttached()); // From this point, the object can start doing whatever it needs to do. state running; } else { llSay(log_spam_channel, "No longer attached"); llDie(); } } timer() { // Use a timer to catch no permissions response llSay(log_spam_channel, "Permissions timer expired"); llDie(); } } // This state starts when permissions are granted and the object is properly attached state running { state_entry() { llSay(log_spam_channel, "off and running!"); } attach(key id) { if (id == NULL_KEY) { // if the object ever un-attaches, make sure it deletes itself llSay(log_spam_channel, "No longer attached"); llDie(); } } } (untested.)
  5. STATUS_ROTATE_X etc. might be prim properties? I'm busy working on a thing and am too lazy to go in-world and test. Try: llSetStatus(STATUS_ROTATE_X|STATUS_ROTATE_Y|STATUS_ROTATE_Z, TRUE);
  6. For me that option is greyed out when nothing is selected; try editing something and see if it comes available with something selected ot edit.
  7. The general solution is to edit the post for a quick update, or report yourself and ask a mod to remove it.
  8. It turns out converting rotations into Euler-vectors in strange orders is non-trivial. I hope nobody ever has to actually use these for anything serious. . . vector uRot2XYZ(rotation rot) { vector euler; vector temp; // x-axis temp = <0.0, 0.0, 1.0> * rot; euler.x = llAtan2(temp.z, temp.y) - PI_BY_TWO; rot /= llEuler2Rot(<euler.x, 0.0, 0.0>); // y-axis temp = <0.0, 0.0, 1.0> * rot; euler.y = -llAtan2(temp.z, temp.x) + PI_BY_TWO; rot /= llEuler2Rot(<0.0, euler.y, 0.0>); // z-axis temp = <1.0, 0.0, 0.0> * rot; euler.z = llAtan2(temp.y, temp.x); rot /= llEuler2Rot(<0.0, 0.0, euler.z>); return euler; } vector uRot2XZY(rotation rot) { vector euler; vector temp; // x-axis temp = <0.0, 1.0, 0.0> * rot; euler.x = llAtan2(temp.z, temp.y); rot /= llEuler2Rot(<euler.x, 0.0, 0.0>); // z-axis temp = <1.0, 0.0, 0.0> * rot; euler.y = llAtan2(temp.y, temp.x); rot /= llEuler2Rot(<0.0, 0.0, euler.y>); // y-axis temp = <0.0, 0.0, 1.0> * rot; euler.z = llAtan2(temp.x, temp.z); rot /= llEuler2Rot(<0.0, euler.z, 0.0>); return euler; } vector uRot2YXZ(rotation rot) { vector euler; vector temp; // y-axis temp = <0.0, 0.0, 1.0> * rot; euler.x = llAtan2(temp.x, temp.z); rot /= llEuler2Rot(<0.0, euler.x, 0.0>); // x-axis temp = <0.0, 1.0, 0.0> * rot; euler.y = llAtan2(temp.z, temp.y); rot /= llEuler2Rot(<euler.y, 0.0, 0.0>); // z-axis temp = <1.0, 0.0, 0.0> * rot; euler.z = llAtan2(temp.y, temp.x); rot /= llEuler2Rot(<0.0, 0.0, euler.z>); return euler; } vector uRot2YZX(rotation rot) { vector euler; vector temp; // y-axis temp = <1.0, 0.0, 0.0> * rot; euler.x = llAtan2(temp.x, temp.z)-PI_BY_TWO; rot /= llEuler2Rot(<0.0, euler.x, 0.0>); // z-axis temp = <1.0, 0.0, 0.0> * rot; euler.y = llAtan2(temp.y, temp.x); rot /= llEuler2Rot(<0.0, 0.0, euler.y>); // x-axis temp = <0.0, 0.0, 1.0> * rot; euler.z = llAtan2(temp.z, temp.y) - PI_BY_TWO; rot /= llEuler2Rot(<euler.z, 0.0, 0.0>); return euler; } vector uRot2ZXY(rotation rot) { vector euler; vector temp; // z-axis temp = <0.0, 1.0, 0.0> * rot; euler.x = llAtan2(temp.y, temp.x)-PI_BY_TWO; rot /= llEuler2Rot(<0.0, 0.0, euler.x>); // x-axis temp = <0.0, 1.0, 0.0> * rot; euler.y = llAtan2(temp.z, temp.y); rot /= llEuler2Rot(<euler.y, 0.0, 0.0>); // y-axis temp = <1.0, 0.0, 0.0> * rot; euler.z = llAtan2(temp.x, temp.z)-PI_BY_TWO; rot /= llEuler2Rot(<0.0, euler.z, 0.0>); return euler; } vector uRot2ZYX(rotation rot) { vector euler; vector temp; // z-axis temp = <1.0, 0.0, 0.0> * rot; euler.x = llAtan2(temp.y, temp.x); rot /= llEuler2Rot(<0.0, 0.0, euler.x>); // y-axis temp = <1.0, 0.0, 0.0> * rot; euler.y = llAtan2(temp.x, temp.z) - PI_BY_TWO; rot /= llEuler2Rot(<0.0, euler.y, 0.0>); // x-axis temp = <0.0, 0.0, 1.0> * rot; euler.z = llAtan2(temp.z, temp.y) - PI_BY_TWO; rot /= llEuler2Rot(<euler.z, 0.0, 0.0>); return euler; } vector uRot2XYX(rotation rot) { vector euler; vector temp; // x-axis temp = <1.0, 0.0, 0.0> * rot; euler.x = llAtan2(temp.z, temp.y)-PI_BY_TWO; rot /= llEuler2Rot(<euler.x, 0.0, 0.0>); // y-axis temp = <1.0, 0.0, 0.0> * rot; euler.y = llAtan2(temp.x, temp.z) - PI_BY_TWO; rot /= llEuler2Rot(<0.0, euler.y, 0.0>); // x-axis temp = <0.0, 1.0, 0.0> * rot; euler.z = llAtan2(temp.z, temp.y); rot /= llEuler2Rot(<euler.z, 0.0, 0.0>); return euler; } vector uRot2XZX(rotation rot) { vector euler; vector temp; // x-axis temp = <1.0, 0.0, 0.0> * rot; euler.x = llAtan2(temp.z, temp.y); rot /= llEuler2Rot(<euler.x, 0.0, 0.0>); // z-axis temp = <1.0, 0.0, 0.0> * rot; euler.y = llAtan2(temp.y, temp.x); rot /= llEuler2Rot(<0.0, 0.0, euler.y>); // x-axis temp = <0.0, 1.0, 0.0> * rot; euler.z = llAtan2(temp.z, temp.y); rot /= llEuler2Rot(<euler.z, 0.0, 0.0>); return euler; } vector uRot2YXY(rotation rot) { vector euler; vector temp; // y-axis temp = <0.0, 1.0, 0.0> * rot; euler.x = llAtan2(temp.x, temp.z); rot /= llEuler2Rot(<0.0, euler.x, 0.0>); // x-axis temp = <0.0, 1.0, 0.0> * rot; euler.y = llAtan2(temp.z, temp.y); rot /= llEuler2Rot(<euler.y, 0.0, 0.0>); // y-axis temp = <1.0, 0.0, 0.0> * rot; euler.z = llAtan2(temp.x, temp.z)-PI_BY_TWO; rot /= llEuler2Rot(<0.0, euler.z, 0.0>); return euler; } vector uRot2YZY(rotation rot) { vector euler; vector temp; // y-axis // interestingly, -PI_BY_TWO results in a different valid answer, the check o which is a negative quaternion. temp = <0.0, 1.0, 0.0> * rot; euler.x = llAtan2(temp.x, temp.z)+PI_BY_TWO; rot /= llEuler2Rot(<0.0, euler.x, 0.0>); // z-axis temp = <0.0, 1.0, 0.0> * rot; euler.y = llAtan2(temp.y, temp.x)-PI_BY_TWO; rot /= llEuler2Rot(<0.0, 0.0, euler.y>); // y-axis temp = <1.0, 0.0, 0.0> * rot; euler.z = llAtan2(temp.x, temp.z)-PI_BY_TWO; rot /= llEuler2Rot(<0.0, euler.z, 0.0>); return euler; } vector uRot2ZXZ(rotation rot) { vector euler; vector temp; // z-axis temp = <0.0, 0.0, 1.0> * rot; euler.x = llAtan2(temp.y, temp.x)-PI_BY_TWO; rot /= llEuler2Rot(<0.0, 0.0, euler.x>); // x-axis temp = <0.0, 0.0, 1.0> * rot; euler.y = llAtan2(temp.z, temp.y)-PI_BY_TWO; rot /= llEuler2Rot(<euler.y, 0.0, 0.0>); // z-axis temp = <1.0, 0.0, 0.0> * rot; euler.z = llAtan2(temp.y, temp.x); rot /= llEuler2Rot(<0.0, 0.0, euler.z>); return euler; } vector uRot2ZYZ(rotation rot) { vector euler; vector temp; // z-axis temp = <0.0, 0.0, 1.0> * rot; euler.x = llAtan2(temp.y, temp.x); rot /= llEuler2Rot(<0.0, 0.0, euler.x>); // Y-axis temp = <0.0, 0.0, 1.0> * rot; euler.y = llAtan2(temp.x, temp.z); rot /= llEuler2Rot(<0.0, euler.y, 0.0>); // z-axis temp = <1.0, 0.0, 0.0> * rot; euler.z = llAtan2(temp.y, temp.x); rot /= llEuler2Rot(<0.0, 0.0, euler.z>); return euler; } default { state_entry() { rotation r = <0.5,0.4,0.3,0.7071>; rotation check; vector XYZ = uRot2XYZ(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<0,0,1>,XYZ.z)* llAxisAngle2Rot(<0,1,0>,XYZ.y)* llAxisAngle2Rot(<1,0,0>,XYZ.x); llOwnerSay(llList2CSV(["XYZ",RAD_TO_DEG*XYZ,check])); vector XZY = uRot2XZY(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<0,1,0>,XZY.z)* llAxisAngle2Rot(<0,0,1>,XZY.y)* llAxisAngle2Rot(<1,0,0>,XZY.x); llOwnerSay(llList2CSV(["XZY",RAD_TO_DEG*XZY,check])); vector YXZ = uRot2YXZ(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<0,0,1>,YXZ.z)* llAxisAngle2Rot(<1,0,0>,YXZ.y)* llAxisAngle2Rot(<0,1,0>,YXZ.x); llOwnerSay(llList2CSV(["YXZ",RAD_TO_DEG*YXZ,check])); vector YZX = uRot2YZX(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<1,0,0>,YZX.z)* llAxisAngle2Rot(<0,0,1>,YZX.y)* llAxisAngle2Rot(<0,1,0>,YZX.x); llOwnerSay(llList2CSV(["YZX",RAD_TO_DEG*YZX,check])); vector ZXY = uRot2ZXY(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<0,1,0>,ZXY.z)* llAxisAngle2Rot(<1,0,0>,ZXY.y)* llAxisAngle2Rot(<0,0,1>,ZXY.x); llOwnerSay(llList2CSV(["ZXY",RAD_TO_DEG*ZXY,check])); vector ZYX = uRot2ZYX(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<1,0,0>,ZYX.z)* llAxisAngle2Rot(<0,1,0>,ZYX.y)* llAxisAngle2Rot(<0,0,1>,ZYX.x); llOwnerSay(llList2CSV(["ZYX",RAD_TO_DEG*ZYX,check])); vector XYX = uRot2XYX(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<1,0,0>,XYX.z)* llAxisAngle2Rot(<0,1,0>,XYX.y)* llAxisAngle2Rot(<1,0,0>,XYX.x); llOwnerSay(llList2CSV(["XYX",RAD_TO_DEG*XYX,check])); vector XZX = uRot2XZX(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<1,0,0>,XZX.z)* llAxisAngle2Rot(<0,0,1>,XZX.y)* llAxisAngle2Rot(<1,0,0>,XZX.x); llOwnerSay(llList2CSV(["XZX",RAD_TO_DEG*XZX,check])); vector YXY = uRot2YXY(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<0,1,0>,YXY.z)* llAxisAngle2Rot(<1,0,0>,YXY.y)* llAxisAngle2Rot(<0,1,0>,YXY.x); llOwnerSay(llList2CSV(["YXY",RAD_TO_DEG*YXY,check])); vector YZY = uRot2YZY(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<0,1,0>,YZY.z)* llAxisAngle2Rot(<0,0,1>,YZY.y)* llAxisAngle2Rot(<0,1,0>,YZY.x); llOwnerSay(llList2CSV(["YZY",RAD_TO_DEG*YZY,check])); vector ZXZ = uRot2ZXZ(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<0,0,1>,ZXZ.z)* llAxisAngle2Rot(<1,0,0>,ZXZ.y)* llAxisAngle2Rot(<0,0,1>,ZXZ.x); llOwnerSay(llList2CSV(["ZXZ",RAD_TO_DEG*ZXZ,check])); vector ZYZ = uRot2ZYZ(r); check = // linden rots are reverse from math rots. llAxisAngle2Rot(<0,0,1>,ZYZ.z)* llAxisAngle2Rot(<0,1,0>,ZYZ.y)* llAxisAngle2Rot(<0,0,1>,ZYZ.x); llOwnerSay(llList2CSV(["ZYZ",RAD_TO_DEG*ZYZ,check])); } }
  9. seems a bit inefficient string add_commas(integer n) { string result = (string)n; integer index = llStringLength(result); while((index-=3)>0) { result = llInsertString(result,index,","); } return result; } then again, I'm not sure the relative efficiency of llInsertString vs 3 passes on a loop. I could make that fancier. . . string add_commas2(integer n) { string s= (string)n; string result; integer index_max = llStringLength(s); integer index = index_max%3; if(index==0) index=3; result+=llGetSubString(s,0,(index-1)); //llOwnerSay(result); for(;index<index_max;index+=3) { result+= ","+llGetSubString(s,index,index+2); //llOwnerSay(result); } return result; }
  10. I'm always happy to try and explain spacial math to anyone who asks, but it's much easier to do in-world with access to 3d. "The i,j,k parameters of a quaternion are a vector representing the axis of rotation, the length of which is the chord length on a unit-diameter circle of the angle to rotate, the real component is the chord length of 180 degrees minus the angle on the same circle" doesn't make a lot of sense without pictures. Even explaining an 'axis of rotation' gets kinda tricky. I've tried explaining it via 2d slices of an object before, but maybe that just confuses things further. The fact that any 'turning' of space always has exactly a line of points that don't change position isn't immediately obvious to many people . . .
  11. It wouldn't be at all hard for anyone familiar with blender to take a open-source body (for example, ruth/roth or one they made themself), expand it 1~2% and invert normals, to get the outline effect. (then ofc. add a rainbow texture and lots of glow.)
  12. Probably some object rezzed in-world, possibly near a landing point so it can scan for avatars more efficiently. Yes, both.
  13. The functions which change an avatar's environment (llSetAgentEnvironment() and llReplaceAgentEnvironment() ) need to have experience permissions, so while you could certainly use them in an attachment, the script would still only work when you're on a parcel that has the experience the script is compiled to enabled.
  14. It's kinda hard to say where your rotation code should go in the context of the whole script without the whole script. I'm also not 100% understanding what you're trying to achieve. Something like: default { state_entry() { llSetStatus(STATUS_PHYSICS,TRUE); llSetHoverHeight(0,TRUE,5.0); llSetTimerEvent(0.1); } timer() { vector posOwner = llList2Vector(llGetObjectDetails(llGetOwner(),[OBJECT_POS]),0); vector Z = <0,0,1>; vector Y = llVecNorm(posOwner-llGetPos()); vector X = Y%Z; Z = X%Y; llRotLookAt(llAxes2Rot(X,Y,Z),0.5,0.1); } } will look it's Y-axis towards its owner, keeping it's Z-axis pointing 'up' in the most obvious way, while floating up to water level. (constants can be adjusted to taste.)
  15. Hey all, Tessa here. I'm planning a simple board game night for some time next week and you (Yes, You!👇) are invited! My collection of games mostly includes 2-player perfect strategy games (Chess,go,reversi,connect-4,Berserker and more) although I do also have Greedy-Greedy, a non-game-specifc deck of cards, and a multi-player strategy game I scripted myself. You are more than welcome to bring your own games or recommend some before the event. This will be hosted on a General-rated region. I'll be announcing the exact time either Friday or Saturday after collecting results from this WhenIsGood poll Please fill it out if you're interested, so I can pick a time (or times) that works for the most people. With any luck, I'll be seeing all of you next week! ~Tessa. P.S. I'll probably be hosting with my alt Eris (Eristizia.Resident) to keep my friends list sane, among other things.
  16. @Haru Takeda A set of animations for holding a hand of cards (as in poker/uno etc.) would be nice.
  17. That's why I made my example above with a while loop rather than a timer. Although, Yeah that's not the nicest method.
  18. You're not just paying for the "technology" or computation power, you're also paying for access to Secondlife(tm)'s virtual world, and the social environment it provides. If you want all the prims and compute power you can pay for, maybe a kitely opensim server would be a better fit for you, just don't expect anyone to visit, or be able to find nice-looking and legal(not copy-botted) clothing.
  19. The way I'd think about it is how long it'd take the landlord to make a return on their investment. Assuming tier is negligible (it isn't but it makes the math easier) Renting at 700/week will make back an initial investment of 150,000 (somewhat low at the moment) in a bit more than 4 years. Given the challenge of actually finding someone to rent the parcel from you, and the long time window, it doesn't really seem like it makes that much business sense to buy the parcel just to rent it. If you're just trying to recoup some of your losses from your giant land-holding scandal though. . .
  20. Another avenue to explore is testing llGetAccel(); If it's neither ZERO_VECTOR, nor <0,0,-9.8>, then some non-gravitational force or impulse (or collision) is being applied to the object. kinda fun to play with: default { state_entry() { vector accel; while(TRUE) { accel=llGetAccel(); if(llVecDist(accel,ZERO_VECTOR)>0.01 && llVecDist(accel,<0,0,-9.8>)>0.01) { llOwnerSay((string)accel); llSleep(0.2); } llSleep(0); } } }
  21. Besides the intellectual intrigue of the problem as stated, I'm having trouble thinking of a case in which I would expect a script that I didn't write* to apply a force to an object that I own, through llPushObject rather than direct contact. Having an attachment/HUD detect if the wearing avatar is being pushed seems reasonable**, but that doesn't seem to be your use-case. Often when LSL doesn't let you do some specific thing, it's useful to take a step back and think about the broader picture of the end result you're trying to achieve and think if there's a better way of going about it. I'm just guessing, but "detecting if an object was pushed by llPushObject" seems like an instrumental part of a larger design to me, and perhaps not actually what you need to do. *If you wrote the pushing script, you could of course llRegionSayTo(); the pushed object that it's being pushed. **For that I'd try and test the direction of llGetVel(), vs <1,0,0>*llGetRot(); making sure the avatar isn't seated nor in mouse-look. turning off detection while controls are in use, and using some trick or other to not fire directly after a collision (I wouldn't be surprised if you'd need to do some tricky logic to not trigger directly *before* a collision as well.)
  22. Depends on the relay. Some relays will basically let you (the 'griefer') temporarily add yourself as an exception to do force teleports, but others seem to miraculously remove your exception the moment you're off sim to offer the teleport. Coffee's method (almost) always works, but it's a mild pain to get region coordinates.
  23. By that logic you could argue that kids should be watching anime, because most of them were adapted from light novels which are ~oh so educational books.
  24. I'm also a bit perplexed. One special feature of note is that certain sections (some of the north west of the continent below horizons) have parcels which are not join-able or sub-dividable (such regions generally have a road exactly along the sim border), and high prices seem to keep a de-facto standard of build quality about, even without Beli-style rules.
×
×
  • Create New...