[sldev] How to determine what an object looks like?

John Hurliman jhurliman at wsu.edu
Tue Mar 13 14:52:04 PDT 2007


Joel Riedesel wrote:
> <sigh>
>
> Been doing that.
>
> Surely it'd take someone who knows this no more than five minutes to
> describe the wire format for this data.
>
> I can read C++ but not as fast as I can write Java...
>
> Cheers,
> Joel

Sure! I charge by the e-mail ;-). Hehe, anyways primitives in Second 
Life are two dimensional drawings extruded along a three dimensional 
path. The two dimensional drawing is called the profile and there is an 
enumeration or constants for ProfileCurve that defines the shape. You 
have your basic square, a triangle, a circle, and a half circle if I can 
recall. Before extrusion the profile can be modified with a cut begin 
and cut end which start at a predefined point in each shape; you'll have 
to either look at the code or look at the shapes to determine what it is 
for each shape. Remember during extrusion the number of faces has to be 
calculated based on whether there is a hollow and/or cut involved which 
can add new faces. The maximum number of faces for any primitive is four 
outer faces + four inner faces + two connecting faces (from a cut) + two 
endcaps = 12 (unless I missed something). Next there is a PathCurve 
which is an enum or constants for the extrusion type. I recall linear 
(straight up) and two different types of rotational (that differ 
slightly to create spheres and torii among other things), although there 
are likely others. Everything is done with unit sizes at these stages, 
so a ProfileCurve of a square would be from -0.5,-0.5,0 to 0.5,0.5,0 
around the 0,0,0 origin (I'm using Z as the up axis like SL, you may 
want to do it differently). With a linear extrusion since you are 
starting at 0,0,0 you go up to 0,0,1 but counting the number of steps 
taken to get there is done using LOD* which is also used to count the 
number of vertices used for rounded profiles. I like how the LL code has 
abstracted this out in to a generic n-gon generator that is used for 
every profile. At each step you calculate a partial transformation of 
the twist, shear, and taper which you'll see translate directly in to 
the rotation, translation, and scale matrices. Apply the matrix 
transformations and throw the resulting points in your vertex buffer; I 
think you might need to be analyzing the TextureEntry stuff as well here 
to properly set the UV coordinates and you are on your own for 
calculating normals/tangents/bitangents or whatever else you need in the 
vertex buffer. The code is split up to fill the vertex buffer using an 
extrusion routine (which does inner, outer, and connecting faces) and 
two endcap routines which handle things on a case by case basis. These 
completed vertex buffers are sent to different parts of the rendering 
pipeline depending on what type of fancy extras are applied. Shiny prims 
go to one, flexible prims to another, basic prims to another, and these 
different paths determine which vertex and pixel shaders will be 
applied. I wouldn't recommend looking at libsecondlife's libprims as it 
is based on outdated information and not a good model to follow (it's 
been moved to the external Google repository to clean up our main repo), 
if you have any more questions just ask here and please attempt to 
organize all of this and add it to the wiki somewhere along with the 
actual enum/constant values for everything.

* There is a bit of a hack in the viewer code to maximize the number of 
vertices used for simple cubes, since cubes are by far the most common 
object and the vertex-based lighting looks better on them with more 
vertices. I've tried removing this hack (so cubes use the minimal number 
of vertices needed to render) and didn't see any change in framerate in 
my limited testing so I left it alone.

John Hurliman


More information about the SLDev mailing list