/*
 * lib.h - vector library definitions
 *
 * Author:  Eric Haines, 3D/Eye, Inc.
 *
 * Modified: 1 October 1992
 *           Alexander R. Enzmann
 *
 * Modified: 17 Mar 1993
 *           Eduard [esp] Schwan
 *           Changed POV-Ray refs to OUTPUT_POVRAY_10 & OUTPUT_POVRAY_20
 *           Changed POV-Ray 1.5 refs to 2.0
 *           Passed bg_color to display routines
 *           Added OUTPUT_RAWTRI output, for creating Raw output for Raw2POV.
 *
 * Modified: 12 April 1993
 *           Alexander R. Enzmann
 *           Added #if statements to control inclusion of code for the
 *           various raytracers.
 *
 * Modified: 27 July 1993
 *           David Hook
 *           Added converter for "art" ray tracer.
 *
 * Modified: 2 August 1993
 *           Eduard [esp] Schwan
 *           Copied comments from lib.c into here for "documenting"
 *           the calls a little better.
 */
#ifndef LIB_H
#define LIB_H

#include "def.h"
#include "libvec.h"

#if __cplusplus
extern "C" {
#endif

/* ------- The version of this Library, see lib_get_version_str() -------- */

#define LIB_VERSION	"3.1a"

/* Raytracers supported by this package (default OUTPUT_POVRAY): */

/* Note: any new renderers should be added between OUTPUT_VIDEO and
   OUTPUT_DELAYED.  These two values are used as a range check that a known
   renderer has been selected in "lib_set_raytracer" */
#define OUTPUT_VIDEO      0 /* Output direct to the screen (sys dependent) */
#define OUTPUT_NFF        1 /* MTV                                         */
#define OUTPUT_POVRAY_10  2 /* POV-Ray 1.0                                 */
#define OUTPUT_POLYRAY    3 /* Polyray v1.4, v1.5                          */
#define OUTPUT_VIVID      4 /* Vivid 2.0                                   */
#define OUTPUT_QRT        5 /* QRT 1.5                                     */
#define OUTPUT_RAYSHADE   6 /* Rayshade                                    */
#define OUTPUT_POVRAY_20  7 /* POV-Ray 2.0 (format is subject to change)   */
#define OUTPUT_RTRACE     8 /* RTrace 8.0.0                                */
#define OUTPUT_PLG        9 /* PLG format for use with "rend386"           */
#define OUTPUT_RAWTRI    10 /* Raw triangle output                         */
#define OUTPUT_ART       11 /* Art 2.3                                     */
#define OUTPUT_DELAYED   12 /* Needed for RTRACE/PLG output.
			       When this is used, all definitions will be
			       stored rather than immediately dumped.  When
			       all definitions are complete, use the call
			       "lib_flush_definitions" to spit them all out. */

/* Default setting of output RT type - change to your favorite & recompile */
#define OUTPUT_RT_DEFAULT   OUTPUT_NFF

/* Sets raw triangle output format to include texture */
#define RAWTRI_WITH_TEXTURES    0	/* set to 1 to include texture */

#define OUTPUT_RESOLUTION       4       /* default amount of polygonalization */

/* ========== don't mess from here on down ============================= */

/* Output library definitions */
#define OUTPUT_CURVES           0       /* true curve output */
#define OUTPUT_PATCHES          1       /* polygonal patches output */

/* The following type definitions are used to build & store the database
   internally.  For some renderers, you need to build the data file according
   to a particular scheme (notably RTrace).  These data types are used to
   hold the objects, lights, etc. until it is time to build the file.  */

/* Type definition for holding a light */
typedef struct light_struct *light_ptr;
struct light_struct {
   COORD4 center_pt;
   light_ptr next;
   };

/* Type definition for holding a surface declaration */
typedef struct surface_struct *surface_ptr;
struct surface_struct {
   char *surf_name;
   unsigned int surf_index;
   COORD3 color;
   double ka, kd, ks, shine, ang, kt, ior;
   surface_ptr next;
   };

/* Diagonally opposite corners of a box */
struct box_struct {
   COORD3 point1, point2;
   };

/* Base point/radius and Apex point/radius */
struct cone_struct {
   COORD4 apex_pt, base_pt;
   };

/* Center, normal, inner, and outer radii of a annulus */
struct disc_struct {
   COORD3 center, normal;
   double iradius, oradius;
   };

/* 2D gridded data for a height field.  Limited support for this thing... */
struct height_struct {
   char *filename;
   float **data;
   unsigned int width, height;
   float x0, x1, y0, y1, z0, z1;
   };

/* Polygon - # of vertices and the 3D coordinates of the vertices themselves */
struct polygon_struct {
   unsigned int tot_vert;
   COORD3 *vert;
   };

/* Smooth patch.  Vertices and normals associated with them. */
struct polypatch_struct {
   unsigned int tot_vert;
   COORD3 *vert, *norm;
   };

/* Center/radius of a sphere */
struct sphere_struct {
   COORD4 center_pt;
   };

/* Center, axis lengths, and exponents of a superquadric */
struct superq_struct {
   COORD3 center_pt;
   double a1, a2, a3, n, e;
   };

/* Center, direction of axis of symmetry, inner, and outer radii of a torus */
struct torus_struct {
   COORD3 center, normal;
   double iradius, oradius;
   };

/* Standard viewpoint stuff */
typedef struct {
   COORD3 from, at, up;
   double angle, aspect, hither, dist;
   int resx, resy;
   MATRIX tx;
   } viewpoint;

#define BOX_OBJ       1
#define CONE_OBJ      2
#define DISC_OBJ      3
#define HEIGHT_OBJ    4
#define POLYGON_OBJ   5
#define POLYPATCH_OBJ 6
#define SPHERE_OBJ    7
#define SUPERQ_OBJ    8
#define TORUS_OBJ     9

/* Union of all the object types */
typedef struct object_struct *object_ptr;
struct object_struct {
   unsigned int object_type;  /* Identify what kind of object */
   unsigned int curve_format; /* Output as surface or as polygons? */
   unsigned int surf_index;   /* Which surface was associated with this object? */
   union {
      struct box_struct       box;
      struct cone_struct      cone;
      struct disc_struct      disc;
      struct height_struct    height;
      struct polygon_struct   polygon;
      struct polypatch_struct polypatch;
      struct sphere_struct    sphere;
      struct superq_struct    superq;
      struct torus_struct     torus;
      } object_data;
   object_ptr next_object;
   };

/* Global variables - manipulate these at your own risk... */
extern viewpoint view;
extern surface_ptr lib_surfaces;
extern object_ptr lib_objects;
extern light_ptr lib_lights;


/*-----------------------------------------------------------------*/
/*
 * Command line option parser
 *
 * -s size - input size of database
 * -r format - input database format to output
 *	0   Output direct to the screen (sys dependent)
 *	1   NFF - MTV
 *	2   POV-Ray 1.0
 *	3   Polyray v1.4, v1.5
 *	4   Vivid 2.0
 *	5   QRT 1.5
 *	6   Rayshade
 *	7   POV-Ray 2.0 (format is subject to change)
 *	8   RTrace 8.0.0
 *	9   PLG format for use with "rend386"
 *	10  Raw triangle output
 *	11  art 2.3
 * -c - output true curved descriptions
 * -t - output tessellated triangle descriptions
 * -f file - output filename (used for showdxf.c only)
 *
 * TRUE returned if bad command line detected
 * NOTE that p_file_name returns a pointer to the file name string
 */
int lib_get_opts PARAMS((int argc, char *argv[], int *p_size, int *p_rdr,
	int *p_curve)) ;

/* Library info functions */
char * lib_get_version_str PARAMS((void));

/* Library setup for IO functions */
void lib_set_output_file PARAMS((FILE *new_outfile));
void lib_set_default_texture PARAMS((char *default_texture));
void lib_set_raytracer PARAMS((int default_tracer));
void lib_set_polygonalization PARAMS((int u_steps, int v_steps));

/* Scene/object generation functions */

/*-----------------------------------------------------------------*/
/*
 * Output viewpoint location.  The parameters are:
 *   From:   The eye location.
 *   At:     A position to be at the center of the image.  A.k.a. "lookat"
 *   Up:     A vector defining which direction is up.
 *   Fov:    Vertical field of view of the camera
 *   Aspect: Aspect ratio of horizontal fov to vertical fov
 *   Hither: Minimum distance to any ray-surface intersection
 *   Resx:   X resolution of resulting image
 *   Resy:   Y resolution of resulting image
 *
 * For all databases some viewing parameters are always the same:
 *
 *   Viewing angle is defined as from the center of top pixel row to bottom
 *     pixel row and left column to right column.
 *   Yon is "at infinity."
 */
void lib_output_viewpoint PARAMS((COORD3 from, COORD3 at, COORD3 up,
				  double fov_angle, double aspect_ratio,
				  double hither, int resx, int resy));


/*-----------------------------------------------------------------*/
/*
 * Output light.  A light is defined by position.  All lights have the same
 * intensity.
 *
 */
void lib_output_light PARAMS((COORD4 center_pt));


/*-----------------------------------------------------------------*/
/*
 * Output background color.  A color is simply RGB (monitor dependent, but
 * that's life).
 * NOTE: Do this BEFORE lib_output_viewpoint(), for display_init()
 */
void lib_output_background_color PARAMS((COORD3 color));


/*-----------------------------------------------------------------*/
/*
 * Output color and shading parameters for all following objects
 *
 * For POV-Ray and Polyray, a character string will be returned that
 * identified this texture.  The default texture will be updated with
 * the name generated by this function.
 *
 * Meaning of the color and shading parameters:
 *    name   = name that this surface can be referenced by...
 *    color  = surface color
 *    ka     = ambient component
 *    kd     = diffuse component
 *    ks     = amount contributed from the reflected direction
 *    shine  = contribution from specular highlights
 *    ang    = angle at which the specular highlight falls to 50% of maximum
 *    t      = amount from the refracted direction
 *    i_of_r = index of refraction of the surface
 *
 */
char *lib_output_color PARAMS((char *name, COORD3 color, double ka,
			       double kd, double ks, double shine,
			       double ang, double kt, double i_of_r));


/*-----------------------------------------------------------------*/
/*
 * Output cylinder or cone.  A cylinder is defined as having a radius and an
 * axis defined by two points, which also define the top and bottom edge of the
 * cylinder.  A cone is defined similarly, the difference being that the apex
 * and base radii are different.  The apex radius is defined as being smaller
 * than the base radius.  Note that the surface exists without endcaps.
 *
 * If format=OUTPUT_CURVES, output the cylinder/cone in format:
 *     "c"
 *     base.x base.y base.z base_radius
 *     apex.x apex.y apex.z apex_radius
 *
 * If the format=OUTPUT_POLYGONS, the surface is polygonalized and output.
 * (4*OUTPUT_RESOLUTION) polygons are output as rectangles by
 * lib_output_polypatch.
 */
void lib_output_cylcone PARAMS((COORD4 base_pt, COORD4 apex_pt,
				int curve_format));


/*-----------------------------------------------------------------*/
void lib_output_disc PARAMS((COORD3 center, COORD3 normal,
			     double iradius, double oradius,
			     int curve_format));


/*-----------------------------------------------------------------*/
void lib_output_height PARAMS((char *, float **, unsigned int, unsigned int,
			       double, double, double, double, double, double));

/*-----------------------------------------------------------------*/
/*
 * Output sphere.  A sphere is defined by a radius and center position.
 *
 * If format=OUTPUT_CURVES, output the sphere in format:
 *     "s" center.x center.y center.z radius
 *
 * If the format=OUTPUT_POLYGONS, the sphere is polygonalized and output.
 * The sphere is polygonalized by splitting it into 6 faces (of a cube
 * projected onto the sphere) and dividing these faces by equally spaced
 * great circles.  OUTPUT_RESOLUTION affects the number of great circles.
 * (6*2*u_resolution*v_resolution) polygons are output as triangles
 * using lib_output_polypatch.
 */
void lib_output_sphere PARAMS((COORD4 center_pt, int curve_format));


/*-----------------------------------------------------------------*/
void lib_output_torus PARAMS((COORD3 center, COORD3 normal,
			      double iradius, double oradius,
			      int curve_format));


/*-----------------------------------------------------------------*/
/* Output box.  A box is defined by a diagonally opposite corners. */
void lib_output_box PARAMS((COORD3 point1, COORD3 point2));


/*-----------------------------------------------------------------*/
/*
 * Output polygon.  A polygon is defined by a set of vertices.  With these
 * databases, a polygon is defined to have all points coplanar.  A polygon has
 * only one side, with the order of the vertices being counterclockwise as you
 * face the polygon (right-handed coordinate system).
 *
 * The output format is always:
 *     "p" total_vertices
 *     vert1.x vert1.y vert1.z
 *     [etc. for total_vertices polygons]
 *
 */
void lib_output_polygon PARAMS((int tot_vert, COORD3 vert[]));


/*-----------------------------------------------------------------*/
/*
 * Output polygonal patch.  A patch is defined by a set of vertices and their
 * normals.  With these databases, a patch is defined to have all points
 * coplanar.  A patch has only one side, with the order of the vertices being
 * counterclockwise as you face the patch (right-handed coordinate system).
 *
 * The output format is always:
 *     "pp" total_vertices
 *     vert1.x vert1.y vert1.z norm1.x norm1.y norm1.z
 *     [etc. for total_vertices polygonal patches]
 *
 */
void lib_output_polypatch PARAMS((int tot_vert, COORD3 vert[], COORD3 norm[]));


/*-----------------------------------------------------------------*/
void lib_output_sq_sphere PARAMS((COORD4 center_pt, double a1, double a2,
				  double a3, double n, double e));


/*-----------------------------------------------------------------*/
void lib_flush_definitions PARAMS((void));


/*-----------------------------------------------------------------*/
void lib_clear_database PARAMS((void));


#if __cplusplus
}
#endif

#endif /* LIB_H */

