📄 rtobject.cpp
字号:
// RTObject.cpp: implementation of the CRTObject class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RayTrace.h"
#include "RTObject.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//构造函数,初始化数据成员
CRTObject::CRTObject()
:
vecReflectDir ( 0,0,0 ),
vecRefractDir ( 0,0,0 )
{
nObjectIndex = 0;
Material = NULL;
Texture = NULL;
HitRay = NULL;
nObjectIndex = 0;
}
//析构函数
CRTObject::~CRTObject()
{
nObjectIndex = 0;
Material = NULL;
Texture = NULL;
HitRay = NULL;
}
//清空反射、透射光线及交点
void CRTObject::Empty()
{
vecReflectDir.Empty();
vecRefractDir.Empty();
IntersectPoint.Empty();
}
/*************************************************************************
*
* 函数名称:
* CRTObject::GetReflectDir()
*
* 参数:
* 无
*
* 返回值:
* CVector - 返回反射光线
*
* 说明:
* 入射光线: 成员变量HitRay,
* 法向量: 成员函数GetNormalVec()计算,
* 归一化后赋于成员变量vecReflectDir,并作为返回值返回
*
************************************************************************/
CVector CRTObject::GetReflectDir()
{
CVector L = HitRay->Direction; //入射光线
CVector N = GetNormalVec(); //法向量
vecReflectDir = L + N * ( 2* (N*L) ); //计算反射光线
vecReflectDir.Normalize(); //归一化
return vecReflectDir;
}
/*************************************************************************
*
* 函数名称:
* CRTObject::CalculateRefractDir()
*
* 参数:
* 无
*
* 返回值:
* 无
*
* 说明:
* 计算折射光线.
* 入射光线: 成员变量HitRay,
* 法向量: 成员函数GetNormalVec()计算,
* 归一化后赋于成员变量vecRefractDir
*
************************************************************************/
void CRTObject::CalculateRefractDir()
{
CVector L = HitRay->Direction; //入射光线
CVector N = GetNormalVec(); //法向量
double cos1 = L*(-1.0) * N;
double para; // para = 1/η ;
if( cos1 > 0 )
para = 1.0 / Material->dRefraction;
else
para = Material->dRefraction;
CVector Temp ( ( N*cos1 - L ) * para );
double TempMult = Temp * Temp;
if( TempMult >= 1.0 )
vecRefractDir.Empty();
else
{
double SQRT = sqrt( 1.0 - TempMult );
if( cos1 < 0 )
SQRT = -SQRT;
vecRefractDir = Temp - N*SQRT;
}
}
/*************************************************************************
*
* 函数名称:
* CRTObject::GetRefractDir()
*
* 参数:
* 无
*
* 返回值:
* CVector - 返回折射射光线
*
* 说明:
* 入射光线: 成员变量HitRay,
* 法向量: 成员函数GetNormalVec()计算,
* 归一化后赋于成员变量vecReflectDir,并作为返回值返回
*
************************************************************************/
CVector CRTObject::GetRefractDir()
{
CalculateRefractDir();
CRay TransRay(IntersectPoint,vecRefractDir);
InitHitRay( &TransRay );
Intersect();
CalculateRefractDir();
return vecRefractDir;
}
/*************************************************************************
*
* 函数名称:
* CRTObject::GetLocalColor()
*
* 参数:
* CRTList &LightList - 光源链表
* CRTList &ObjectList - 景物链表
*
* 返回值:
* CVector - 返回交点的颜色值
*
* 说明:
* 用整体光照明模型计算交点处的局部光亮度,并返回其值
* 其中包含了阴影测试
*
************************************************************************/
CVector CRTObject::GetLocalColor(CRTList &LightList, CRTList &ObjectList)
{
CVector LocalIntens;
CVector LocalColor;
CVector Addition;
CVector LightDir;
int LightNumber = LightList.GetNodeNum();
int ObjectNumber = ObjectList.GetNodeNum();
CRTObject *pObj = NULL;
CLight *pLight = NULL;
CVector N;
double alpha;
int i,j;
BOOL bBeshaded;
//环境光强
LocalIntens = Material->vecAmbient;
for( i = 1; i <= LightNumber; i++ )
{
//得到交点到光源的方向向量LightRay
pLight = (CLight*)LightList.GetNode( i );
LightDir = pLight->GetLocation();
LightDir -= IntersectPoint;
double dist = LightDir.GetLength();
LightDir.Normalize();
CRay LightRay(IntersectPoint,LightDir);
if( pLight->IsInArea(IntersectPoint) )
{
bBeshaded = FALSE; //遮挡标志
for( j = 1; j <= ObjectNumber; j++ )
{
if( j != nObjectIndex ) //排除与本身比较
{
pObj = (CRTObject*)ObjectList.GetNode( j );
pObj->InitHitRay( &LightRay );
double d = pObj->Intersect();
if( d > 0.0 && d < dist ) //有景物遮挡当前物体
{
if( pObj->GetMaterial()->bTransparency ) //折射
{
N = pObj->GetNormalVec();
alpha = 0.2 * fabs( LightDir*N ) + 0.2;//the first prameter may be more than 0.2
Addition = pLight->GetIntensity();
Addition *= alpha;
Addition.ElemMult(pObj->GetMaterial()->vecTransmission);
LocalIntens += Addition;
}
else
{
bBeshaded = TRUE; //置遮挡标志
}
}
pObj->InitHitRay(NULL);
}
}
if(!bBeshaded) //未被遮挡
{
N = GetNormalVec();
LocalIntens += UnshadowedPoint( LightDir, N, pLight ) ;
}
}
}
if( Texture ) //纹理影响
{
LocalColor = Mapping();
LocalColor.ElemMult( LocalIntens );
}
else
LocalColor = LocalIntens;
return LocalColor;
}
/*************************************************************************
*
* 函数名称:
* CRTObject::UnshadowedPoint()
*
* 参数:
* CVector LightDir - 光源光线方向
* CVector N - 法向量
* CLight *Light - 光源指针
*
* 返回值:
* CVector - 返回交点的颜色值
*
* 说明:
* 入射光线: 成员变量LightDir,
* 法向量: N,
* 计算给定条件下的点的光亮度,并作为返回值返回
*
************************************************************************/
CVector CRTObject::UnshadowedPoint(CVector LightDir, CVector N, CLight *Light)
{
double NdotD = LightDir * N;
CVector Diff,Spec;
if( NdotD <= 0.0 ) //光源位于景物后面
{
if( !Material->bTransparency )
{
Diff.Empty();
Spec.Empty();
}
else
{
//漫反射
Diff = Material->vecDiffuse;
Diff *= fabs( NdotD );
Diff.ElemMult( Light->GetIntensity() );
}
}
else
{
//漫反射
Diff = Material->vecDiffuse;
Diff *= NdotD;
Diff.ElemMult( Light->GetIntensity() );
//镜面反射
CVector Temp = LightDir;
Temp -= HitRay->Direction;
Temp *= 0.5;
Temp.Normalize();
double cone = Temp * N;
if( cone > 0.5 )
{
double Glint = exp( Material->dGloss * log( cone ) );
Spec = Material->vecSpecular;
Spec *= Glint;
Spec.ElemMult( Light->GetIntensity() );
}
else
Spec.Empty();
}
return Diff + Spec;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -