home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: Graphics
/
Graphics.zip
/
povsrc31.zip
/
glow.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-01-06
|
8KB
|
356 lines
/****************************************************************************
* glow.c
*
* This module contains functions for the glow feature.
*
*****************************************************************************/
#include "frame.h"
#ifdef GlowPatch
#include "povray.h"
#include "vector.h"
#include "matrices.h"
#include "povproto.h"
#include "colour.h"
#include "express.h"
#include "pigment.h"
#include "warps.h"
#include "glow.h"
#include "parse.h"
#include "parstxtr.h"
#include "tokenize.h"
#include "texture.h"
/*****************************************************************************
* Local preprocessor defines
******************************************************************************/
/*****************************************************************************
* Local typedefs
******************************************************************************/
/*****************************************************************************
* Static functions
******************************************************************************/
static void Compute_Glow(GLOW * Glow, INTERSECTION * Isect, RAY * Ray, COLOUR Colour);
/*****************************************************************************
* Local variables
******************************************************************************/
/*****************************************************************************
*
* FUNCTION Create_Glow()
*
*
*
* INPUT
*
* OUTPUT
*
* RETURNS pointer to a GLOW struct
*
* AUTHOR
*
* Chris Huff
*
* DESCRIPTION
*
* Creates and initializes a glow.
*
* CHANGES
*
* 2000.9.02: Creation.
*
******************************************************************************/
GLOW * Create_Glow()
{
GLOW * New = (GLOW *)POV_MALLOC(sizeof(GLOW), "glow");
Make_Vector(New->Center, 0, 0, 0);
Make_Colour(New->Colour, 1, 1, 1);
New->Glow_Type = 1;
New->Size = 1;
New->Cutoff_Radius = 0;
New->fade_pow = 1;
New->Warps = NULL;
New->next = NULL;
return New;
}
/*****************************************************************************
*
* FUNCTION Add_Glow()
*
*
*
* INPUT
*
* OUTPUT
*
* RETURNS
*
* AUTHOR
*
* Chris Huff
*
* DESCRIPTION
*
* Adds a glow to the list in Frame.
*
* CHANGES
*
* 2000.9.02: Creation.
*
******************************************************************************/
void Add_Glow(GLOW * Glow)
{
Glow->next = Frame.Glows;
Frame.Glows = Glow;
/* GLOW_PTR * newGlowList = NULL;
if(Frame.NumOfGlows == 0)
{
Frame.Glows = POV_MALLOC(sizeof(GLOW_PTR), "glow pointer array");
Frame.Glows[0] = Glow;
}
else
{
Frame.Glows = POV_REALLOC(Frame.Glows, (Frame.NumOfGlows+2)*sizeof(GLOW_PTR), "glow pointer array");
*//* newGlowList = POV_MALLOC((Frame.NumOfGlows+2)*sizeof(GLOW_PTR), "glow pointer array");
memcpy(newGlowList, Frame.Glows, (Frame.NumOfGlows+1)*sizeof(GLOW_PTR));
POV_FREE(Frame.Glows);
Frame.Glows = newGlowList;*//*
Frame.Glows[Frame.NumOfGlows] = Glow;
}*/
Frame.NumOfGlows++;
}
/*****************************************************************************
*
* FUNCTION Destroy_Glow()
*
*
*
* INPUT
*
* OUTPUT
*
* RETURNS
*
* AUTHOR
*
* Chris Huff
*
* DESCRIPTION
*
* Destroys a glow.
*
* CHANGES
*
* 2000.9.02: Creation.
*
******************************************************************************/
void Destroy_Glow(GLOW * Glow)
{
if(Glow->Warps != NULL)
{
Destroy_TPat_Fields(Glow->Warps);
POV_FREE(Glow->Warps);
}
POV_FREE(Glow);
}
/*****************************************************************************
*
* FUNCTION Destroy_Glow_List()
*
*
*
* INPUT
*
* OUTPUT
*
* RETURNS
*
* AUTHOR
*
* Chris Huff
*
* DESCRIPTION
*
* Destroys a list of glows.
*
* CHANGES
*
* 2000.9.02: Creation.
*
******************************************************************************/
void Destroy_Glow_List(GLOW * Glow_List)
{
GLOW * Glow = Glow_List;
GLOW * Next_Glow = NULL;
while(Glow != NULL)
{
Next_Glow = Glow->next;
Destroy_Glow(Glow);
Glow = Next_Glow;
}
/* unsigned int j;
for(j=0; j<Frame.NumOfGlows; j++)
{
Destroy_Glow(Frame.Glows[j]);
Frame.Glows[j] = NULL;
POV_FREE(Frame.Glows);
}*/
}
/*****************************************************************************
*
* FUNCTION Do_Glow()
*
*
*
* INPUT
*
* OUTPUT
*
* RETURNS
*
* AUTHOR
*
* Chris Huff
*
* DESCRIPTION
*
* Calculates effect of a single glow.
*
* CHANGES
*
* 2000.9.02: Creation.
*
******************************************************************************/
static void Compute_Glow(GLOW * Glow, INTERSECTION * Isect, RAY * Ray, COLOUR Colour)
{
VECTOR Pt;/*Point on plane perpendicular to ray and passing through glow*/
VECTOR lightDir;/*direction of glow source*/
COLOUR scattered_light;
DBL Depth = Isect->Depth;/*Distance to intersection*/
DBL scattering = 0;
DBL cosA;/*cosine of the angle between the ray and the direction of the glow source*/
DBL Dist;
/* cosA Computing */
VSub(lightDir, Ray->Initial, Glow->Center);
VDot(cosA, lightDir, Ray->Direction);
/* d0 Computing */
VScale(Pt, Ray->Direction, -cosA);
VAddEq(Pt, Ray->Initial);
if(Glow->Warps != NULL)
Warp_EPoint(Pt, Pt, Glow->Warps, FALSE);
VSubEq(Pt, Glow->Center);
VLength(Dist, Pt);
if(Glow->Cutoff_Radius == 0 || Dist < Glow->Cutoff_Radius)
{
/* scattered energy integration along ray */
switch(Glow->Glow_Type)
{
case 0:/* A model, I(d) = 1/d^2 */
Dist /= Glow->Size;
scattering = (atan((Depth+cosA)/Dist) - atan(cosA/Dist))/Dist;
/* scattering *= Glow->Size;*/
break;
case 1:/* B model, I(d) = 1/(d^2+1) */
{
DBL d0;
DBL denom = 1;
VDot(d0, Pt, Pt);
denom = sqrt(d0 + 1)/Glow->Size;
if(Depth >= Max_Distance) /* Optimization */
scattering = (M_PI_2 - atan(cosA/denom))/denom;
else
scattering = (atan((Depth+cosA)/denom) - atan(cosA/denom))/denom;
/* scattering *= Glow->Size;*/
}
break;
case 2:/*exp() falloff*/
if(cosA < 0)
scattering = exp(-Dist/Glow->Size);
/* scattered_intensity = exp(-Dist/(Glow->Size+Depth/Glow->Size));*/
break;
case 3:/*Cosine falloff*/
{
DBL d = Dist/Glow->Size;
if(d < 1 && cosA < 0)
scattering = sin(max(0, 1-d)*M_PI_2);
}
break;
}
if(Glow->fade_pow != 1)
{
if(Glow->fade_pow == 2)
scattering *= scattering;
else
scattering = pow(scattering, Glow->fade_pow);
}
Scale_Colour(scattered_light, Glow->Colour, scattering);
Add_Colour(Colour, Colour, scattered_light);
}
}
/*****************************************************************************
*
* FUNCTION Do_Glow()
*
*
*
* INPUT
*
* OUTPUT
*
* RETURNS
*
* AUTHOR
*
* Chris Huff
*
* DESCRIPTION
*
* Calculates glow effect.
*
* CHANGES
*
* 2000.9.02: Creation.
*
******************************************************************************/
void Do_Glow(INTERSECTION * Isect, RAY * Ray, COLOUR Colour)
{
GLOW * Glow = Frame.Glows;
while(Glow != NULL)
{
Compute_Glow(Glow, Isect, Ray, Colour);
Glow = Glow->next;
}
/* unsigned int j;
for(j=0; j<Frame.NumOfGlows; j++) {;}*/
// Compute_Glow(Frame.Glows[j], Isect, Ray, Colour);
}
void Transform_Glow(GLOW * Glow, TRANSFORM * Trans)
{
MTransPoint(Glow->Center, Glow->Center, Trans);
}
#endif