Sunday 22 April 2007

Holodeck teaching/meeting space on Eduserv Island


I liked the concept of a Second Life 'holodeck' so much (see my previous post on An English Village) that I decided to experiment with building my own version on Eduserv Island.

I used the idea of a flexible meeting/teaching space in an unused corner of Eduserv Island as the basis for my experimentation.

First I built up three differently configured seating arrangements for the available space, one with 10 seats arranged in a circle, another with 20 seats in a square and a final one consisting of 40 seats laid out theatre style with a screen at the front.

For each arrangement, I linked all the prims together to form a single seating object which I then copied to my inventory.

So far so good...

Next, I created a touchable object, a white post with a ball on top, that is used to hold each of the seating objects and that rezzes those objects on demand (i.e. when it is touched). The post contains a simple script, as follows:

integer controlchannel = 999;
integer current;
integer num;

default
{
state_entry() {
num = llGetInventoryNumber(INVENTORY_OBJECT);
current = 0;
llSetText("Touch to\nrearrange\nseating",
<1, 1, 1>, 1.0);
}

touch_start(integer total_number) {
//llSay(0, "Touched.");
llSay(controlchannel, "kill linked objects");
vector eul = <0, 0, 180>;
eul *= DEG_TO_RAD; //convert to radians
rotation quat = llEuler2Rot(eul);
llRezObject(llGetInventoryName(INVENTORY_OBJECT,
current), llGetPos() + <5.25, -5, 0>,
ZERO_VECTOR, quat, 0);
current++;
if (current >= num) { current = 0;}
}
}

What this script does is to query the post's inventory to find out how many seating arrangement objects there are (llGetInventoryNumber()). Each time it is touched (touch_start()) the post sends a simple chat-based message to the currently rezzed seating object, telling it to delete itself (llSay()), then rezzes the next seating object in the list (llRezObject()).

Each rezzed seating object also contains a simple script, as follows:

integer controlchannel = 999;

default
{
state_entry() {
llListen(controlchannel, "",
NULL_KEY, "");
}

listen(integer channel, string name,
key id, string message) {
if (llToLower(message) ==
"kill linked objects") {
llDie();
}
}

on_rez(integer param) {
llSetPos(<35.384, 22.658, 25.126>);
}
}

This script listens for incoming messages from the white post (llListen()), kills itself on demand (llDie()) and positions the seating object in the correct location when it is first rezzed (llSetPos());

It's a pretty simple approach, but seems to work well, at least within the fairly trivial set of functional requirements I set myself.