/* hf.h,v 1.1.1.1 1995/02/27 07:38:33 explorer Exp */

/*
 * Copyright (C) 1989, 1991, Craig E. Kolb
 * All rights reserved.
 *
 * This software may be freely copied, modified, and redistributed
 * provided that this copyright notice is preserved on all copies.
 *
 * You may not distribute this software, in whole or in part, as part of
 * any commercial product without the express consent of the authors.
 *
 * There is no warranty or other guarantee of fitness of this software
 * for any purpose.  It is provided solely "as is".
 *
 */

#ifndef HF_H
#define HF_H

#define GeomHfCreate(f) GeomCreate((GeomRef)HfCreate(f), HfMethods())

/*
 * Any height values <= Hf_UNSET is not considered to be part of the
 * height field. Any trianges containing such a vertex will not be
 * rendered.  This allows one to render non-square height fields.
 */
#define HF_UNSET		(-1000.)

/*
 * Number of datapoints in a single cell.  If you've got loads of memory,
 * decrease this number.  The 'optimal' number is quite system-dependent,
 * but something around 20 seems to work well. For systems without much
 * memory, this constant should be greater than or equal to the largest
 * height field which will be rendered, thus making the algorithm
 * non-hierarchical.
 */
#define BESTSIZE		16

/*
 * Size of triangle cache.
 */
#define CACHESIZE		6

/*
 * Used to differentiate between the two triangles used to represent a cell:
 *	a------d
 *      |\     |
 *      | \TRI2|	TRI2 == c-->d-->a-->c
 *      |  \   |
 *      |   \  |
 *	|    \ |
 *      |TRI1 \|	TRI1 == c-->a-->b-->c
 *      b------c
 */
#define TRI1			1
#define TRI2			2

typedef struct {
  int stepX, stepY;
  Float tDX, tDY;
  float minz, maxz;
  int outX, outY;
  Vector cp, pDX, pDY;
} Trav2D;

typedef struct hfTri {
  Vector v1, v2, v3, norm;
  Float d;
  char type;
  struct hfTri *next, *prev;
} hfTri;

typedef struct {
  int len;
  hfTri *head, *tail;
} TriQueue;

typedef struct {
  float **data;		/* Altitude points */
  float minz, maxz;
  int size, *lsize;	/* # of points/side */
  int BestSize; 		/* "best" division size */
  float iBestSize;	/* inverse of above (for faster computation) */
  int levels;		/* log base BestSize of size */
  float ***boundsmax;	/* high data values at various resolutions. */
  float ***boundsmin;
  float *spacing;
  hfTri hittri, **q;	/* hit triangle and triangle cache */
  int qtail, qsize;	/* end and length of cache */
  Float boundbox[2][3];	/* bounding box of Hf */
} Hf;

extern GeomRef  HfCreate _PROTO((char *));
extern Methods	*HfMethods METHODS_PROTO;
extern int	HfIntersect INTERSECT_PROTO;
extern int      HfNormal NORMAL_PROTO;
extern void     HfUV UV_PROTO;
extern void	HfBounds BOUNDS_PROTO;
extern char	*HfName NAME_PROTO;
extern void     HfStats STATS_PROTO;
extern void     HfMethodRegister _PROTO((UserMethodType));

/*
 * These used to be static, but since fl.c uses them to generate fractal
 * landscapes by using internally generated heightfields, I felt duplicated
 * code in fl.c was pointless...
 */
void integrate_grid _PROTO((Hf *, int));
float minalt _PROTO((int, int, float **));
float maxalt _PROTO((int, int, float **));

#endif /* HF_H */
