/* ifs.h,v 1.1.1.1 1995/02/27 07:38:34 explorer Exp */

/*
 * Philippe Bekaert - bekaert@cs.kuleuven.ac.be - 12 jan 93
 */

#ifndef IFS_H
#define IFS_H
#include "geom.h"
#include "libcommon/transform.h"
#include "libcommon/common.h"

#define CONSTANT_NORMAL_WEIGHTING 0
#define HIGHPASS_NORMAL_WEIGHTING 1
#define LOWPASS_NORMAL_WEIGHTING 2

#define GeomCIfsCreate(m,c,l,o)	GeomCreate((GeomRef)IfsCreate(m,c,l,o), CIfsMethods())
#define GeomIfsCreate(m,o)	GeomCreate((GeomRef)IfsCreate(m,(Geom *)NULL,(Geom *)NULL,o), IfsMethods())

/* list of transforms */
typedef struct IfsTransList {
  Trans *trans, *transtail;       /* head and tail of transforms */
  int rang;
  struct IfsTransList *next;
} IfsTransList;

/*
 * Ifs
 */
typedef struct IfsMap {                 /* Ifs map structure */
  Trans *trans, *transtail;       /* head and tail of transformation list */
  RSMatrix matrix, imatrix;       /* matrix and inverse after resolving and composing the transformations */
  Float contractivity;            /* contractivity of the resolved map */
  int uniform;                    /* TRUE if map does uniform scaling */
  short animated;                 /* TRUE if the map is animated */
  int rang;                       /* for hierarchical IFS */
} IfsMap;                         

struct IfsExtent {                      /* Ifs extent structure */
  Float r, rsq;                   /* the extent is a sphere: r=radius */
  Vector c;                       /*                         c=centre */
};

typedef struct IfsOptions {                     /* options */
  int depth;                      /* max recursion depth */
  Float size;                     /* min extent size */
  int normalweighting;            /* normal weighting method */
  int boxbounding, spherebounding; /* box/sphere as bounding volume */
  char *listfilename;	/* file to produce a list of volumes in */
} IfsOptions;

typedef struct Ifs {    
  IfsMap *maps;	                /* IFS maps */
  int nrmaps;                     /* nr of Ifs maps */
  int uniform_maps;               /* all maps do uniform scaling */
  int frame;                      /* frame for which it is initialised */
  Float contractivity;            /* max. contractivity of the maps */
  Float size;                     /* estimated size of attractor */    
  Float (*normalweight)();        /* normal weighting function */
  Float time;                     /* time for which the maps are resolved */
  short animated;                 /* TRUE if maps are animated */
  Geom *condensation;             /* condensation set */
  Geom *leaves;                   /* leaves for Oppenheimer tree */
  Float condensize, leavesize;	/* size of condensation & leaves */
  Float bounds[2][3];             /* attractor bounding box */
  struct IfsExtent extent;        /* tightly fitting sphere */
  int boxbounding;		/* TRUE for using bounding box instead of sphere */
  Vector normal, intersectpos;    /* hierarchically computed normal */
  IfsOptions options;             /* options */
} Ifs;

typedef struct TEList {                 /* Transformed Extent List */
  RSMatrix matrix, imatrix;       /* transformation matrix and inverse */
  Ray ray;                        /* inverse transformed ray */
  Float   dist;                   /* distance to ray-origin */
  Float   size;                   /* size of transformed extend */
  Float   distfac;                /* ray stretching factor */
  Vector normal;                  /* hierarchically computed normal */
  int depth;                      /* recursion depth */
  int rang;                       /* rang of map last used */
  struct TEList *next, *prev;     /* doubly linked list */
} TEList;

extern GeomRef  IfsCreate _PROTO((IfsTransList *, Geom *, Geom *,
				   IfsOptions *));
extern Methods	*CIfsMethods METHODS_PROTO;
extern Methods  *IfsMethods METHODS_PROTO;
extern int	CIfsIntersect INTERSECT_PROTO;
extern int      IfsIntersect INTERSECT_PROTO;
extern int      IfsEnter ENTER_PROTO;
extern int      IfsNormal NORMAL_PROTO;
extern void	IfsBounds BOUNDS_PROTO;
extern void     CIfsStats STATS_PROTO;
extern void     IfsStats STATS_PROTO;
extern char	*CIfsName NAME_PROTO;
extern char     *IfsName NAME_PROTO;
extern void     IfsMethodRegister _PROTO((UserMethodType));

#endif /* IFS_H */


