[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