//------------------------------------------------------------
// $Id: calcRayTrSRGDist.cc,v 1.2 2000/05/15 14:20:43 yamauchi Exp $
//------------------------------------------------------------
//	calcRayTrSRGDist.cc
//	calculation of Secondary Ray Generation unit for 
//	distributed ray-tracing
//	1999/3/23
//	(C) 1998-1999 Copyright TOKUNAGA Mayumi  徳永 真由美
//	(C) 1998-1999 Copyright	YAMAUCHI Hitoshi 山内 斉
//------------------------------------------------------------
#include "calcRayTrSRGgetdir.h"

//----------------------------------------------------
// 2nd Ray を複数に散らす方法
//	Tokunaga and YAMAUCHI
//----------------------------------------------------
YorN PEClass::
secondRayGenWithDistrbute(Ray *pRay, const materialClass *pMat, 
			  objBaseClass * pHitObj)
{
    YorN isGenerateRay = NO;	// レイは発生するか? 
    
    // この ray は反射・屈折回数を越えているか
    if(pRay->getReflectedNum() >= this->mViewData.getMaxRayRefNum())
    {				// 越えている。ray は発生しない。
	return(isGenerateRay);
    }
    
    //------------------------------------------------------------
    // 反射二次レイを new し、PE の処理キューへ登録
    //------------------------------------------------------------
    Vector3 reflectRayDir, reflectRayCoeff;
    YorN isGenReflectRay = 
	getReflectionRayDirRayTrace(pRay, pMat, 
				    this->mViewData.getMinRayRefCoeffNorm(),
				    pHitObj, 
				    &reflectRayDir,
				    &reflectRayCoeff);
    if(isGenReflectRay == YES)	// ray の発生は可能．輝度を託す．
    {
	this->mFrustum.setTopAngleRadandRotate(pMat->getFrustumHalfTopRad(), 
					       pMat->getSpecTransCosN(),
					       reflectRayDir);
	for(int i = 0; i < this->mFrustum.getTotalSampleNum(); i++)
	{
	    Vector3 nextDir = this->mFrustum.getSamplePixelPos(i);
	    nextDir.VNormalize();
	    Vector3 newCoeff = reflectRayCoeff * this->mFrustum.getWeight(i);
	    Ray *pNewRay = 
		Ray::newForReflectionRayTracing(pRay, 	  nextDir, 
						newCoeff, pHitObj);
	    Vector3 newColor = pRay->getColor() * this->mFrustum.getWeight(i);
	    pNewRay->setColor(newColor);

	    this->setRayPtrToThisPE(pNewRay);		   
	}
	isGenerateRay = YES;
	// 反射レイ生成を数えるのならばここ Hint TOKUNAGA
    }
    
    //------------------------------------------------------------
    // 透過二次レイを new し、PE の処理キューへ登録
    //------------------------------------------------------------
    Vector3 refractedRayDir, refractedRayCoeff;
    YorN isGenRefractedRay = 
	getRefractionRayDirRayTrace(pRay, pMat, 
				    this->mViewData.getMinRayRefCoeffNorm(),
				    pHitObj, 
				    &refractedRayDir, 
				    &refractedRayCoeff);
    
    if(isGenRefractedRay == YES)
    {
	this->mFrustum.setTopAngleRadandRotate(pMat->getFrustumHalfTopRad(), 
					       pMat->getSpecTransCosN(),
					       reflectRayDir);

	for(int i = 0; i < this->mFrustum.getTotalSampleNum(); i++)
	{
	    Vector3 nextDir = this->mFrustum.getSamplePixelPos(i);
	    nextDir.VNormalize();
	    Vector3 newRefractCoeff = 
		pRay->getRefCoeff() * this->mFrustum.getWeight(i);
	    Ray *pNewRay = 
		Ray::newForReflectionRayTracing(pRay, nextDir, 
						newRefractCoeff, pHitObj);

	    // ray を発生した。既に輝度は託されているのか?
	    if(isGenerateRay == NO)
	    {			// 託されていない。輝度を託す
		Vector3 newRefractColor = 
		    pRay->getColor() * this->mFrustum.getWeight(i);
		pNewRay->setColor(newRefractColor);
	    }
	    this->setRayPtrToThisPE(pNewRay);
	}
	isGenerateRay = YES;
	// 屈折レイ生成を数えるのならばここ Hint TOKUNAGA
    }
    return(isGenerateRay);
}
