/*
 * ifs.h
 *
 * 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 */
              size,                     /* estimated size of attractor */    
              (*normalweight)(),        /* normal weighting function */
              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 */
                size,                   /* size of transformed extend */
                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 Ifs	*IfsCreate();
extern Methods	*CIfsMethods(), *IfsMethods();
extern int	CIfsIntersect(), IfsIntersect(), IfsEnter(), IfsNormal();
extern void	IfsBounds(), CIfsStats(), IfsStats();
extern char	*CIfsName(), *IfsName();

#endif /* IFS_H */





