.comment-link {margin-left:.6em;}
Moriash Moreau: My Second Life
Wednesday, August 22, 2007
August Update
It's amazing how time works, sometimes. Weeks pass like days, yet days seem to take weeks. Or something like that. Sounded more profound in my head.

So, here it is, four weeks since my last update. Unfortunately, my RL has sapped both time and motivation for enjoying my SL, lately. So there's really not much to report here. Been kind of coasting since the Relay, in any case. I'd been working so long toward that goal that I hadn't given any thought at all to what would happen after. And now that it's disappeared from the collective SL unconscious for another year, I'm kind of floundering. I have found time and volition to work on a couple of silly projects, though.

Behold the amazing Mo-Tech Stress Relief HUD. Under pressure? Feeling stressed out? Just touch the red STRESS button, and a sheet of our patented Stress Relief Paper (AKA Bubble Wrap) will instantly appear. Just pop, pop, pop your cares away! And don't worry, once you pop that last bubble, the Stress Relief HUD will automatically create more. Now available for free from your friends at Mo-Tech Industries! Get yours now!

Ahem. Got a bit carried away there. Anyway, if you'd like a Stress HUD, you can pick one up on the second floor of the Mo-Tech shop. Link's up there on the right.

This one proved to be kind of an interesting project, mostly due to the number of prims involved. By necessity, each bubble is its own prim. Oh how I wish LSL had some method of returning which face was clicked! It would have reduced the prim count by at least four or five fold. As it was, this simple HUD weighs in at 79 prims. And that was after cutting it down multiple times.

I opted for a centralized script method, mostly to keep the sim from grinding to a screeching halt each time it was rezzed. It would have been much easier to put a script in each bubble, but sixty-some-odd scripts (one per whole bubble) for each HUD would have been a tad irresponsible. I'd intended using bitwise operators to track the status of each prim, with the prim at link number 1 being represented as bit 1 (2^1), link 2 being bit 2 (2^2), link 3 being bit 3 (2^3) and so on. You can probably see the flaw in this proposition: it would ultimately end up with 79 bits. (I tracked the 10 or so non-bubble prims as dummy values in the set, so that I wouldn't have to come up with an alternative numbering scheme. Much easier to just keep everything keyed to its link number.) This comes out to an integer potentially as large as 2^80 - 1. Strangely enough, LSL just isn't prepared to deal with numbers like 1,208,925,819,614,629,174,706,175.

