Archive for the ‘MV-SL-Tutorials’ Category

Creating a Slideshow Viewer, Part 2: Reading the Inventory

Sunday, October 16th, 2011

This is the second installment in my small series about creating a slideshow viewer (based on my new texture vendors). In this one, I’ll be showing you how to add images to the viewer.

In my original texture vendors, the prim which displayed the images was responsible for creating a list of the images available, and then of moving through the images when it received a message from one of the buttons.

In the new version, all of this is handled by the Frame prim, which looks for touch events and determines which button was ‘clicked’, and which then updates the texture on the Display prim. This is made possible by another relatively new script function, llSetLinkTexture(), which allows the texture of a prim to be assigned by another (linked) prim.

There are two elements to handling the images. The simplest is assigning a specified texture to the Display prim. However, in order to do this the Frame needs to have the textures stored in it, and needs to be able to make a list of the available textures.

Let’s start by creating this list. First, edit the Frame prim. As the Frame prim and the Display prim are linked, click the ‘Edit linked’ check box on the build dialog, then click on the Frame. Now switch to the contents tab, and drop your images (textures or snapshots) into it.

Now we need to write a script that will create a list of those images. If you have been following along, you will already have a script in the Frame prim, to handle the buttons. Update this to the following code:

    // A list to hold the image keys
    list images = [];
    readImages()
    {
        // Count the number of textures
        integer count = llGetInventoryNumber(INVENTORY_TEXTURE);
        integer i;
        string name;
        images = [];
        // Look through all the texture
        for (i = 0; i < count; i++)
        {
            name = llGetInventoryName(INVENTORY_TEXTURE, i);
            // Get the key, and add it it to the list
            images += [llGetInventoryKey(name)];
        }
        // If we have at least one image, display the first one.
        if (llGetListLength(images) > 0)
        {
            llSetLinkTexture(LINK_ROOT, llList2Key(images, 0), 0);
        }
    }
    float btn_Cols = 8.0;
    float btn_Rows = 8.0;
    integer btn_Id(vector pos)
    {
        integer button = (btn_Row(pos) * (integer)btn_Cols) + btn_Col(pos);
        return button;
    }
    integer btn_Row(vector pos)
    {
        // Flip the y-axis, so that it runs from top to bottom.
        float y = 1.0 - pos.y;
        integer row = (llFloor((y * 10) * btn_Rows) / 10);
        return row;
    }
    integer btn_Col(vector pos)
    {
        integer col = (llFloor((pos.x * 10) * btn_Cols) / 10);
        return col;
    }
    default
    {
        state_entry()
        {
            readImages();
        }

        touch_end(integer count)
        {
            vector mousePos = llDetectedTouchST(0);
            integer id = btn_Id(mousePos);
            llOwnerSay("Button " + (string)id + " pressed");
        }
    }
    

This finds all the texture items in the prim’s contents, and stores their names in the Image list. Once that is done, it gets the first image from the list, and assigns it on the Display prim.

The llSetLinkTexture() function is used to display the image. The allows us to set the texture of another prim, in this case the display prim, by specifying the prim number, the UUID of the texture (which we read from our list), and the face, which is here assumed to be face 0.

One thing to be careful about here is that it assumes that the Display prim is prim 0, that is, the root prim. If you don’t already know how to do this, the trick is that when you select the prims that you want to link, the root prim should be the last prim that you select before linking. In this case there are only two prims, so select the Frame prim first, then Shift+Click the Display prim to add it to the selection. Finally link the prims (the option to link is on the Build menu in Viewer 2, and in most third-party viewers).

Creating a Slideshow Viewer, Part 1: Buttons

Tuesday, October 11th, 2011

Recently I decided to update my Texture Vendors. If you have seen my stores inworld, you will know that the Texture Vendors display one texture at a time, with buttons to let you cycle through the different textures in the set.

The current version of the vendors was created quite a while ago, and uses techniques that are now out-dated and inefficient. Each vendor uses three scripts — one for each button, and a script in the central prim to actually display the texture. Messages are sent from the script to the central prim to tell it to change textures.

