/* Copyright (c) 1999, TNCCI Inc.
 * 
 * mandeltex.c
 *
 * blender plugin for exploring Benoit Mandelbrot's fractal set.
 *
 * (source written/compiled by rob haarsma, between dec 95 and april 1999)
 * 
 * Contact:      rob@captainvideo.nl   
 * Information:  http://www.captainvideo.nl/blender
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 */

#include "math.h"
#include "plugin.h"

#define NR_TYPES	1


float result[8];
float cfra;

float	x, y, z, x1;
int	do_reset = FALSE;

extern float hnoise(float noisesize, float x, float y, float z);

/* plugin menu and variables******************************************* */

char name[]= "Fractal";
char stnames[NR_TYPES][16]= {"Mandelbrot" };

VarStruct varstr[]= {
	/* butcode,	name,		default, min,   max	tooltips comment*/
	{   LABEL,		"",		0,	 0,	0,	""},
	{   NUM|FLO,	"iterations",	20.0,	 0.0, 1000.0,	
	"Mandeltex plugin: Number of fractal calculations"}, 
	{   NUMSLI|FLO,	"sx ",		3.8,	-10.0, 10.0,	
	"Mandeltex plugin: Scale fractal in x direction"}, 
	{   NUMSLI|FLO,	"sy ",		3.8,	-10.0, 10.0,	
	"Mandeltex plugin: Scale fractal in y direction"}, 
	{   NUMSLI|FLO,	"sz ",		3.8,	-10.0, 10.0,	
	"Mandeltex plugin: Scale fractal in z direction"}, 
	{   LABEL,		"",		0,	 0,	0,	""},
	{   LABEL,		"",		0,	 0,	0,	""},
	{   NUM|FLO,	"x ",		0.0,	-2.0,	2.0,	
	"Mandeltex plugin: Move fractal in x direction"}, 
	{   NUM|FLO,	"y ",		0.0,	-2.0,	2.0,	
	"Mandeltex plugin: Move fractal in y direction"}, 
	{   NUM|FLO,	"z ",		0.0,	-2.0,	2.0,	
	"Mandeltex plugin: Move fractal in z direction"}, 
	{   NUM|FLO,	"v ",		0.0,	-2.0,	2.0,	
	"Mandeltex plugin: Move fractal in the fourth dimension"}, 
	{   LABEL,		"phaseIV  '99",	0,	 0,	0,	""},
};
typedef struct Cast {
	float dum1, it, sx, sy, sz, dum2, dum3, x, y, u, v, dum4;
} Cast;

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

int plugin_tex_doit(int, Cast*, float*, float*, float*);

int plugin_tex_getversion(void) 
{	
	return B_PLUGIN_VERSION;
}

void plugin_but_changed(int but) 
{
}

void plugin_init(void)
{
}

void plugin_getinfo(PluginInfo *info)
{
	info->name= name;
	info->stypes= NR_TYPES;
	info->nvars= sizeof(varstr)/sizeof(VarStruct);
	
	info->snames= stnames[0];
	info->result= result;
	info->cfra= &cfra;
	info->varstr= varstr;

	info->init= plugin_init;
	info->tex_doit=  (TexDoit) plugin_tex_doit;
	info->callback= plugin_but_changed;
}

int plugin_tex_doit(int stype, Cast *cast, float *texvec, float *dxt, float *dyt)
{
	float x, y, u, v, z, s;
	int i;

	x = (texvec[0] + -cast->x) * cast->sx;
	y = (texvec[1] + -cast->y) * cast->sy;
	u = (texvec[2] + cast->u) * cast->sz;
	v = cast->v * cast->sz;
	
	for(i = 0; i < (int)cast->it; i++)
	{
		z = x;
		x = x * x - y * y + u;
		y = 2.0 * z * y + v;
		s = x * x + y * y;
		if(s > 255)
			break;
	}

	result[0] = 1.0 - (i / cast->it);
	result[4]= 1.0;

	return 0;
}

