Second Life Phantom Collisions
I’ve been given the opportunity to do some coding for Second Life. Before I started, I was presented with a number of horror stories about the Linden Scripting Language (LSL). While it’s not as bad as a thought it might be, there are certainly some oddities, some due to the language itself and some due to seemingly arbitrary limitations of the environment.
The first major issue that I ran into involved the detection of collisions with phantom prims. The project was a guided transportation system in which a vehicle would be provided a direction (vector) based on hidden prims that it collided with in the environment. The hidden prims providing the direction are transparent, so they cannot be seen in the environment. They are also phantom, since we didn’t want avatars blocked by invisible objects and becoming confused. However, no collision events (collision nor collision_start) are triggered in the vehicle. In this case, I’m using a vehicle, but the same applies to any prim or set of linked prims. By default, collisions with phantom objects are not detected by either object. Collisions can be detected by the phantom object with the inclusion of this function.
llVolumeDetect(TRUE);
However, this only allows collisions to be detected by the phantom prim and not by the vehicle that needs the information. The non-phantom prim will not detect collisions with phantom prims under any conditions. This meant that the vehicle pulling the new direction from the phantom prim was out of the question. Since the phantom prim could detect the collision, it must be the one to act.
collision_start(integer total_number)
{
llWhisper(channelNumber, message);
}
At the start of the collision, the phantom prim broadcasts the message on a non-0 channel. Using a non-0 channels helps to cut down on chat spam. In this case, I also used llWhisper, since the listening vehicle is moving slowly and will certainly be within 10 meters. llSay sends the message 20 meters, where it might be picked up by more vehicles.
In order to keep the chat to a minimum and ensure that only the vehicle involved in the collision acted upon the message, there are a number of other techniques used as well. The colliding objects all have the same name, so I can use a collision filter to ensure that only collisions with specifically named prims are detected.
llCollisionFilter(vehiclePrimName, NULL_KEY, TRUE);
While the collision event is fired continuously during the collision between two prims, the collision_start event is supposedly only fired once at the beginning of the collision. That certainly doesn’t appear to be the case, since collision_start is being fired multiples times as well. In order to limit this to a single event, get the key of the colliding object and only fire the event of the key is different from the last key. I also set a timer to clear the last key, so that future collisions with the same object will be effective, after 15 seconds in this case.
collision_start(integer total_number)
{
currentKey = llDetectedKey(0);
if ( currentKey != lastKey )
{
llWhisper(chatChannel, (string)currentKey + ";" + message);
lastKey = currentKey;
llSetTimerEvent(15);
}
}
timer()
{
lastKey = NULL_KEY;
llSetTimerEvent(0);
}
On collision with a specifically named prim if there was no collision with that prim in the last 15 seconds, the message is whispered on a non-0 channel. Of course, you will need to ensure that the vehicle is listening for the message on the same channel. I also pass the key of the colliding object, so that any object receiving the message can validate the message was intended for it.
This solution is a bit of a kludge, but it produces the desired result.
Comments
Leave a Reply