With some of the new features that have appeared over the last couple of years it should now be possible to reduce those three scripts into one much more efficient script, and that’s what I am planning on doing.

While I am doing it, I am also going to write it up in this blog, because the basic idea of a gadget which lets you move forwards and backwards through a set of images obviously has more uses than just as a texture vendor.

The slideshow needs at least two buttons, to move forwards and backwards through the slides. It might need ‘first’ and ‘last’ buttons as well.

Until a couple of years ago the only reasonable way to implement buttons was to create a prim for each button, with a script in each prim to detect a touch event, and probably then to send a message to some kind of controller. This is the way my existing vendors work, and you can see that this is hardly efficient for either prims or scripts.

In Viewer 1.21, however, the llDetectedTouchST() function was introduced (along with some other related and useful functions). This allows you to detect which point on a prim face was touched. This makes it possible to have several buttons as a single texture, and then determine which button was actually clicked on.

Second Life Wiki: “Detected” functions

To test this out, and create a starting point for the viewer, I’m going to create two prims. One will be the surface on which the images will be displayed, and the other will be the surrounding frame, which will include any buttons.

Create two prims, one with a size of 1.0 x 1.0 x 0.1, which will be the frame, and the other with a size of 0.75, 0.75, x 0.1, which will be the display face. For the frame, set it to hollow, at a value of 80, and rotate both prims so that they are facing the right way. Centre the display prim inside the frame prim. Given those values, you should find that the prims fit together exactly. Set the textures to blank.

If you want a larger version, try setting the frame to 2.0 x 2.0 x 0.1, hollowed to 75, and the display frame to 1.5 x 1.5 x 0.1.

To test the buttons, I’m going to use a grid texture. I’ll assign it by UUID using a temporary script, so that you can use the same texture. In the Frame prim, create the following script. You might need to change the ‘face’ parameter to get the image onto the correct side of the prim. Once the texture has been applied, you can delete the script again:

    default
    {
        state_entry()
        {
            integer face = 0;
            llSetTexture("53e5f19a-70a0-ae65-831f-da5f4ec69fdb", face);
        }
    }
    

You should end up with something like this (I’ve coloured the display prim for clarity, but actually you should leave it white):

Blog tutmisc 0002a

We now have an 8×8 grid, of which the outermost cells are visible. Now we can test the button-handling. To work out which cell was clicked on requires a little bit of calculation, based on the size of the grid. The code I’m using is relatively generic, so you can modify it for different button layouts simply by changing the ‘btn_Rows’ and ‘btn_Cols’ values.

Create a new script in the Frame prim, and copy in the following code:

    float btn_Cols = 8.0;
    float btn_Rows = 8.0;
    integer btn_Id(vector pos)
    {
        integer button = (btn_Row(pos) * (integer)btn_Cols) + btn_Col(pos);
        return button;
    }
    integer btn_Row(vector pos)
    {
        // Flip the y-axis, so that it runs from top to bottom.
        float y = 1.0 - pos.y;
        integer row = (llFloor((y * 10) * btn_Rows) / 10);
        return row;
    }
    integer btn_Col(vector pos)
    {
        integer col = (llFloor((pos.x * 10) * btn_Cols) / 10);
        return col;
    }
    default
    {
        touch_end(integer count)
        {
            vector mousePos = llDetectedTouchST(0);
            integer id = btn_Id(mousePos);
            llOwnerSay("Button " + (string)id + " pressed");
        }
    }

Now try clicking on the grid. As you do so, it should display (in local chat) the number of the cell that you clicked. The top-left cell should be 0, and the bottom-right cell should be 63. You might need to rotate the prim if this is not the case, although as long as you know which cell is where, you don’t necessarily need to do that. It’s just more convenient.

Aside: Why am I using touch_end() instead of touch_start()? This is because if you use touch_start() to trigger a state change, the touch_end gets ‘lost’ (it’s expecting the wrong script state), which can cause problems, and result in touches not being detected. Using touch_end() is safer. If you know that you are not going to change state, you can use touch_start().

