//------------------------------------------------------------
// $Id: triangleObject.h,v 1.2 2000/05/21 18:43:03 yamauchi Exp $
//------------------------------------------------------------
//	triangle object 
//	1996/3/18 
//	(C) Copyright Hitoshi Yamauchi
//	三角形のポリゴン
//------------------------------------------------------------
#ifndef _triangleObject_h
#define _triangleObject_h 1

#include <assert.h>
#include "Vector3.h"
#include "ray.h"
#include "object.h"

class triangleObjectClass : public objBaseClass {
protected:
    Vector3 	mVertex[3];	// 頂点
    
    // geometry info. (must be calculated)
    Vector3     mEdge[3];       // エッジのベクトル(正規化しない)
    Vector3     mNrm;           // パッチ法線ベクトル
    Vector3     mEdgeNrm[3];    // エッジから内部を見るベクトル
    double      mPlaneConst;    // 平面の定数
    double      mEdgeConst[3];	// パッチに垂直なエッジの平面定数
    double      mArea;          // パッチ面積
    
    // radiosity value
    Vector3     mRadiosity;     // ラジオシティ値
    Vector3     mNonRad;        // 未放射ラジオシティ値    

    // for lock (in radiation queue or not)
    YorN 	mIsInRadiationQ;

    // for shading 
    Vector3	mIntensity[3]; // 各頂点の輝度
    int		mAddedIntensityNum[3]; // 輝度を足した数

protected:
    double  getPlaneConstant(void) const{ return(this->mPlaneConst);	}
    Vector3 getEdgeNormal(int i) const 	{ return(this->mEdgeNrm[i]);	}
    double  getEdgeConstant(int i) const{ return(this->mEdgeConst[i]);	}
    void calcGeometoryInfo(void);
    
public:
    triangleObjectClass(void);
    triangleObjectClass(int objectNumber,  	int materialID,
			const Vector3& v1,	const Vector3& v2,
			const Vector3& v3, 	const Vector3& spcpos,
			const Vector3& nonRad);
    triangleObjectClass(const triangleObjectClass& rhs);    
    const triangleObjectClass operator=(const triangleObjectClass& rhs);
    
    //----- radiosity
    // rad には既にフォームファクタが掛かっている
    virtual void   addUnshotRadiosity(const Vector3& rad); 
    // 計算終了時に radiosity 値を update する (その時に未放射のエネルギを返す)
    virtual double flushUnshotRadiosityNInitVerInt(void);
    virtual double getNonRadEnergy(void) const;

    // radiation queue に何度も入れないように(lock & unlock)
    virtual void setInRadiationQueue(void) 
    {	
	assert(this->mIsInRadiationQ == NO);
	this->mIsInRadiationQ = YES; // lock
    }
    virtual void unsetInRadiationQueue(void)
    {
	assert(this->mIsInRadiationQ == YES);
	this->mIsInRadiationQ = NO; // unlock
    }
    virtual YorN isInRadiationQueue(void)const{ return(this->mIsInRadiationQ);}
    virtual double getArea(void) const	      { return(this->mArea);     }
    virtual const Vector3 getGCenter(void) const; // { return(this->mGpos); }
    virtual const Vector3 getNClearNonRadAndUpdateRadiosity(void);
    // virtual const Vector3 getNonRad(void)  { return(this->mNonRad);	}
    virtual void  calcVerIntAveVal(void);
    
    //-----
    // 物体までの距離(if ret PlusInfty =  not hit)
    virtual double getDistance(const Ray *const apRay, Vector3 *pHitPos);
    // friend ostream& operator<<(ostream& s, const triangleObjectClass& rhs); 
    virtual Vector3 getNormal(void) const { return(this->mNrm);	    }
    virtual Vector3 getNormal(const Vector3& hitpos) const 
    {
	return(this->mNrm);	    cerr << hitpos << endl;	// for Wall
    }
    virtual void addIntensityToVertex(const VertexIntensity& vint);
    
    virtual void  getRadVer(VertexIntensity *pRadiosityVertexInfo3);
    virtual void  getVerIntensity(VertexIntensity *pIntensityVertexInfo3);
    // get*RadiosityColor() in calcRayTrIC
    virtual Vector3 getFlatRadiosityColor(const Vector3& hitPos);
    virtual Vector3 getShadedRadiosityColor(const Vector3& hitPos); 
    
    virtual void print(const char *pHead);
    virtual void getMpi2Form(int outputType, char *pRes);
    virtual int  who(void) const;
    virtual YorN checkSpcPos(const Vector3 &partmin, 
			     const Vector3 &subSpcSize, 
			     int subdivnum) const;
   

//------------------------------
// for 2 dimension output 
#ifdef FOR_2DIM_OUT
    virtual int  get2dimPoiNumbers(void) const;
    virtual void get2dimPoint(int idx, double *x, double *y, double *z);
#endif
//------------------------------
};

#endif				// #ifndef _triangleObject_h 
