Jump to content

GManB

Resident
  • Posts

    237
  • Joined

  • Last visited

Everything posted by GManB

  1. That's what I am doing. The list holds just the randomized indexes into a notecard with the answers. I don't see any way other than a list. One could randomly generate the indexes but to avoid dups you would have to keep a list of the used values. Not efficient in time. G
  2. A script I am writing is getting pretty large and am running up against the 64K memory limit (which I think is the maximum for a script). I have some general questions and then an ask about a specific chunk of code. Any general patterns to keep programs under the 64K limit? I assume I could break the program up into separate, communicating, programs. Any comments on general patterns for such a separation? Any general ideas for saving memory? Here is the code that's taking up the last bits of memory. If totalNumAnswers is over about 600 I get the stack heap collision message. I could limit the number of answers to about 1K, I think, reasonably. I'm guessing storing strings is probably less memory intensive than integers, but any thoughts? The description of llListRandomize seems to indicate that it randomizes the elements in the list in place but anyone know any gotchas? CreateScrambledAnswerList() { integer i = 0; scrambledAnswerIndicies = []; for(i=0;i<totalNumAnswers;i++) { scrambledAnswerIndicies = scrambledAnswerIndicies + (string)i; } scrambledAnswerIndicies = llListRandomize(scrambledAnswerIndicies, 1); } Thanks, G
  3. Thanks. I got the Slink dev kit, MayaStar ( I use Maya for creating mesh), and Marvelous Designer. Watched a bunch of videos andanaged to create a halter top dress, rig it, and import to sl. An avatar can wear it. Lots to learn about how get a good mesh and rigging but I understand the work flow now. Thanks, G
  4. @KT Kingsley Could you post how I would export the .dae file with Firestorm? I have looked and searched but can't find out how to do this. Thanks, G
  5. Thanks Chic and KT! I now have the high-level view of the process that I needed to get started. Thanks so much, and best holiday wishes to you and yours!! I purchased the MayaStar plugin for Maya as I use Maya for creating mesh. About to start viewing the tutorial videos. Here's a pic of my first attempt at a women's silk blouse. Not the greatest but good enough to attempt rigging, I think. https://gyazo.com/d231423b4fe291d37c5ef87b34963c68 I modified the human female shape that comes with Maya to match the proportions of a friend of mine who has a Maitreya Laura body. Rigging this to the rigged model that comes with MayaStar will, I am almost certain, provide me only with some skill and a lot of laughs... About the 'difficulty' getting a 'real' creators kit.... [lots of expletives deleted] (got that off my chest a bit).... Wow, what a transparent attempt to keep clothing prices high... simply restrict who can make them... I did apply for a Maitreya kit and got zero response... seems like this artificially imposed oligopoly is just aching for disruption... Cheers, G
  6. I posted this in Fashion but not many ppl follow that forum so I thought I would cross post. I've built, textured, and scripted a fair number of mesh objects and I thought I'd give clothing a try. Could someone give me a high level overview of how a mesh object, that looks a lot like a blouse :), becomes a blouse? Ie., fits nicely on a body and moves, mostly, with the body. I tried just attaching the blouse to my chest with the obviously and hilarious results. Are there scripts that need to be added to its contents? If so, are such scripts available, and where do I find them (or do I write them)? What makes a piece of clothing specific to a body type? What typically comes in the developer kit I see for some bodies? Any and all responses appreciated greatly! G
  7. I've built, textured, and scripted a fair number of mesh objects and I thought I'd give clothing a try. Could someone give me a high level overview of how a mesh object, that looks a lot like a blouse :), becomes a blouse? Ie., fits nicely on a body and moves, mostly, with the body. I tried just attaching the blouse to my chest with the obviously and hilarious results. Are there scripts that need to be added to its contents? If so, are such scripts available, and where do I find them (or do I write them)? What makes a piece of clothing specific to a body type? What typically comes in the developer kit I see for some bodies? Any and all responses appreciated greatly! G
  8. Thanks. I found another way. Attach via right-click from inventory. Position with build tool. Detach-to-inventory. Now the prim 'remembers' it's position on the screen and when I call llAttachToAvatarTemp(), with, apparently any attache point, the HUD/prim attaches to location where it was when it was detached-to-inventory. @KT Kingsley I agree. This positioning is just to be the default initial and there is another artifact in this game I am building, the game table.For the table I set the avs cam to look straight down onto the table with the table positioned to the left side of the display and I wanted the HUD on the right side but, obviously, fully visible. Users are free to move things around and adjust their cam as they see fit. As a side note I was surprised at the number of friends who did not know how to move a HUD around on a display :(... Or resize it as well... They all clamored for a resize button ... @Nova ConvairAh, missed that it's the center of the *root* prim not the center of the linkset. That's my experiment with the transparent prim didn't change the behavior. G
  9. I am using llAttachToAvatarTemp(ATTACH_HUD_*) to attach an object as a HUD from a script in a manner so that the user has only to reply 'Yes' to the permissions UI. The size of the object is <0.01100, 0.43733, 0.59333> and the orientation is correct (in that the proper face appears on the display when attached). The object is a link set. If I attach to either ATTACH_HUD_CENTER_1 or ...2, I see the complete proper face. If I use any of the other ATTACH_HUD_* values however part of the object's proper face is off the display. E.g., if I use ATTACH_HUD_TOP then the top have of the object's face is off-display or for ATTACH_HUD_TOP_RIGHT only the lower left quarter of the object's face is visible. It seemed as though llAttachToAvatarTemp() was attaching so that the center of the object was at the position but linking in a transparent prim so that the center of the newly linked object was in an appropriate position made no different in the visible portion of the object's face. Note that I see the exact same positioning when I attach the object by right clicking the object's entry in my inventory and selecting 'Attach to HUD'. I, of course, have HUDs that position themselves in the corners with proper visibility. How can I control the positioning of a HUD using llAttachToAvatarTemp()? Also, my customer wants a resize button in the HUD. I haven't tried this yet but I am assuming llSetScaleByFactor() should work as expected. If there are any quirks here I'd appreciate knowing. Thanks, G
  10. Agree. The practicality depends on the rate of change of the notecard. If that is hourly, then this isn't practical. If quarterly then it works.
  11. I *may* have a (rather cheeky) solution to the original question not involving external databases or Experiences. I offer a brief description to stimulate discussion (including why this might not work) and for the simple pleasure of (possibly) finding a cute workaround. Inherent in the original post is that editing the central notecard causes it to have a new uuid and, thus, the problem end up being how to get this new uuid to the servers. The cheeky solution is to use the Display Name of an Avatar as a repository for the new uuid (we need some tweaks to the uuid and these are explained below). An Avatar's display name is available grid-wide whether the avatar is logged in or not via llRequestDisplayName(key id). The idea would be to create an SL account specifically for the purpose of passing these new uuids. The servers can poll for a new uuid, say, daily, by making a call to llRequestDisplayName(key id) with the id of the avatar of this new account, convert it to a uuid and check to see if it is new, and if so, begin using it to read the new notecard. Tweaks: A display name is limited to 31 characters and a uuid has 32 significant characters (less the hyphens '-'). So we would need to encode the uuid into a base64 representation. ------------- An example: llOwnerSay(HexToBase64("59cf1ef6ce1bdd30ba22fe8aa404b11c")); ("59cf..." is the uuid of a notecard less the hyphens, 32 characters) output: Wc8e9s4b3TC6Iv6KpASxHA (22 characters and thus could be used as a display name). ----------------- Another issue is that a base64 representation includes the characters '/' and '+' neither of which are allowed in a display name. So we would need to do some post-processing to the base64 and replace those to characters with two that are allowed in a display name but are not in the base64 set. There are a number of these so it's not an issue. If there is some interest in this solution I'll be happy to collaborate on implementing and testing it. Cheers, G
  12. I thought I'd post the code I have decided to use and add, for posterity, some observations made along the way. The two simple code snippets below create and control the desired motion in a prim. The Controller toggles, on touch, either a link message or a call to llResetOtherScript(). The TumbleScript waits for a link message to start tumbling then does a state change to the infinite loop. When reset the TumbleScript returns to the default state and waits for the message. I don't think two states are actually needed but it seems cleaner to me but probably mostly aesthetics. The infinite loop is very similar to what Wulfie R posted above with a couple of modifications. We conducted some experiments and noticed that llGetTime() is actually incremented only once per sim frame. Thus, multiple calls to it within the same frame return the same value. Given that, the rotation was being actually changed only once per sim frame. Also noticing that the time was being used as just a strictly increasing value we could get rid of the call to llGetTime(). The initial rot value can be just about anything, but zero seems nice. The iteration increment is the time of a sim frame so I would expect this loop to iterate about once per sim frame which gives nice smooth motion. The rotation increment comes from noting that in the initial script the returned values from llGetTime() went up about 0.022 each time it returned a value different from the previous call. I did attempt to use KFM but never got smooth motion or if smooth not the tumbling I wanted. Not sure why but am certain I don't really understand KFM details well enough. I understand our natural aversion to infinite loops but this solution seems reasonably safe. In the final version I will give the owner some options to change the rotation speed and maybe the multipliers for different rotational patterns. Here's a link to the finished result. https://gyazo.com/51e7c3fde4ee83e5162a62f37d864b54 ------------------------ Controller --------------------- integer tumbling = FALSE; default { touch_start(integer total_number) { if (tumbling == FALSE) { tumbling = TRUE; llMessageLinked(LINK_THIS, 0, "startTumbling", NULL_KEY); } else { llResetOtherScript("TumblerScript"); tumbling = FALSE; } } } -----------------------Controller END ----------------------- --------------------- TumbleScript ----------------- float initialRotValue = 0; float rotIncrement = 0.022; float iterationIncrement = 0.022; rotation r = ZERO_ROTATION; float xMultiplier = 1.0; float yMultiplier = 0.5; float zMultiplier = 2.0; default { link_message(integer sender_num, integer num, string str, key id) { if (str == "startTumbling") { state tumbling; } } } state tumbling { state_entry() { while (TRUE) { r = llEuler2Rot(<initialRotValue * xMultiplier, 0.0, 0.0>) * llEuler2Rot(<0.0, initialRotValue * yMultiplier, 0.0>) * llEuler2Rot(<0.0, 0.0, initialRotValue * zMultiplier>); initialRotValue += rotIncrement; llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROTATION, r]); llSleep(iterationIncrement); } } } --------------------- TumbleScript END -----------------
  13. If I do end up using KFM it also prevents any events being received by the script in which it it running. So, I will need one of the above techniques to keep control of the tumbler. Seems I'll need three scripts. My current thinking is to use llResetOtherScript() when the main script needs to send a command but the main script will not be in the tumbler. So I need a script in the tumbler to receive a message for the tumbler (start, stop, change speed, change the ratios among the axes, etc), from the main script, call llResetOtherScript() on the tumbler, then send the message from the main script to the tumbler via a link_message. In the end I need only the tumbler script because the tumbler already has the script to receive commands from the main script. I am looking forward to seeing this work!!
  14. I've left mine running. with the llSleep(), for a while and it smoothed out. Could be the compute demand of the sim lessened. Any thoughts on how we might slow the rotation speed? I think, that we would need smaller intervals between subsequent calls to llGetTime() while keeping the loop iteration time constant. Not easily done, I see. So, I'll probably collect a list of times from this loop, find the average different between two subsequent measurements, and then just increment the 'time' variable by smaller values. This increment can then be used to simply adjust the rotation speed. Make sense? G
  15. @Wulfie ReanimatorNot, yet. I will probably put it on the MP but I will drop you a copy now. I put the loop in a different state just to test if I could regain control w/o resetting the script. Of course, that didn't work. Also, I experimented with values for the argument to llSleep() from 1.0 to .01. None seemed to affect the rotation rate. My guess is that since we are using time waiting longer just results in a larger difference in the value of time. I will try the above suggestion to get control. But I also want to investigate the motion keyframe api. I'm thinking to generate the list of rotation as we do here then feed it to mkf. Using time should still be fine because here we are just interpreting it as a float and not really a time. G default { touch_start(integer total_number) { if (startRotation == TRUE) { startRotation = FALSE; } else { startRotation = TRUE; state spinning; } } } state spinning { touch_start(integer num_detected) { llOwnerSay("foo"); } state_entry() { float time; rotation r; while (startRotation == TRUE) { time = llGetTime(); r = llEuler2Rot(<time, 0, 0>) * llEuler2Rot(<0, time*0.5, 0>) * llEuler2Rot(<0, 0, time*2>); llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROTATION, r]); llSleep(0.1); } } }
  16. Smoother, but not as smooth as in the video you gave. Is there any way for a prim that is executing such a loop to receive another event? AFAIK there is not but am hoping to be told otherwise. Thanks, G
  17. Yes! Multiprim objects are next on my list. Here is a video of the object for which I want the different rotation. https://gyazo.com/725d43956b1dab765a0c7f7b7700a209 Next is to make something similar where the spikes rotate individually. G
  18. Yes, axis of rotation to change smoothly over time. The video is exactly the motion I want. How did you get it so smooth? Are you using llTargetOmega or llSetLinkPrimativeParamsFast and a timer? I tried the latter and my object's motion is very jerky. Thanks, G
  19. I'd like to have an object rotate smoothly around all three axes simultaneously. I suppose the best RL analog would be a spacecraft tumbling around its axes. I do not want to change the position of the object. I've tried with llTargetOmega() but setting varying values for x,y,z in the vector argument just sets an axis of rotation, that is offset from the world axes by the values, and the object rotates around that axis. I'm experimenting with llSetLinkPrimitiveParamsFast(), code snippet below. But the motion is jerky. Right now I am just incrementing the rotation or each axis by the same amount but would vary this to give more interesting motion later.) Any ideas on how to do with with smoother motion, maybe with KFM? Or even some way with llTargetOmega() that I am not seeing? Thanks, G touch_start(integer total_number) { integer i = 0; if (startRotation == TRUE) { llSetTimerEvent(0.022); startRotation = FALSE; } else { llSetTimerEvent(0.0); startRotation = TRUE; } } timer() { llSetLinkPrimitiveParamsFast(LINK_THIS, [PRIM_ROTATION, llEuler2Rot(<xDegree, yDegree, zDegree>*DEG_TO_RAD)]); xDegree += 0.2; if (xDegree > 360.0) xDegree = 0.0; yDegree += 0.2; if (yDegree > 360.0) yDegree = 0.0; zDegree += 0.2; if (zDegree > 360.0) zDegree = 0.0; }
  20. Thanks Sabrina! Yes, what you suggest was what I had in mind. Cheers, G
  21. Thanks. In going through the Best Scripter Tips and Shortcuts I realized I had fallen into a trap I had dug myself out of a few months ago. lol In previous execution environments, with which I have been deeply involved, timers were separate objects, more than one was possible, and they each fired at their given rate independently of other timers. So we could do the equivalent of llSetTimerEvent(7.0); llSetTimerEvent(3.0); and we would get events at times, 3, 6, 7, 9, 12, 14, 15, ... The trap was thinking in that model instead of the LSL environment where the above would generate events at 3,6,9,12,15 ... (no events at 7 and 14) because we essentially have only one timer object and the call with 3.0 as the argument resets that timer. In the LSL single timer model global variables are sufficient. And, as in Rolig's example, for multiple timers we have to create a 'base' timer that evenly divides all of the work timers and keep track of the individual times ourselves in timer(). G
  22. As far as I can tell there is no way to distinguish what call to llSetTimerEvent() is being handled once inside the timer() function. I find myself having to rely on global variables way too much to make things work. Seems like this could get complicated pretty easily. Is there another way to create timed events that can be handled more like, say, a dataserver event? Thanks, G
  23. I don't see any api specific to getting a notecard description and getting object descriptions seems to apply only to a prim. Am I missing something? Thanks, G
×
×
  • Create New...