LSL Scripts: Scrolling floating text

Wednesday, August 24th, 2011

This is one of an occasional series of small but (I hope) useful pieces of code.

Floating text above a prim has a lot of uses in Second Life, and here is a script which might add even more possibilities. This takes advantage of the fact that you can display multiple lines of text and uses this to create a scrolling text display, like so:

It works very simply. We have a list which stores the lines to be displayed. To add a new line to the text, and to scroll the text up, we remove the first entry in the list, and add the new entry at the end. To display the text, we just string the entries in the list together, separating them with a new-line, and set the result as the floating-text for the prim.

In this little example program, a line of text is added whenever the prim is touched.

list lines = ["", "", "", "", ""];
addLine(string line)
{
    // Add the new message to the end of the list, losing the first entry
    // from the list at the same time.
    lines = llList2List(lines, 1, llGetListLength(lines) - 1) + [line];
    // Concatenate the lines together, separated by a new-line.
    string output = llDumpList2String(lines, "\n");
    // Set the result as the floating text.
    llSetText(output, , 1.0);
}
default
{
    touch_start(integer count)
    {
        addLine("Touched at " + llGetTimestamp());
    }
}

Japanese House Textures, Set 3

Thursday, June 2nd, 2011

This is a new set of textures based on my previous Japanese House textures, this time with a painted red wood theme. There are 20 textures in this mostly, mostly at 512 x 512, but with a few at 256 x 512 for narrow panels such as doors.

You can see the whole set on the Gallery page but here is a preview of some of the textures:

As usual, you will find it on the SL Marketplace at  or inworld at the main store:

Second Life Marketplace page

Main Templar Creations Store

 

Second Life Prim Lights – 3

Saturday, July 10th, 2010

Full-bright and Glow

This is the last article in my short (and rather infrequent) series about lights in Second Life. I’m going to take a look at two elements of textures which are often used in conjunction with lights, and which are also widely misunderstood and misused.

Let’s start with Full-bright. This can be switched on or off on the Texture tab of the Build dialog, and applies to the currently selected texture, or to all the textures on the currently selected object if you haven’t selected an  individual face.

What does it actually do? The most obvious effect is that during SL ‘night’ the texture will appear bright (as the name of the option suggests). During daylight the effect is, predictably, less obvious. In fact, sometimes the object might actually appear to be darker in daylight.

Here is the same scene in both day and night. The picture on the wall has full-bright set on it, and you can probably see that the picture is displayed identically in both light settings.

Full-bright example

Let’s step back a moment. How does Second Life create the ‘night-time’ effect? Well, apart from changing the sky, it obviously makes all the objects in the world darker. It does this by taking the colour which they should be, and blending it with the ‘nighttime’ colours.

What might be less obvious, is that it does something similar during daylight. It takes the colours, and adjusts them according to the current lighting. This is how you get the distinctive orange lighting effect at sunset that some people  complained about when Windlight was first released.

When you set a texture to full-bright, this blending is switched off for that texture, so it always displayed at it’s actual colour, regardless of the current lighting. At night, this has the effect of making the object seem to light up — in fact, it is simply not being darkened.

So much for full-bright. Now what about its companion, Glow? Unlike full-bright, this is exactly what it says. When you set a glow value for an object, it acquires a glowing halo around it. This can range from a subtle, barely visible aura, up to a near-blinding glare.

Glow example

Transparency tends to lessen the effect of glow slightly (the lower row in the picture has transparency applied).

Under most circumstances, using low values is best, usually no more than about 0.25, and often less than that.

One thing to be aware of is that if two glowing objects overlap in the viewer, the glow effect is doubled. This is not always what you want to happen, so you probably need to be careful if you place glowing objects close together.

Overlapped glow example

Another unfortunate effect that I’ve often seen is where the glow is being used with an object which has a partially-transparent texture. For the glow to show up in this case it needs to be set quite high. When the texture is fully loaded, the effect is subtle and often beautiful. Unfortunately, while the texture is still being loaded, the glow is in full force, and often overwhelmingly bright. There is not much that can be done about this, but if you intend to use this kind of effect, you should be aware of this pitfall.

