home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / avril / avrilref.txt < prev    next >
Text File  |  1996-03-19  |  135KB  |  2,833 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7.  
  8.  
  9.  
  10.                               AVRIL Technical Reference
  11.                                      Version 2.0
  12.                                     March 28, 1995
  13.  
  14.                                      Bernie Roehl
  15.  
  16.  
  17.  
  18.           Note: This is the technical reference manual for version 2.0 of
  19.           AVRIL.  The tutorial is a separate document.  The appendices for
  20.           this technical reference manual are also stored separately.
  21.  
  22.                This document describes AVRIL from a technical perspective,
  23.           and explains the data types and functions that are available. 
  24.           Anything that is not documented here should not be used, since
  25.           it's subject to change in future releases of AVRIL.  Also keep in
  26.           mind that some of the routines described below may be implemented
  27.           as macros, and that this may also change in future releases; none
  28.           of your code should assume that any particular routine is either
  29.           a macro or a real function.
  30.  
  31.                There are a number of important concepts that are essential
  32.           to an understanding of how AVRIL works.  Let's start by examining
  33.           them.
  34.  
  35.           Basic Data Types
  36.  
  37.                AVRIL uses a left-handed coordinate system; if the X axis
  38.           points to the right, and the Y axis points up, then Z points
  39.           straight ahead.  If you're looking at the origin from the
  40.           positive end of an axis, a clockwise rotation is a positive
  41.           rotation angle.
  42.  
  43.                Distances in AVRIL are represented by vrl_Scalars, and
  44.           rotation angles by vrl_Angles.  AVRIL can be compiled to use
  45.           either floating point or fixed point, so it's important to use
  46.           the vrl_Scalar and vrl_Angle types for portability.  vrl_Scalars
  47.           should always be treated as (long) integer values, regardless of
  48.           whether floating or fixed point is used.  vrl_Angles are always
  49.           measured in degrees (converted to the internal vrl_Angle format,
  50.           of course).  A third fundamental data type is vrl_Factor, which
  51.           is used for things like the return value of trig functions; a
  52.           special constant called VRL_UNITY is #defined to be a vrl_Factor
  53.           of 1.
  54.  
  55.                In a floating point implementation, all three types
  56.           (vrl_Scalars, vrl_Angles and vrl_Factors) are stored as floats;
  57.           in a fixed-point implementation, they're all 32-bit integers
  58.           (which will be "long" on many systems).  The following macros are
  59.  
  60.                            AVRIL Technical Reference Manual               1
  61.  
  62.  
  63.  
  64.  
  65.  
  66.           provided for converting between floating point (or regular
  67.           integers) and the three special types:
  68.  
  69.                float2scalar(float);
  70.                           scalar2float(vrl_Scalar);
  71.  
  72.                           float2angle(float);
  73.                           angle2float(vrl_Angle);
  74.  
  75.                           float2factor(float);
  76.                           factor2float(vrl_Factor);
  77.  
  78.           Several routines are provided to support portable multiplication
  79.           and division of the types:
  80.  
  81.                vrl_Factor vrl_ScalarDivide(vrl_Scalar a, vrl_Scalar b);
  82.                           vrl_Scalar vrl_ScalarMultDiv(vrl_Scalar a, vrl_Scalar b, vrl_Scalar c);
  83.                           vrl_Scalar vrl_FactorMultiply(vrl_Factor a, vrl_Scalar b);
  84.  
  85.           The first of these routines simply divides two vrl_Scalars and
  86.           returns a vrl_Factor result; the absolute value of a should be
  87.           less than or equal to the absolute value of b.  The second
  88.           routine multiplies two vrl_Scalars and divides by a third, using
  89.           a 64-bit intermediate result; in other words, it computes
  90.           (a*b)/c.  The third routine multiplies a vrl_Factor by a
  91.           vrl_Scalar and returns a vrl_Scalar result; it can also be used
  92.           for multiplying two vrl_Factors, or an integer or long value by a
  93.           vrl_Factor.  The order of the operands is significant, because C
  94.           automatically promotes ints to longs.
  95.  
  96.                In floating-point implementations of AVRIL, there may be
  97.           occasions where the computed value of a vrl_Scalar has a
  98.           fractional part; in such cases you should use the following
  99.           function:
  100.  
  101.                vrl_Scalar vrl_ScalarRound(vrl_Scalar value);
  102.  
  103.           to round to the nearest valid vrl_Scalar value.  To take the
  104.           absolute value of a vrl_Scalar, use the function
  105.  
  106.                vrl_Scalar vrl_ScalarAbs(vrl_scale value);
  107.  
  108.           There are currently two trig routines, vrl_Sine() and
  109.           vrl_Cosine(); they both take vrl_Angles as parameters and return
  110.           vrl_Factors:
  111.  
  112.                vrl_Factor vrl_Sine(vrl_Angle angle);
  113.                           vrl_Factor vrl_Cosine(vrl_Angle angle)                                                               ;
  114.  
  115.           The routine vrl_MathInit() should be called before calling any of
  116.           the trig functions; it pre-computes the trig tables.  This is
  117.           done in the vrl_SystemStartup() routine (found in system.c).
  118.  
  119.                            AVRIL Technical Reference Manual               2
  120.  
  121.  
  122.  
  123.  
  124.  
  125.                Positions on the screen (i.e., pixel coordinates) are
  126.           represented using the vrl_ScreenPos type, for future portability. 
  127.           Fractional screen positions (used in scan-converting polygons)
  128.           are represented using the vrl_ScreenCoord type.  This type is
  129.           currently used only by the vrl_Display family of routines.
  130.  
  131.                There are several other basic types used in AVRIL: vrl_Time
  132.           is a measure of elapsed time in ticks, vrl_Color is used to
  133.           represent colors (both 8-bit and 24-bit) and vrl_Boolean is a
  134.           true/false type value (non-zero being true).  The types vrl_32bit
  135.           and vrl_unsigned32bit are used for signed and unsigned 32-bit
  136.           numbers, and vrl_16bit and vrl_unsigned16bit are used for signed
  137.           and unsigned 16-bit numbers.  The function
  138.  
  139.                vrl_32bit abs32(vrl_32bit value);
  140.  
  141.           will return the absolute value of a 32-bit number, independent of
  142.           whether 32-bit values are of type int or type long.
  143.  
  144.           Vectors
  145.  
  146.                A vrl_Vector is a three-element array, which can be indexed
  147.           by the #defined constants X, Y and Z; for example, if v is a
  148.           vector then v[X] is the X-component of the vector.  In general,
  149.           vrl_Vectors are made up of three vrl_Scalars; however, a
  150.           normalized vector (such as a facet normal, a basis vector, or a
  151.           vector that's been normalized using the vrl_VectorNormalize()
  152.           function) will actually have vrl_Factors as elements.  The
  153.           following functions perform fundamental operations on
  154.           vrl_Vectors:
  155.  
  156.                void vrl_VectorCreate(vrl_Vector result, vrl_Scalar x, vrl_Scalar y, vrl_Scalar z);
  157.                           void vrl_VectorCopy(vrl_Vector destination, vrl_Vector source);
  158.                           void vrl_VectorAdd(vrl_Vector result, vrl_Vector v1, vrl_Vector v2);
  159.                           void vrl_VectorSub(vrl_Vector result, vrl_Vector v1, vrl_Vector v2);
  160.                           void vrl_VectorNegate(vrl_Vector v);
  161.                           vrl_Factor vrl_VectorDotproduct(vrl_Vector v1, vrl_Vector v2);
  162.                           vrl_Scalar vrl_VectorCrossproduct(vrl_Vector result, vrl_Vector v1, vrl_Vector v2);
  163.                           vrl_Scalar vrl_VectorMagnitude(vrl_Vector v);
  164.                           void vrl_VectorNormalize(vrl_Vector v);
  165.                           vrl_Scalar vrl_VectorDistance(vrl_Vector v1, vrl_Vector v2);
  166.                           void vrl_VectorScale(vrl_Vector v, vrl_Scalar newmag);
  167.                           void vrl_VectorRescale(vrl_Vector v, vrl_Scalar newmag);
  168.                           void vrl_VectorPrint(FILE *out, char *str, vrl_Vector v);
  169.                           vrl_Boolean vrl_VectorEqual(vrl_Vector v1, vrl_Vector v2);
  170.                           void vrl_VectorZero(vrl_Vector v);
  171.  
  172.                  The vrl_VectorCreate() function takes three vrl_Scalars and
  173.           assembles them into a vrl_Vector.  The vrl_VectorCopy(),
  174.           vrl_VectorAdd() and vrl_VectorSub() routines do element-by-
  175.           element copies, additions and subtractions of vrl_Vectors.  The
  176.           vrl_VectorNegate() function reverses the direction of a
  177.  
  178.                            AVRIL Technical Reference Manual               3
  179.  
  180.  
  181.  
  182.  
  183.  
  184.           vrl_Vector by flipping the sign of each of its components.  The
  185.           vrl_VectorDotproduct() routine computes the dot product (inner
  186.           product) of two vectors; at least one of the vectors should be
  187.           normalized for this to work properly.
  188.  
  189.                The vrl_VectorCrossproduct() routine computes the vector
  190.           cross product (outer product) of two vectors.  This is likely to
  191.           be slow, since it normalizes the result (which involves doing a
  192.           square root operation).  It returns the magnitude of the vector
  193.           prior to normalization.  The vrl_Magnitude() routine returns the
  194.           magnitude of a vector, and the vrl_VectorNormalize() routine
  195.           scales a vector so that it has a magnitude of 1.
  196.  
  197.                The vrl_VectorDistance() routine takes two vrl_Vectors (each
  198.           representing a point in space) and computes the distance between
  199.           those two points.  The vrl_Scale() function takes a normalized
  200.           vrl_Vector and scales all its components by the given amount; the
  201.           vrl_Rescale() function takes a non-normalized vector and re-
  202.           scales it to have the specified magnitude.
  203.  
  204.                The vrl_VectorPrint() routine prints out a message followed
  205.           by the values of each of the components of the vrl_Vector,
  206.           enclosed in square brackets.  Do not attempt to write to the
  207.           screen with this routine, since it will not work well in graphics
  208.           mode.
  209.  
  210.                The vrl_VectorEqual() routine returns a non-zero value if
  211.           the two vrl_Vectors are identical, and vrl_VectorZero() sets the
  212.           components of a vrl_Vector to zero.  The [0,0,0] vector is
  213.           sometimes needed, so a global vrl_Vector variable called
  214.           vrl_VectorNULL is defined.
  215.  
  216.           Matrices
  217.  
  218.                A vrl_Matrix is a 4 by 3 array that stores location and
  219.           orientation information.  All AVRIL matrices are homogeneous; the
  220.           upper 3 by 3 submatrix stores rotation information and the last
  221.           3-element row stores a translation vector.  You should never have
  222.           to deal with the vrl_Matrix type directly.  However, in case you
  223.           do have a need to deal with actual matrices, the following
  224.           routines are provided:
  225.  
  226.                void vrl_MatrixIdentity(vrl_Matrix m);
  227.                           void vrl_MatrixCopy(vrl_Matrix result, vrl_Matrix m);
  228.                           void vrl_MatrixMultiply(vrl_Matrix result, vrl_Matrix m1, vrl_Matrix m2);
  229.                           void vrl_MatrixInverse(vrl_Matrix result, vrl_Matrix m);
  230.                           void vrl_MatrixRotX(vrl_Matrix m, vrl_Angle angle, vrl_Boolean leftside);
  231.                           void vrl_MatrixRotY(vrl_Matrix m, vrl_Angle angle, vrl_Boolean leftside);
  232.                           void vrl_MatrixRotZ(vrl_Matrix m, vrl_Angle angle, vrl_Boolean leftside);
  233.                           void vrl_MatrixRotVector(vrl_Matrix m, vrl_Angle angle, vrl_Vector vector,
  234.                                   vrl_Boolean leftside);
  235.                           void vrl_MatrixResetRotations(vrl_Matrix m);
  236.  
  237.                                               AVRIL Technical Reference Manual               4
  238.  
  239.  
  240.  
  241.  
  242.  
  243.                           void vrl_MatrixGetBasis(vrl_Vector v, vrl_Matrix m, int axis);
  244.                           void vrl_MatrixSetBasis(vrl_Matrix m, vrl_Vector v, int axis);
  245.                           void vrl_MatrixTranslate(vrl_Matrix result, vrl_Scalar x, vrl_Scalar y, vrl_Scalar z);
  246.                           void vrl_MatrixSetTranslation(vrl_Matrix result,
  247.                                   vrl_Scalar x, vrl_Scalar y, vrl_Scalar z);
  248.                           void vrl_MatrixGetTranslation(vrl_Vector v, vrl_Matrix m);
  249.                           void vrl_MatrixGetRotations(vrl_Matrix m, vrl_Angle *rx, vrl_Angle *ry, vrl_Angle *rz);
  250.  
  251.           The vrl_MatrixIdentity() function sets the matrix to zeroes,
  252.           except for the diagonal elements which are set to VRL_UNITY.  The
  253.           vrl_MatrixCopy() and vrl_MatrixMultiply() routines are used to
  254.           copy and multiply matrices, and the vrl_MatrixInverse() routine
  255.           computes the matrix inverse.  The various rotation functions
  256.           apply a rotation around X, Y, Z or a specified vector by a given
  257.           angle; the vrl_MatrixResetRotations() routine sets all the
  258.           rotations to zero.  Several of the vrl_Matrix routines use a
  259.           leftside parameter; a non-zero value for this parameter specifies
  260.           that the transformation should be applied as a pre-multiplication
  261.           instead of a post-multiplication.
  262.  
  263.                The function vrl_MatrixGetBasis() gets one of the basis
  264.           vectors of the rotation part of the matrix; this is equivalent to
  265.           (but faster than) transforming an axis-aligned unit vector by the
  266.           matrix.  In other words, vrl_MatrixGetBasis(v, m, X) is
  267.           equivalent to transforming the vector [1,0,0] by the rotation
  268.           part of the matrix m and storing the result in the vector v.
  269.  
  270.                The vrl_MatrixTranslate() routine applies a translation to
  271.           the matrix, and vrl_MatrixSetTranslation() sets the actual
  272.           translation part of the matrix.  The vrl_MatrixGetTranslation()
  273.           routine fills the given vector with the current translation part
  274.           of the matrix, and vrl_MatrixGetRotations() gets the angles
  275.           which, when applied in the order Y, X, Z, produces the rotation
  276.           part of the matrix.
  277.  
  278.           Transforms
  279.  
  280.                You should never have to use any of the transform functions
  281.           directly; this is all handled for you by AVRIL.  A vector can be
  282.           transformed by a matrix, or each component of the transform (X, Y
  283.           or Z) can be computed separately:
  284.  
  285.                void vrl_Transform(vrl_Vector result, vrl_Matrix m, vrl_Vector v);
  286.                           vrl_Scalar vrl_TransformX(vrl_Matrix m, vrl_Vector v);
  287.                           vrl_Scalar vrl_TransformY(vrl_Matrix m, vrl_Vector v);
  288.                           vrl_Scalar vrl_TransformZ(vrl_Matrix m, vrl_Vector v);
  289.  
  290.           Coordinate Systems
  291.  
  292.                AVRIL allows objects to be translated or rotated in five
  293.           different coordinate systems.  This may seem like a lot, but
  294.           they're easy to get used to.  An object can be moved in its own
  295.  
  296.                            AVRIL Technical Reference Manual               5
  297.  
  298.  
  299.  
  300.  
  301.  
  302.           local coordinate system, the coordinate system of the object it's
  303.           attached to, the "world" coordinate system, the viewer's
  304.           coordinate system, or the coordinate system of another object.
  305.  
  306.                For example, consider a bicycle on an open train car.  The
  307.           bicycle is facing sideways, so that if you were sitting on it
  308.           you'd be watching the scenery go by on the right side of the
  309.           train.  The train itself is moving northeast.  If we translate
  310.           the bicycle along the positive Z axis in its local coordinate
  311.           system, it will travel sideways off the train car, in a south-
  312.           easterly direction.  If we move it in the positive Z direction of
  313.           its parent, it will move to the rider's left, towards the front
  314.           of the train (northeast).  If we move it in the positive Z
  315.           direction in the world, it will move due north.  If we're looking
  316.           at it from directly above, moving the bicycle in the viewer's
  317.           positive Z direction would send it through the train car and down
  318.           into the ground.  If a bird is flying due south, then moving the
  319.           bicycle in the positive Z direction relative to the bird would
  320.           make the bike move due south.
  321.  
  322.                We represent these various coordinate systems by the
  323.           constants VRL_COORD_LOCAL, VRL_COORD_PARENT, VRL_COORD_WORLD, and
  324.           VRL_COORD_OBJREL.  The view-relative coordinate system is just a
  325.           special case of the VRL_COORD_OBJREL coordinate frame, with the
  326.           viewer as the object that the movement should be relative to.
  327.  
  328.           Worlds
  329.  
  330.                In AVRIL, a virtual world is a collection of objects, light
  331.           sources, virtual cameras and miscellaneous attributes.  You can
  332.           have any number of worlds within a single AVRIL application;
  333.           they're distinct from each other, and you can switch between them
  334.           whenever you like.
  335.  
  336.                When you run an AVRIL program, a default world is created
  337.           and initialized for you; if you only plan on having one world in
  338.           your application, you don't have to do anything special.  If you
  339.           want to create additional worlds, you can simply declare
  340.           variables of type vrl_World and initialize them by calling
  341.           vrl_WorldInit(&yourworld); however, it's probably better to
  342.           dynamically allocate them using vrl_malloc().  In fact, the
  343.           simplest way to create a world is with the vrl_WorldCreate()
  344.           function, which allocates the space and initializes the world for
  345.           you.  To make a given world current, use the
  346.           vrl_WorldSetCurrent() function; the vrl_WorldGetCurrent()
  347.           function can be used to get a pointer to the current world.
  348.  
  349.                vrl_World *vrl_WorldInit(vrl_World *world);
  350.                           vrl_World *vrl_WorldCreate(void);
  351.                           void vrl_WorldSetCurrent(vrl_World *world);
  352.                           vrl_World *vrl_WorldGetCurrent(void);
  353.  
  354.  
  355.                                               AVRIL Technical Reference Manual               6
  356.  
  357.  
  358.  
  359.  
  360.  
  361.           You can easily add objects, light sources and cameras to the
  362.           current world, and remove them; you can also count how many of
  363.           each the current world contains, and get pointers to the linked
  364.           list of lights, linked list of cameras and the hierarchical tree
  365.           of objects  You can also find lights, cameras and objects by
  366.           name.
  367.  
  368.                void vrl_WorldAddLight(vrl_Light *light);
  369.                           void vrl_WorldRemoveLight(vrl_Light *light);
  370.                           vrl_Light *vrl_WorldFindLight(char *name);
  371.  
  372.                           void vrl_WorldAddCamera(vrl_Camera *camera);
  373.                           void vrl_WorldRemoveCamera(vrl_Camera *camera);
  374.                           vrl_Camera *vrl_WorldFindCamera(char *name);
  375.  
  376.                           void vrl_WorldAddObject(vrl_Object *obj);
  377.                           void vrl_WorldRemoveObject(vrl_Object *obj);
  378.                           vrl_Object *vrl_WorldFindObject(char *name);
  379.  
  380.                           int vrl_WorldCountObjects(void);
  381.                           int vrl_WorldCountLights(void);
  382.                           int vrl_WorldCountCameras(void);
  383.  
  384.                           vrl_Light *vrl_WorldGetLights(void);
  385.                           vrl_Light *vrl_WorldGetCameras(void);
  386.                           vrl_Object *vrl_WorldGetObjectTree(void);
  387.  
  388.           If you need to iterate through the linked list of lights or
  389.           cameras, you can use the functions
  390.  
  391.                vrl_Light *vrl_LightGetNext(vrl_Light *light);
  392.                           vrl_Camera *vrl_CameraGetNext(vrl_Camera *camera);
  393.  
  394.           You can also obtain information about the total number of facets
  395.           in the world, the minimum and maximum bounds of the world, the
  396.           center of the world and the radius of the world's bounding sphere
  397.           using these functions:
  398.  
  399.                int vrl_WorldCountFacets(void);
  400.                           void vrl_WorldGetBounds(vrl_Vector v1, vrl_Vector v2);
  401.                           void vrl_WorldGetCenter(vrl_Vector v);
  402.                           vrl_Scalar vrl_WorldGetSize(void);
  403.  
  404.           Each world has a "current camera" through which the world is
  405.           seen; you can set the current camera, or get a pointer to it
  406.           using these routines:
  407.  
  408.                void vrl_WorldSetCamera(vrl_Camera *cam);
  409.                           vrl_Camera *vrl_WorldGetCamera(void);
  410.  
  411.  
  412.  
  413.  
  414.                            AVRIL Technical Reference Manual               7
  415.  
  416.  
  417.  
  418.  
  419.  
  420.           The clearing of the screen prior to each frame, and the use (and
  421.           colors) of the horizon, are controlled by the following
  422.           functions:
  423.  
  424.                void vrl_WorldSetScreenClear(int n);
  425.                           int vrl_WorldGetScreenClear(void);
  426.                           void vrl_WorldToggleScreenClear(void);
  427.  
  428.                           void vrl_WorldSetHorizon(int n);
  429.                           int vrl_WorldGetHorizon(void);
  430.                           void vrl_WorldToggleHorizon(void);
  431.  
  432.                           void vrl_WorldSetGroundColor(int color);
  433.                           int vrl_WorldGetGroundColor(void);
  434.  
  435.                           void vrl_WorldSetSkyColor(int color);
  436.                           int vrl_WorldGetSkyColor(void);
  437.  
  438.           The rate at which the user moves and turns is controlled by the
  439.           "turn" step and the "move" step.  In addition, the movement
  440.           "mode" can be set to 0 or 1; if it's 1 (the default) then simple
  441.           movement can move the user vertically, otherwise they stay on the
  442.           ground.  Note that these are really only suggestions, and it's up
  443.           to the application to make use of them.
  444.  
  445.                void vrl_WorldSetMovementMode(int n);
  446.                           int vrl_WorldGetMovementMode(void);
  447.                           void vrl_WorldToggleMovementMode(void);
  448.  
  449.                           void vrl_WorldSetMovestep(vrl_Scalar distance);
  450.                           vrl_Scalar vrl_WorldGetMovestep(void);
  451.  
  452.                           void vrl_WorldSetTurnstep(vrl_Angle angle);
  453.                           vrl_Angle vrl_WorldGetTurnstep(void);
  454.  
  455.                  There's a flag, stored in the world data structure, which
  456.           indicates whether or not the world is being rendered
  457.           stereoscopically; the following routines access that flag:
  458.  
  459.                void vrl_WorldSetStereo(int n);
  460.                           int vrl_WorldGetStereo(void);
  461.                           void vrl_WorldToggleStereo(void);
  462.  
  463.           The world data structure also stores a pointer to the stereo
  464.           configuration being used.  That pointer can be accessed using the
  465.           following routines:
  466.  
  467.                vrl_WorldSetStereoConfiguration(conf);
  468.                           vrl_StereoConfiguration *vrl_WorldGetStereoConfiguration(void);
  469.  
  470.  
  471.  
  472.  
  473.                            AVRIL Technical Reference Manual               8
  474.  
  475.  
  476.  
  477.  
  478.  
  479.           In addition to the standard, "cyclopean" camera, there are
  480.           cameras in the world for the left and right eyes.  The functions
  481.           to access them are:
  482.  
  483.                void vrl_WorldSetLeftCamera(cam);
  484.                           vrl_Camera *vrl_WorldGetLeftCamera(void);
  485.                           void vrl_WorldSetRightCamera(cam);
  486.                           vrl_Camera *vrl_WorldGetRightCamera(void);
  487.  
  488.           Finally, additional aspects of the virtual world such as the
  489.           ambient light level and the "scale factor" (the number of real-
  490.           world millimeters per unit of distance in the virtual world) can
  491.           be set and queried using the following functions:
  492.  
  493.                void vrl_WorldSetAmbient(vrl_Factor ambient);
  494.                           vrl_Factor vrl_WorldGetAmbient(void);
  495.  
  496.                           void vrl_WorldSetScale(vrl_Scalar scale);
  497.                           vrl_Scalar vrl_WorldGetScale(void);
  498.  
  499.           Objects
  500.  
  501.                Objects are the most important entities in a virtual world. 
  502.           All objects have a location and orientation, and they can be
  503.           attached to each other in a tree-structured hierarchy.  Each
  504.           object can have a shape (i.e. geometric description) and a
  505.           surface map.  You can create an object statically (by declaring a
  506.           variable of type vrl_Object) or dynamically (either by using
  507.           vrl_malloc() to allocate the space and vrl_ObjectInit() to
  508.           initialize it, or by simply calling vrl_ObjectCreate()).  If you
  509.           use vrl_ObjectCreate(), you can optionally specify a shape for
  510.           the object to use; if you don't want to assign a shape, use NULL. 
  511.           You can also destroy objects using vrl_ObjectDestroy().
  512.  
  513.                vrl_Object *vrl_ObjectInit(vrl_Object *obj);
  514.                           vrl_Object *vrl_ObjectCreate(vrl_Shape *shape);
  515.                           void vrl_ObjectDestroy(vrl_Object *object);
  516.  
  517.                  You can create an exact copy of an object using the function
  518.  
  519.                vrl_Object *vrl_ObjectCopy(vrl_Object *obj);
  520.  
  521.           Note that the newly-created object will share all the same
  522.           properties (including the shape and surface map) as the original
  523.           and will be in the exact same location as the original; you
  524.           should probably move it.  The copy will have nothing attached to
  525.           it (it doesn't inherit children from the original), and will be a
  526.           sibling of the original (sharing the same parent, if any).
  527.  
  528.           Objects can be rotated around any of the axes, in any coordinate
  529.           frame, using the following function:
  530.  
  531.  
  532.                            AVRIL Technical Reference Manual               9
  533.  
  534.  
  535.  
  536.  
  537.  
  538.                           void vrl_ObjectRotate(vrl_Object *obj, vrl_Angle angle, int axis,
  539.                                   vrl_CoordFrame frame, vrl_Object *relative_to);
  540.  
  541.           The axis is one of the defined constants X, Y or Z.  The frame is
  542.           one of the coordinate frames discussed earlier.  If the frame is
  543.           VRL_COORD_OBJREL, then the relative_to parameter points to the
  544.           object that motion should be relative to.  For example, to rotate
  545.           an object 45 degrees around the viewer's Z axis, you would make
  546.           the following call:
  547.  
  548.                vrl_ObjectRotate(obj, float2angle(45), Z,
  549.                                   VRL_COORD_OBJREL, vrl_CameraGetObject(vrl_WorldGetCamera()));
  550.  
  551.           You can also orient an object to "look" in a particular direction
  552.           using the function
  553.  
  554.                void vrl_ObjectLookAt(vrl_Object *obj, vrl_Vector forward, vrl_Vector up);
  555.  
  556.           The object will be rotated so that it's Z axis points along the
  557.           forward vector, and its Y axis points in the general direction of
  558.           the up vector.  Note that the actual Y orientation may be
  559.           different, unless you make sure that up is perpendicular to
  560.           forward.  The up and forward vectors are specified in world
  561.           coordinates, and should both be unit vectors; you may find the
  562.           vrl_VectorNormalize() function handy for this.
  563.  
  564.           Translations of an object are done with the following function:
  565.  
  566.                void vrl_ObjectTranslate(vrl_Object *obj, vrl_Vector v,
  567.                                   vrl_CoordFrame frame, vrl_Object *relative_to);
  568.  
  569.           The object is moved along the vrl_Vector v in the specified
  570.           frame.  The meaning of the relative_to parameter is the same as
  571.           it was for vrl_ObjectRotate().
  572.  
  573.           The vrl_ObjectRotate() and vrl_ObjectTranslate() routines both
  574.           apply a rotation to the current state of the object.  If you wish
  575.           to make the rotations absolute, call vrl_ObjectRotReset(obj).  If
  576.           you wish to make translations absolute, call
  577.           vrl_ObjectVectorMove(obj, vrl_VectorNULL)  to set the
  578.           translations to zero.  These should both be done before applying
  579.           the vrl_ObjectRotate() and vrl_ObjectTranslate() functions.
  580.  
  581.           The vrl_ObjectRotate() and vrl_ObjectTranslate() functions should
  582.           be used for all object rotation and translation.  Some older
  583.           functions are also provided for rotating and moving objects
  584.           relative to their parent (one of the more common cases); they are
  585.           as follows:
  586.  
  587.                void vrl_ObjectMove(vrl_Object *obj, vrl_Scalar x, vrl_Scalar y, vrl_Scalar z);
  588.                           void vrl_ObjectRelMove(vrl_Object *obj, vrl_Scalar x, vrl_Scalar y, vrl_Scalar z);
  589.                           void vrl_ObjectRotX(vrl_Object *obj, vrl_Angle angle);
  590.  
  591.                                               AVRIL Technical Reference Manual              10
  592.  
  593.  
  594.  
  595.  
  596.  
  597.                           void vrl_ObjectRotY(vrl_Object *obj, vrl_Angle angle);
  598.                           void vrl_ObjectRotZ(vrl_Object *obj, vrl_Angle angle);
  599.                           void vrl_ObjectRotVector(vrl_Object *obj, vrl_Angle angle, vrl_Vector vector);
  600.                           void vrl_ObjectRotReset(vrl_Object *obj);
  601.                           void vrl_ObjectVectorMove(vrl_Object *obj, vrl_Vector v);
  602.                           void vrl_ObjectVectorRelMove(vrl_Object *obj, vrl_Vector v);
  603.  
  604.           An object's current location can be obtained in two ways, either
  605.           component-by-component for each of X, Y and Z, or copied into a
  606.           vector:
  607.  
  608.                vrl_Scalar vrl_ObjectGetWorldX(vrl_Object *object);
  609.                           vrl_Scalar vrl_ObjectGetWorldY(vrl_Object *object);
  610.                           vrl_Scalar vrl_ObjectGetWorldZ(vrl_Object *object);
  611.                           void vrl_ObjectGetWorldLocation(vrl_Object *object, vrl_Vector v);
  612.  
  613.                           vrl_Scalar vrl_ObjectGetRelativeX(vrl_Object *object);
  614.                           vrl_Scalar vrl_ObjectGetRelativeY(vrl_Object *object);
  615.                           vrl_Scalar vrl_ObjectGetRelativeZ(vrl_Object *object);
  616.                           void vrl_ObjectGetRelativeLocation(vrl_Object *object, vrl_Vector v);
  617.  
  618.           The World versions of the functions return the absolute world
  619.           coordinates; the Relative versions return the coordinates
  620.           relative to the object's parent.
  621.  
  622.           The rotation angles of objects, either relative to the world or
  623.           to their parent, can be obtained using the following routines:
  624.  
  625.                void vrl_ObjectGetWorldRotations(vrl_Object *object,
  626.                                   vrl_Angle *rx, vrl_Angle *ry, vrl_Angle *rz);
  627.                           void vrl_ObjectGetRelativeRotations(vrl_Object *object,
  628.                                   vrl_Angle *rx, vrl_Angle *ry, vrl_Angle *rz);
  629.  
  630.           The current world-space orientation of an object's "forward",
  631.           "up" and "right" vectors can be obtained using the following
  632.           routines:
  633.  
  634.                void vrl_ObjectGetForwardVector(vrl_Object *object, vrl_Vector v);
  635.                           void vrl_ObjectGetRightVector(vrl_Object *object, vrl_Vector v);
  636.                           void vrl_ObjectGetUpVector(vrl_Object *object, vrl_Vector v);
  637.  
  638.           The vectors filled in by these routines will all be normalized.
  639.  
  640.           An object can be attached to another object, or detached from
  641.           whatever object it is currently attached to; you can also find
  642.           out the "parent" of the object:
  643.  
  644.                vrl_Object *vrl_ObjectAttach(vrl_Object *obj, vrl_Object *newparent);
  645.                           vrl_Object *vrl_ObjectDetach(vrl_Object *obj);
  646.                           vrl_Object *vrl_ObjectGetParent(vrl_Object *obj);
  647.  
  648.  
  649.  
  650.                            AVRIL Technical Reference Manual              11
  651.  
  652.  
  653.  
  654.  
  655.  
  656.           The vrl_ObjectAttach() and vrl_ObjectDetach() functions return a
  657.           pointer to the object's previous parent if any.  Note that
  658.           movement and rotation in the VRL_COORD_PARENT system (including
  659.           that performed using vrl_ObjectRotX() and other similar
  660.           functions) is carried out relative to the object's parent.  In
  661.           other words, if the object is attached to another object, its
  662.           location and orientation will depend on that of its parent; if
  663.           the parent moves, the child will move with it.  However, if the
  664.           child moves the parent will stay where it is.
  665.  
  666.           You can find the "root" of an object tree using the following
  667.           function:
  668.  
  669.                vrl_Object *vrl_ObjectFindRoot(vrl_Object *obj);
  670.  
  671.           You can walk an entire object tree, executing a function on each
  672.           node of the tree, using the following routine:
  673.  
  674.                void vrl_ObjectTraverse(vrl_Object *object, int (*function)(vrl_Object *obj));
  675.  
  676.           The function is called once for each object in the hierarchy, and
  677.           is given a pointer to the object it's being called on; if the
  678.           function returns a non-zero value at any point, the tree is not
  679.           processed any further.  All parent objects are processed before
  680.           their descendants.
  681.  
  682.           The distance between two objects can be found using
  683.  
  684.                vrl_Scalar vrl_ObjectComputeDistance(vrl_Object *obj1, vrl_Object *obj2);
  685.  
  686.           The shape and surface map of an object can be altered at any
  687.           time, and as often as needed, using the following routines:
  688.  
  689.                void vrl_ObjectSetShape(vrl_Object *object, vrl_Shape *shape);
  690.                           vrl_Shape *vrl_ObjectGetShape(vrl_Object *object);
  691.  
  692.                           void vrl_ObjectSetSurfacemap(vrl_Object *object, vrl_Surfacemap *map);
  693.                           vrl_Surfacemap *vrl_ObjectGetSurfacemap(vrl_Object *object);
  694.  
  695.           Objects can be flagged as invisible (in which case they're not
  696.           drawn) or highlighted (in which case they're drawn with a bright
  697.           outline).  They can also have a "layer" property, and individual
  698.           layers can be made visible or invisible, as described later in
  699.           the section on Layers.  Note that layer zero is always visible;
  700.           in effect, an object whose layer is zero will appear on all
  701.           layers.  The following routines are used to set, query and toggle
  702.           those values:
  703.  
  704.                void vrl_ObjectSetVisibility(vrl_Object *object, int vis);
  705.                           int vrl_ObjectGetVisibility(vrl_Object *object);
  706.                           void vrl_ObjectToggleVisibility(vrl_Object *object);
  707.  
  708.  
  709.                                               AVRIL Technical Reference Manual              12
  710.  
  711.  
  712.  
  713.  
  714.  
  715.                           void vrl_ObjectSetHighlight(vrl_Object *object, highlight);
  716.                           int vrl_ObjectGetHighlight(vrl_Object *object);
  717.                           void vrl_ObjectToggleHighlight(vrl_Object *object);
  718.  
  719.                           void vrl_ObjectSetLayer(vrl_Object *object, int layer);
  720.                           int vrl_ObjectGetLayer(vrl_Object *object);
  721.  
  722.           AVRIL supports the idea of "fixed" objects; you can mark an
  723.           object as fixed or movable, and find out its current status,
  724.           using the following functions:
  725.  
  726.                void vrl_ObjectMakeFixed(vrl_Object *object);
  727.                           void vrl_ObjectMakeMovable(vrl_Object *object);
  728.                           vrl_Boolean vrl_ObjectIsFixed(vrl_Object *object);
  729.  
  730.           You can also find out the boundaries of an object (in world
  731.           coordinates) using the functions
  732.  
  733.                void vrl_ObjectGetMinbounds(vrl_Object *object, vrl_Vector v);
  734.                           void vrl_ObjectGetMaxbounds(vrl_Object *object, vrl_Vector v);
  735.  
  736.           The vectors returned by these two functions can be thought of as
  737.           the opposite corners of the object's bounding box.
  738.  
  739.                AVRIL will normally select a level of detail for an object
  740.           automatically; however, you can override this mechanism on an
  741.           object-by-object basis using two routines to set and get the
  742.           current "forced" rep for an object:
  743.  
  744.                void vrl_ObjectSetRep(vrl_Object *object, vrl_Rep *rep);
  745.                           vrl_Rep *vrl_ObjectGetRep(vrl_Object *object);
  746.  
  747.           If you want automatic representation selection to be re-enabled
  748.           for the object, just use vrl_ObjectSetRep(obj, NULL).  See the
  749.           section on Representations for details.
  750.  
  751.           Whenever an object moves, all the objects "descended" from that
  752.           object must be updated.  The following function will update the
  753.           object and all its descendants:
  754.  
  755.                vrl_Object *vrl_ObjectUpdate(vrl_Object *object);
  756.  
  757.           You should generally only call this once per frame, on the object
  758.           tree for the current world; the macro vrl_WorldUpdate() can be
  759.           used to do this more concisely.
  760.  
  761.                A vrl_Object can have several other properties associated
  762.           with it.  These include a name, a function, and some application-
  763.           specific data.  The function associated with an object gets
  764.           called whenever the object is processed during the tree-walking
  765.           that vrl_ObjectUpdate() performs.  The following routines allow
  766.           you to get and set these additional properties:
  767.  
  768.                            AVRIL Technical Reference Manual              13
  769.  
  770.  
  771.  
  772.  
  773.  
  774.                           void vrl_ObjectSetName(vrl_Object *obj, char *str);
  775.                           char *vrl_ObjectGetName(vrl_Object *obj);
  776.                           void vrl_ObjectSetFunction(vrl_Object *obj, vrl_ObjectFunction fn);
  777.                           vrl_ObjectFunction *vrl_ObjectGetFunction(vrl_Object *obj);
  778.                           void vrl_ObjectSetApplicationData(vrl_Object *obj, void *data);
  779.                           void *vrl_ObjectGetApplicationData(vrl_Object *obj);
  780.  
  781.           Shapes
  782.  
  783.                As described earlier, AVRIL keeps shape information separate
  784.           from object descriptions, so that shapes can be re-used by
  785.           multiple objects.  Shapes (entities of type vrl_Shape) are
  786.           generally read from PLG files using the vrl_ReadPLG() function,
  787.           described later.  You can also create them using the
  788.           vrl_Primitive family of functions, also described later in this
  789.           document.  The syntax for PLG files is described in Appendix C.
  790.  
  791.                You can modify a shape after it's been loaded; bear in mind
  792.           that any changes you make to a shape will affect all objects
  793.           using that shape!  To re-scale a shape, or shift all the vertices
  794.           in the shape relative to the shape's origin point, use the
  795.           following functions:
  796.  
  797.                void vrl_ShapeRescale(vrl_Shape *shape, float sx, float sy, float sz);
  798.                           void vrl_ShapeOffset(vrl_Shape *shape, vrl_Scalar tx, vrl_Scalar ty, vrl_Scalar tz);
  799.  
  800.                  After making changes to a shape (or any representation within a
  801.           shape), you should call vrl_ShapeUpdate() to recompute the
  802.           shape's bounds.
  803.  
  804.                void vrl_ShapeUpdate(vrl_Shape *shape);
  805.  
  806.           The vrl_ShapeRescale() and vrl_ShapeOffset() routines call
  807.           vrl_ShapeUpdate() automatically, so you don't have to do it
  808.           again; it's only when you move individual vertices that you need
  809.           to worry about it.
  810.  
  811.           Shapes can have a default surface map, which is used for objects
  812.           that don't set one of their own.  A pointer to a shape's default
  813.           surface map can be obtained, or a pointer to a new surfacemap for
  814.           a shape set, by calling the functions
  815.  
  816.                vrl_Surfacemap *vrl_ShapeGetSurfacemap(vrl_Shape *shape);
  817.                           void vrl_ShapeSetSurfacemap(vrl_Shape *shape, vrl_Surfacemap *map);
  818.  
  819.           To get a pointer to the representation of a shape that will be
  820.           used at a given on-screen size, use following function:
  821.  
  822.                           vrl_Rep *vrl_ShapeGetRep(vrl_Shape *shape, vrl_Scalar size);
  823.  
  824.           To add an additional representation to an existing shape, use the
  825.           function
  826.  
  827.                            AVRIL Technical Reference Manual              14
  828.  
  829.  
  830.  
  831.  
  832.  
  833.                           void vrl_ShapeAddRep(vrl_Shape *shape, vrl_Rep *rep, vrl_Scalar size);
  834.  
  835.           The size parameter gives the apparent on-screen size in pixels at
  836.           which the shape should be used.  You can find out how many
  837.           representations a shape has using the function
  838.  
  839.                int vrl_ShapeCountReps(vrl_Shape *shape);
  840.  
  841.           A shape's name can be set or obtained using the functions
  842.  
  843.                void vrl_ShapeSetName(vrl_Shape *shape, char *str);
  844.                           char *vrl_ShapeGetName(vrl_Shape *shape);
  845.  
  846.           Shapes are kept internally in a singly-linked list; if you need
  847.           to iterate through the list, the following two functions can be
  848.           used
  849.  
  850.                           vrl_Shape *vrl_ShapeGetList(void);
  851.                           vrl_Shape *vrl_ShapeGetNext(vrl_Shape *shape)
  852.  
  853.           You can also locate a shape by name using
  854.  
  855.                           vrl_Shape *vrl_ShapeFind(char *name);
  856.  
  857.           Representations
  858.  
  859.                A shape can have any number of representations, at various
  860.           levels of detail.  Each representation (vrl_Rep) has a set of
  861.           vertices (each of type vrl_Vector) and a set of facets (each of
  862.           type vrl_Facet).  A representation can also have a "sorting type"
  863.           field; this will be explained in more detail in future releases
  864.           of this documentation.
  865.  
  866.                You can traverse the list of representations for a shape,
  867.           calling a function on each representation, by using the following
  868.           routine:
  869.  
  870.                void vrl_ShapeTraverseReps(vrl_Shape *shape, int (*function(vrl_Rep *rep)));
  871.  
  872.           The function is called once for every representation, and is
  873.           given the representation as a parameter.  If the function returns
  874.           a non-zero value, the processing of the representation list stops
  875.           at that rep.
  876.  
  877.                The other approach is to iterate through the linked list of
  878.           representations using the functions
  879.  
  880.                vrl_Rep *vrl_ShapeGetFirstRep(vrl_Shape *shape);
  881.                           vrl_Rep *vrl_RepGetNext(vrl_Rep *rep);
  882.  
  883.           You can set and get a vrl_Rep's sorting type, find out the
  884.           approximate size (in pixels) at which a rep becomes effective, as
  885.  
  886.                            AVRIL Technical Reference Manual              15
  887.  
  888.  
  889.  
  890.  
  891.  
  892.           well as count the number of vertices and facets in a rep using
  893.           the following functions:
  894.  
  895.                void vrl_RepSetSorting(vrl_Rep *rep, int type);
  896.                           int vrl_RepGetSorting(vrl_Rep *rep);
  897.  
  898.                           int vrl_RepGetSize(vrl_Rep *rep);
  899.  
  900.                           int vrl_RepCountVertices(vrl_Rep *rep);
  901.                           int vrl_RepCountFacets(vrl_Rep *rep);
  902.  
  903.                  There are also "traversal" functions for vertices and facets:
  904.  
  905.                void vrl_RepTraverseVertices(vrl_Rep *rep, int (*function)(vrl_Vector *vertex));
  906.                           void vrl_RepTraverseFacets(vrl_Rep *rep, int (*function)(vrl_Facet *facet));
  907.  
  908.           If you need to get or set the values of a vertex's coordinates,
  909.           you can use the functions
  910.  
  911.                void vrl_RepGetVertex(vrl_Rep *rep, int n, vrl_Vector v);
  912.                           void vrl_RepSetVertex(vrl_Rep *rep, int n, vrl_Vector v);
  913.  
  914.           Be careful when using vrl_RepSetVertex(); it's easy to move a
  915.           vertex and create non-planar or non-convex facets, which confuse
  916.           the renderer.  You can only move vertices safely if you know the
  917.           vrl_Rep is composed entirely of triangles, since by their nature
  918.           triangles are always planar and convex.  In any case, be sure to
  919.           call vrl_ShapeUpdate() after moving any vertices.
  920.  
  921.           To support Gouraud shading, functions are provided to compute
  922.           vertex normals by averaging the normal vectors of all the polys
  923.           which share the vertex in a vrl_Rep or a vrl_Shape:
  924.  
  925.                void vrl_RepComputeVertexNormals(vrl_Rep *rep);
  926.                           void vrl_ShapeComputeVertexNormals(vrl_Shape *shape);
  927.  
  928.           Make sure that the polygons normals have already been computed
  929.           (by the vrl_ShapeUpdate() function) before calling
  930.           vrl_RepComputeVertexNormals().
  931.  
  932.           There's also a function for computing edge information for a
  933.           representation; currently, this information is not used:
  934.  
  935.                void vrl_RepBuildEdges(vrl_Rep *rep);
  936.  
  937.           Facets
  938.  
  939.                AVRIL's terminology is slightly different from some other VR
  940.           systems; a "facet" is a flat three-dimensional entity, whereas a
  941.           "polygon" is a two dimensional area on the screen.  The job of
  942.           the graphics pipeline is to turn facets into polygons.
  943.  
  944.  
  945.                            AVRIL Technical Reference Manual              16
  946.  
  947.  
  948.  
  949.  
  950.  
  951.                Facets in AVRIL have an array of integers that specify which
  952.           vertices in the representation should be connected (and in what
  953.           sequence) to form the outline of the facet.  Facets also have an
  954.           index into the surface map for an object, to determine what the
  955.           surface properties of the facet should be.  They also have a flag
  956.           that indicates whether or not the facet should be highlighted.
  957.  
  958.                The surface index of any facet can be set or queried at any
  959.           time using the following two routines:
  960.  
  961.                void vrl_FacetSetSurfnum(vrl_Facet *facet, int n);
  962.                           int void vrl_FacetGetSurfnum(vrl_Facet *facet);
  963.  
  964.           The highlighting of the facet can be set, queried or toggled
  965.           using the following routines:
  966.  
  967.                void vrl_FacetSetHighlight(vrl_Facet *facet, int high);
  968.                           int vrl_FacetGetHighlight(vrl_Facet *facet);
  969.                           void vrl_FacetToggleHighlight(vrl_Facet *facet);
  970.  
  971.           The number of points in the facet, the index of any particular
  972.           point, or a pointer to the vertex for a particular point, can all
  973.           be obtained using these routines:
  974.  
  975.                int vrl_FacetCountPoints(vrl_Facet *facet);
  976.                           int vrl_FacetGetPoint(vrl_Facet *facet, int n);
  977.                           vrl_Vector *vrl_FacetGetVertex(vrl_Rep *rep, vrl_Facet *facet, int n); 
  978.  
  979.           vrl_Facets can be identified by an ID number.  The ID number for
  980.           a vrl_Facet can be set and read, and a vrl_Facet with a
  981.           particular ID can be found, using the following functions:
  982.  
  983.                void vrl_FacetSetId(vrl_Facet *facet, vrl_unsigned16bit n);
  984.                           vrl_unsigned16bit vrl_FacetGetId(vrl_Facet *facet);
  985.                           vrl_Facet *vrl_RepFindFacet(vrl_Rep *rep, vrl_unsigned16bit id);
  986.  
  987.           Surfaces
  988.  
  989.                AVRIL surfaces are designed for expandability.  At the
  990.           moment, each vrl_Surface consists of a type, a hue and a
  991.           brightness.  The types are SURF_SIMPLE (no lighting, just a fixed
  992.           color), SURF_FLAT (for flat shading), SURF_GOURAUD (for Gouraud
  993.           shading), SURF_METAL (for a pseudo-metallic effect) and
  994.           SURF_GLASS (for a partially transparent effect).  Surfaces are
  995.           initialized and modified using the following routines:
  996.  
  997.                vrl_Surface *vrl_SurfaceInit(vrl_Surface *surf);
  998.                           vrl_Surface *vrl_SurfaceCreate(vrl_unsigned8bit hue);
  999.  
  1000.                           void vrl_SurfaceSetType(vrl_Surface *surf, vrl_LightingType type);
  1001.                           vrl_LightingType vrl_SurfaceGetType(vrl_Surface *surf);
  1002.  
  1003.  
  1004.                                               AVRIL Technical Reference Manual              17
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010.                           void vrl_SurfaceSetHue(vrl_Surface *surf, unsigned char h);
  1011.                           unsigned char vrl_SurfaceGetHue(vrl_Surface *surf);
  1012.  
  1013.                           void vrl_SurfaceSetBrightness(vrl_Surface *surf, unsigned char b);
  1014.                           unsigned char vrl_SurfaceGetBrightness(vrl_Surface *surf);
  1015.  
  1016.           The hue and brightness values are 8-bit unsigned quantities; the
  1017.           maximum brightness value is therefore 255.
  1018.  
  1019.                Future versions of AVRIL may support specular shading; the
  1020.           following two functions allow you to set and get the specular
  1021.           exponent value, which controls the "sharpness" of the specular
  1022.           highlights:
  1023.  
  1024.                void vrl_SurfaceSetExponent(vrl_Surface *surf, vrl_Exponent exp);
  1025.                           vrl_Exponent vrl_SurfaceGetExponent(vrl_Surface *surf);
  1026.  
  1027.                For backwards compatibility with REND386, AVRIL includes
  1028.           functions to convert a 16-bit REND386 surface descriptor into a
  1029.           vrl_Surface, and vice-versa:
  1030.  
  1031.                vrl_Surface *vrl_SurfaceFromDesc(vrl_unsigned16bit desc, vrl_Surface *surf);
  1032.                           vrl_unsigned16bit vrl_SurfaceToDesc(vrl_Surface *surf);
  1033.  
  1034.           As surfaces are created, they are added to a list; the following
  1035.           functions allow you to iterate through the list:
  1036.  
  1037.                vrl_Surface *vrl_SurfaceGetList(void);
  1038.                           vrl_Surface *vrl_SurfaceGetNext(vrl_Surface *surf);
  1039.  
  1040.           Surface Maps
  1041.  
  1042.                Surface maps contain an array of pointers to surfaces; you
  1043.           can create a surface map with room for a particular number of
  1044.           entries, find out how many entries the map contains, and access
  1045.           entries within a map, using the following routines:
  1046.  
  1047.                vrl_Surfacemap *vrl_SurfacemapCreate(int n);
  1048.                           int vrl_SurfacemapCountEntries(vrl_Surfacemap *map);
  1049.                           vrl_Surface *vrl_SurfacemapGetSurface(vrl_Surfacemap *map, int surfnum);
  1050.                           vrl_Surface *vrl_SurfacemapSetSurface(vrl_Surfacemap *map, int surfnum,
  1051.                                   vrl_Surface *surface);
  1052.  
  1053.           As surfacemaps are defined, they are added to a list; the list
  1054.           can be iterated through using the following functions:
  1055.  
  1056.                vrl_Surfacemap *vrl_SurfacemapGetList(void);
  1057.                           vrl_Surfacemap *vrl_SurfacemapGetNext(vrl_Surfacemap *map);
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.                            AVRIL Technical Reference Manual              18
  1064.  
  1065.  
  1066.  
  1067.  
  1068.  
  1069.           Lights
  1070.  
  1071.                Lights in AVRIL have a number of properties; they can be on
  1072.           or off, they can have an intensity, they can have a "type", and
  1073.           they can be associated with an object.  The on/off and intensity
  1074.           properties are similar to a household dimmer; rotating the knob
  1075.           on a dimmer alters the intensity, and pushing it in toggles the
  1076.           light on and off.
  1077.  
  1078.                The current version of AVRIL only supports ambient lights
  1079.           and directional lights; point sources will be supported soon. 
  1080.           Any light that is not associated with an object is considered
  1081.           ambient; this is in addition to the overall ambient light level
  1082.           for the world.  A directional light uses the orientation of the
  1083.           object it's associated with to determine which direction the
  1084.           light should come from.  A point source light (once implemented)
  1085.           will use the location of the object it's associated with to
  1086.           determine where the light comes from.
  1087.  
  1088.                As with worlds and objects, lights can be statically or
  1089.           dynamically created and destroyed using the following functions:
  1090.  
  1091.                vrl_Light *vrl_LightInit(vrl_Light *light);
  1092.                           vrl_Light *vrl_LightCreate(void);
  1093.                           void vrl_LightDestroy(vrl_Light *light);
  1094.  
  1095.           The light's type value can be one of LIGHT_AMBIENT,
  1096.           LIGHT_DIRECTIONAL or LIGHT_POINTSOURCE, and is set and queried
  1097.           using the following two functions:
  1098.  
  1099.                void vrl_LightSetType(vrl_Light *light, int type);
  1100.                           int vrl_LightGetType(vrl_Light *light);
  1101.  
  1102.           The light's on/off status can be checked and altered, and the
  1103.           intensity set and queried, using these functions:
  1104.  
  1105.                void vrl_LightOn(vrl_Light *light);
  1106.                           void vrl_LightOff(vrl_Light *light);
  1107.                           void vrl_LightToggle(vrl_Light *light);
  1108.                           vrl_Boolean vrl_LightIsOn(vrl_Light *light);
  1109.  
  1110.                           void vrl_LightSetIntensity(vrl_Light *light, vrl_Factor inten);
  1111.                           vrl_Factor vrl_LightGetIntensity(vrl_Light *light);
  1112.  
  1113.           Notice that the intensity values are vrl_Factors; they should
  1114.           never be less than zero or greater than VRL_UNITY.
  1115.  
  1116.                You can make and break associations between a light source
  1117.           and an object, and determine what object a light source is
  1118.           currently associated with, using the following routines:
  1119.  
  1120.                void vrl_LightAssociate(vrl_Light *light, vrl_Object *object);
  1121.  
  1122.                                               AVRIL Technical Reference Manual              19
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.                           void vrl_LightDisAssociate(vrl_Light *light);
  1129.                           vrl_Object *vrl_LightGetObject(vrl_Light *light);
  1130.  
  1131.           Many of the routines that were used for objects earlier have
  1132.           counterparts that are used for light sources; they're implemented
  1133.           as macros that just perform the operations on the object with
  1134.           which the light source is associated.
  1135.  
  1136.                vrl_LightMove(light, x, y, z);
  1137.                           vrl_LightRelMove(light, x, y, z);
  1138.                           vrl_LightVectorMove(light, v);
  1139.                           vrl_LightVectorRelMove(light, v);
  1140.                           vrl_LightRotX(light, angle);
  1141.                           vrl_LightRotY(light, angle);
  1142.                           vrl_LightRotZ(light, angle);
  1143.                           vrl_LightRotVector(light, angle, vector);
  1144.                           vrl_LightRotReset(light);
  1145.                           vrl_LightRotate(light, angle, axis, frame, relative_to);
  1146.                           vrl_LightTranslate(light, v, axis, frame, relative_to);
  1147.                           vrl_LightLookAt(light, forward, up);
  1148.                           vrl_LightAttach(obj, newparent);
  1149.                           vrl_LightDetach(obj);
  1150.                           vrl_LightGetWorldX(light);
  1151.                           vrl_LightGetWorldY(light);
  1152.                           vrl_LightGetWorldZ(light);
  1153.                           vrl_LightGetWorldLocation(light, v);
  1154.                           vrl_LightGetWorldRotations(light, rx, ry, rz);
  1155.                           vrl_LightGetRelativeX(light);
  1156.                           vrl_LightGetRelativeY(light);
  1157.                           vrl_LightGetRelativeZ(light);
  1158.                           vrl_LightGetRelativeLocation(light, v);
  1159.                           vrl_LightGetRelativeRotations(light, rx, ry, rz);
  1160.  
  1161.           It's important to note the difference between attaching and
  1162.           associating light sources.  A light source can be associated with
  1163.           an object, which means it will use that object's location and
  1164.           orientation as its own.  The object with which the light is
  1165.           associated can be attached to another object, and "inherit"
  1166.           location and orientation information from it.  The
  1167.           vrl_LightAttach() and vrl_LightDetach() routines are provided
  1168.           only as a convenience; what you're really attaching and detaching
  1169.           with those routines is the object that the light is associated
  1170.           with.  You generally associate a light source with an object
  1171.           once, and leave it that way; you can attach or detach the light
  1172.           however you want after that.
  1173.  
  1174.                Lights can have other attributes as well, just as objects
  1175.           can; specifically, they can have a name and some application-
  1176.           specific data, which are accessed using the following functions:
  1177.  
  1178.                void vrl_LightSetName(vrl_Light *light, char *str);
  1179.                           char *vrl_LightGetName(vrl_Light *light);
  1180.  
  1181.                                               AVRIL Technical Reference Manual              20
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.                           void vrl_LightSetApplicationData(vrl_Light *light, void *data);
  1188.                           void *vrl_LightGetApplicationData(vrl_Light *light);
  1189.  
  1190.           Cameras
  1191.  
  1192.                AVRIL allows you to have any number of virtual cameras. 
  1193.           Each camera is associated with an object, much as lights are. 
  1194.           However, unlike lights, cameras must be associated with an
  1195.           object; there's no such thing as an "ambient" camera.  Cameras
  1196.           are initialized and destroyed just like objects or light sources:
  1197.  
  1198.                vrl_Camera *vrl_CameraInit(vrl_Camera *camera);
  1199.                           vrl_Camera *vrl_CameraCreate(void);
  1200.                           void vrl_CameraDestroy(vrl_Camera *camera);
  1201.  
  1202.           Cameras have only a few properties that are important; in
  1203.           particular, a zoom factor, an aspect ratio, and hither and yon
  1204.           clipping plane distances.  These are all set and queried using
  1205.           the following routines:
  1206.  
  1207.                void vrl_CameraSetZoom(vrl_Camera *camera, float zoom);
  1208.                           float vrl_CameraGetZoom(vrl_Camera *camera);
  1209.  
  1210.                           void vrl_CameraSetAspect(vrl_Camera *camera, float asp);
  1211.                           float vrl_CameraGetAspect(vrl_Camera *camera);
  1212.  
  1213.                           void vrl_CameraSetHither(vrl_Camera *camera, vrl_Scalar hither);
  1214.                           vrl_Scalar vrl_CameraGetHither(vrl_Camera *camera);
  1215.  
  1216.                           void vrl_CameraSetYon(vrl_Camera *camera, vrl_Scalar yon);
  1217.                           vrl_Scalar vrl_CameraGetYon(vrl_Camera *camera);
  1218.  
  1219.           Notice that the zoom factor and aspect ratio are floats; this may
  1220.           change in a future release of AVRIL.  The zoom factor works like
  1221.           the zoom on a camera; the higher the zoom, the more the image is
  1222.           magnified.  The zoom is the tangent of half the field of view. 
  1223.           The aspect ratio is the ratio between the horizontal and vertical
  1224.           zoom factors.  The hither clipping distance is the distance in
  1225.           virtual space from the camera to the invisible plane at which
  1226.           objects will be "clipped".  The "yon" distance is like an
  1227.           invisible wall; any object entirely on the far side of the wall
  1228.           will not be seen.
  1229.  
  1230.                The routines for associating a camera with an object and for
  1231.           determining what object a camera is currently associated with are
  1232.           as follows:
  1233.  
  1234.                void vrl_CameraAssociate(vrl_Camera *camera, vrl_Object *object);
  1235.                           vrl_Object *vrl_CameraGetObject(vrl_Camera *camera);
  1236.  
  1237.  
  1238.  
  1239.  
  1240.                            AVRIL Technical Reference Manual              21
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.           There's no vrl_CameraDisAssociate() function, as there was for
  1247.           lights; cameras must be associated with an object in order to
  1248.           have any meaning.
  1249.  
  1250.                Again, routines are provided for manipulating and querying
  1251.           the location and orientation of a virtual camera; these are
  1252.           macros, just as they were for lights:
  1253.  
  1254.                vrl_CameraMove(camera, x, y, z);
  1255.                           vrl_CameraRelMove(camera, x, y, z);
  1256.                           vrl_CameraVectorMove(camera, v);
  1257.                           vrl_CameraVectorRelMove(camera, v);
  1258.                           vrl_CameraRotX(camera, angle);
  1259.                           vrl_CameraRotY(camera, angle);
  1260.                           vrl_CameraRotZ(camera, angle);
  1261.                           vrl_CameraRotVector(camera, angle, vector);
  1262.                           vrl_CameraRotReset(camera);
  1263.                           vrl_CameraRotate(camera, angle, axis, frame, relative_to);
  1264.                           vrl_CameraLookAt(camera, forward, up);
  1265.                           vrl_CameraTranslate(camera, v, axis, frame, relative_to);
  1266.                           vrl_CameraAttach(obj, newparent);
  1267.                           vrl_CameraDetach(obj);
  1268.                           vrl_CameraGetWorldX(camera);
  1269.                           vrl_CameraGetWorldY(camera);
  1270.                           vrl_CameraGetWorldZ(camera);
  1271.                           vrl_CameraGetWorldLocation(camera, v);
  1272.                           vrl_CameraGetWorldRotations(camera, rx, ry, rz);
  1273.                           vrl_CameraGetRelativeX(camera);
  1274.                           vrl_CameraGetRelativeY(camera);
  1275.                           vrl_CameraGetRelativeZ(camera);
  1276.                           vrl_CameraGetRelativeLocation(camera, v);
  1277.                           vrl_CameraGetRelativeRotations(camera, rx, ry, rz);
  1278.  
  1279.           Camera can have other attributes as well, just as objects and
  1280.           lights can; specifically, they can have a name and some
  1281.           application-specific data, which are accessed using the following
  1282.           functions:
  1283.  
  1284.                void vrl_CameraSetName(vrl_Camera *camera, char *str);
  1285.                           char *vrl_CameraGetName(vrl_Camera *camera);
  1286.                           void vrl_CameraSetApplicationData(vrl_Camera *camera, void *data);
  1287.                           void *vrl_CameraGetApplicationData(vrl_Camera *camera);
  1288.  
  1289.           In addition, there are three routines that obtain the current
  1290.           "forward", "right" and "up" vectors for a camera:
  1291.  
  1292.                vrl_CameraGetForwardVector(camera, v)
  1293.                           vrl_CameraGetRightVector(camera, v)
  1294.                           vrl_CameraGetUpVector(camera, v)
  1295.  
  1296.  
  1297.  
  1298.  
  1299.                            AVRIL Technical Reference Manual              22
  1300.  
  1301.  
  1302.  
  1303.  
  1304.  
  1305.           Layers
  1306.  
  1307.                Layers were described earlier, in the section on objects. 
  1308.           The routines for dealing with layers are as follows:
  1309.  
  1310.                void vrl_LayerOn(int n);
  1311.                           void vrl_LayerOff(int n);
  1312.                           void vrl_LayerToggle(int n);
  1313.                           int vrl_LayerIsOn(int n);
  1314.                           void vrl_LayerAllOn(void);
  1315.                           void vrl_LayerAllOff(void);
  1316.  
  1317.           The last two routines, vrl_LayerAllOn() and vrl_LayerAllOff(),
  1318.           turn all the layers on or off at once.  By default, all layers
  1319.           are on.
  1320.  
  1321.           Stereoscopic Rendering
  1322.  
  1323.           Stereoscopic rendering consists of generating two images, one for
  1324.           the left eye and one for the right.  The world data structure
  1325.           maintains a flag indicating whether stereoscopic rendering should
  1326.           be used, as well as pointers to the left-eye and right-eye
  1327.           cameras and the stereo configuration information; see the section
  1328.           on Worlds for more information.
  1329.  
  1330.           There are a number of ways of transferring the separate left and
  1331.           right images to the viewer's eyes; among them are anaglyph
  1332.           techniques that use red and blue filters, field sequential
  1333.           techniques that use shutter glasses, optical techniques that use
  1334.           a split screen, alternate-scanline techniques, and systems that
  1335.           use more than one VGA card.
  1336.  
  1337.           In addition, there are systems that provide stereoscopic depth
  1338.           without using separate images: the patented "Chromadepth"
  1339.           technique used in some comic books and laser light shows is one,
  1340.           and SIRDS (Single-Image Random Dot Stereograms, or "Magic Eye"
  1341.           pictures) are another.
  1342.  
  1343.           In AVRIL, information about the current stereo configuration is
  1344.           stored in a structure of type vrl_StereoConfiguration.  Such a
  1345.           structure can be created (or initialized) using the following
  1346.           functions:
  1347.  
  1348.                vrl_StereoConfiguration *vrl_StereoCreateConfiguration(void);
  1349.                           vrl_StereoConfiguration *vrl_StereoInitConfiguration(vrl_StereoConfiguration *conf);
  1350.  
  1351.           The type of stereoscopic viewing is defined by a constant; the
  1352.           possible values are listed in Appendix I.  Setting and getting
  1353.           the type of stereoscopic viewing is done using the following
  1354.           functions:
  1355.  
  1356.                void vrl_StereoSetType(vrl_StereoConfiguration *conf, vrl_StereoType st_type);
  1357.  
  1358.                                               AVRIL Technical Reference Manual              23
  1359.  
  1360.  
  1361.  
  1362.  
  1363.  
  1364.                           vrl_StereoType vrl_StereoGetType(vrl_StereoConfiguration *conf);
  1365.  
  1366.           Some systems, like Chromadepth and SIRDS, use a single "eye";
  1367.           most others use two eyes.  There's a function for determining the
  1368.           number of "eyes" used by the current stereo type:
  1369.  
  1370.                int vrl_StereoGetNeyes(vrl_StereoConfiguration *conf);
  1371.  
  1372.           You can alter the amount by which each eye's image is shifted on
  1373.           the screen using the following functions:
  1374.  
  1375.                void vrl_StereoSetLeftEyeShift(vrl_StereoConfigurtion *conf, int shift);
  1376.                           int vrl_StereoGetLeftEyeShift(vrl_StereoConfigurtion *conf);
  1377.                           void vrl_StereoSetRightEyeShift(vrl_StereoConfigurtion *conf, int shift);
  1378.                           int vrl_StereoGetRightEyeShift(vrl_StereoConfigurtion *conf);
  1379.  
  1380.           This shift is necessary, due to differences between HMDs.  The
  1381.           total shift (the sum of that which is computed and that which is
  1382.           explicitly set by the functions above) can be obtained using the
  1383.           following functions:
  1384.  
  1385.                int vrl_StereoGetTotalLeftShift(vrl_StereoConfiguration *conf);
  1386.                           int vrl_StereoGetTotalRightShift(vrl_StereoConfiguration *conf);
  1387.  
  1388.           It may be necessary, because of the way an HMD's optics are
  1389.           constructed, to rotate the virtual eyes inwards or outwards. 
  1390.           This is done using the following functions:
  1391.  
  1392.                void vrl_StereoSetLeftEyeRotation(vrl_StereoConfiguration *conf, vrl_Angle rot);
  1393.                           vrl_Angle vrl_StereoGetLeftEyeRotation(vrl_StereoConfiguration *conf);
  1394.                           void vrl_StereoSetRightEyeRotation(vrl_StereoConfiguration *conf, vrl_Angle rot);
  1395.                           vrl_Angle vrl_StereoGetRightEyeRotation(vrl_StereoConfiguration *conf);
  1396.  
  1397.           The eye spacing and convergence distance (both in world units)
  1398.           can be manipulated using the following functions:
  1399.  
  1400.                void vrl_StereoSetEyespacing(vrl_StereoConfiguration *conf, float spacing);
  1401.                           float vrl_StereoGetEyespacing(vrl_StereoConfiguration *conf);
  1402.                           void vrl_StereoSetConvergence(vrl_StereoConfiguration *conf, float conv);
  1403.                           float vrl_StereoGetConvergence(vrl_StereoConfiguration *conf);
  1404.  
  1405.           By using various values for eyespacing and convergence distance,
  1406.           a strong or weaker stereo effect can be achieved.
  1407.  
  1408.           The Chromadepth technique is unusual, in that it uses distance to
  1409.           compute a color between extreme red and extreme blue.  Since only
  1410.           a finite number of palette entries is available, it's necessary
  1411.           to optimize their use over a range of distance; this range is
  1412.           represented by the "ChromaNear" and "ChromaFar" values, which can
  1413.           be altered using the following functions:
  1414.  
  1415.                void vrl_StereoSetChromaNear(vrl_StereoConfiguration *conf, vrl_Scalar val);
  1416.  
  1417.                                               AVRIL Technical Reference Manual              24
  1418.  
  1419.  
  1420.  
  1421.  
  1422.  
  1423.                           vrl_Scalar vrl_StereoGetChromaNear(vrl_StereoConfiguration *conf);
  1424.                           void vrl_StereoSetChromaFar(vrl_StereoConfiguration *conf, vrl_Scalar val);
  1425.                           vrl_Scalar vrl_StereoGetChromaFar(vrl_StereoConfiguration *conf);
  1426.  
  1427.           After altering any of the values in a vrl_StereoConfiguration
  1428.           structure, the following function should be called:
  1429.  
  1430.                int vrl_StereoConfigure(vrl_StereoConfiguration *conf);
  1431.  
  1432.           In order for the system to render a scene stereoscopically, both
  1433.           the left-eye and right-eye cameras must exist in the current
  1434.           world; to create them initially, use the following function:
  1435.  
  1436.                int vrl_StereoSetup(void);   /* creates a pair of cameras */
  1437.  
  1438.           There are a number of routines in the scan-conversion module
  1439.           (i.e., the display driver) that relate to stereoscopic viewing;
  1440.           they are described in the section on display drivers.
  1441.  
  1442.           For more information about stereoscopic rendering and its
  1443.           implementation, see the source code in system.c (which makes all
  1444.           the appropriate calls).
  1445.  
  1446.           File I/O Routines
  1447.  
  1448.                AVRIL supports the PLG file format, the FIG file format, and
  1449.           most of the WLD file format; these formats are described in the
  1450.           Appendices.  The library contains routines for reading each of
  1451.           those formats:
  1452.  
  1453.                vrl_Shape *vrl_ReadPLG(FILE *in);
  1454.                           vrl_Object *vrl_ReadObjectPLG(FILE *in);
  1455.                           int vrl_ReadWLD(FILE *in);
  1456.                           vrl_Object *vrl_ReadFIG(FILE *in, vrl_Object *parent, char *rootname);
  1457.  
  1458.           The vrl_ReadPLG() routine reads a shape from the specified file
  1459.           and returns a pointer to it.  The vrl_ReadObjectPLG() routine is
  1460.           similar, but it also allocates an object and assigns the shape to
  1461.           it.
  1462.  
  1463.                The vrl_ReadWLD() function reads a world description from
  1464.           the file into the current world; you can make as many calls to
  1465.           this routine as you like, combining a number of WLD files.  While
  1466.           reading a WLD file, statements may be encountered which the WLD
  1467.           parser doesn't recognize; these are passed to an application-
  1468.           defined function called
  1469.  
  1470.                void vrl_ReadWLDfeature(int argc, char *argv[], char *rawtext);
  1471.  
  1472.           The argc and argv[] parameters are just like the ones passed to a
  1473.           main() function in C; the rawtext parameter is the original input
  1474.           line.
  1475.  
  1476.                            AVRIL Technical Reference Manual              25
  1477.  
  1478.  
  1479.  
  1480.  
  1481.  
  1482.                The vrl_ReadFIG() routine lets you specify a "parent" object
  1483.           to which the newly-read object tree should be attached, as well
  1484.           as the name of the root object.  Any segment names (segnames)
  1485.           that are assigned in the FIG file will be added to the current
  1486.           world's list of objects as rootname.segname.
  1487.  
  1488.                All the routines listed above assume you've already opened
  1489.           the file; there are also routines for loading objects, figures
  1490.           and entire worlds from files, given the filename:
  1491.  
  1492.                vrl_Object *vrl_ObjectLoadPLGfile(char *filename);
  1493.                           vrl_Object *vrl_ObjectLoadFIGfile(char *filename);
  1494.                           int *vrl_LoadWLDfile(char *filename);
  1495.  
  1496.           While loading a PLG file, a scale factor and offset can be
  1497.           applied.  The vertices read from the file are multiplied by the
  1498.           scaling factors, and then the offsets are added to them.  The
  1499.           scale factors and offsets are set using:
  1500.  
  1501.                void vrl_SetReadPLGscale(float x, float y, float z);
  1502.                           void vrl_SetReadPLGoffset(float x, float y, float z);
  1503.  
  1504.           FIG files can also have a scale factor applied to them.  In
  1505.           addition, parts of a figure that have a "segnum" value set can
  1506.           have pointers to their objects placed into a parts array
  1507.           specified by the user:
  1508.  
  1509.                void vrl_SetReadFIGscale(float x, float y, float z);
  1510.                           void vrl_SetReadFIGpartArray(vrl_Object **ptr, int maxparts);
  1511.  
  1512.           If the ptr is not NULL, then any parts in the FIG file that have
  1513.           a segnum will create an entry in the array, indexed by the segnum
  1514.           value.  The maxparts value is the number of elements the caller
  1515.           has provided space for in the array.
  1516.  
  1517.                There are several other routines that support file
  1518.           operations.  Two routines maintain a kind of "current directory"
  1519.           for file loading; they are
  1520.  
  1521.                void vrl_FileSetLoadpath(char *path);
  1522.                           char *vrl_FileFixupFilename(char *fname);
  1523.  
  1524.           The first sets the given path (if not NULL) to be the directory
  1525.           that subsequent filename fixups should use.  The second routine
  1526.           is used to generate a full filename, with the current loadpath
  1527.           prepended.  Note that filenames beginning with '/' or '\' are not
  1528.           modified.  Also note that vrl_FileFixupFilename() returns a
  1529.           pointer to an internal buffer, which will be rewritten on the
  1530.           next call to vrl_FileFixupFilename().  If you really need to keep
  1531.           the fixed-up filename around, you should strcpy() it to another
  1532.           buffer or strdup() it.
  1533.  
  1534.  
  1535.                            AVRIL Technical Reference Manual              26
  1536.  
  1537.  
  1538.  
  1539.  
  1540.  
  1541.           System and Application routines
  1542.  
  1543.                These routines are described in detail in the Tutorial, but
  1544.           here's a quick summary:
  1545.  
  1546.                vrl_Boolean vrl_SystemStartup(void);
  1547.                           void vrl_SystemRun(void);
  1548.                           vrl_RenderStatus *vrl_SystemRender(vrl_Object *list);
  1549.                           vrl_Time vrl_SystemGetRenderTime(void);
  1550.                           vrl_Time vrl_SystemGetFrameRate(void);
  1551.                           void vrl_SystemCommandLine(int argc, char *argv[]);
  1552.  
  1553.                           void vrl_SystemRequestRefresh(void);
  1554.                           vrl_Boolean vrl_SystemQueryRefresh(void);
  1555.  
  1556.                           void vrl_SystemStartRunning(void);
  1557.                           void vrl_SystemStopRunning(void);
  1558.                           vrl_Boolean vrl_SystemIsRunning(void);
  1559.  
  1560.                           void vrl_ApplicationDrawUnder(void);
  1561.                           void vrl_ApplicationDrawOver(vrl_RenderStatus *stat);
  1562.                           void vrl_ApplicationInit(void);
  1563.                           void vrl_ApplicationKey(vrl_unsigned16bit c);
  1564.                           void vrl_ApplicationMouseUp(int x, int y, unsigned int buttons);
  1565.  
  1566.           These are not really part of AVRIL's "guts", since you don't need
  1567.           to use anything in system.c (which is the only module that knows
  1568.           about the vrl_Application functions).
  1569.  
  1570.           User Interface
  1571.  
  1572.                The current version of AVRIL has a few primitive user
  1573.           interface routines for you to use.  A better user interface needs
  1574.           to be designed; in the meantime, here are the routines:
  1575.  
  1576.                void vrl_UserInterfaceBox(int width, int height, int *x, int *y);
  1577.                           void vrl_UserInterfacePopMsg(char *msg);
  1578.                           void vrl_UserInterfacePopText(char *text[]);
  1579.                           int vrl_UserInterfaceDismiss(void);
  1580.                           int vrl_UserInterfacePopMenu(char *text[]);
  1581.                           int vrl_UserInterfaceMenuDispatch(char *text[], int (**funcs)(void));
  1582.                           vrl_unsigned16bit vrl_UserInterfacePopPrompt(char *prompt, char *buff, int n);
  1583.  
  1584.           The vrl_UserInterfaceBox() routine puts up a nice bordered box,
  1585.           centered on the screen.  The width and height determine the size
  1586.           of the box.  When the routine returns, x and y will contain the
  1587.           screen coordinates of the top-left corner of the box.  Either can
  1588.           be NULL, indicating that you don't care about the values.
  1589.  
  1590.                The vrl_UserInterfacePopMsg() routine displays a one-line
  1591.           text message.  The vrl_UserInterfacePopText() routine puts up a
  1592.  
  1593.  
  1594.                            AVRIL Technical Reference Manual              27
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.           multi-line message; the array of string pointers has to have a
  1601.           NULL pointer entry at the end.
  1602.  
  1603.                The vrl_UserInterfaceDismiss() routine is useful after
  1604.           you've called either vrl_UserInteracePopMsg() or
  1605.           vrl_UserInterfacePopText(); it waits for the user to press a key
  1606.           or click the mouse.
  1607.  
  1608.                The vrl_UserInterfacePopMenu() routine displays a menu and
  1609.           waits for the user to select an item.  If the user clicks on an
  1610.           item with the mouse, the index of that item will be returned as
  1611.           the value of the function.  If the user presses a key, the menu
  1612.           is searched item by item until one is found that has an uppercase
  1613.           letter matching the key the user entered; the index of that entry
  1614.           is returned.  If the user clicks outside the menu, or presses
  1615.           ESC, the value -1 is returned.
  1616.  
  1617.                The vrl_UserInterfaceMenuDispatch() routine is similar to
  1618.           vrl_UserInterfacePopMenu(), but it takes an array of pointers to
  1619.           functions as a second parameter.  When an item in the menu is
  1620.           selected, the corresponding function is called.  No parameters
  1621.           are passed to that function.
  1622.  
  1623.                The vrl_UserInterfacePopPrompt() box displays a prompt to
  1624.           the user and lets them enter a text response.  The backspace key
  1625.           is supported.  The user can end their input using either ENTER or
  1626.           ESC; the key they press to end their input is returned as the
  1627.           value of the function.
  1628.  
  1629.                There are two other routines which are not really part of
  1630.           the user interface; they're used to overlay text on the screen or
  1631.           display the compass.  They're typically called from
  1632.           vrl_ApplicationDrawOver().
  1633.  
  1634.                void vrl_UserInterfaceDrawCompass(vrl_Camera *camera, int x, int y, int armlen);
  1635.                           void vrl_UserInterfaceDropText(int x, int y, vrl_Color, char *text);
  1636.  
  1637.           In vrl_UserInterfaceDrawCompass(), the x and y values are the
  1638.           location of the "origin" of the compass and armlen is the length
  1639.           of each arm.  (The arms will of course seem shorter because of
  1640.           perspective).  The x, y and armlen values are in screen
  1641.           coordinates (i.e., pixels).  The camera is used to obtain
  1642.           orientation information about the user's viewpoint.
  1643.  
  1644.                The vrl_UserInterfaceDropText() routine displays the text
  1645.           message at the given screen coordinates in the given color, with
  1646.           a black (i.e., color 0) drop shadow.
  1647.  
  1648.  
  1649.  
  1650.  
  1651.  
  1652.  
  1653.                            AVRIL Technical Reference Manual              28
  1654.  
  1655.  
  1656.  
  1657.  
  1658.  
  1659.           Tasks
  1660.  
  1661.                The pseudo-tasking mechanism is described in the Tutorial. 
  1662.           Tasks are added using vrl_TaskCreate(), which takes a pointer to
  1663.           the function, a pointer to the data, and the period.  The tasks
  1664.           should be run periodically by calling vrl_TaskRun(), which is
  1665.           normally done in vrl_SystemRun().  The tasks can obtain a pointer
  1666.           to their data by calling vrl_TaskGetData(), the elapsed time
  1667.           since they last ran by calling vrl_TaskGetElapsed(), and the
  1668.           current time by calling vrl_TaskGetTimeNow().  Note that for any
  1669.           given call to vrl_TaskRun(), all the tasks will receive the same
  1670.           value from vrl_TaskGetTimeNow(); this is different from
  1671.           vrl_TimerRead(), since the timer runs independently of the tasks. 
  1672.           You may want to use one or the other of those two functions
  1673.           depending on the circumstances.
  1674.  
  1675.                vrl_Boolean vrl_TaskCreate(void (*function)(void), void *data, vrl_Time period);
  1676.                           void vrl_TaskRun(void);
  1677.                           void *vrl_TaskGetData(void);
  1678.                           vrl_Time vrl_TaskGetElapsed(void);
  1679.                           vrl_Time vrl_TaskGetTimeNow(void);
  1680.  
  1681.           Primitives
  1682.  
  1683.                AVRIL currently provides five utility routines for creating
  1684.           simple geometric primitives.  Each takes a surface map pointer;
  1685.           if the value is NULL, the default color for geometric primitives
  1686.           is used.
  1687.  
  1688.                vrl_Shape *vrl_PrimitiveBox(vrl_Scalar width, vrl_Scalar height, vrl_Scalar depth,
  1689.                                   vrl_Surfacemap *map);
  1690.  
  1691.                           vrl_Shape *vrl_PrimitiveCone(vrl_Scalar radius, vrl_Scalar height, int nsides,
  1692.                                   vrl_Surfacemap *map);
  1693.  
  1694.                           vrl_Shape *vrl_PrimitiveCylinder(vrl_Scalar bottom_radius, vrl_Scalar top_radius,
  1695.                                   vrl_Scalar height, int nsides, vrl_Surfacemap *map);
  1696.  
  1697.                           vrl_Shape *vrl_PrimitivePrism(vrl_Scalar width, vrl_Scalar height, vrl_Scalar depth,
  1698.                                   vrl_Surfacemap *map);
  1699.  
  1700.                           vrl_Shape *vrl_PrimitiveSphere(vrl_Scalar radius, int vsides, int hsides,
  1701.                                   vrl_Surfacemap *map);
  1702.  
  1703.           The box and sphere have their origin at their geometric centers,
  1704.           the cone and the cylinder have their origin at the center of
  1705.           their bases, and the prism has its origin at one corner.  You can
  1706.           use vrl_ShapeOffset() to change these choices if you wish.
  1707.  
  1708.  
  1709.  
  1710.  
  1711.  
  1712.                            AVRIL Technical Reference Manual              29
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.           Rendering
  1719.  
  1720.                The rendering "engine" needs to be initialized before any
  1721.           actual rendering is done.  The renderer needs to know how much
  1722.           memory to allocate for itself, as well as the maximum number of
  1723.           objects, facets, vertices and lights it will have to contend
  1724.           with.  When the program is ready to exit, vrl_RenderQuit() should
  1725.           be called to cleanly shut down the engine.
  1726.  
  1727.                vrl_Boolean vrl_RenderInit(int maxvert, int maxf, int maxobjs, int maxlights,
  1728.                                   unsigned int mempoolsize);
  1729.                           void vrl_RenderQuit(void);
  1730.  
  1731.           The routines in system.c normally handle the calling of
  1732.           vrl_RenderInit(), and the setting up of an atexit() function for
  1733.           vrl_RenderQuit().
  1734.  
  1735.           Two functions are used to give the renderer a pointer to the
  1736.           current camera and list of lights, and to set the current ambient
  1737.           lighting level (usually that for the current world):
  1738.  
  1739.                void vrl_RenderBegin(vrl_Camera *camera, vrl_Light *lights);
  1740.                           void vrl_RenderSetAmbient(vrl_Factor amb);
  1741.  
  1742.           Finally, two functions do the actual drawing; one draws a
  1743.           horizon, the other renders a list of objects (such as that
  1744.           returned by vrl_ObjectUpdate() or vrl_WorldUpdate()).
  1745.  
  1746.                void vrl_RenderHorizon(void);
  1747.                           vrl_Status *vrl_RenderObjlist(vrl_Object *objects);
  1748.  
  1749.           The vrl_RenderObjlist() function returns a pointer to a status
  1750.           struct, which is described in the Tutorial.
  1751.  
  1752.                Since the renderer can highlight objects and draw them in
  1753.           wireframe, there are functions for setting and getting the colors
  1754.           used for highlighting and wireframe:
  1755.  
  1756.                void vrl_RenderSetWireframeColor(vrl_Color color);
  1757.                           vrl_Color vrl_RenderGetWireframeColor(void);
  1758.                           void vrl_RenderSetHighlightColor(vrl_Color color);
  1759.                           vrl_Color vrl_RenderGetHighlightColor(void);
  1760.  
  1761.           You can also set and get the rendering mode:
  1762.  
  1763.                void vrl_RenderSetDrawMode(int mode);
  1764.                           int vrl_RenderGetDrawMode(void);
  1765.  
  1766.           At the moment, the only values supported for the mode are 0
  1767.           (normal) and 1 (wireframe).
  1768.  
  1769.  
  1770.  
  1771.                            AVRIL Technical Reference Manual              30
  1772.  
  1773.  
  1774.  
  1775.  
  1776.  
  1777.           For stereoscopic rendering, a horizontal shift factor is
  1778.           required:
  1779.  
  1780.                void vrl_RenderSetHorizontalShift(int npixels);
  1781.  
  1782.           There are two functions that allow you to monitor a particular
  1783.           point on the screen, render the world, and then see what objects
  1784.           and facets were under the cursor (and nearest the viewer).
  1785.  
  1786.                void vrl_RenderMonitorInit(int x, int y);
  1787.                           vrl_Boolean vrl_RenderMonitorRead(vrl_Object **obj, vrl_Facet **facet, int *vertnum);
  1788.  
  1789.           The x and y values are coordinates in the current screen window
  1790.           (such as those passed to vrl_ApplicationMouseUp()).  The obj
  1791.           pointer (if not NULL) gets set to point to the object the cursor
  1792.           was over; similarly, the facet pointer (if not NULL) gets set to
  1793.           point to the facet the cursor was over.  The vertnum pointer is
  1794.           not currently used.  If nothing was under the cursor,
  1795.           vrl_RenderMonitorRead() returns zero.  Remember that you must
  1796.           call vrl_RenderObjlist() between the call to
  1797.           vrl_RenderMonitorInit() and vrl_RenderMonitorRead(); typically,
  1798.           you would call it as vrl_RenderObjlist(NULL) to just re-render
  1799.           the last object list that was used.
  1800.  
  1801.                If you need to find out where on the screen a specific
  1802.           vertex will be drawn, you can use the following function:
  1803.  
  1804.                void vrl_TransformVertexToScreen(vrl_ScreenCoord *x, vrl_ScreenCoord *y, vrl_Object *obj,
  1805.                                   vrl_Vector vertex);
  1806.  
  1807.           The vertex is assumed to be in the object's coordinate system. 
  1808.           The vertex is transformed, projected, scaled and shifted and the
  1809.           screen coordinates are stored in x and y.  Note that the values
  1810.           are of type vrl_ScreenCoord, so you should right shift the
  1811.           results by VRL_SCREEN_FRACT_BITS.  The vrl_ObjectToScreen()
  1812.           function uses information computed during the most recent call to
  1813.           vrl_RenderBegin(), so the values will not reflect any changes
  1814.           made since then.
  1815.  
  1816.           The Timer
  1817.  
  1818.                AVRIL has a set of routines which deal with the timer; these
  1819.           will vary from one platform to another, but they should all
  1820.           provide the same high-level interface to application software.
  1821.  
  1822.                vrl_Boolean vrl_TimerInit(void);
  1823.                           void vrl_TimerQuit(void);
  1824.                           vrl_Time vrl_TimerRead(void);
  1825.                           vrl_Time vrl_TimerGetTickRate(void);
  1826.                           void vrl_TimerDelay(vrl_Time milliseconds);
  1827.  
  1828.  
  1829.  
  1830.                                               AVRIL Technical Reference Manual              31
  1831.  
  1832.  
  1833.  
  1834.  
  1835.  
  1836.           These routines let you initialize, de-initialize and read the
  1837.           timer.  The vrl_TimerGetTickRate() routine returns the number of
  1838.           ticks per second that the timer runs at.  The higher this number
  1839.           is, the more accurate the frames/second calculations will be
  1840.           (among other things).  It is expected that all future versions of
  1841.           AVRIL will use 1000 ticks per second, so that each tick is one
  1842.           millisecond; however, to be on the safe side, always use
  1843.           vrl_TimerGetTickRate().
  1844.  
  1845.           The Mouse
  1846.  
  1847.           Like the timer routines, the mouse routines will differ from
  1848.           platform to platform, but the high-level interface should remain
  1849.           the same.
  1850.  
  1851.                vrl_Boolean vrl_MouseInit(void);
  1852.                           void vrl_MouseQuit(void);
  1853.                           vrl_Boolean vrl_MouseReset(void);
  1854.                           vrl_Boolean vrl_MouseRead(int *x, int *y, unsigned int *buttons);
  1855.                           void vrl_MouseSetUsage(int u);
  1856.                           int vrl_MouseGetUsage(void);
  1857.                           void vrl_MouseSetPointer(void *u);
  1858.                           void *vrl_MouseGetPointer(void);
  1859.  
  1860.           These routines let you initialize and read the mouse.  Since the
  1861.           mouse can be used either as a screen-oriented pointer or as a 6D
  1862.           input device (see the Devices section), there has to be some way
  1863.           of toggling between those two functions.  That's what the
  1864.           vrl_MouseSetUsage() and vrl_MouseGetUsage() functions are for; a
  1865.           non-zero value means the mouse is a 6D device, a zero value means
  1866.           it's a screen pointer.
  1867.  
  1868.                When the mouse is a 6D device, it's useful to be able to
  1869.           obtain a pointer to the vrl_Device which is using it; similarly,
  1870.           the vrl_Device function (described later) must be able to set
  1871.           that pointer.  That's what the vrl_MouseSetPointer() and
  1872.           vrl_MouseGetPointer() calls do; they set and get a pointer to the
  1873.           vrl_Device that's using the mouse for 6D input.
  1874.  
  1875.           The Keyboard
  1876.  
  1877.           Like the timer and the mouse, the keyboard routines will be
  1878.           implemented very differently on different platforms, but they
  1879.           should provide a consistent high-level interface.
  1880.  
  1881.                vrl_Boolean vrl_KeyboardCheck(void);
  1882.                           unsigned int vrl_KeyboardRead(void);
  1883.  
  1884.           The vrl_KeyboardCheck() routine returns non-zero if a key has
  1885.           been pressed, and vrl_KeyboardRead() returns the actual key. 
  1886.           Most keys just return their ASCII values; see the file avrilkey.h
  1887.  
  1888.  
  1889.                            AVRIL Technical Reference Manual              32
  1890.  
  1891.  
  1892.  
  1893.  
  1894.  
  1895.           for definitions of special keys (like arrows, function keys,
  1896.           etc).
  1897.  
  1898.           Memory Allocation Routines
  1899.  
  1900.           AVRIL has three functions which are (at the moment) just wrappers
  1901.           around the standard malloc(), calloc() and free() functions.  You
  1902.           should always use these functions rather than the system
  1903.           equivalents, for compatability with future versions of AVRIL.
  1904.  
  1905.                void *vrl_malloc(unsigned int nbytes);
  1906.                           void *vrl_calloc(unsigned int nitems, unsigned int item_size);
  1907.                           void vrl_free(void *ptr);
  1908.  
  1909.           Raster Routines
  1910.  
  1911.           AVRIL uses the notion of a "raster", a rectangular array of pixel
  1912.           values.  In most cases, all rendering is done into a raster,
  1913.           which may or may not correspond to an actual physical screen; in
  1914.           cases where it doesn't, it's necessary to copy ("blit") the
  1915.           raster to the display.
  1916.  
  1917.           Each raster has a height, a width, a depth (number of bits per
  1918.           pixel) a window (the rectangular region within the raster into
  1919.           which rendering is done) and a "rowbytes" value (the number of
  1920.           bytes per horizontal row of pixels).
  1921.  
  1922.           The following routines are used to deal with rasters:
  1923.  
  1924.                vrl_Raster *vrl_RasterCreate(vrl_ScreenPos width, vrl_ScreenPos height,
  1925.                                   vrl_unsigned16bit depth);
  1926.                           void vrl_RasterDestroy(vrl_Raster *raster);
  1927.                           void vrl_RasterSetWindow(vrl_Raster *raster,
  1928.                                   vrl_ScreenPos left, vrl_ScreenPos top, vrl_ScreenPos right, vrl_ScreenPos bottom);
  1929.                           void vrl_RasterGetWindow(vrl_Raster *raster, vrl_ScreenPos *left, vrl_ScreenPos *top,
  1930.                                   vrl_ScreenPos *right, vrl_ScreenPos *bottom);
  1931.                           vrl_ScreenPos vrl_RasterGetHeight(vrl_Raster *r);
  1932.                           vrl_ScreenPos vrl_RasterGetWidth(vrl_Raster *r);
  1933.                           vrl_ScreenPos vrl_RasterGetDepth(vrl_Raster *r);
  1934.                           vrl_ScreenPos vrl_RasterGetRowbytes(vrl_Raster *r);
  1935.                           void vrl_RasterSetRowbytes(vrl_Raster *r, vrl_ScreenPos n);
  1936.  
  1937.           The reason for setting the number of bytes per row of pixels has
  1938.           to do with alternate scan-line encoding; if you render the left
  1939.           and right images into the left and right halves of a 640-pixel
  1940.           wide screen, and then set the rowbytes value to 320, you wind up
  1941.           with a raster that has the left-eye image on the even scanlines
  1942.           and the right-eye image on the odd scanlines.
  1943.  
  1944.           You can read scanlines from a raster into a buffer, or write them
  1945.           from a buffer into the raster.  You can also obtain a pointer to
  1946.  
  1947.  
  1948.                            AVRIL Technical Reference Manual              33
  1949.  
  1950.  
  1951.  
  1952.  
  1953.  
  1954.           the actual data for the raster (i.e. the raw array of pixel
  1955.           values).
  1956.  
  1957.                void vrl_RasterReadScanline(vrl_Raster *r, int n, unsigned char *buff);
  1958.                           void vrl_RasterWriteScanline(vrl_Raster *r, int n, unsigned char *buff);
  1959.                           unsigned char *vrl_RasterGetData(vrl_Raster *r);
  1960.  
  1961.           Even though you can obtain a pointer to the actual data, it's
  1962.           generally a bad idea to do anything with it.
  1963.  
  1964.           Palettes and Huemaps
  1965.  
  1966.           AVRIL makes use of a "palette", a collection of (up to) 256
  1967.           colors.  Each of those colors has three 8-bit components -- one
  1968.           for red, one for green and one for blue.  On the PC's VGA card,
  1969.           only 6 bits are actually used for each component.
  1970.  
  1971.           The vrl_Color values that AVRIL uses are (in a paletted
  1972.           implementation) used to index the palette to select an actual
  1973.           color.  In order to do shading of facets and vertices, AVRIL
  1974.           divides the palette into a number of "hues", with a number of
  1975.           shades for each hue.  By default, the first 16 entries of the
  1976.           256-color palette are simple non-shaded colors (for use in menus
  1977.           and overlaid text); the remaining 240 colors are treated as 15
  1978.           hues with 16 shades each.
  1979.  
  1980.           However, this is not etched in stone.  AVRIL supports the use of
  1981.           a "hue map", which relates a hue index to a start color in the
  1982.           palette and a count of the number of shades.  For example, by
  1983.           using the hue map, you could choose to have 64 shades of flesh
  1984.           tone (instead of 16) in order to represent human beings more
  1985.           accurately.
  1986.  
  1987.           A hue is represented by a vrl_Hue type, and a palette by a
  1988.           vrl_Palette type.  Palettes have a flag that indicates that
  1989.           they've been changed; this is important, since it forces the
  1990.           system to update the physical palette stored in the video
  1991.           hardware.
  1992.  
  1993.           The following functions will initialize a palette, read a palette
  1994.           and huemap data from a file, get and set individual entries in
  1995.           the palette, get a pointer to a palette's huemap, and read and
  1996.           check the "changed" status of the palette:
  1997.  
  1998.                void vrl_PaletteInit(vrl_Palette *pal);
  1999.                           int vrl_PaletteRead(FILE *in, vrl_Palette *pal);
  2000.                           vrl_Color vrl_PaletteGetEntry(vrl_Palette *pal, int n);
  2001.                           void vrl_PaletteSetEntry(vrl_Palette *pal, int n, vrl_Color color);
  2002.                           vrl_Boolean vrl_PaletteHasChanged(vrl_Palette *pal);
  2003.                           void vrl_PaletteSetChanged(vrl_Palette *pal, vrl_Boolean flag);
  2004.                           vrl_Hue *vrl_PaletteGetHuemap(vrl_Palette *pal);
  2005.  
  2006.  
  2007.                            AVRIL Technical Reference Manual              34
  2008.  
  2009.  
  2010.  
  2011.  
  2012.  
  2013.           Each world structure has a palette built into it; you can obtain
  2014.           a pointer to it using the following function:
  2015.  
  2016.                vrl_Palette *vrl_WorldGetPalette(void);
  2017.  
  2018.           Bear in mind that the palettes we're discussing here are
  2019.           independent of the actual, physical palette that's maintained by
  2020.           the video hardware; see the section on Video routines for more
  2021.           information about the hardware palette.
  2022.  
  2023.           Video Routines
  2024.  
  2025.                AVRIL takes care of all the "high-level" functions required
  2026.           of a VR library, including the handling of input devices, reading
  2027.           files, maintaining data structures, doing transforms and lighting
  2028.           calculations and so on.  AVRIL makes calls to lower-level
  2029.           routines to do things like accessing the display device; in fact,
  2030.           it has two separate levels of interface to the display hardware.
  2031.  
  2032.                The lowest-level display interface is the video driver.  The
  2033.           video driver is responsible for such things as entering and
  2034.           exiting graphics mode, hiding and displaying the cursor and
  2035.           loading the hardware palette.  Video drivers are easy to replace,
  2036.           and you can write your own to support whatever graphics modes you
  2037.           wish to use.
  2038.  
  2039.                Internally, the video driver is just a function; see
  2040.           Appendix G for information about how to write one.  The
  2041.           application-visible functions that access that driver are
  2042.           described here.
  2043.  
  2044.                void vrl_VideoSetDriver(vrl_VideoDriverFunction driver);
  2045.  
  2046.           This function sets the video driver function to use; all
  2047.           subsequent calls to the vrl_Video family of routines will
  2048.           ultimately be passed to the specified function.  See Appendix G
  2049.           for more details.
  2050.  
  2051.                int vrl_VideoGetVersion(void);
  2052.                           char *vrl_VideoGetDescription(void);
  2053.  
  2054.           These two functions allow you to find out which version of the
  2055.           video driver specification the currently-selected driver
  2056.           supports, and to get a textual description of the driver.
  2057.  
  2058.                int vrl_VideoSetup(int mode);
  2059.                           int vrl_VideoGetMode(void);
  2060.  
  2061.                  The vrl_VideoSetup() function puts the system into graphics mode;
  2062.           the mode parameter specifies the graphics submode to use (for
  2063.           drivers that support multiple graphics modes).  The meaning of
  2064.           the mode parameter is specific to the driver being used; 0x1234
  2065.  
  2066.                            AVRIL Technical Reference Manual              35
  2067.  
  2068.  
  2069.  
  2070.  
  2071.  
  2072.           may mean completely different things to different video drivers. 
  2073.           The function returns a non-zero value if it was unable to enter
  2074.           the specified graphics mode.  The vrl_VideoGetMode() function
  2075.           returns the current graphics mode; this may or may not be the one
  2076.           that was requested.
  2077.  
  2078.                void vrl_VideoShutdown(void);
  2079.  
  2080.           This function shuts down the video subsystem and returns the
  2081.           hardware to whatever mode it was in prior to the last call to
  2082.           vrl_VideoSetup().
  2083.  
  2084.                The video subsystem provides a vrl_Raster describing the
  2085.           actual physical framebuffer.  To obtain a pointer to the raster
  2086.           (from which information such as the height, width and depth of
  2087.           the video adapter may be obtained), use the following function:
  2088.  
  2089.                vrl_Raster *vrl_VideoGetRaster(void);
  2090.  
  2091.           Many video adapters support multiple pages.  AVRIL has the notion
  2092.           of a "current drawing page" (to which all output is written) and
  2093.           a "current view page" (the one that's being displayed on the
  2094.           physical screen).  The following functions allow you to find out
  2095.           how many pages the adapter has, and to set and query the value of
  2096.           each of those pages:
  2097.  
  2098.                int vrl_VideoGetNpages(void);
  2099.                           void vrl_VideoSetDrawPage(int page);
  2100.                           int vrl_VideoGetDrawPage(void);
  2101.                           void vrl_VideoSetViewPage(int page);
  2102.                           int vrl_VideoGetViewPage(void);
  2103.  
  2104.           Most current video adapters have 8 bits per pixel, and a
  2105.           "palette" of 256 colors.  You can find out whether the video
  2106.           adapter being used has a palette by using the function
  2107.  
  2108.                vrl_Boolean vrl_VideoHasPalette(void);
  2109.  
  2110.           You can read and write a range of values within the palette using
  2111.           the following functions:
  2112.  
  2113.                void vrl_VideoSetPalette(int start, int end, vrl_Palette *palette);
  2114.                           void vrl_VideoGetPalette(int start, int end, vrl_Palette *palette);
  2115.  
  2116.           On some systems, you actually render to an off-screen vrl_Raster
  2117.           in system memory and then copy (or "blit") the image onto the
  2118.           screen.  This is done by the function
  2119.  
  2120.                void vrl_VideoBlit(vrl_Raster *raster)
  2121.  
  2122.  
  2123.  
  2124.  
  2125.                                               AVRIL Technical Reference Manual              36
  2126.  
  2127.  
  2128.  
  2129.  
  2130.  
  2131.           You may only want to update the physical display during the
  2132.           vertical blanking interval; to monitor the vertical retrace, use
  2133.           the following function:
  2134.  
  2135.                vrl_Boolean vrl_VideoCheckRetrace(void);
  2136.  
  2137.           The video subsystem is responsible for the on-screen cursor.  The
  2138.           following functions allow you to hide the cursor, show it again,
  2139.           reset it to its initial state, move it and set its appearance:
  2140.  
  2141.                void vrl_VideoCursorHide(void);
  2142.                           void vrl_VideoCursorShow(void);
  2143.                           void vrl_VideoCursorReset(void);
  2144.                           void vrl_VideoCursorMove(vrl_ScreenPos x, vrl_ScreenPos y);
  2145.                           void vrl_VideoCursorSetAppearance(void *app);
  2146.  
  2147.           Whenever you write to the currently visible page (the viewpage)
  2148.           you should first call vrl_VideoCursorHide() to prevent the mouse
  2149.           from being "squashed" under a falling polygon.  When you're
  2150.           finished updating the display, call vrl_VideoCursorShow() to let
  2151.           the rodent run free again.  The vrl_SystemRender() routine, found
  2152.           in system.c, shows how these routines are used.  The user
  2153.           interface routines do the calls to vrl_VideoCursorHide() and
  2154.           vrl_VideoCursorShow(), so you don't need to worry about them when
  2155.           you use those functions.
  2156.  
  2157.                Note that the system keeps a count of the number of times
  2158.           you've called vrl_VideoCursorHide() and vrl_VideoCursorShow();
  2159.           for example, if you hide the mouse cursor twice, you have to show
  2160.           it twice before it actually appears.  The vrl_VideoCursorReset()
  2161.           routine resets the "hidden" count.
  2162.  
  2163.                The vrl_VideoCursorMove() routine moves the cursor to a
  2164.           particular spot on the screen, and the
  2165.           vrl_VideoCursorSetAppearance() routine sets a new visual
  2166.           appearance for the cursor (the data that is pointed to by the app
  2167.           parameter varies from driver to driver).
  2168.  
  2169.           Display Routines
  2170.  
  2171.                The display subsystem is the "back end" of the rendering
  2172.           pipeline; it's responsible for actually drawing polygons (and
  2173.           lines, and text) into a raster.
  2174.  
  2175.                Internally, the display driver is just a function (much like
  2176.           the video driver, or any of the input device drivers); see
  2177.           Appendix H for information about how to write one.  The
  2178.           application-visible functions that access that driver are
  2179.           described here.
  2180.  
  2181.                void vrl_DisplaySetDriver(vrl_DisplayDriverFunction driver);
  2182.  
  2183.  
  2184.                            AVRIL Technical Reference Manual              37
  2185.  
  2186.  
  2187.  
  2188.  
  2189.  
  2190.           This function sets the display driver function to use; all
  2191.           subsequent calls to the vrl_Display family of routines will
  2192.           ultimately be passed to the specified function.
  2193.  
  2194.                int vrl_DisplayInit(vrl_Raster *raster);
  2195.                           void vrl_DisplayQuit(void);
  2196.  
  2197.           These two routines are responsible for initializing and de-
  2198.           initializing the display subsystem.  The raster parameter
  2199.           specifies a raster to use; this may be an off-screen buffer in
  2200.           system memory, or the actual physical framebuffer returned by
  2201.           vrl_VideoGetRaster().
  2202.  
  2203.           You can change the raster being used; to set or query the raster,
  2204.           use the following functions:
  2205.  
  2206.                void vrl_DisplaySetRaster(vrl_Raster *r);
  2207.                           vrl_Raster *vrl_DisplayGetRaster(void);
  2208.  
  2209.           You can directly obtain the height, width and depth of the
  2210.           current display raster using the following routines:
  2211.  
  2212.                int vrl_DisplayGetWidth(void);
  2213.                           int vrl_DisplayGetHeight(void);
  2214.                           int vrl_DisplayGetDepth(void);
  2215.  
  2216.           You can obtain the current version of the display driver, and a
  2217.           string describing the driver, using the following functions:
  2218.  
  2219.                int vrl_DisplayGetVersion(void);
  2220.                           char *vrl_DisplayGetDescription(void);
  2221.  
  2222.           The display subsystem contains routines for clearing the screen,
  2223.           drawing individual points (i.e. pixels), drawing lines, drawing
  2224.           boxes, and drawing text:
  2225.  
  2226.                void vrl_DisplayClear(vrl_Color color);
  2227.                           void vrl_DisplayPoint(vrl_ScreenPos x, vrl_ScreenPos y, vrl_Color color);
  2228.                           void vrl_DisplayLine(vrl_ScreenPos x1, vrl_ScreenPos y1, vrl_ScreenPos x2,
  2229.                                   vrl_ScreenPos y2, vrl_Color color);
  2230.                           void vrl_DisplayBox(vrl_ScreenPos x1, vrl_ScreenPos y1, vrl_ScreenPos x2,
  2231.                                   vrl_ScreenPos y2, vrl_Color color);
  2232.                           void vrl_DisplayText(vrl_ScreenPos x, vrl_ScreenPos y, vrl_Color color,
  2233.                                    char *message);
  2234.  
  2235.           When drawing a string of text, it's sometimes necessary to find
  2236.           out how wide and high it will appear on screen; the following two
  2237.           functions provide that information:
  2238.  
  2239.                vrl_ScreenPos vrl_DisplayGetTextWidth(char *string);
  2240.                           vrl_ScreenPos vrl_DisplayGetTextHeight(char *string);
  2241.  
  2242.  
  2243.                            AVRIL Technical Reference Manual              38
  2244.  
  2245.  
  2246.  
  2247.  
  2248.  
  2249.           The rendering engine (or the application) may need to find out
  2250.           what capabilities the display driver has; in particular, whether
  2251.           it can do things like Gouraud shading and X-Y clipping.  The
  2252.           following routines provide the answers:
  2253.  
  2254.                vrl_Boolean vrl_DisplayCanGouraud(void);
  2255.                           vrl_Boolean vrl_DisplayCanXYclip(void);
  2256.  
  2257.           When rendering, certain tasks have to be performed at the
  2258.           beginning and end of every frame; the application informs the
  2259.           display driver when a frame begins and ends using the following
  2260.           two functions:
  2261.  
  2262.                void vrl_DisplayBeginFrame(void);
  2263.                           void vrl_DisplayEndFrame(void);
  2264.  
  2265.           Some display drivers are capable of Z-buffering, either in
  2266.           hardware or in software.  The following routines are provided to
  2267.           support Z-buffers:
  2268.  
  2269.                vrl_DisplayUseZbuffer(flag)
  2270.                           void vrl_DisplaySetZbuffer(vrl_Raster *r);
  2271.                           vrl_Raster *vrl_DisplayGetZbuffer(void);
  2272.                           void vrl_DisplayClearZbuffer(depth);
  2273.  
  2274.           These functions allow you to set and get pointers to the
  2275.           vrl_Raster that will be used as a Z-buffer (if software Z-
  2276.           buffering is used).  The vrl_DisplayClearZbuffer() routine clears
  2277.           the currently-set Z-buffer (hardware or software) to the
  2278.           specified depth value.  The vrl_DisplayUseZbuffer() routine tells
  2279.           the display driver whether or not to use the Z-buffer; the flag
  2280.           is non-zero if Z-buffering should be enabled, and the return
  2281.           value is 0 if no Z-buffer is present, 1 if a software Z-buffer is
  2282.           available, or 2 if a hardware Z-buffer is available.  Note that
  2283.           as of version 2.0, AVRIL does not yet support Z-buffering.
  2284.  
  2285.                Some shading algorithms have greater computational expense
  2286.           than others do.  It's possible to limit the complexity of the
  2287.           shading that the display driver uses by calling the following
  2288.           function:
  2289.  
  2290.                void vrl_DisplaySetShading(int value);
  2291.  
  2292.           The higher the value parameter, the more time is spent on shading
  2293.           (e.g. Gouraud versus flat, dithering enabled or disabled, etc). 
  2294.           The exact meaning is up to the display driver.
  2295.  
  2296.           Updating the actual, physical display from the off-screen buffer
  2297.           is done by calling the routine
  2298.  
  2299.                void vrl_DisplayUpdate(void);
  2300.  
  2301.  
  2302.                            AVRIL Technical Reference Manual              39
  2303.  
  2304.  
  2305.  
  2306.  
  2307.  
  2308.           For drivers that write straight to the physical framebuffer, the
  2309.           vrl_DisplayUpdate() function does nothing; for those that use
  2310.           off-screen buffers, it does the blit.
  2311.  
  2312.           Some display drivers need to perform certain re-calculations
  2313.           whenever the palette changes; to inform the display driver of a
  2314.           new palette, call the following routine:
  2315.  
  2316.                void vrl_DisplayUpdatePalette(vrl_Palette *palette);
  2317.  
  2318.           You can specify a rectangular on-screen window, to limit the area
  2319.           of the screen that the display driver will write to.  You can
  2320.           also find out the location and size of that window.  The
  2321.           functions to do so are as follows:
  2322.  
  2323.                void vrl_DisplaySetWindow(vrl_ScreenPos x1, vrl_ScreenPos y1, vrl_ScreenPos x2,
  2324.                                   vrl_ScreenPos y2);
  2325.                           void vrl_DisplayGetWindow(vrl_ScreenPos *x1, vrl_ScreenPos *y1,
  2326.                                   vrl_ScreenPos *x2, vrl_ScreenPos *y2);
  2327.  
  2328.           Note that stereoscopic rendering may have an impact on the "real"
  2329.           windows being used.
  2330.  
  2331.           The display subsystem also has support for stereoscopic viewing. 
  2332.           It understands certain types of viewing, and must be informed
  2333.           when the stereo type changes.  You can set and query the stereo
  2334.           type using the following two functions:
  2335.  
  2336.                void vrl_DisplayStereoSetType(VRL_STEREO_TYPE stype);
  2337.                           VRL_STEREO_TYPE vrl_DisplayStereoGetType(void);
  2338.  
  2339.           You can specify which "eye" is being drawn to, and which should
  2340.           be displayed, using the following functions:
  2341.  
  2342.                void vrl_DisplayStereoSetDrawEye(VRL_STEREO_EYE eye);
  2343.                           VRL_STEREO_EYE vrl_DisplayStereoGetDrawEye(void);
  2344.                           void vrl_DisplayStereoSetViewEye(VRL_STEREO_EYE eye);
  2345.                           VRL_STEREO_EYE vrl_DisplayStereoGetViewEye(void);
  2346.  
  2347.           The eye parameter is one of the values VRL_STEREOEYE_LEFT or
  2348.           VRL_STEREOEYE_RIGHT.
  2349.  
  2350.                Some stereoscopic viewing systems subdivide the screen,
  2351.           putting the left-eye image in one area and the right-eye image in
  2352.           another; the two are then optically "shuffled" to the appropriate
  2353.           eye.  The specific screen areas to use for each eye are set using
  2354.           the following functions:
  2355.  
  2356.                void vrl_DisplayStereoSetLeftWindow(vrl_ScreenPos x1, vrl_ScreenPos y1, vrl_ScreenPos x2,
  2357.                                   vrl_ScreenPos y2);
  2358.                           void vrl_DisplayStereoSetRightWindow(vrl_ScreenPos x1, vrl_ScreenPos y1, vrl_ScreenPos x2,
  2359.                                   vrl_ScreenPos y2);
  2360.  
  2361.                                               AVRIL Technical Reference Manual              40
  2362.  
  2363.  
  2364.  
  2365.  
  2366.  
  2367.           And finally, some stereoscopic viewing systems use more than one
  2368.           display card.  The following function is used to specify a
  2369.           "callback" or "upcall" function that should be called to select a
  2370.           specific card:
  2371.  
  2372.                void vrl_DisplayStereoSetCardFunction(void (*function)(VRL_STEREO_EYE));
  2373.  
  2374.           The callback function is told which card should be written to;
  2375.           the value is one of the constants VRL_STEREOEYE_NEITHER,
  2376.           VRL_STEREOEYE_LEFT, VRL_STEREOEYE_RIGHT or VRL_STEREOEYE_BOTH. 
  2377.           The function will be called by the video subsystem in order to
  2378.           select either, neither or both of the video cards.
  2379.  
  2380.           PCX File Routines
  2381.  
  2382.           There are two functions that deal with files in PCX format:
  2383.  
  2384.                vrl_Boolean vrl_ReadPCX(FILE *in);
  2385.                           vrl_Boolean vrl_WritePCX(FILE *out);
  2386.  
  2387.           The first one reads a PCX file into the current drawing page, the
  2388.           other writes the current drawing page out to disk as a PCX file.
  2389.  
  2390.           Devices
  2391.  
  2392.           AVRIL has support for input devices providing multiple "degrees
  2393.           of freedom" (DOF).  In fact, AVRIL's devices are even more
  2394.           general; each device can have an arbitrary number of input and
  2395.           output channels.
  2396.  
  2397.                To use a device in AVRIL, you must first "open" it; this is
  2398.           analogous to opening a file.  When you're finished with the
  2399.           device, you should "close" it; you can close all open devices
  2400.           using vrl_DeviceCloseAll(), which is set as an atexit() function
  2401.           by vrl_SystemStartup().
  2402.  
  2403.                vrl_Device *vrl_DeviceOpen(vrl_DeviceDriverFunction fn, vrl_SerialPort *port);
  2404.                           void vrl_DeviceClose(vrl_Device *device);
  2405.                           void vrl_DeviceCloseAll(void);
  2406.  
  2407.           Most input devices communicate over a serial port; the port
  2408.           parameter is a pointer to such a port that's been opened with
  2409.           vrl_SerialOpen().  See the section on Serial Ports for more
  2410.           details.  Devices (such as the keyboard) that don't use a serial
  2411.           port should pass NULL as the port parameter.  The fn parameter is
  2412.           a function that operates the device; there are a number of these
  2413.           already defined for popular devices, and it's easy to write your
  2414.           own if you have unusual devices you wish to support.  They are
  2415.           listed in avrildrv.h, and in the cfg.c file; you should update
  2416.           those files as you add drivers.
  2417.  
  2418.  
  2419.  
  2420.                            AVRIL Technical Reference Manual              41
  2421.  
  2422.  
  2423.  
  2424.  
  2425.  
  2426.                If you need to get a pointer to the serial port associated
  2427.           with a device, just call the following function:
  2428.  
  2429.                vrl_SerialPort *vrl_DeviceGetPort(vrl_Device *device);
  2430.  
  2431.           Devices can have a "mode" associated with them, whose meaning is
  2432.           specific to each device.  You can set and get a device's current
  2433.           mode using these two functions:
  2434.  
  2435.                void vrl_DeviceSetMode(vrl_Device *device, int mode);
  2436.                           int vrl_DeviceGetMode(vrl_Device *device);
  2437.  
  2438.           Devices can also have "nicknames"; for example, your application
  2439.           might deal with a head-tracker called "headtrack" which would be
  2440.           defined (in the configuration file, most likely) to be the device
  2441.           used for head tracking (e.g. a Polhemus Isotrak or a Logitech Red
  2442.           Baron).  You can set and query the nickname of a device, or find
  2443.           a device with a particular nickname, using the following
  2444.           functions:
  2445.  
  2446.                char *vrl_DeviceGetNickname(vrl_Device *device);
  2447.                           void vrl_DeviceSetNickname(vrl_Device *device, char *nickname);
  2448.                           vrl_Device *vrl_DeviceFind(char *nickname);
  2449.  
  2450.           Once a device has been opened, you can easily find out how many
  2451.           input channels it has, and how many two-state buttons are on the
  2452.           device, using the following two functions:
  2453.  
  2454.                int vrl_DeviceGetNchannels(vrl_Device *device);
  2455.                           int vrl_DeviceGetNButtons(vrl_Device *device);
  2456.  
  2457.           Sometimes devices can get into a strange state, or drift from
  2458.           their initial settings; the function vrl_DeviceReset() resets a
  2459.           device to the state it was in just after it was opened.
  2460.  
  2461.                int vrl_DeviceReset(vrl_Device *device);
  2462.  
  2463.           For many devices, resetting a device also marks the current
  2464.           values of all its channels as the "zero" value for that channel. 
  2465.           To mark the current values as being the "maximum" values, call
  2466.           the function
  2467.  
  2468.                void vrl_DeviceSetRange(vrl_Device *device);
  2469.  
  2470.           Devices should be periodically "polled" to see if they have
  2471.           anything to report; this is normally done in the vrl_SystemRun()
  2472.           function.  An individual device can be polled using
  2473.           vrl_DevicePoll(), which returns a non-zero value if new data was
  2474.           acquired.  All the devices can be polled by calling
  2475.           vrl_DevicePollAll(), which returns a non-zero value if any of the
  2476.           devices had new data.
  2477.  
  2478.  
  2479.                            AVRIL Technical Reference Manual              42
  2480.  
  2481.  
  2482.  
  2483.  
  2484.  
  2485.                           int vrl_DevicePoll(vrl_Device *device);
  2486.                           void vrl_DevicePollAll(void);
  2487.  
  2488.           You can get the current value of a channel's input by calling
  2489.           vrl_DeviceGetValue(), and you can read the button status on the
  2490.           device using vrl_DeviceGetButtons():
  2491.  
  2492.                vrl_Scalar vrl_DeviceGetValue(vrl_Device *device, int channel);
  2493.                           vrl_unsigned32bit vrl_DeviceGetButtons(vrl_Device *device);
  2494.  
  2495.           Each bit corresponds to a single button on the device.
  2496.  
  2497.                The first six channels are special, since they correspond to
  2498.           the six basic degrees of freedom a device can have.  The first
  2499.           three, whose channel numbers are the #defined values X, Y, and Z,
  2500.           provide the three-dimensional location of the input device in its
  2501.           private coordinate system.  The next three, whose channel numbers
  2502.           are the #defined values XROT, YROT and ZROT, provide the rotation
  2503.           of the device around each of the three axes.  Every device is
  2504.           expected to provide at least those six values; others, such as
  2505.           glove-like input devices, may have a separate channel for the
  2506.           flexion of each finger.
  2507.  
  2508.                You can determine whether a channel's value has changed
  2509.           since the previous poll by using vrl_DeviceChannelGetChanged(),
  2510.           and you can use vrl_DeviceGetChangedButtons() to obtain a
  2511.           vrl_unsigned32bit word whose bits indicate whether the
  2512.           corresponding buttons have changed state since the previous poll.
  2513.  
  2514.                vrl_Boolean vrl_DeviceGetChanged(vrl_Device *device, int channel);
  2515.                           vrl_unsigned32bit vrl_DeviceGetChangedButtons(vrl_Device *device);
  2516.  
  2517.           Note that "previous poll" means the one prior to the most recent
  2518.           one; in other words, you would check the changed flags
  2519.           immediately after a call to vrl_DevicePoll() or
  2520.           vrl_DevicePollAll() in order to see if they've changed since the
  2521.           last time through.
  2522.  
  2523.                Some devices (such as the Logitech Cyberman and the Global
  2524.           Devices Controller) are capable of output as well as input.  You
  2525.           can find out the number of output channels a device has using the
  2526.           following function:
  2527.  
  2528.                int vrl_DeviceGetNOutputChannels(vrl_Device *device);
  2529.  
  2530.           There are some devices that shouldn't be polled too frequently
  2531.           (possibly because the polling takes a long time).  Devices
  2532.           drivers typically set their own polling frequency when they're
  2533.           initialized, but you can read and set the polling period using
  2534.           these two functions:
  2535.  
  2536.  
  2537.  
  2538.                                               AVRIL Technical Reference Manual              43
  2539.  
  2540.  
  2541.  
  2542.  
  2543.  
  2544.                           void vrl_DeviceSetPeriod(vrl_Device *device, vrl_Time period);
  2545.                           vrl_Time vrl_DeviceGetPeriod(vrl_Device *device);
  2546.  
  2547.           Some devices provide fewer than six degrees of freedom; in
  2548.           particular, some devices (such as sourceless head trackers)
  2549.           provide only rotational information, while others might provide
  2550.           only positional information.  In addition, some axes are
  2551.           absolute, while others are relative; for example, a magnetic
  2552.           tracker provides absolute rotation, whereas a joystick usually
  2553.           provides a rate of rotation.  Two functions are used to determine
  2554.           what a device's suggested modes of operation are for translation
  2555.           and rotation:
  2556.  
  2557.                vrl_DeviceMotionMode vrl_DeviceGetRotationMode(vrl_Device *device);
  2558.                           vrl_DeviceMotionMode vrl_DeviceGetTranslationMode(vrl_Device *device);
  2559.  
  2560.           Each of these two functions returns one of the values
  2561.           VRL_MOTION_NONE (i.e., this type of motion is not reported by
  2562.           this device), VRL_MOTION_RELATIVE (i.e. this device provides
  2563.           relative information) or VRL_MOTION_ABSOLUTE (this device
  2564.           provides absolute information).
  2565.  
  2566.                It's important to note that these are all suggestions from
  2567.           the device driver as to how it should be used; you can still
  2568.           choose, in your application, to treat any device as either
  2569.           absolute or relative.
  2570.  
  2571.                To understand what these next few functions do, it's
  2572.           important to understand what kind of processing the system does
  2573.           on the values once it receives them from the device.  Each
  2574.           channel can be in either "accumulate" or "non-accumulate" mode. 
  2575.           For accumulating devices, the value is first checked to see how
  2576.           close it is to zero; if it's less than a channel-specific
  2577.           deadzone value, then the value is considered to be zero.  For
  2578.           non-accumulating devices, the deadzone value is treated as a
  2579.           minimum change from the most recently read value for this
  2580.           channel; a device that moves by less than the deadzone amount
  2581.           between consecutive polls will not change in value.
  2582.  
  2583.                The value is then scaled so that its maximum value is less
  2584.           than a channel-specific scale value.  For channels with the
  2585.           accumulate flag set, the value is also scaled by the elapsed
  2586.           time; the scale for such channels is treated as the maximum rate
  2587.           of change per second.
  2588.  
  2589.           The accumulate, scale and deadzone values can be set and read
  2590.           using the following calls:
  2591.  
  2592.                vrl_Scalar vrl_DeviceGetDeadzone(vrl_Device *device, int channel);
  2593.                           void vrl_DeviceSetDeadzone(vrl_Device *device, int channel, vrl_Scalar value);
  2594.                           vrl_Scalar vrl_DeviceGetScale(vrl_Device *device, int channel);
  2595.                           vrl_DeviceSetScale(vrl_Device *device, int channel, vrl_Scalar value);
  2596.  
  2597.                                               AVRIL Technical Reference Manual              44
  2598.  
  2599.  
  2600.  
  2601.  
  2602.  
  2603.                           vrl_Boolean vrl_DeviceGetAccumulate(vrl_Device *device, int channel);
  2604.                           void vrl_DeviceSetAccumulate(vrl_Device *device, int channel, vrl_Boolean value);
  2605.  
  2606.           If you like, you can bypass all that processing and obtain the
  2607.           actual, "raw" value being reported by the device by calling
  2608.  
  2609.                vrl_Scalar vrl_DeviceGetRawValue(vrl_Device *device, int channel);
  2610.  
  2611.           Devices are kept internally in a linked list; if you want to
  2612.           iterate over the list, you can do it with the following two
  2613.           functions:
  2614.  
  2615.                vrl_Device *vrl_DeviceGetFirst(void);
  2616.                           vrl_Device * vrl_DeviceGetNext(vrl_Device *device);
  2617.  
  2618.           You can retrieve a human-readable description of a device by
  2619.           calling the function
  2620.  
  2621.                char *vrl_DeviceGetDesc(vrl_Device *device);
  2622.  
  2623.           You can produce output on any of the device's channels by calling
  2624.  
  2625.                void vrl_DeviceOutput(vrl_Device *device, int channel, vrl_Scalar value);
  2626.  
  2627.           The channel and the value (which ought to be in the range 0 to
  2628.           255) are passed along to the device; if it's capable of
  2629.           outputting that value on that channel, it does.  Not all devices
  2630.           are capable of producing output, and those that can have a
  2631.           variety of different ways of doing it (including sound and
  2632.           vibration).  All you can be sure of is that a value of zero will
  2633.           turn the output off, and a non-zero value will turn it on.
  2634.  
  2635.                Note that it's possible to have an "output-only" device; it
  2636.           will report zero for all its input values, but still respond to
  2637.           output requests.  This might be one approach to supporting motion
  2638.           platforms, for example.
  2639.  
  2640.                Some 2D devices can map their two axes into 6 degrees of
  2641.           freedom using combinations of buttons.  There are two functions
  2642.           to get and set the mapping tables they use:
  2643.  
  2644.                void vrl_DeviceSetButtonmap(vrl_Device *device, vrl_DeviceButtonmap *b);
  2645.                           vrl_DeviceButtonmap *vrl_DeviceGetButtonmap(vrl_Device *device);
  2646.  
  2647.           Buttonmaps are a fairly complex topic, and are discussed in more
  2648.           detail in Appendix F.
  2649.  
  2650.           Serial Ports
  2651.  
  2652.           Since many input devices use serial communications, AVRIL
  2653.           contains a library of serial port routines.  These will mostly be
  2654.  
  2655.  
  2656.                            AVRIL Technical Reference Manual              45
  2657.  
  2658.  
  2659.  
  2660.  
  2661.  
  2662.           of interest to people writing device drivers, but they might also
  2663.           be used for modem communications.
  2664.  
  2665.                To some extent, serial port support will be platform-
  2666.           dependent; the meaning of the various parameters in the
  2667.           vrl_SerialOpen() call will be different on different systems. 
  2668.           However, all the other routines should be the same regardless of
  2669.           platform.
  2670.  
  2671.                A serial port can be opened and closed using
  2672.           vrl_SerialOpen() and vrl_SerialClose() respectively; all the
  2673.           serial ports can be closed at once using vrl_SerialCloseAll(),
  2674.           which gets set as an atexit() function by vrl_SystemStartup(). 
  2675.           The communications parameters can be set using
  2676.           vrl_SerialSetParameters().
  2677.  
  2678.                vrl_SerialPort *vrl_SerialOpen(unsigned int address, int irq, unsigned int buffsize);
  2679.                           void vrl_SerialClose(vrl_SerialPort *port);
  2680.                           void vrl_SerialCloseAll(void);
  2681.                           void vrl_SerialSetParameters(vrl_SerialPort *port, unsigned int baud,
  2682.                                   vrl_ParityType parity, int databits, int stopbits);
  2683.  
  2684.           The address parameter to vrl_SerialOpen() is interpreted
  2685.           differently on different platforms; on PC-compatible machines,
  2686.           it's the base address of the UART chip (usually 0x3F8 for COM1,
  2687.           0x2F8 for COM2).  The irq parameter is also system-dependent; on
  2688.           PC-compatible machines, it's the hardware interrupt level the
  2689.           serial port uses (usually 4 for COM1, 3 for COM2).
  2690.  
  2691.                The buffsize parameter is the size of buffer to use for
  2692.           incoming data.  If it's set to zero, the port will be in a non-
  2693.           buffered mode; this may mean that characters get lost.  Such a
  2694.           mode would only be used if you're doing your own handshake with
  2695.           the device; in other words, you send it a byte to poll it, and
  2696.           then sit in a tight loop receiving the resulting data.  In this
  2697.           case, the irq value is ignored.
  2698.  
  2699.                The baud parameter to the vrl_SerialSetParameters() function
  2700.           is the baud rate; this is usually 9600 for most input devices. 
  2701.           The parity parameter is one of VRL_PARITY_NONE, VRL_PARITY_EVEN
  2702.           or VRL_PARITY_ODD; most devices use VRL_PARITY_NONE.  The
  2703.           databits field is the number of data bits per transmitted byte;
  2704.           this is either 7 or 8, and most devices use 8.  The number of
  2705.           stop bits can be 1 or 2, and is usually 1.  Newly-opened serial
  2706.           ports are set up to be 9600 baud, VRL_PARITY_NONE, 8 data bits
  2707.           and 1 stop bit.
  2708.  
  2709.                The vrl_SerialCheck() routine will return a non-zero value
  2710.           if there are unread characters in the input buffer (or if there's
  2711.           a character waiting at the UART, if the port is in unbuffered
  2712.           mode).  The vrl_SerialGetc() routine reads and returns a byte. 
  2713.           It should not be called unless you know there's a character
  2714.  
  2715.                            AVRIL Technical Reference Manual              46
  2716.  
  2717.  
  2718.  
  2719.  
  2720.  
  2721.           waiting; in buffered mode, such a call will return zero, while in
  2722.           unbuffered mode the call will block until a character arrives! 
  2723.           The vrl_SerialFlush() routine will get rid of any characters
  2724.           waiting in the input buffer.
  2725.  
  2726.                vrl_Boolean vrl_SerialCheck(vrl_SerialPort *port);
  2727.                           unsigned int vrl_SerialGetc(vrl_SerialPort *port);
  2728.                           void vrl_SerialFlush(vrl_SerialPort *p);
  2729.  
  2730.           The vrl_SerialPutc() and vrl_SerialPutString() routines put out
  2731.           single characters and null-terminated strings of characters
  2732.           respectively.  The terminating null byte is not sent by
  2733.           vrl_SerialPutString().
  2734.  
  2735.                void vrl_SerialPutc(unsigned int c, vrl_SerialPort *port);
  2736.                           void vrl_SerialPutString(unsigned char *s, vrl_SerialPort *p);
  2737.  
  2738.           There are also two routines for controlling the state of the DTR
  2739.           and RTS lines:
  2740.  
  2741.                void vrl_SerialSetDTR(vrl_SerialPort *port, vrl_Boolean value);
  2742.                           void vrl_SerialSetRTS(vrl_SerialPort *port, vrl_Boolean value);
  2743.  
  2744.           and one for setting the size of the serial FIFO, if applicable:
  2745.  
  2746.                void vrl_SerialFifo(vrl_SerialPort *p, int n);
  2747.  
  2748.           Packet Routines
  2749.  
  2750.           Many serial devices communicate by sending "packets" of data. 
  2751.           There are four routines in AVRIL to support the reception of
  2752.           packets:
  2753.  
  2754.                vrl_DevicePacketBuffer *vrl_DeviceCreatePacketBuffer(int buffsize);
  2755.                           void vrl_DeviceDestroyPacketBuffer(vrl_DevicePacketBuffer *buff);
  2756.                           vrl_Boolean vrl_DeviceGetPacket(vrl_SerialPort *port, vrl_DevicePacketBuffer *buff);
  2757.                           unsigned char *vrl_DevicePacketGetBuffer(vrl_DevicePacketBuffer *buff);
  2758.  
  2759.           The vrl_DeviceCreatePacketBuffer() function creates a packet
  2760.           buffer with room for the specified number of bytes;
  2761.           vrl_DeviceDestroyPacketBuffer() destroys such a buffer.  The
  2762.           vrl_DevicePacketGetBuffer() routine returns a pointer to the
  2763.           actual data packet.
  2764.  
  2765.                The vrl_DeviceGetPacket() routine is designed to handle a
  2766.           particular type of packet, a fixed-size one in which the leading
  2767.           byte has the top bit set and none of the other bytes do.  This
  2768.           format is used by the Logitech Cyberman, among other devices. 
  2769.           You can use this routine directly, or you can write your own
  2770.           (with a different name, of course); the source code is found in
  2771.           packet.c, and the vrl_DevicePacketBuffer data structure is in
  2772.           avril.h (and it's not expected to change, unlike many other
  2773.  
  2774.                            AVRIL Technical Reference Manual              47
  2775.  
  2776.  
  2777.  
  2778.  
  2779.  
  2780.           internal data structures).  The vrl_DeviceGetPacket() routine
  2781.           returns a non-zero value if a complete packet has been received
  2782.           (i.e. exactly buffsize bytes have been received, starting with a
  2783.           byte that has the top bit set).
  2784.  
  2785.           More information
  2786.  
  2787.           Remember that the appendices to this document are in a separate
  2788.           file, as is the Tutorial.
  2789.  
  2790.  
  2791.  
  2792.  
  2793.  
  2794.  
  2795.  
  2796.  
  2797.  
  2798.  
  2799.  
  2800.  
  2801.  
  2802.  
  2803.  
  2804.  
  2805.  
  2806.  
  2807.  
  2808.  
  2809.  
  2810.  
  2811.  
  2812.  
  2813.  
  2814.  
  2815.  
  2816.  
  2817.  
  2818.  
  2819.  
  2820.  
  2821.  
  2822.  
  2823.  
  2824.  
  2825.  
  2826.  
  2827.  
  2828.  
  2829.  
  2830.  
  2831.  
  2832.  
  2833.                            AVRIL Technical Reference Manual              48