Fortunately, I figured this out before wasting a lot of time on clueless debugging after the fact. (Surprisingly, too, considering that this is the first project I've done that even attempted to use bitwise operations. Oh well, maybe next time.) Instead, I settled on a list of integer 1's and 0's for status indicators. Prim 1 ended up as list entry 1, prim 2 as entry 2, and so on. Each time a bubble is touched, the script checks its link number, and compares it to the value in the list. If it's 1, it pops the bubble (swapping from a whole to a popped bubble texture, and playing one of three random popping sounds) and swaps the value to 0. When all the values are 0, revert all the bubbles back to 1, reset the popped bubble textures to unpopped, and we're good to go.

As an aside, I also tried using one long string instead of a list, and using string search and replace operations to check each time (character "1" in spot 47 corresponding to link 47, and so on). I timed each operation, and found that, in this instance, they were about equally fast. (A pokey half second per search, give or take a few hundredths. Oh Mono, where art thou?) Kind of surprising. I'd heard that string operations were generally faster than lists. Not this time, anyway. Worth noting, although your mileage may vary with more complex list items.

The other recent project is a working umbrella. This started out as an attempt to get my head around sculpties. Actually, I'd intended the bubble wrap to be my first significant sculpty project, but I couldn't make a convincingly "smooshed" bubble model. I'll probably come back to that later, when my skills improve and when I figure out some of the more sophisticated freeware modeling software. I'd love to make giant-size, three-dimensional, functional bubble wrap. Perhaps with a diving board, and a modest push to loft the av into the air with each pop... Hrm. Okay, maybe I'll get back to this sooner than later. It'll be a metric assload of prims, but I think I can make it work out.

But I digress. Sculpty umbrella. The umbrella fabric (two prims, one open, one closed) was made using Yuzuru Jewell's Rokuro software, set for six-fold symmetry (would have preferred eight, to match the typical large umbrella, but this looks convincing enough). The animations were made using Vinay Pulim's Avimator. Nothing terribly cutting edge or original about this one. Touch, and it swaps from the closed sculpt (switching to alpha 0.0) to the open sculpt (alpha 1.0), and triggers the Hold Umbrella animation. Touch it again, and it reverses the process and shuts down the animation.

From there, scope creep kicked in. It wasn't enough to just have a functioning umbrella! That just wouldn't be me.

First, I added in a simple parachute function. The basic function came together easily enough: run a timer, check for avatar status each tick. If the avatar is in the air and not flying, he must be falling. Trigger a custom falling animation (hanging free from the umbrella, which is pointing straight above), run an llSetForce to reduce gravity, and use impulses to prevent speed from exceeding a fixed downward velocity. Easy enough.

I've found that the fall-down effect will trigger if an avatar hits the ground faster than about 15 m/s. Currently, the umbrella limits falling speed to 10 m/s, but does nothing to limit lateral speed. So, if someone were to start falling with a good amount of forward velocity (say by turning off flight while flying forward at full speed), he'd still potentially hit the ground too fast and fall down. I spent some time trying to come up with a parasailing variant but, for now, I'll just stick with the safe-fall option for vertical movement. Maybe I'll get around to making it into a high-performance aerial vehicle at some future date.

As it turned out, dealing with the animations turned out to be kind of tricky. The problem is that the position of the avatar's hand changes relative to the umbrella's desired orientation. Basically, I had to come up with a way to rotate the attachment for each condition: held and falling. The held rotation needs to be free-floating, so that the end user can tweak it for his own needs. The falling rotation needs to leave the umbrella pointing straight up.

Rotation is easy, simply a matter of calling llSetLocalRot. But I never could find a way to rotate an attachment to an arbitrary rotation relative to the world. llSetRot, llSetLocalRot, llLookAt, llRotLookAt... All end up changing behavior relative to the attachment point. I'm stumped. I ultimately ended up having to rotate the umbrella attachment until it looked more or less vertical when the fall animation was called, then using llGetLocalRot to get the rotation. That rotation was hard coded into the script. Inelegant, but it works. If anyone out there knows a way to make an attachment rotate to face an arbitrary direction (say true North or straight up) from an arbitrary attachment point (say right hand), please leave me a comment.

From there, I ended up adding a slightly modified version of the elevation control script from my ancient Personal Gravity Control HUD (my clunky version of a flight assist). Type "/1 345", and the umbrella will pop open and fly to 345 meters, dragging the user behind it. It's nice to have canned scripts like that lying around, ready to enhance any random product that comes along with only a couple of minor tweaks.

I'm doing something similar with a generalized version of a menu-driven color control script. Activate the color menu, and select the desired color from the dialog box. Simple, and part of multiple projects already, but I've never taken the time to make it truly universal. Now, if I can just work out a vexing bug with the brightness control (allowing the user to pick, say, light, medium, and dark blue), I'll have a useful canned script that can be used with projects from now on. Well worth the time, even if this umbrella never makes it to public distribution.

Next up, perhaps, is a particle rainstorm that appears on demand. Or maybe I'll just leave well enough alone. We'll see.
You said...
Oh how I wish LSL had some method of returning which face was clicked!

It does...
edit the object
select the "select texture" radio button
hit [shift][control][alt] T
Now that's a good trick! Thanks! But not really what I was talking about. I meant some scripting language command that would allow the script to know which face a user touched on a touch event. Seems like it would be an easy thing to add (but then don't all the "simple" SL enhancements!), especially given that the trick you mention reads it out for you.

Anyhow, thanks for the tip. That'll come in handy!
Hehe.. love these old posts. Ye asked, ye have received. New functions available in SL (connected with mono) now not only return the face clicked, but the coordinates on the face in a relative displacement vector :P
Post a Comment

Links to this post:

Create a Link

Return to Main Page