Partially-rezzed glow example

Glow and full-bright work very effectively together when creating a light. As a simple example, rez a prim, set its transparency to 25 (if you set it too high you will lose some of the effect), then switch full-bright on and set the glow to 0.2. The result will, of course, not actually illumine the surroundings unless you set the Light feature on, but this kind of ‘fake light’ can give the illusion of there being more lights than SL actually supports, especially if you use several of these in conjunction with a single ‘real’ light.

Full-bright and glow lighting example

Some SL photographers make use of a interesting effect which happens when an avatar stands in front of a ‘glowing’ texture. This is easier to show than to describe, although the effect is quite subtle, and is caused by the glow slightly spilling over the edges of anything in front of it. Here are ‘without’ and ‘with’ glow versions (this is a rather exaggerated version, with the glow set quite high to make the effect obvious):

Photo-glow effect

However, if you intend to save your photos, there is an issue to be aware of, which is that the Second Life snapshots tend not to capture glow correctly. For example, the scene of streetlights on a wall (above) was captured using my computer’s screen-capture, rather than the Second Life screenshot, which looked like this:

Glow snapshot problem

Finally, ‘glow’ works best when it is used for subtle effect, and with some restraint. Whatever you do with ‘glow’, please don’t do this:

Glow abuse example

Dark SF Textures – Set 2

Monday, May 31st, 2010

This is my second set of textures with a dark science-fiction theme (think ‘Quake’, or similar games). Lots of metal plates and piping, and a few lights and control boxes thrown in. All the textures are 512 x 512, and you can view them all at the Texture Gallery.

To buy this set, either visit the main store in-world, or the XstreetSL page:

XstreetSL Page

Main Store

A Not-So-Brief Guide to SLurls

Thursday, May 20th, 2010

This started out as ‘A Brief Guide…’, but I found that there was more to say about them than I thought!

If you are familiar with SecondLife, you will certainly have come across SLurls. In-world, they appear as hyperlinks (you can see them as such in chat or in notices, amongst other places). They look like normal web addresses, like this:

http://slurl.com/secondlife/Ling/183/113/54

When you click on them in-world, instead of launching a browser they will display a landmark, from which you can teleport to the location.

So far, not very interesting. Where things get a little more interesting is when you come across an SLurl on a normal web-page, outside of Second Life. If you click on one of these, you will end up on a web-page that shows the Second Life world map, highlighting the location that the SLurl points at:

What happens when you click on the ‘Teleport’ button depends on whether you have Second Life installed, and (if it’s installed), whether it is running at the time.

If Second Life is already running, a landmark for the location will be displayed for you in the Viewer.

If you have Second Life installed, but it is not currently running, it will be launched, and when you log-in you will be taken directly to the location indicated by the SLurl (although the exact details of what happens will depend on the browser you are using, and possibly the Second Life Viewer as well).

One thing to note is that SLurls work like landmarks, in that if the location has a fixed teleport point, you will be taken there, rather than to the exact location specified in the SLurl.

This is all quite straight-forward, even if it takes several paragraphs to explain. But what if you want to create your own SLurls?

There are three ways to do this. Let’s take the simplest one first. In Second Life, visit the location that you want the SLurl to point to, open up the World Map, and click the ‘Copy SLurl’ button that you should find somewhere near the bottom of the right-hand side.

This will copy the SLurl to the clipboard — you can open up a text or document editor, and simply paste it in.

If you are using Viewer 2, you will also find a ‘Copy SLurl’ option on any landmarks that are stored in your inventory. Right-click the landmark to open the menu that has this option:

Speaking of Viewer 2, it uses a different style of SLurl, and takes you to a different web-page (if you click on an SLurl outside Second Life), but you still get a world map with a teleport button. The main difference is that the web-page is in Viewer 2 style.

If you are interested, here are examples of the old and the new versions:

Old version: http://slurl.com/secondlife/Ling/183/113/54

