⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtobject.cpp

📁 蒙特卡罗方法可以有效地解决复杂的工程问题
💻 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 + -