home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: Graphics
/
Graphics.zip
/
povsrc31.zip
/
pigment.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-01-21
|
25KB
|
860 lines
/****************************************************************************
* pigment.c
*
* This module implements solid texturing functions that modify the color
* transparency of an object's surface.
*
* from Persistence of Vision(tm) Ray Tracer
* Copyright 1996,1999 Persistence of Vision Team
*---------------------------------------------------------------------------
* NOTICE: This source code file is provided so that users may experiment
* with enhancements to POV-Ray and to port the software to platforms other
* than those supported by the POV-Ray Team. There are strict rules under
* which you are permitted to use this file. The rules are in the file
* named POVLEGAL.DOC which should be distributed with this file.
* If POVLEGAL.DOC is not available or for more info please contact the POV-Ray
* Team Coordinator by email to team-coord@povray.org or visit us on the web at
* http://www.povray.org. The latest version of POV-Ray may be found at this site.
*
* This program is based on the popular DKB raytracer version 2.12.
* DKBTrace was originally written by David K. Buck.
* DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
*
*****************************************************************************/
/*
Some texture ideas garnered from SIGGRAPH '85 Volume 19 Number 3,
"An Image Synthesizer" By Ken Perlin.
Further Ideas Garnered from "The RenderMan Companion" (Addison Wesley).
*/
#include "frame.h"
#include "vector.h"
#include "povproto.h"
#include "texture.h"
#include "colour.h"
#include "image.h"
#include "matrices.h"
#include "pigment.h"
#include "txttest.h"
#ifdef BlobPatternPatch
#include "pattern.h"/*Chris Huff blob pigment*/
#endif
/*****************************************************************************
* Local preprocessor defines
******************************************************************************/
/*****************************************************************************
* Local typedefs
******************************************************************************/
/*****************************************************************************
* Local variables
******************************************************************************/
static BLEND_MAP_ENTRY Black_White_Entries[2] /* =
{{0.0, FALSE, {{0.0, 0.0, 0.0, 0.0, 0.0}}},
{1.0, FALSE, {{1.0, 1.0, 1.0, 0.0, 0.0}}}} */ ;
static BLEND_MAP Gray_Default_Map =
{ 2, FALSE, COLOUR_TYPE, -1, Black_White_Entries};
static BLEND_MAP_ENTRY Bozo_Entries[6] /* =
{{0.4, FALSE, {{1.0, 1.0, 1.0, 0.0, 0.0}}},
{0.4, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
{0.6, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
{0.6, FALSE, {{0.0, 0.0, 1.0, 0.0, 0.0}}},
{0.8, FALSE, {{0.0, 0.0, 1.0, 0.0, 0.0}}},
{0.8, FALSE, {{1.0, 0.0, 0.0, 0.0, 0.0}}}} */ ;
static BLEND_MAP Bozo_Default_Map =
{ 6, FALSE, COLOUR_TYPE, -1, Bozo_Entries};
static BLEND_MAP_ENTRY Wood_Entries[2] /* =
{{0.6, FALSE, {{0.666, 0.312, 0.2, 0.0, 0.0}}},
{0.6, FALSE, {{0.4, 0.1333, 0.066, 0.0, 0.0}}}} */ ;
static BLEND_MAP Wood_Default_Map =
{ 2, FALSE, COLOUR_TYPE, -1, Wood_Entries};
static BLEND_MAP_ENTRY Mandel_Entries[5] /* =
{{0.001, FALSE, {{0.0, 0.0, 0.0, 0.0, 0.0}}},
{0.001, FALSE, {{0.0, 1.0, 1.0, 0.0, 0.0}}},
{0.012, FALSE, {{1.0, 1.0, 0.0, 0.0, 0.0}}},
{0.015, FALSE, {{1.0, 0.0, 1.0, 0.0, 0.0}}},
{0.1, FALSE, {{0.0, 1.0, 1.0, 0.0, 0.0}}}} */ ;
static BLEND_MAP Mandel_Default_Map =
{ 5, FALSE, COLOUR_TYPE, -1, Mandel_Entries};
static BLEND_MAP_ENTRY Agate_Entries[6] /* =
{{0.0, FALSE, {{1.0, 1.0, 1.0, 0.0, 0.0}}},
{0.5, FALSE, {{0.95, 0.75, 0.5, 0.0, 0.0}}},
{0.5, FALSE, {{0.9, 0.7, 0.5, 0.0, 0.0}}},
{0.6, FALSE, {{0.9, 0.7, 0.4, 0.0, 0.0}}},
{0.6, FALSE, {{1.0, 0.7, 0.4, 0.0, 0.0}}},
{1.0, FALSE, {{0.6, 0.3, 0.0, 0.0, 0.0}}}} */ ;
static BLEND_MAP Agate_Default_Map =
{ 6, FALSE, COLOUR_TYPE, -1, Agate_Entries};
static BLEND_MAP_ENTRY Radial_Entries[4] /* =
{{0.0, FALSE, {{0.0, 1.0, 1.0, 0.0, 0.0}}},
{0.333, FALSE, {{1.0, 1.0, 0.0, 0.0, 0.0}}},
{0.666, FALSE, {{1.0, 0.0, 1.0, 0.0, 0.0}}},
{1.0, FALSE, {{0.0, 1.0, 1.0, 0.0, 0.0}}}} */ ;
static BLEND_MAP Radial_Default_Map =
{ 4, FALSE, COLOUR_TYPE, -1, Radial_Entries};
static BLEND_MAP_ENTRY Marble_Entries[3] /* =
{{0.0, FALSE, {{0.9, 0.8, 0.8, 0.0, 0.0}}},
{0.9, FALSE, {{0.9, 0.08, 0.08, 0.0, 0.0}}},
{0.9, FALSE, {{0.0, 0.0, 0.0, 0.0, 0.0}}}} */ ;
static BLEND_MAP Marble_Default_Map =
{ 3, FALSE, COLOUR_TYPE, -1, Marble_Entries};
static BLEND_MAP_ENTRY Brick_Entries[2] /* =
{{0.0, FALSE, {{0.5, 0.5, 0.5, 0.0, 0.0}}},
{1.0, FALSE, {{0.6, 0.15, 0.15, 0.0, 0.0}}}} */ ;
BLEND_MAP Brick_Default_Map =
{ 2, FALSE, COLOUR_TYPE, -1, Brick_Entries};
#ifdef TrianglulairSquarePatch
static BLEND_MAP_ENTRY Hex_Entries[3] =
{{0.0, FALSE, {{0.0, 0.0, 1.0, 0.0, 0.0}}},
{1.0, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
{2.0, FALSE, {{1.0, 0.0, 0.0, 0.0, 0.0}}}} ;
static BLEND_MAP_ENTRY Ter_Entries[6] =
{{0.0, FALSE, {{0.0, 0.0, 1.0, 0.0, 0.0}}},
{1.0, FALSE, {{1.0, 0.0, 0.0, 0.0, 0.0}}},
{2.0, FALSE, {{1.0, 0.0, 1.0, 0.0, 0.0}}},
{3.0, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
{4.0, FALSE, {{0.0, 1.0, 1.0, 0.0, 0.0}}},
{5.0, FALSE, {{1.0, 1.0, 0.0, 0.0, 0.0}}}} ;
static BLEND_MAP_ENTRY Square_Entries[4] =
{{0.0, FALSE, {{0.0, 0.0, 0.0, 0.0, 0.0}}},
{1.0, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
{2.0, FALSE, {{1.0, 0.0, 0.0, 0.0, 0.0}}},
{3.0, FALSE, {{1.0, 1.0, 1.0, 0.0, 0.0}}}} ;
#else
static BLEND_MAP_ENTRY Hex_Entries[3] /*=
{{0.0, FALSE, {{0.0, 0.0, 1.0, 0.0, 0.0}}},
{1.0, FALSE, {{0.0, 1.0, 0.0, 0.0, 0.0}}},
{2.0, FALSE, {{1.0, 0.0, 0.0, 0.0, 0.0}}}} */;
#endif
BLEND_MAP Hex_Default_Map =
{ 3, FALSE,COLOUR_TYPE, -1, Hex_Entries};
#ifdef TrianglulairSquarePatch
BLEND_MAP Ter_Default_Map =
{ 6, FALSE,COLOUR_TYPE, -1, Ter_Entries};
BLEND_MAP Square_Default_Map =
{ 4, FALSE,COLOUR_TYPE, -1, Square_Entries};
#endif
BLEND_MAP Check_Default_Map =
{ 2, FALSE,COLOUR_TYPE, -1, Hex_Entries}; /* Yes... Hex_Entries, not Check [CY] */
/*****************************************************************************
* Static functions
******************************************************************************/
static void Do_Average_Pigments (COLOUR Colour, PIGMENT *Pigment, VECTOR EPoint,INTERSECTION *Intersection);
#ifdef BlobPatternPatch
static int blob_pigment(VECTOR TPoint, PIGMENT * Pigment, COLOUR Colour, INTERSECTION *Intersection);
#endif
/*****************************************************************************
*
* FUNCTION
*
* Create_Pigment
*
* INPUT
*
* OUTPUT
*
* RETURNS
*
* pointer to the created pigment
*
* AUTHOR
*
* POV-Ray Team
*
* DESCRIPTION : Allocate memory for new pigment and initialize it to
* system default values.
*
* CHANGES
*
******************************************************************************/
PIGMENT *Create_Pigment ()
{
PIGMENT *New;
New = (PIGMENT *)POV_MALLOC(sizeof (PIGMENT), "pigment");
Init_TPat_Fields((TPATTERN *)New);
Make_Colour(New->Colour, 0.0,0.0,0.0) ;
New->Blend_Map = NULL;
return (New);
}
/*****************************************************************************
*
* FUNCTION
*
* Copy_Pigment
*
* INPUT
*
* Old -- point to pigment to be copied
*
* RETURNS
*
* pointer to the created pigment
*
* AUTHOR
*
* POV-Ray Team
*
* DESCRIPTION : Allocate memory for new pigment and initialize it to
* values in existing pigment Old.
*
* CHANGES
*
******************************************************************************/
PIGMENT *Copy_Pigment (PIGMENT *Old)
{
PIGMENT *New;
if (Old != NULL)
{
New = Create_Pigment ();
Copy_TPat_Fields ((TPATTERN *)New, (TPATTERN *)Old);
if (Old->Type == PLAIN_PATTERN)
{
Assign_Colour(New->Colour,Old->Colour);
}
New->Next = (TPATTERN *)Copy_Pigment((PIGMENT *)Old->Next);
}
else
{
New = NULL;
}
return (New);
}
/*****************************************************************************
*
* FUNCTION
*
* Destroy_Pigment
*
* INPUT
*
* pointer to pigment to destroied
*
* OUTPUT
*
* RETURNS
*
* AUTHOR
*
* POV-Ray Team
*
* DESCRIPTION : free all memory associated with given pigment
*
* CHANGES
*
******************************************************************************/
void Destroy_Pigment (PIGMENT *Pigment)
{
if (Pigment != NULL)
{
Destroy_Pigment((PIGMENT *)Pigment->Next);
Destroy_TPat_Fields ((TPATTERN *)Pigment);
POV_FREE(Pigment);
}
}
/*****************************************************************************
*
* FUNCTION
*
* Post_Pigment
*
* INPUT
*
* OUTPUT
*
* RETURNS
*
* AUTHOR
*
* Chris Young
*
* DESCRIPTION
*
* CHANGES
*
******************************************************************************/
int Post_Pigment(PIGMENT *Pigment)
{
int i, Has_Filter;
BLEND_MAP *Map;
if (Pigment == NULL)
{
Error("Missing pigment");
}
if (Pigment->Flags & POST_DONE)
{
return(Pigment->Flags & HAS_FILTER);
}
if (Pigment->Type == NO_PATTERN)
{
Pigment->Type = PLAIN_PATTERN;
Make_Colour(Pigment->Colour, 0.0, 0.0, 0.0) ;
Warning(150, "No pigment type given.\n");
}
Pigment->Flags |= POST_DONE;
switch (Pigment->Type)
{
case PLAIN_PATTERN:
Destroy_Warps (Pigment->Warps);
Pigment->Warps = NULL;
break;
case NO_PATTERN:
case BITMAP_PATTERN:
break;
default:
if (Pigment->Blend_Map == NULL)
{
switch (Pigment->Type)
{
case BOZO_PATTERN: Pigment->Blend_Map = &Bozo_Default_Map; break;
case BRICK_PATTERN: Pigment->Blend_Map = &Brick_Default_Map; break;
case WOOD_PATTERN: Pigment->Blend_Map = &Wood_Default_Map; break;
case MAGNET1M_PATTERN:
case MAGNET1J_PATTERN:
case MAGNET2M_PATTERN:
case MAGNET2J_PATTERN:
case MANDEL3_PATTERN:
case MANDEL4_PATTERN:
case JULIA_PATTERN:
case JULIA3_PATTERN:
case JULIA4_PATTERN:
case MANDEL_PATTERN: Pigment->Blend_Map = &Mandel_Default_Map;break;
case RADIAL_PATTERN: Pigment->Blend_Map = &Radial_Default_Map;break;
case AGATE_PATTERN: Pigment->Blend_Map = &Agate_Default_Map; break;
case MARBLE_PATTERN: Pigment->Blend_Map = &Marble_Default_Map;break;
case HEXAGON_PATTERN: Pigment->Blend_Map = &Hex_Default_Map; break;
#ifdef TrianglulairSquarePatch
case TERNAIRE_PATTERN: Pigment->Blend_Map = &Ter_Default_Map; break;
case SQUARE_PATTERN: Pigment->Blend_Map = &Square_Default_Map; break;
#endif
case CHECKER_PATTERN: Pigment->Blend_Map = &Check_Default_Map; break;
#ifdef ObjectPatternPatch
case OBJECT_PATTERN: Pigment->Blend_Map = &Check_Default_Map; break;/*Chris Huff object pattern*/
#endif
case AVERAGE_PATTERN: Error("Missing pigment_map in average pigment"); break;
default: Pigment->Blend_Map = &Gray_Default_Map; break;
}
}
break;
}
/* Now we test wether this pigment is opaque or not. [DB 8/94] */
Has_Filter = FALSE;
if ((fabs(Pigment->Colour[FILTER]) > EPSILON) ||
(fabs(Pigment->Colour[TRANSM]) > EPSILON))
{
Has_Filter = TRUE;
}
if ((Map = Pigment->Blend_Map) != NULL)
{
if ((Map->Type == PIGMENT_TYPE) || (Map->Type == DENSITY_TYPE))
{
for (i = 0; i < Map->Number_Of_Entries; i++)
{
Has_Filter |= Post_Pigment(Map->Blend_Map_Entries[i].Vals.Pigment);
}
}
else
{
for (i = 0; i < Map->Number_Of_Entries; i++)
{
Has_Filter |= fabs(Map->Blend_Map_Entries[i].Vals.Colour[FILTER])>EPSILON;
Has_Filter |= fabs(Map->Blend_Map_Entries[i].Vals.Colour[TRANSM])>EPSILON;
}
}
}
if (Has_Filter)
{
Pigment->Flags |= HAS_FILTER;
}
if (Pigment->Next != NULL)
{
Post_Pigment((PIGMENT *)Pigment->Next);
}
return(Has_Filter);
}
/*****************************************************************************
*
* FUNCTION
*
* Compute_Pigment
*
* INPUT
*
* Pigment - Info about this pigment
* EPoint - 3-D point at which pattern is evaluated
* Intersection - structure holding info about object at intersection point
*
* OUTPUT
*
* Colour - Resulting color is returned here.
*
* RETURNS
*
* int - TRUE, if a color was found for the given point
* FALSE, if no color was found (e.g. areas outside an image map
* that has the once option)
*
* AUTHOR
*
* POV-Ray Team
*
* DESCRIPTION
* Given a 3d point and a pigment, compute colour from that layer.
* (Formerly called "Colour_At", or "Add_Pigment")
*
* CHANGES
* Added pigment map support [CY 11/94]
* Added Intersection parameter for UV support NK 1998
*
******************************************************************************/
int Compute_Pigment (COLOUR Colour, PIGMENT *Pigment, VECTOR EPoint, INTERSECTION *Intersection)
{
int Colour_Found;
VECTOR TPoint;
DBL value;
register DBL fraction;
BLEND_MAP_ENTRY *Cur, *Prev;
COLOUR Temp_Colour;
BLEND_MAP *Blend_Map = Pigment->Blend_Map;
if (Pigment->Type <= LAST_SPECIAL_PATTERN)
{
Colour_Found = TRUE;
switch (Pigment->Type)
{
case NO_PATTERN:
Make_Colour(Colour, 0.0, 0.0, 0.0);
break;
case PLAIN_PATTERN:
Assign_Colour(Colour,Pigment->Colour);
break;
case AVERAGE_PATTERN:
/* NK 1998 reset_children - added TRUE */
Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment, TRUE);
Do_Average_Pigments(Colour,Pigment,TPoint,Intersection);
break;
case BITMAP_PATTERN:
/* NK 1998 reset_children - added FALSE - do not execute RESET_CHILDREN warps */
Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment, FALSE);
Make_Colour(Colour, 0.0, 0.0, 0.0);
Colour_Found = image_map (TPoint, Pigment, Colour);
break;
#ifdef NoisePigmentPatch
case NOISE_PIGMENT:/*Chris Huff noise pigment*/
{
COLC mnR = Pigment->Vals.NoisePigment.Min[0];
COLC mnG = Pigment->Vals.NoisePigment.Min[1];
COLC mnB = Pigment->Vals.NoisePigment.Min[2];
COLC mxR = Pigment->Vals.NoisePigment.Max[0];
COLC mxG = Pigment->Vals.NoisePigment.Max[1];
COLC mxB = Pigment->Vals.NoisePigment.Max[2];
Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment,FALSE);
Make_Colour(Colour, 0.0, 0.0, 0.0);
switch(Pigment->Vals.NoisePigment.NoiseType)
{
case 0:/*plain color*/
{
Colour[0] = (FRAND()*(mxR-mnR))+mnR;
Colour[1] = (FRAND()*(mxG-mnG))+mnG;
Colour[2] = (FRAND()*(mxB-mnB))+mnB;
}
break;
case 1:/*plain monochrome*/
{
DBL n = FRAND();
Colour[0] = (n*(mxR-mnR))+mnR;
Colour[1] = (n*(mxG-mnG))+mnG;
Colour[2] = (n*(mxB-mnB))+mnB;
}
break;
case 2:/*gaussian color*/
{
Colour[0] = (((FRAND()+FRAND()+FRAND())/3)*(mxR-mnR))+mnR;
Colour[1] = (((FRAND()+FRAND()+FRAND())/3)*(mxG-mnG))+mnG;
Colour[2] = (((FRAND()+FRAND()+FRAND())/3)*(mxB-mnB))+mnB;
}
break;
case 3:/*gaussian monochrome*/
{
DBL n = (FRAND()+FRAND()+FRAND())/3;
Colour[0] = (n*(mxR-mnR))+mnR;
Colour[1] = (n*(mxG-mnG))+mnG;
Colour[2] = (n*(mxB-mnB))+mnB;
}
break;
default:/*plain color*/
{
Colour[0] = FRAND();
Colour[1] = FRAND();
Colour[2] = FRAND();
}
}
Colour_Found = TRUE;
}
break;
#endif
#ifdef BlobPatternPatch
case BLOB_PIGMENT:/*Chris Huff blob pigment*/
Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment,FALSE);
Make_Colour(Colour, 0.0, 0.0, 0.0);
Colour_Found = blob_pigment(TPoint, Pigment, Colour,Intersection);
break;
#endif
default:
Error("Pigment type %d not yet implemented",Pigment->Type);
}
return(Colour_Found);
}
Colour_Found = FALSE;
/* NK 19 Nov 1999 added Warp_EPoint */
Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment, FALSE);
value = Evaluate_TPat ((TPATTERN *)Pigment,TPoint,Intersection);
Search_Blend_Map (value, Blend_Map, &Prev, &Cur);
if (Blend_Map->Type == COLOUR_TYPE)
{
Colour_Found = TRUE;
Assign_Colour(Colour, Cur->Vals.Colour);
}
else
{
/* NK 1998 reset_children - added ", TRUE" - RESET_CHILDREN warps will be executed */
Warp_EPoint (TPoint, EPoint, (TPATTERN *)Pigment, TRUE);
if (Compute_Pigment(Colour, Cur->Vals.Pigment,TPoint,Intersection))
{
Colour_Found = TRUE;
}
}
if (Prev != Cur)
{
if (Blend_Map->Type == COLOUR_TYPE)
{
Colour_Found = TRUE;
Assign_Colour(Temp_Colour, Prev->Vals.Colour);
}
else
{
if (Compute_Pigment(Temp_Colour, Prev->Vals.Pigment, TPoint,Intersection))
{
Colour_Found = TRUE;
}
}
fraction = (value - Prev->value) / (Cur->value - Prev->value);
Colour[RED] = Temp_Colour[RED] + fraction * (Colour[RED] - Temp_Colour[RED]);
Colour[GREEN] = Temp_Colour[GREEN] + fraction * (Colour[GREEN] - Temp_Colour[GREEN]);
Colour[BLUE] = Temp_Colour[BLUE] + fraction * (Colour[BLUE] - Temp_Colour[BLUE]);
Colour[FILTER] = Temp_Colour[FILTER] + fraction * (Colour[FILTER] - Temp_Colour[FILTER]);
Colour[TRANSM] = Temp_Colour[TRANSM] + fraction * (Colour[TRANSM] - Temp_Colour[TRANSM]);
}
return(Colour_Found);
}
/*****************************************************************************
*
* FUNCTION
*
* INPUT
*
* OUTPUT
*
* RETURNS
*
* AUTHOR
*
* DESCRIPTION
*
* CHANGES
* Added Intersection parameter for UV support NK 1998
*
******************************************************************************/
static void Do_Average_Pigments (COLOUR Colour, PIGMENT *Pigment, VECTOR EPoint, INTERSECTION *Intersection)
{
int i;
COLOUR LC;
BLEND_MAP *Map = Pigment->Blend_Map;
SNGL Value;
SNGL Total = 0.0;
Make_Colour (Colour, 0.0, 0.0, 0.0);
for (i = 0; i < Map->Number_Of_Entries; i++)
{
Value = Map->Blend_Map_Entries[i].value;
Compute_Pigment (LC,Map->Blend_Map_Entries[i].Vals.Pigment,EPoint,Intersection);
Colour[RED] += LC[RED] *Value;
Colour[GREEN] += LC[GREEN] *Value;
Colour[BLUE] += LC[BLUE] *Value;
Colour[FILTER]+= LC[FILTER]*Value;
Colour[TRANSM]+= LC[TRANSM]*Value;
Total += Value;
}
Colour[RED] /= Total;
Colour[GREEN] /= Total;
Colour[BLUE] /= Total;
Colour[FILTER]/= Total;
Colour[TRANSM]/= Total;
}
/*****************************************************************************
*
* FUNCTION Make_Pigment_Entries
*
* INPUT None
*
* OUTPUT Initializes default pigment blend_map values.
*
* RETURNS None
*
* AUTHOR Steve Demlow, Dec. '95
*
* DESCRIPTION Some pre-ANSI compilers won't auto-initialize unions, so these
* have to be done in regular code.
*
* CHANGES
*
******************************************************************************/
void Make_Pigment_Entries()
{
static unsigned char Made = FALSE;
if (Made) {
return;
}
Made = TRUE;
Make_Blend_Map_Entry(Black_White_Entries[0] , 0.0, FALSE, 0.0, 0.0, 0.0, 0.0, 0.0);
Make_Blend_Map_Entry(Black_White_Entries[1] , 1.0, FALSE, 1.0, 1.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Bozo_Entries[0], 0.4, FALSE, 1.0, 1.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Bozo_Entries[1], 0.4, FALSE, 0.0, 1.0, 0.0, 0.0, 0.0);
Make_Blend_Map_Entry(Bozo_Entries[2], 0.6, FALSE, 0.0, 1.0, 0.0, 0.0, 0.0);
Make_Blend_Map_Entry(Bozo_Entries[3], 0.6, FALSE, 0.0, 0.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Bozo_Entries[4], 0.8, FALSE, 0.0, 0.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Bozo_Entries[5], 0.8, FALSE, 1.0, 0.0, 0.0, 0.0, 0.0);
Make_Blend_Map_Entry(Wood_Entries[0], 0.6, FALSE, 0.666, 0.312, 0.2, 0.0, 0.0);
Make_Blend_Map_Entry(Wood_Entries[1], 0.6, FALSE, 0.4, 0.1333, 0.066, 0.0, 0.0);
Make_Blend_Map_Entry(Mandel_Entries[0], 0.001, FALSE, 0.0, 0.0, 0.0, 0.0, 0.0);
Make_Blend_Map_Entry(Mandel_Entries[1], 0.001, FALSE, 0.0, 1.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Mandel_Entries[2], 0.012, FALSE, 1.0, 1.0, 0.0, 0.0, 0.0);
Make_Blend_Map_Entry(Mandel_Entries[3], 0.015, FALSE, 1.0, 0.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Mandel_Entries[4], 0.1, FALSE, 0.0, 1.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Agate_Entries[0], 0.0, FALSE, 1.0, 1.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Agate_Entries[1], 0.5, FALSE, 0.95, 0.75, 0.5, 0.0, 0.0);
Make_Blend_Map_Entry(Agate_Entries[2], 0.5, FALSE, 0.9, 0.7, 0.5, 0.0, 0.0);
Make_Blend_Map_Entry(Agate_Entries[3], 0.6, FALSE, 0.9, 0.7, 0.4, 0.0, 0.0);
Make_Blend_Map_Entry(Agate_Entries[4], 0.6, FALSE, 1.0, 0.7, 0.4, 0.0, 0.0);
Make_Blend_Map_Entry(Agate_Entries[5], 1.0, FALSE, 0.6, 0.3, 0.0, 0.0, 0.0);
Make_Blend_Map_Entry(Radial_Entries[0], 0.0, FALSE, 0.0, 1.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Radial_Entries[1], 0.333, FALSE, 1.0, 1.0, 0.0, 0.0, 0.0);
Make_Blend_Map_Entry(Radial_Entries[2], 0.666, FALSE, 1.0, 0.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Radial_Entries[3], 1.0, FALSE, 0.0, 1.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Marble_Entries[0], 0.0, FALSE, 0.9, 0.8, 0.8, 0.0, 0.0);
Make_Blend_Map_Entry(Marble_Entries[1], 0.9, FALSE, 0.9, 0.08, 0.08, 0.0, 0.0);
Make_Blend_Map_Entry(Marble_Entries[2], 0.9, FALSE, 0.0, 0.0, 0.0, 0.0, 0.0);
Make_Blend_Map_Entry(Brick_Entries[0], 0.0, FALSE, 0.5, 0.5, 0.5, 0.0, 0.0);
Make_Blend_Map_Entry(Brick_Entries[1], 1.0, FALSE, 0.6, 0.15, 0.15, 0.0, 0.0);
Make_Blend_Map_Entry(Hex_Entries[0], 0.0, FALSE, 0.0, 0.0, 1.0, 0.0, 0.0);
Make_Blend_Map_Entry(Hex_Entries[1], 1.0, FALSE, 0.0, 1.0, 0.0, 0.0, 0.0);
Make_Blend_Map_Entry(Hex_Entries[2], 2.0, FALSE, 1.0, 0.0, 0.0, 0.0, 0.0);
}
#ifdef BlobPatternPatch
/*Chris Huff-blob pattern*/
static int blob_pigment(VECTOR TPoint, PIGMENT * Pigment, COLOUR Colour, INTERSECTION *Intersection)
{
COLOUR totalCol;
DBL totalStrength = 0;
DBL threshold = Pigment->Vals.Blob.blob_threshold;
DBL max_density = Pigment->Vals.Blob.max_density;
BLOB_PATTERN_DATA * currentComponent = Pigment->Vals.Blob.blob_dat;
if(currentComponent == NULL)
return 0;/*If the list of components is empty, don't do anything*/
totalCol[0] = 0;
totalCol[1] = 0;
totalCol[2] = 0;
while(currentComponent != NULL)
{
DBL temp = 0;
COLOUR tempColour;
if(currentComponent->type == 3)
{/*intercept "pigment" component, must be handled here*/
Compute_Pigment(tempColour, currentComponent->pigment, TPoint, Intersection);
if(currentComponent->inverse == TRUE)
temp = 1-(GREY_SCALE(tempColour));
else
temp = GREY_SCALE(tempColour);
temp *= currentComponent->strength*eval_density_func(temp, currentComponent->falloff, currentComponent->function);
totalStrength += temp;
}
else
{
temp = blob_comp_strength(TPoint, currentComponent);
totalStrength += temp;
Compute_Pigment(tempColour, currentComponent->pigment, TPoint, Intersection);
}
totalCol[0] += tempColour[0]*temp;
totalCol[1] += tempColour[1]*temp;
totalCol[2] += tempColour[2]*temp;
currentComponent = currentComponent->next;
}
if(totalStrength < threshold)
totalStrength = threshold;
if(totalStrength > max_density)
totalStrength = max_density;
totalCol[0] = totalCol[0]*(totalStrength - threshold)/(max_density-threshold);
totalCol[1] = totalCol[1]*(totalStrength - threshold)/(max_density-threshold);
totalCol[2] = totalCol[2]*(totalStrength - threshold)/(max_density-threshold);
Colour[0] = totalCol[0];
Colour[1] = totalCol[1];
Colour[2] = totalCol[2];
return 1;
}
#endif