New version: http://maps.secondlife.com/secondlife/Ling/183/113/54

Ok, so much for the easiest way of creating SLurls. The second way is slightly more complicated, but adds some very nice features.

Before you begin, you’ll need to know the details of the location that you want the SLurl to point to. To do this, visit the location in Second Life, then open up the world map and take a note of the region name, and the x, y, and z values for the location.

Now visit the SLurl website, simply by using your favourite browser to go to http://maps.secondlife.com (or http://slurl.com if you prefer the old version). On this page you will see a ‘Build your own SLurls’ link, near the top right. This will take you to a new page with various edit boxes on it.

Fill in the Region name, and the x, y, and z boxes, with the values you noted earlier.

For now, leave the other boxes empty, and click the ‘Generate’ button. Your SLurl will appear in the edit box at the bottom. Test it by clicking the ‘Go’ button. You should be taken to a new page showing the World Map for the location which you entered.

Returning to the Build SLurl page, select the generated SLurl, copy it, and paste to wherever you want to use it.

This SLurl will be exactly the same as the one generated by the World Map inside Second Life. However, you can improve on this by filling in the other edit boxes on the Build SLurl page.

The Window Title is the simplest. If you enter some text here and generate an SLurl, when you visit the World Map using it you will see the title appear on the ‘pop-up’ marker for the location.

The Window Message works in a very similar way, adding some descriptive text to the pop-up.

The Window Image is more complicated. For this to work, you need to be able to specify the web address of a picture. If you have your own web-site, you can upload a picture to your site, then fill in the address for it here.

Generate the SLurl again, and click ‘Go’, and now you should see your picture in place of the default picture. As far as I can tell, any size of picture will be accepted (within reason!).

Using the Picture and Description together can be a good advertising tool if you are a Second Life merchant. Here’s an example of what I could do to advertise one of my prefabs:

View the Medieval Farmhouse in-world

I mentioned that there were three ways to create an SLurl, but so far I’ve only shown you two ways. The third way is to construct one manually. This would be a whole post in its own right, but if you are familiar with URLs it isn’t too difficult to roll your own SLurl.

I won’t go into details, but here is a quick breakdown, using the Version 2 format, and taking my ‘Medieval Farmhouse’ SLurl as an example (see the link above):

The basic template is this:

http://maps.secondlife.com/secondlife/Region/x/y/z?img=[address]&title=[title]&msg=[description]

The first part is the basic URL:

http://maps.secondlife.com/secondlife

This is followed by the Region name and the x, y, z values:

/Ling/193/113/54

There are then three optional parameters: img, title, and msg (the description):

img=http%3A//www.templarcreations.com/blogpics/blog_prefab_0001a.png

title=Medieval%20Farmhouse

msg=22%20prims%2C%2016m%20x%2016m%2C%20L%24250

As you can see, the ‘msg’ parameter can easily get messy, because you have to replace any special characters.

And finally … the Teleport button on the World Map page conceals another URL, but in a different format, like this: secondlife://Ling/193/113/54. It is possible to link directly to a location using this format. This will by-pass the
World Map, and (assuming that Second Life is installed) go straight to Second Life. It probably isn’t a good idea to use this, because it is not exactly user-friendly, and if the user doesn’t have Second Life installed, instead of ending up on the World Map page (which will lead them to more information about Second Life) it will simply display an error. On the other hand, for Second Life users it gives more direct access (I can imagine it being used to create a web-page of useful landmarks, for example).

Medieval Textures and Farmhouse

Saturday, May 8th, 2010

Not one, but two new releases. They are closely related though — one is a set of Medieval Village textures, and the other is a Medieval Farmhouse which makes use of some of those textures.

The Medieval Village texture set consists of 34 textures, including both transparent and non-transparent versions of the four textures which incorporate windows. (The Farmhouse uses the non-transparent versions, in case you were wondering).

Note: These are the same textures that were freebies in the recent TextureMania hunt. The only difference is that the thatch texture has been replaced, and the transparent windows have been added.

