#ifndef _WREND_
#define _WREND_

#include <wgt5.h>

/* 
   WordUp Graphics Toolkit V5.0  Rendering Library
   Copyright 1995 Egerter Software
*/

#ifdef __cplusplus
  extern "C" {
#endif


/* Triangle Rendering Methods */
#define WIREFRAME              0
#define SOLID                  1
#define GOURAUD                2
#define TEXTURE                3
#define FLAT_SHADED_TEXTURE    4
#define GOURAUD_SHADED_TEXTURE 5
#define TRANSLUCENT_TEXTURE    6
#define TRANSLUCENT_GOURAUD    7


#define M_PI 3.1415926535897932384626

#define POLYBUF  20000          /* Maximum polys per frame */
#define OBJBUF     100          /* Maximum objects in world */
#define MAXKEYS 100             /* Maximum animation keys per object */
#define MAXCHILDREN 10          /* Maximum child objects per parent */
#define MAX_TEXTURES 10         /* Maximum textures loaded at once */

extern float    render_shades;  /* Number of colors reserved for shading a 
                                   single color */
extern int      render_all;     /* 0 = backface removal */


/* Our 3D system structures */
typedef struct
{
  float         x, y, z;
} point3d;                      /* A single 3D point */


typedef struct
{
  point3d       local;
  point3d       world;
  point3d       normal;
  int           screenx, screeny;
  unsigned char connected;
  unsigned char rotated;
} vertex;                       /* A vertex of a polygon */


typedef struct
{
  int           vertex1;
  int           vertex2;
  int           vertex3;
  int           type;
  point3d       normal;
  point3d       center;
  short         status;
  unsigned char color;
} triangle_3d;                   /* A 3D triangle */


typedef struct
{
 float          sx, sy, sz; /* Scale */
 float          tx, ty, tz; /* Translation */
 float          rx, ry, rz; /* Rotation */
 int            framenumber;
 char           update_scale;
 char           update_rotation;
 char           update_translation;
} keydata;                      /* Key animation data */


typedef struct
{
  int           start_poly;
  int           end_poly;
  int           startpoints;
  int           points;

  float         minx;
  float         maxx;
  float         miny;
  float         maxy;
  float         minz;
  float         maxz;

  /* Added for animation */
  float         translatex;
  float         translatey;  /* Added to each vertex each frame */
  float         translatez;

  float         pivotx;
  float         pivoty;  /* Pivot location for this object */
  float         pivotz;

  float         scalex;
  float         scaley;  /* Multiplied by each vertex based on the distance */
  float         scalez;  /* from the pivot location */

  float         rotatex;
  float         rotatey;  /* Each vertex is rotated by this amount */
  float         rotatez;

  /* Hierarchy */
  short int     level;
  short         maxchild;               /* Number of children */
  unsigned short int children[MAXCHILDREN];
  short         parent;                 /* Parent of this object */

  keydata       keylist[MAXKEYS];       /* Array of key frames */
  int           maxframe;               /* Max animation frame */
  int           currentframe;           /* Current animation frame */
  
  int           tstepsleft;             /* Translation steps left */
  int           rstepsleft;             /* Rotation steps left */
 
  char          name[15];               /* Name of object */
} object_3d;


/* For shaded texture mapping */
extern unsigned char *render_shadetable;

extern tpoint   renderpoly[3];  /* Used to draw one triangle at a time */

typedef struct {
  int           number;                 /* Sorted polygon # */
  float         depth;                  /* Center depth of polygon */
} sort;

extern sort sorted_polys[POLYBUF];

typedef struct
{
 long           sx[3];
 long           sy[3];
} polytexture;

extern polytexture ptext[POLYBUF];      /* Holds texture coordinates for each
                                           triangle in the polylist */

extern point3d  camera;                 /* Camera position */
extern point3d  camera_norm;            /* Camera position */
extern point3d  focus;                  /* Target position */
extern point3d  tvect;                  /* Eye vector */

typedef struct {
  point3d       world;
  point3d       normal;
} light;                                /* Light position */

extern float    fov;                    /* Field of view in degrees */
extern float    dist;                   /* Distance from viewer */
extern float    m11, m12, m21, m22, m23, m31, m32, m33;

extern triangle_3d polylist[POLYBUF];      /* Polygon list for world */
extern object_3d objectlist[OBJBUF];     /* Object list for world */

extern block    textures[MAX_TEXTURES];

extern float    camera_x, camera_y, camera_z;
extern float    focus_x, focus_y, focus_z;
extern float    light_x, light_y, light_z;
extern float    camera_angle;
extern int      worldpoints;
extern int      totalpoly;
extern int      totalobjects;


/* The following are defined in wrendani.c, used for moving, scaling, and 
   rotating objects. */
extern void translate_object (object_3d *obj, vertex *pts, float x, float y, 
                              float z);
/* Adds x,y,z to each 3D point in the object */


extern void scale_object     (object_3d *obj, vertex *pts, 
                              float x, float y, float z,
                              float px, float py, float pz);
/* Scales by x,y,z, based on the distance from px,py,pz */


extern void rotate_object    (object_3d *obj, vertex *pts, 
                              float x, float y, float z,
                              float px, float py, float pz);
/* Rotates the object by x,y,z around the center point px,py,pz */


extern void set_object_pivot (object_3d *obj, float x, float y, float z);
/* Sets x,y,z as the center of the object */


extern void rotate_point (float *ptx, float *pty, float *ptz,
                          float x, float y, float z,
                          float px, float py, float pz);
/* Rotates a single point by x,y,z around px,py,pz */


/* The following are defined in wrend.c: */

extern void map_plane (float x, float y, float z, long *u, long *v, float scale);
/* Given a 3D point, maps the point onto the x/y plane */

extern float dot_product (point3d *a, point3d *b);
/* Compute the dot product between two 3D vectors */

extern void wset_focus (float a, float b, float c);
/* Sets where the camera is looking at */

extern void wset_camera (float a, float b, float c);
/* Sets the position of the camera */

extern void wset_light (float a, float b, float c);
/* Sets the position of the light */

extern void wset_view (void);
/* Sets up the viewing matrix based on the camera position and direction */

extern void wworld_2_view (object_3d *obj, int *drawtotal, vertex *vlist);
/* Transform the 3D coordinates to 2D coordinates */

extern void calc_normal (vertex *wp1, vertex *wp2, vertex *wp3, point3d *norm);
/* Calculates a normal vector given three vertices */

extern void map_points (short obj, vertex *pts, float scale);
/* Map all the texture coordinates onto a plane, given an object and a scale */

extern int sortkeys (keydata *a, keydata *b);
/* Sorts the animation keys by their frame number */

extern void adjust_object (object_3d *objp, float rx, float ry, float rz, 
                    float px, float py, float pz);
/* Modify an object's animation data if it has a parent */

extern void duplicate_frame (object_3d *obj, int frame, int framenumber);
/* Copies one animation key to another */

extern void build_hierarchy (void);
/* Connects children and parents together */

extern void add_key_translate (object_3d *obj, int framenumber, float x, float y, 
                        float z);
/* Adds a translation animation key */

extern void add_key_scale (object_3d *obj, int framenumber, float x, float y,
                    float z);
/* Adds a scale animation key */

extern void add_key_rotate (object_3d *obj, int framenumber, float x, float y, 
                    float z);
/* Adds a rotation animation key */

extern int find_object (char *name);
/* Given the name of an object, returns the index in objectlist */

extern void add_child (int parent, int child);
/* Adds a child to a parent object */

extern void load_3ds (char *filename, vertex *pts);
/* Loads a 3D Studio file */

extern int compare (sort *a, sort *b);
/* Used for sorting */

extern void draw_polys (vertex *pts, int drawtotal);
/* Draws the polygons */

extern void wset_object_color (int obj, unsigned char col);
/* Sets the color of each triangle in an object, used for solid, gouraud, and
   texture.  For textured objects, the color represents the texture number
   from the textures array. */

extern void wset_object_type (int obj, int type);
/* Sets the rendering method for an object */

extern void wreset_3d_system (void);
/* Resets the engine so you can load in a new object */

#ifdef __cplusplus
}
#endif

#endif
