Streaming Cost test

Test Plan Name:

Streaming Cost test

Sources

https://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost
https://wiki.secondlife.com/wiki/Mesh_Accounting_Test

Purpose

Verify the amount of data streamed to the viewer is within the expected range.

Tests

Target visible triangles from center of region at medium mesh detail (in preferences) is 250 thousand triangles.
To verify a mesh object's streaming cost is being calculated correctly:


If visible triangles is too high, the streaming cost is being too forgiving for the mesh object in question. If it's too low, streaming cost is being too strict.

Helper Script

Use this script to automatically fill a region with a particular mesh. Put the object to test in the rezzer's inventory and rename it to "test_object" then say "streamrez <cost>" where <cost> is the streaming cost of the object. It helps to make the rezzer a tall post (say a 1x1x10m prim) so you can track its progress from a distance.

<lsl>

move_to(vector target_pos, float tolerance) {

   vector cur_pos = llGetPos();
   
   while (llVecDist(<cur_pos.x, cur_pos.y, 0.0>, <target_pos.x, target_pos.y, 0.0>) > tolerance)
   {
       llSetLinkPrimitiveParamsFast(LINK_THIS,[PRIM_POSITION, target_pos]);
       cur_pos = llGetPos();
   }   

}

do_stream_rez(float cost) {

   llSetColor(<1,0,0>, ALL_SIDES);
   integer count = (integer) (15000/cost); 
   
   integer side = (integer) llSqrt((float) count);
   
   float pad = 16.0;
   float spacing = (256.0-pad*2.0)/side;
   
   vector start_pos = llGetPos();
   float z = start_pos.z;
   
   integer i;
   rotation rot = llGetRot();
   
   for (i = 0; i < side; i++)
   {
       integer j;
       for (j = 0; j < side; j++)
       {
           float x = pad+i*spacing;
           float y = pad+j*spacing;
           if (i%2 == 0)
           {
               y = 256.0-y;
           }
           vector target = <x,y,z>;
       
           move_to(target, 8.0);
       
           llRezObject("test_object", target, 
                       <0,0,0>, rot, side);
       }
   }
       
   move_to(<128,128,z>, 0.0);
   llSetColor(<0,1,0>, ALL_SIDES);

}

default {

   state_entry()
   {
       llSetColor(<1,1,0>, ALL_SIDES);
       llListen(0, "", llGetOwner(), "");
   }
   
   listen(integer channel, string name, key id, string message)
   {
       if (id == llGetOwner())
       {
           list params = llParseString2List(message, [" "], [""]);
           integer count = llGetListLength(params);
           if (count == 2)
           {
               if (llList2String(params, 0) == "streamrez")
               {
                   float cost = llList2Float(params, 1);
                   do_stream_rez(cost);
               }
           }
       }
   }

}

</lsl>