The farmhouse is a small prefab, only 22 prims, and covering 16m x 16m, so it should fit comfortably even inside a small 512m parcel (unless it is a very oddly shaped parcel).

A few samples:


As usual, they are available in-world at the main store, and on-line on the Xstreet website:

Templar Creations Main Store (look outside for the Medieval Farmhouse)

XStreet – Medieval Village Textures
XStreet – Medieval Farmhouse

Exhibition Hall Textures – Set 1

Monday, May 3rd, 2010

I recently completed a small commission project, building an exhibition hall for the Geneva Motor Show:

I created a number of textures specifically for this, and I’ve taken these and improved them a bit (I think!), added some additional ones, and am now releasing them as a new texture set.

Here’s a few samples, and an example of them in use:

As usual, you’ll find them on XStreet, and in-world at the Main Store:

XStreet Page

Templar Creations Main Store

Second Life Viewer 2.0 — Some Brief Tips

Monday, April 5th, 2010

I don’t like it, you don’t like it, but LL is determined to force it down our throats. There’s plenty of discussion elsewhere about the pros and cons of the new Viewer 2.0, so I won’t pick that up here. Instead, I’ll just bring a few tips that might make your experience a little bit better.

Skins
Because I’m a builder, I’m approaching this mainly from the point of view of a creator in Second Life, but my first tip is one that will be useful for anyone: download the Starlight skin!

Let me explain (if you don’t already know). Viewer 2.0 comes with the ability to change ‘skins’ — in other words, the appearance of the interface. At the moment, unfortunately, they don’t seem to have put in place an easy mechanism for installing and switching between skins, so for now it is a case of copying and renaming folders. If you are comfortable with doing this, there is already one third-party skin which is well worth having, which is the Starlight skin created by Hitomi Tiponi.

Starlight, Viewer 2.0 skin

The most significant thing that is does is to change the right-hand slidebar so that it overlays the main viewer screen, rather than squashing the display. This squashing of the display seems to be a major complaint about the new Viewer (and I certainly don’t like it myself, and find it very disconcerting and distracting), so a fix to this is more than welcome.

Viewer 2.0 Starlight sidebar

Debug Menu

If you do regular building or scripting in Second Life, you probably find the Advanced/Debug menu invaluable. Under Viewer 2.0, the Advanced menu can be summoned up using the traditional CTRL+ALT+D incantation. At the bottom of this menu you will find a ‘Developer Menu’ option — select this, and a Developer menu (essentially the old Debug menu) will appear, will the old familiar options in it.

Activate Group

Bizarrely, this seems to be a well-hidden option, unless I am missing something obvious (which is always possible). To get to this, open the sidebar, and select the Groups tab. It is not immediately obvious, but there is a right-click menu available for the group names, and this menu has the ‘Activate’ option.

It took me quite a while to find that one…

Shared Media

Possibly the only reason to really celebrate the arrival of Viewer 2.0 is that we finally have the long-awaited HTML-on-a-prim. Some people have reported problems with getting this to work, but so far it has worked impeccably for me.

To display a resource from the web (usually a webpage), create a new prim and size it appropriately. Select a single face before continuing. On the texture tab of the build menu, there is a new ‘Media’ option at the bottom, with a small plus sign. Click the plus, and a new dialog will appear. Fill in the URL of the page you want to display, and click Apply.

Shared media on build dialog

If all goes well, the page should display on the selected face of the prim. The page will be fully active — if there are links, they can be clicked on.

Note that you can apply different media sources to different faces. Here’s a cube running two YouTube videos simultaneously:

Shared media example

For a jaw-dropping example (and a hint of what might now be possible), try applying http://collabedit.com/ to a prim face, then clicking the ‘Click here to create a new document’ button.

In a few seconds you will have a document which you can edit directly from Second Life. On a prim.

Editing on a prim

What’s more, it’s collaborative, so in theory someone else can edit the same document with you (I’ll admit that I haven’t had a chance to try the ‘collaborative’ part, so I’m not sure how or even whether it will work…once I find out, I’ll let you know).