Streaming Cost test

Category:Test Plans
Category:Mesh
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:
* Open preferences->graphics and click "Reset"
* Ensure that Mesh detail: Objects is set to "Mid"
* Set draw distance to 256m or greater
* Go to a flat, empty region
* Place a copy of the mesh object in a corner of the sim
* Set the mesh physics shape type to "convex hull" and ensure that the prim equivalence cost matches the object's streaming cost (bound by streaming cost, not physics cost)
* Move your avatar to the center of the sim
* If necessary, scale the mesh object up so that it remains visible from the center of the region when placed at a region corner (prevent object from disappearing due to interest list)
* Place copies of the mesh around the region, distributing evenly at ground level, until the simulator reports the parcel is full
* Stand at the center of the sim, and do a complete 360 degree turn, ensuring every copy of the mesh object is loaded at appropriate LoD.
* Open develop->consoles->scene statistics
* Ensure "Region Object Streaming Cost" is approximately 15000
* Ensure "Visible" entry for "Region Object Triangle Counts" indicates approximately 250 thousand triangles are visible (+/- 80 thousand).
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>