/* patch.h,v 1.1.1.1 1995/02/27 07:38:35 explorer Exp */

/************************* GIVE HIM SOME PROPS **************************
 *   A set of routines for creating and raytracing bicubic surface
 *   patches.  The file patch.h contains function prototypes for
 *   the routines in this file.
 *
 *   User Routines:
 *     NewPatch - Allocates the patch data structures and returns a pointer.
 *     DefPatch - Defines a patch, given a patch pointer.
 *     IsectPatch - Intersects a ray and a patch. Returns u, v, t, pnt. 
 *     NormalPatch - Given a patch and a u, v position, returns the normal.
 *     FreePatch - Deallocates a patch.
 *     
 *   Additionally, there is one useful routine not specific to patches:
 *     BoxIntersect - Given a ray and a box, returns the intersection point.
 *
 * Copyright (c) 1990, by Sean Graves and Texas A&M University 
 *
 * Permission is hereby granted for non-commercial reproduction and use of
 * this program, provided that this notice is included in any material copied
 * from it. The author assumes no responsibility for damages resulting from
 * the use of this software, however caused.
 *
 **************************************************************************/

#ifndef PATCH_H
#define PATCH_H

#define GeomPatchCreate(t,gx,gy,gz,d) GeomCreate((GeomRef)PatchCreate(t,gx,gy,gz,d), PatchMethods())

#define NEWTON_TOL ((Float) 0.00001)
#define MAX_ITER 10
#define OVERLAP 0.1
#define INF (1.0e69)
#define MAXDIV 16
#define TOL 0.0001

#ifndef ABS
#define ABS(x) ((x) < 0 ? -(x) : (x))
#endif
 
typedef Float MATRIX[4][4];

typedef struct tnode *TreePtr;   /* Pointer to a tree node */

typedef struct {
  MATRIX geomx, geomy, geomz;   /* Geometry matrices */
  MATRIX M, MT;                 /* Spline basis, transpose */
  MATRIX Md, MdT;               /* Deriv. spline basis, transpose */
  MATRIX Mx, My, Mz;            /* Blending matrices (MGMT) */
  MATRIX Mxdu, Mxdv;            /* For calculation of surface normals */
  MATRIX Mydu, Mydv;
  MATRIX Mzdu, Mzdv;
  TreePtr tree;                 /* Points to bounding-box hierarchy */
} Patch, *PatchPtr;

/*********************************************************************/

typedef struct tnode {           /* A node in the bnding-box hierarchy */
  Float u_mid, v_mid;           /* Approximate guess for u, v */
  Vector box_min, box_max;       /* Extent of box */
  TreePtr child[4];             /* Pointers to four children of node */
} TreeNode;

/*******************************************************************/

typedef struct lnode *ListPtr;     /* Pointer to intersection list elt */

typedef struct lnode {             /* Intersection list elt */
  Float t;                        /* Distance from ray origin to int */
  TreePtr node;                   /* Pointer to box node */
  ListPtr next;                   /* Next element in list */
} ListNode; 

/*********************************************************************/

typedef struct {                   /* Intersection record returned */
  Vector isect;
  Float t, u, v;
} Isectrec;

#define BEZIER    1  /* Bezier */
#define CARDINAL  2  /* Catmull-Rom */
#define BSPLINE   3  /* B-spline */
#define HERMITE   4  /* Hermite */
#define BETAPLINE 5

#define DIV 8

/******************* Function Prototypes ***************************/

void mmult4x4_4x4 _PROTO((MATRIX, MATRIX, MATRIX));
void mmult1x4_4x1 _PROTO((MATRIX, Float [1][4], Float [4][1]));
void mmult4x4_4x1 _PROTO((Float [4][1], Float [4][4], Float [4][1]));
void mmult1x4_4x4 _PROTO((Float [1][4], Float [1][4], Float [4][4]));
void PatchNewton _PROTO((PatchPtr, TreePtr, Ray, Isectrec *));
void free_list _PROTO((ListPtr));
void normalize _PROTO((Vector *));
void cross_product _PROTO((Vector *, Vector, Vector));
void transpose _PROTO((MATRIX, MATRIX));
void DefPatch _PROTO((PatchPtr, MATRIX, MATRIX, MATRIX, MATRIX, int));
void FreePatch _PROTO((PatchPtr));
void samplepatch _PROTO((PatchPtr, int));
void pm_mult _PROTO(());

Float length _PROTO((Vector, Vector));
Float vec_mag _PROTO((Vector));
Float eval_patch _PROTO((Float, MATRIX, MATRIX, MATRIX, Float));
Float dot_product _PROTO((Vector, Vector));
Float PatchBoxIntersect _PROTO((Ray, Vector, Vector));

TreePtr buildtree _PROTO((int, int, int, int, int));

ListPtr insert_node _PROTO((ListPtr, TreePtr, Float));

PatchPtr NewPatch _PROTO((void));

Vector NormalPatch _PROTO((PatchPtr, Float, Float));

Isectrec IsectPatch _PROTO((PatchPtr, Ray *));

int fcmp _PROTO((Float, Float));
int IsParallel _PROTO((Vector, Vector));
 
extern GeomRef       PatchCreate _PROTO((int, MATRIX, MATRIX, MATRIX, int));
extern int           PatchIntersect INTERSECT_PROTO;
extern int           PatchEnter ENTER_PROTO;
extern int           PatchNormal NORMAL_PROTO;
extern void          PatchBounds BOUNDS_PROTO;
extern void          PatchStats STATS_PROTO;
extern void          PatchUV UV_PROTO;
extern char         *PatchName NAME_PROTO;
extern Methods      *PatchMethods METHODS_PROTO;
extern void          PatchMethodRegister _PROTO((UserMethodType));

#endif /* PATCH_H */


