Creating a Slideshow Viewer, Part 2: Reading the Inventory

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:

[cpp]
// 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");
}
}
[/cpp]

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).

Comments

Leave a Reply