www.pudn.com > Ì廿֯Âë.rar > ray.cpp, change:2001-12-09,size:10165b
#include <stdlib.h>
#include <math.h>
#include "ray.h"
//---- abstract class Ray -------------------------------------------
Ray::Ray(Volume *vol, TransferFunction *tf)
{
m_volume = vol;
m_tf = tf;
m_usetf = false;
m_step_length = 1.0f;
}
Ray::~Ray()
{
}
void
Ray::UseTransFunc(bool use)
{
m_usetf = use;
}
void
Ray::UseHighlights(bool use)
{
m_usehighlights = use;
}
void
Ray::SetStepLength(float steplength)
{
m_step_length = steplength;
}
void
Ray::Cast(coord3 pos, coord3 dir, rgba &color)
{
}
//----- "First Hit" --------------------------------------------------------
void
RayFirstHitNN::SetThreshold(int threshold)
{
m_threshold = threshold;
}
void
RayFirstHitNN::Cast(coord3 pos, coord3 dir, rgba &color)
{
coord3 start;
coord3 end;
float dist;
if (m_volume->GetRayEnds(start, end, pos, dir, dist))
{
data_t data;
grad_t grad;
coord3 ndir;
coord3 pt = start;
vec_normalize(&ndir, &dir);
coord3 sdir;
vec_scale(&sdir, &ndir, m_step_length);
while (dist > 0)
{
if (m_volume->GetData(pt, data))
if (data > m_threshold)
{
m_volume->GetGradient(pt, grad);
double k = fabs(grad.x*ndir.x + grad.y*ndir.y + grad.z*ndir.z);
if (m_usetf) m_tf->GetColor(data, color); else white(color);
if (m_usehighlights)
{
double h = pow(k, 16);
int r = (int)(color.r * k + 255 * h);
int g = (int)(color.g * k + 255 * h);
int b = (int)(color.b * k + 255 * h);
if (r > 255) color.r = 255; else color.r = r;
if (g > 255) color.g = 255; else color.g = g;
if (b > 255) color.b = 255; else color.b = b;
color.a = 255;
}
else
{
color.r = (unsigned char)(color.r * k);
color.g = (unsigned char)(color.g * k);
color.b = (unsigned char)(color.b * k);
color.a = 255;
}
return;
}
dist -= m_step_length;
vec_add(&pt, &pt, &sdir);
}
}
anycolor(color, 0, 0, 100);
}
void
RayFirstHitTL::Cast(coord3 pos, coord3 dir, rgba &color)
{
coord3 start;
coord3 end;
float dist;
if (m_volume->GetRayEnds(start, end, pos, dir, dist))
{
data_t data;
data_t prevdata = -1;
grad_t grad;
coord3 ndir;
coord3 pt = start;
vec_normalize(&ndir, &dir);
coord3 sdir;
vec_scale(&sdir, &ndir, m_step_length);
while (dist > 0)
{
if (m_volume->GetDataTL(pt, data))
if (data > m_threshold)
{
if (prevdata > 0)
{
vec_scale(&sdir, &sdir, ((float)(m_threshold-data))/(data-prevdata));
vec_add(&pt, &pt, &sdir);
}
m_volume->GetGradientTL(pt, grad);
double k = fabs(grad.x*ndir.x + grad.y*ndir.y + grad.z*ndir.z);
if (m_usetf) m_tf->GetColor(data, color); else white(color);
if (m_usehighlights)
{
double h = pow(k, 16);
int r = (int)(color.r * k + 255 * h);
int g = (int)(color.g * k + 255 * h);
int b = (int)(color.b * k + 255 * h);
if (r > 255) color.r = 255; else color.r = r;
if (g > 255) color.g = 255; else color.g = g;
if (b > 255) color.b = 255; else color.b = b;
color.a = 255;
}
else
{
color.r = (unsigned char)(color.r * k);
color.g = (unsigned char)(color.g * k);
color.b = (unsigned char)(color.b * k);
color.a = 255;
}
return;
}
prevdata = data;
dist -= m_step_length;
vec_add(&pt, &pt, &sdir);
}
}
anycolor(color, 0, 0, 100);
}
//----- Max. Intensity --------------------------------------------------------
void
RayMaxIntensityNN::Cast(coord3 pos, coord3 dir, rgba &color)
{
coord3 start;
coord3 end;
float dist;
int max = 0;
if (m_volume->GetRayEnds(start, end, pos, dir, dist))
{
data_t data;
coord3 ndir;
coord3 pt = start;
vec_normalize(&ndir, &dir);
coord3 sdir;
vec_scale(&sdir, &ndir, m_step_length);
while (dist > 0)
{
if (m_volume->GetData(pt, data))
{
if (data > max) max = data;
}
dist -= m_step_length;
vec_add(&pt, &pt, &sdir);
}
if (m_usetf) m_tf->GetColor(max, color); else gray(color, max >> 4);
return;
}
anycolor(color, 0, 0, 100);
}
void
RayMaxIntensityTL::Cast(coord3 pos, coord3 dir, rgba &color)
{
coord3 start;
coord3 end;
float dist;
int max = 0;
if (m_volume->GetRayEnds(start, end, pos, dir, dist))
{
data_t data;
coord3 ndir;
coord3 pt = start;
vec_normalize(&ndir, &dir);
coord3 sdir;
vec_scale(&sdir, &ndir, m_step_length);
while (dist > 0)
{
if (m_volume->GetDataTL(pt, data))
{
if (data > max) max = data;
}
dist -= m_step_length;
vec_add(&pt, &pt, &sdir);
}
if (m_usetf) m_tf->GetColor(max, color); else gray(color, max >> 4);
return;
}
anycolor(color, 0, 0, 100);
}
//----- Transparency ----------------------------------------------------
void
RayTransparencyNN::SetTransFuncVolume(TransferFunctionVolume *tfv)
{
m_tfv = tfv;
}
void
RayTransparencyNN::Cast(coord3 pos, coord3 dir, rgba &color)
{
m_step_length = 1.0f;
coord3 start;
coord3 end;
float dist;
if (m_volume->GetRayEnds(start, end, pos, dir, dist))
{
data_t data;
grad_t grad;
float transparency;
rgba col;
coord3 ndir;
coord3 pt = start;
vec_normalize(&ndir, &dir);
coord3 sdir;
vec_scale(&sdir, &ndir, m_step_length);
float alpha = 1.0f;
float Ir = 0.0f;
float Ig = 0.0f;
float Ib = 0.0f;
float k, mul;
while ((dist > 0) && (alpha > TRANSPARENCYLIMIT))
{
if (m_volume->GetData(pt, data))
{
m_volume->GetGradient(pt, grad);
m_tf->GetTransparency(data, transparency);
if (m_usetf) m_tf->GetColor(data, col); else white(col);
k = (float)fabs(grad.x*ndir.x + grad.y*ndir.y + grad.z*ndir.z);
mul = alpha * (1.0f-transparency) * k;
if (m_usehighlights)
{
float i = (float)(255 * pow(k, 16));
Ir = Ir + (mul * (col.r + i));
Ig = Ig + (mul * (col.g + i));
Ib = Ib + (mul * (col.b + i));
}
else
{
Ir = Ir + (mul * col.r);
Ig = Ig + (mul * col.g);
Ib = Ib + (mul * col.b);
}
alpha = alpha * transparency;
}
dist -= m_step_length;
vec_add(&pt, &pt, &sdir);
}
if (alpha > TRANSPARENCYLIMIT)
{
rgba bcol;
m_tf->GetBackgroundColor(bcol);
Ir = Ir + (alpha * bcol.r);
Ig = Ig + (alpha * bcol.g);
Ib = Ib + (alpha * bcol.b);
}
if (Ir > 255) Ir = 255;
if (Ig > 255) Ig = 255;
if (Ib > 255) Ib = 255;
color.r = (unsigned char)(Ir);
color.g = (unsigned char)(Ig);
color.b = (unsigned char)(Ib);
color.a = 255;
return;
}
m_tf->GetBackgroundColor(color);
}
void
RayTransparencyTL::Cast(coord3 pos, coord3 dir, rgba &color)
{
m_step_length = 1.0f;
coord3 start;
coord3 end;
float dist;
if (m_volume->GetRayEnds(start, end, pos, dir, dist))
{
data_t data;
grad_t grad;
float transparency;
rgba col;
coord3 ndir;
coord3 pt = start;
vec_normalize(&ndir, &dir);
coord3 sdir;
vec_scale(&sdir, &ndir, m_step_length);
float alpha = 1.0f;
float Ir = 0.0f;
float Ig = 0.0f;
float Ib = 0.0f;
float k, mul;
while ((dist > 0) && (alpha > TRANSPARENCYLIMIT))
{
if (m_volume->GetDataTL(pt, data))
{
m_volume->GetGradientTL(pt, grad);
m_tfv->GetTransparencyTL(pt, transparency);
if (m_usetf) m_tfv->GetColor(pt, col); else white(col);
k = (float)fabs(grad.x*ndir.x + grad.y*ndir.y + grad.z*ndir.z);
mul = alpha * (1.0f-transparency) * k;
if (m_usehighlights)
{
float i = (float)(255 * pow(k, 16));
Ir = Ir + (mul * (col.r + i));
Ig = Ig + (mul * (col.g + i));
Ib = Ib + (mul * (col.b + i));
}
else
{
Ir = Ir + (mul * col.r);
Ig = Ig + (mul * col.g);
Ib = Ib + (mul * col.b);
}
alpha = alpha * transparency;
}
dist -= m_step_length;
vec_add(&pt, &pt, &sdir);
}
if (alpha > TRANSPARENCYLIMIT)
{
rgba bcol;
m_tf->GetBackgroundColor(bcol);
Ir = Ir + (alpha * bcol.r);
Ig = Ig + (alpha * bcol.g);
Ib = Ib + (alpha * bcol.b);
}
if (Ir > 255) Ir = 255;
if (Ig > 255) Ig = 255;
if (Ib > 255) Ib = 255;
color.r = (unsigned char)(Ir);
color.g = (unsigned char)(Ig);
color.b = (unsigned char)(Ib);
color.a = 255;
return;
}
m_tf->GetBackgroundColor(color);
}