`
daojin
  • 浏览: 675574 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

把空间中的三角形组织为二叉树的代码!~(能跑,很慢!所有的数据都是现算的(包括n多矩阵乘法)!)

阅读更多
#include "stdafx.h"
#include "OpenGL.h"
#include "Map.h"
#include "math.h"
#include "ArrayInterTriangle.h"
#include <iostream.h>
#include <stdio.h>
#include <bitset>
extern 	unsigned int m_ID;
#include <math.h>
#include<stdexcept>
#include<time.h>
extern bool	Lbutdown;	// 鼠标左键
extern bool	Rbutdown;	// 鼠标左键
//////////////////////////////////////////////////////////////////////
extern HWND	hWnd;
//定义最近的距离视点最近的鼠标物体:
//定义一个结构来保存所有的物体:
#include<list>
int TreeDepth=0;
#include<vector>
using std::bitset;
using std::list;
using std::vector;
using std::runtime_error;
using std::length_error;
class Triangle{
public:
	Triangle(){
		for(int i=0;i<3;i++)
		{
		a[i]=0;
		b[i]=0;
		c[i]=0;
		}
	}
	Triangle(const Triangle& tri)
	{
		for(int i=0;i<3;i++)
		{
		   this->a[i]=tri.a[i];
		   this->b[i]=tri.b[i];
		   this->c[i]=tri.c[i];
		}
	}
   Triangle& operator =(const Triangle & tri){
	    for(int i=0;i<3;i++)
		{
		   this->a[i]=tri.a[i];
		   this->b[i]=tri.b[i];
		   this->c[i]=tri.c[i];
		} 
		return *this;
	}
    float a[3];
	float b[3];
	float c[3];
};
class TheTreeObect{
	int maxlen;
	int currentFlip;
	Triangle *Triangles;
public:
	static int gouzaoshu;
   	int n;
	~TheTreeObect(){
		delete [] this->Triangles;
	}
	void SetAsNode(const Triangle &currentFlip){  
		 delete [] Triangles;
		 Triangles=new Triangle[1];
		 Triangles[0]=currentFlip;
		 n=1;
		 maxlen=1;
	}
	void resetTriangle(Triangle *pTri,int n1){
		if(n1>maxlen)
		{
			delete[] this->Triangles;
			Triangles=new Triangle[n1+10];
			this->maxlen=n1+10;
		}
		for(int i=0;i<n1;i++){     
			this->Triangles[i]=pTri[i];
		}
		this->n=n1;	
	}
	TheTreeObect(const TheTreeObect &obj):n(obj.n),maxlen(obj.maxlen)
	{
		Triangles=new Triangle[maxlen];
		for(int i=0;i<n;i++)
		{
		 Triangles[i]=obj.Triangles[i];
		}
	}
	TheTreeObect & operator=(const TheTreeObect & obj)
	{	
		if(obj.n>maxlen){
		  delete [] Triangles;
		  Triangles=new Triangle[obj.maxlen];
		  this->maxlen=obj.maxlen;
		}
		for(int m=0;m<obj.n;m++){
			Triangles[m]=obj.getTriangles()[m];
		}
		this->n=obj.n;
		return *this;
	}
	TheTreeObect(){
		this->Triangles= new Triangle[10];
		this->maxlen=10;
		n=0;
	}
    int add(Triangle triangle)
	{	  	
	      if(n==maxlen){
			maxlen=n+10;
			Triangle* temp=Triangles;
			Triangles=new Triangle[n+10];		
			for(int i=0;i<n;i++){
			  Triangles[i]=temp[i];
			}
			delete [] temp;
			temp=NULL;
		  }
		  Triangles[n++]=triangle;		  
		  return n;
	}
	int getN() const{
	return n;
	}
	Triangle *getTriangles ()const
	{
	  return Triangles;
	}
	void outPutSanjiao(Triangle triangle) const
	{
	             float *a=triangle.a;
				 float a0=a[0];
				 float a1=a[1];
				 float a2=a[2];
				 cout<<endl<<a0<<"  "<<a1<<"  "<<a2<<"  "<<endl;
				 float *b=triangle.b;
				 float b0=b[0];
				 float b1=b[1];
				 float b2=b[2];
				 cout<<b0<<"  "<<b1<<"  "<<b2<<"  "<<endl;
				 float *c=triangle.c;
				 float c0=c[0];
				 float c1=c[1];
				 float c2=c[2];
				 cout<<c0<<"  "<<c1<<"  "<<c2<<"  "<<endl;
	}
	void outPut() const
	{
	        for(int i=0;i<n;i++)
			{
			      outPutSanjiao(Triangles[i]);   
			}
	}
    TheTreeObect(float (*triangle)[3][3],int n1)
	{
		//cout<<"TheTreeObect(float (*triangle)[3][3],int n1) ///begin"<<endl;
		Triangles= new Triangle[n1+10];
		this->maxlen=n1+10;
		this->n=n1;
		for(int i=0;i<n;i++){
			for(int j=0;j<3;j++){
		      Triangles[i].a[j]=triangle[i][0][j];
			  Triangles[i].b[j]=triangle[i][1][j];
			  Triangles[i].c[j]=triangle[i][2][j];
			}			  
		}
	//	cout<<"TheTreeObect(float (*triangle)[3][3],int n1) ///end"<<endl;
	}
};
int TheTreeObect::gouzaoshu=0;
int NodeGouZaoShu;
//而叉树节点是一个特殊的物体。。它只有一个平面。
class BSPNode:public TheTreeObect{
public:
	virtual ~BSPNode(){
		NodeGouZaoShu--;
		delete pBackChild;
		delete pFrontChild;
	}
    BSPNode():TheTreeObect(){
	   NodeGouZaoShu++;
	   IsLeaf=true;
	   pBackChild=NULL;
       pFrontChild=NULL;
	   n=0;
	}
	bool IsLeaf;
	BSPNode(const TheTreeObect& obj):TheTreeObect(obj){
		NodeGouZaoShu++;
		pBackChild=NULL;
        pFrontChild=NULL;
		IsLeaf=true;
	}
    BSPNode* pBackChild;
	BSPNode* pFrontChild;
	//查看物体的第index个三角形是否与既定面共面。
    void outPutSanjiao(Triangle triangle) const
	{
	             float *a=triangle.a;
				 float a0=a[0];
				 float a1=a[1];
				 float a2=a[2];
				 cout<<endl<<a0<<"  "<<a1<<"  "<<a2<<"  "<<"|";
				 float *b=triangle.b;
				 float b0=b[0];
				 float b1=b[1];
				 float b2=b[2];
				 cout<<b0<<"  "<<b1<<"  "<<b2<<"  "<<"|";
				 float *c=triangle.c;
				 float c0=c[0];
				 float c1=c[1];
				 float c2=c[2];
				 cout<<c0<<"  "<<c1<<"  "<<c2<<"  "<<endl;
	}
	void outPutSanJiaos(Triangle* pTriangle,int n) const
	{
	        for(int i=0;i<n;i++)
			{
			      outPutSanjiao(pTriangle[i]);   
			}
	}
	void outPutVector(char *p,float *pf,int n) const
	{
		   for(int j=0;p[j]!='\0';p++)
		   {
			cout<<p[j];
		   }
		    cout<<":"<<endl;
	       for(int i=0;i<n;i++)
			{
			 cout<<pf[i]<<endl;
			}   
	}
	bool IsFomFront(Triangle sanjiao,Triangle flipflat,bool &same,bool &divied){
        divied=false;
		same=false;
		bitset<3> position[3];
		float dir[3];
		bool Front[3];
		bool IsNotInFlat[3];
	    float point[3];
		memcpy(point,sanjiao.a,3*sizeof(float));
		//int currentFlip=getFlip();
		VectBinus(flipflat.a,point,dir);
		IsNotInFlat[0]=IsIntersectWithTriangle(
			point,
			dir,
			flipflat.a,
			flipflat.b,
			flipflat.c,
			point,
			Front[0]
			);
        memcpy(point,sanjiao.b,3*sizeof(float));
		VectBinus(flipflat.b,point,dir);
		IsNotInFlat[1]=IsIntersectWithTriangle(
			point,
			dir,
			flipflat.a,
			flipflat.b,
			flipflat.c,
			point,
			Front[1]
			);
        memcpy(point,sanjiao.c,3*sizeof(float));
		VectBinus(flipflat.c,point,dir);
		IsNotInFlat[2]=IsIntersectWithTriangle(
			point,
			dir,
			flipflat.a,
			flipflat.b,
			flipflat.c,
			point,
			Front[2]
			);
        for(int i=0;i<3;i++)
		{
		    if(!IsNotInFlat[i])position[i].set(0);else
				if(Front[i])position[i].set(1);else
					position[i].set(2);
		}
		//每个点的三个状态对应为 position[0],position[1],position[2];
		bitset<3> positi=position[0]&position[1]&position[2];
		if(positi[0])
		{ 
			same=true;
			//查看方向是否相同
            //求得他们的发线:
           float flat_3_flip[3];
		   float flat_3_temp[3];
            qiuFaXiangLiang(
				flipflat.a,
				flipflat.b,
				flipflat.c,
				flat_3_flip);
			 qiuFaXiangLiang(
				sanjiao.a,
				sanjiao.b,
				sanjiao.c,
				flat_3_temp);
			 float dotval=DotProduct(flat_3_flip,flat_3_temp);
			 if(dotval<0){
				 //点积为负值
			    return false;
			 }else
				 //点积为正值
				 return true;
		}else {
			positi=position[0]|position[1]|position[2];
				//不共面并且没有在后面的点!!
			if(!positi[2])
			{
				return true;
			}
				//不共面没有前面的点
			else if(!positi[1])
			{
				return false;
			}else 
			{	
				//不共面,既有前面的点,也有后面的点。
				divied=true;
				return false;
			}
		}
	}
	//函数功能:判断一个三角形来自另外一个三角形所在平面的何方。
	//功能描述:如果共面,则same为true,divided为false,方向相同则返回true,否则返回false;
	 //         如果不共面,则根据在前还是后,还是divided ,进行返回。
	bool IsFomFront(const TheTreeObect& obj,int index,const int &currentFlip,bool &same,bool &divied){
        divied=false;
		same=false;
		bitset<3> position[3];
		float dir[3];
		bool Front[3];
		bool IsNotInFlat[3];
	    float point[3];
		memcpy(point,obj.getTriangles()[index].a,3*sizeof(float));
		//int currentFlip=getFlip();
		VectBinus(obj.getTriangles()[currentFlip].a,point,dir);
		IsNotInFlat[0]=IsIntersectWithTriangle(
			point,
			dir,
			obj.getTriangles()[currentFlip].a,
			obj.getTriangles()[currentFlip].b,
			obj.getTriangles()[currentFlip].c,
			point,
			Front[0]
			);
        memcpy(point,obj.getTriangles()[index].b,3*sizeof(float));
		VectBinus(obj.getTriangles()[currentFlip].b,point,dir);
		IsNotInFlat[1]=IsIntersectWithTriangle(
			point,
			dir,
			obj.getTriangles()[currentFlip].a,
			obj.getTriangles()[currentFlip].b,
			obj.getTriangles()[currentFlip].c,
			point,
			Front[1]
			);
        memcpy(point,obj.getTriangles()[index].c,3*sizeof(float));
		VectBinus(obj.getTriangles()[currentFlip].c,point,dir);
		IsNotInFlat[2]=IsIntersectWithTriangle(
			point,
			dir,
			obj.getTriangles()[currentFlip].a,
			obj.getTriangles()[currentFlip].b,
			obj.getTriangles()[currentFlip].c,
			point,
			Front[2]
			);
        for(int i=0;i<3;i++)
		{
		    if(!IsNotInFlat[i])position[i].set(0);else
				if(Front[i])position[i].set(1);else
					position[i].set(2);
		}
		//每个点的三个状态对应为 position[0],position[1],position[2];
		bitset<3> positi=position[0]&position[1]&position[2];
		if(positi[0])
		{ 
			same=true;
			//查看方向是否相同
            //求得他们的发线:
           float flat_3_flip[3];
		   float flat_3_temp[3];
            qiuFaXiangLiang(
				obj.getTriangles()[currentFlip].a,
				obj.getTriangles()[currentFlip].b,
				obj.getTriangles()[currentFlip].c,
				flat_3_flip);
			 qiuFaXiangLiang(
				obj.getTriangles()[index].a,
				obj.getTriangles()[index].b,
				obj.getTriangles()[index].c,
				flat_3_temp);
			 float dotval=DotProduct(flat_3_flip,flat_3_temp);
			 if(dotval<0){
				 //点积为负值
			    return false;
			 }else
				 //点积为正值
				 return true;
		}else {
			positi=position[0]|position[1]|position[2];
				//不共面并且没有在后面的点!!
			if(!positi[2])
			{
				return true;
			}
				//不共面没有前面的点
			else if(!positi[1])
			{	
				return false;
			}else 
			{	
				//不共面,既有前面的点,也有后面的点。
				divied=true;
				return false;
			}
		}
	}
	//函数功能:从所有的备选三角形列表中找到一个最佳的分割平面。
	int getTheBestDivider(vector<int> TheDividerList,bool &found, const TheTreeObect& obj){
			   int pinggu_value;
		       found=false;
		       int theOptimizedValue;
			   int theOpTriagl;
			   bool IsInit=false;                 
			   bool AllFront=true;
			   bool AllBack=true;
	    	   for(int flip=0;flip<TheDividerList.size();flip++){
				    int N_FRONT=0;
					int N_BACK=0;
					int N_DIVIDE=0;
					if(
					 !IsTriangle(
					   obj.getTriangles()[TheDividerList[flip]].a,
					   obj.getTriangles()[TheDividerList[flip]].b,
					   obj.getTriangles()[TheDividerList[flip]].c
					   )
					 )continue;
					for(int index=0;index<obj.getN();index++){
						bool front;
						bool same;
						bool divided;
						front=IsFomFront(obj,index,flip,same,divided);
						if(divided){
							N_DIVIDE++;
							AllBack=false;
							AllFront=false;
						}
						else if(front){
							AllBack=false;
							N_FRONT++;
						}else {
							N_BACK++;
							AllFront=false;
						}
					}//for end
					if(!AllBack&&!AllFront){
					   found=true;
					}		
					pingguvalue=fabs(N_FRONT-N_BACK)+N_DIVIDE;
					if(!IsInit){
						theOpTriagl=flip;
						theOptimizedValue=pinggu_value;
						IsInit=true;
					}
					else if(pinggu_value<theOptimizedValue){ 
							theOpTriagl=flip;
							theOptimizedValue=pinggu_value;
					}	
			   }
			   if(found){   
				   return theOpTriagl;
			   }else return 0;  
	}
   
	//参数:triangle:待分割的三角形
	//divider: 分割面
	//pTri:分割后的三角形
	//p_front:前,还是后
	//返回:分割后的三角形个数
	int divideTriangle(Triangle triangle,Triangle divider,Triangle* &pTri,bool *& p_front){		
		//定义Bool型变量记录以顶点出发的变是否与平面相交。
        bool notdivided[3];
		//边
		float dingdian[3][3];
		//边是向量。从对应的顶点出发的边。
		float bian[3][3];
		//构造三角形集合:
		//记录顶点三角是否有效:
		bool valid[3];
	    //bool front[3];
        float dingdiansanjiao[3][3][3];
		//对顶点和边向量进行赋值
		//平面方程系数
		float flat[4];
		unsigned char dingdianweizhi[3];
		if(!qiuPingMianFangCheng(divider.a,divider.b,divider.c,flat))
			return -1;
        for(int i=0;i<3;i++)
		{
		  dingdian[0][i]=triangle.a[i];
		  dingdian[1][i]=triangle.b[i];
		  dingdian[2][i]=triangle.c[i];
		}
		for(i=0;i<3;i++)
		{
		 int j=i+1;
		 if(j==3)j=0;
		 VectBinus(dingdian[j],dingdian[i],bian[i]);	
		}
		//判断各个顶点与平面的位置关系
		const unsigned char QIAN=0;
		const unsigned char SHANG=1;
		const unsigned char HOU=2;
		for(i=0;i<3;i++)
		{
		  	float k=
				 flat[0]*dingdian[i][0]
				+flat[1]*dingdian[i][1]
				+flat[2]*dingdian[i][2]
				+flat[3];
			if(k>0.00001)dingdianweizhi[i]=QIAN;
			else if(k<-0.00001)dingdianweizhi[i]=HOU;
			else dingdianweizhi[i]=SHANG;
		}
		unsigned char jiaodianweizhi[3];
		float jiaodian[3][3];
		unsigned char m=0;
		pTri =new Triangle[1+2];
		p_front=new bool[3];
		int n=0;
		for(i=0;i<3;i++)
		{
			if(fabs(dingdianweizhi[i]-dingdianweizhi[i==2?0:i+1])==2)
			{
				jiaodianweizhi[i]=SHANG;
			   	calInsert(dingdian[i],bian[i],flat,jiaodian[i]);
				notdivided[i]=false;
			}else
			{
				//交点退化为顶点
			/*	for(int j=0;j<3;j++)
				{
					jiaodian[i][j]=dingdian[i][j];
				}
				*/
				memcpy(jiaodian[i],dingdian[i],sizeof(jiaodian[i]));
				jiaodianweizhi[i]=dingdianweizhi[i];
			    notdivided[i]=true;
			}
		}
        memcpy(pTri[n].a,jiaodian[0],sizeof(jiaodian[0]));
		memcpy(pTri[n].b,jiaodian[1],sizeof(jiaodian[1]));
		memcpy(pTri[n].c,jiaodian[2],sizeof(jiaodian[2]));
		if(jiaodianweizhi[0]==QIAN||jiaodianweizhi[1]==QIAN||jiaodianweizhi[2]==QIAN){
			p_front[n]=true;
		}else if(jiaodianweizhi[0]==HOU||jiaodianweizhi[1]==HOU||jiaodianweizhi[2]==HOU)
		{
		    p_front[n]=false;
		}
	    n++;
        for(i=0;i<3;i++)
		{
			if(!notdivided[i])
			{
				valid[i]=true;
				int next;
				int pre;
				next=(i==2?0:i+1);
				pre=(i==0?2:i-1);
				dingdiansanjiao[i][0][0]=dingdian[i][0];
				dingdiansanjiao[i][0][1]=dingdian[i][1];
				dingdiansanjiao[i][0][2]=dingdian[i][2];
				dingdiansanjiao[i][1][0]=jiaodian[i][0];
				dingdiansanjiao[i][1][1]=jiaodian[i][1];
				dingdiansanjiao[i][1][2]=jiaodian[i][2];
				if(!notdivided[pre]){
				dingdiansanjiao[i][2][0]=jiaodian[pre][0];
				dingdiansanjiao[i][2][1]=jiaodian[pre][1];
				dingdiansanjiao[i][2][2]=jiaodian[pre][2];
				}else{
				dingdiansanjiao[i][2][0]=dingdian[pre][0];
				dingdiansanjiao[i][2][1]=dingdian[pre][1];
				dingdiansanjiao[i][2][2]=dingdian[pre][2];
				
				}
				memcpy(pTri[n].a,dingdiansanjiao[i][0],sizeof(float [3]));
				memcpy(pTri[n].b,dingdiansanjiao[i][1],sizeof(dingdiansanjiao[i][0]));
              	memcpy(pTri[n].c,dingdiansanjiao[i][2],sizeof(dingdiansanjiao[i][0]));
				if(dingdianweizhi[i]==QIAN){
					p_front[n]=true;
				}else if(dingdianweizhi[i]==HOU)
				{
					p_front[n]=false;
				}
				n++;
			}
		}
		Triangle* tri=pTri;
		bool * temp_front=p_front;
		pTri=new Triangle[n];
		p_front=new bool[n];
		for( m=0;m<n;m++)
		{
			pTri[m]=tri[m];
			p_front[m]=temp_front[m];
		}
		delete [] tri;
		delete [] temp_front;
	    return n;
}
void addObject(const TheTreeObect & obj){
	    vector<int> TheDividerList;	
		if(IsLeaf){
			bool IsFront=false;
			bool NoUsed=true;
			int divide_index=0;
			TheTreeObect _obj;
			for(int j=0;j<getN();j++){
				 _obj.add(getTriangles()[j]);
			}
			for(j=0;j<obj.getN();j++){
				_obj.add(obj.getTriangles()[j]);
			}		
			for(int i=0;i<_obj.getN();i++)
			{
				NoUsed=true;
				for(int j=0;j<TheDividerList.size();j++)
				{
				 bool sameFlat=false;
				 bool divided=false;	
				 IsFront=IsFomFront(_obj,i,TheDividerList[j],sameFlat,divided);	
				 //int m=TheDividerList[j];
				 if(sameFlat){		 		
					 NoUsed=false; 	
					 break;
					} 	 
				}
				if(NoUsed){
					TheDividerList.push_back(i);			 
				} 			
			}
			bool found=false;
			divide_index=getTheBestDivider(TheDividerList,found,_obj);
			if(!found)
			{
                 this->resetTriangle(_obj.getTriangles(),_obj.getN());
			     return;
			}else 
			{
				TheTreeObect  Front_obj;
				TheTreeObect  Back_obj;	
				for(i=0;i<_obj.getN();i++){
					bool sameFlat=false;
					bool divided=false;
					IsFront=IsFomFront(_obj,i,TheDividerList.at(divide_index),sameFlat,divided);
					//如果交叉.
					if(divided){
					//分解三角形
						Triangle* pTri;
						bool * p_front;
						int number=divideTriangle(_obj.getTriangles()[i],_obj.getTriangles()[TheDividerList.at(divide_index)],pTri,p_front);
						Triangle* temp_p= pTri;
						bool * temp_f=p_front;
						for(i=0;i<number;i++){
							if(*temp_f){
								Front_obj.add(*temp_p);			
							}
							else{			
								Back_obj.add(*temp_p);
							}
							temp_f++;
							temp_p++;
						}
						temp_f=NULL;
						temp_p=NULL;
						delete [] pTri;
						delete [] p_front;
					}
				    else if(IsFront){
						Front_obj.add(_obj.getTriangles()[i]);
					}
					else{
						Back_obj.add(_obj.getTriangles()[i]);
					}
				} 
				IsLeaf=false;
				pFrontChild=new BSPNode();
				pBackChild=new BSPNode();
				pFrontChild->addObject(Front_obj);
				pBackChild->addObject(Back_obj);
	    		this->SetAsNode(_obj.getTriangles()[TheDividerList.at(divide_index)]);
			}//(else if(!found end))       
		}//IsLeaf End;
	}
	//功能描述:更新节点..
	void UpdateByModels(const Triangle* theTriangles,int n){	
			typedef  float   float_33[3][3];
			float (*p)[3][3];
			p=new float_33 [n];
			for(int i=0;i<n;i++)
			{
				for(int j=0;j<3;j++)
				{
					p[i][0][j]=theTriangles[i].a[j];
					p[i][1][j]=theTriangles[i].b[j];
					p[i][2][j]=theTriangles[i].c[j];
				}
			}
			TheTreeObect* BAK_Obj=new TheTreeObect(p,n);
			if(IsLeaf){
				this->addObject(*BAK_Obj);
			}
			else if(!IsLeaf)
			{
				TheTreeObect* FrontObj=new TheTreeObect();
				TheTreeObect* BackObj=new TheTreeObect();	
				for(int j=0;j<n;j++)
				{
					bool front=false;
					bool same=false;
					bool divided=false;
					Triangle sanjiao=BAK_Obj->getTriangles()[j];
					Triangle flipflat=this->getTriangles()[0];
					front=IsFomFront(sanjiao,flipflat,same,divided);
					if(divided)
					{
						//分解三角形
						Triangle* pTri;
						bool * p_front;
						int number=divideTriangle(sanjiao,flipflat,pTri,p_front);
						Triangle* temp_pTri= pTri;
						bool * temp_p_Front=p_front;
						for(int i=0;i<number;i++){
							if(*temp_p_Front)
								FrontObj->add(*temp_pTri);
							else
								BackObj->add(*temp_pTri);
							temp_p_Front++;
							temp_pTri++;
						}	
							delete [] pTri;
							delete [] p_front;				
					}//divided End;
					else if(front){
						FrontObj->add(theTriangles[j]);				   
					}
					else {
						BackObj->add(theTriangles[j]);
					}
				}//for End;
				((BSPNode*)pFrontChild)->UpdateByModels(FrontObj->getTriangles(),FrontObj->getN());		
	      		((BSPNode*)pBackChild)->UpdateByModels(BackObj->getTriangles(),BackObj->getN());
				delete FrontObj;
				delete BackObj;
				FrontObj=NULL;
				BackObj=NULL;
			}//if(!leaf end)
			delete  BAK_Obj;
			BAK_Obj=NULL;
			delete[] p;	
			p=NULL;
	}//UpdateByModelEnd;
void outPut(){
	    if(IsLeaf)
		{
			cout<<"IsLeaf:True"<<endl;
			outPutSanJiaos(this->getTriangles(),this->getN());
		}
		else if(!IsLeaf)
		{
			cout<<"IsLeaf:false"<<endl;
			outPutSanjiao(this->getTriangles()[0]);
			((BSPNode*)pFrontChild)->outPut();
			((BSPNode*)pBackChild)->outPut();
		}
	}
};
class BSPTree{   
public:
	 BSPTree(){
	  pTree=new BSPNode();
	}
	 ~BSPTree(){
	   delete[] pTree;
	 }
     BSPNode* pTree;
	 //更新二叉树:
	 void UpdateByModels(const Triangle* Triangle,int n){
	       pTree->UpdateByModels(Triangle,n); 
	 };
	 void addObject(TheTreeObect obj){
	   pTree->addObject(obj);

	 }
	 void outPut(){
	   pTree->outPut();
	 }
};
//....
class nearestobject{	   
   private:	
	 bool IsInited;
	 static nearestobject* const theOnlyOne;
	 int index;
	 float nearpoint[3]; 
	 float point[3]; 
	 float nearestDistance;
	 nearestobject():IsInited(false),index(0),nearestDistance(0.0){
		point[0]=0.0;
		point[1]=0.0;
		point[2]=0.0;
	 }
	  void setLookPoint(float nearpoint[3]){
	       this->nearpoint[0]=nearpoint[0];
		   this->nearpoint[1]=nearpoint[1];
		   this->nearpoint[2]=nearpoint[2];
	  }
	  void VectBinus(float a[3],float b[3],float c[3]){
		c[0]=a[0]-b[0];
		c[1]=a[1]-b[1];
		c[2]=a[2]-b[2];
	  }
		//计算模
	  double calMole(float a[3]){
		return sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
	  }
   public:
	  static  nearestobject* GetNearestP(){
	            return theOnlyOne;
	  }
	  //初始化一个近裁剪面点,一个线上的点,以及点对应物体的index;
      //返回:是否已经被初始化过
	  bool Init(float nearpoint[3],float farpoint[3]){
		 if(!IsInited){  
			setLookPoint(nearpoint);
			for(int i=0;i<3;i++)
			{
			   this->point[i]=point[i];
			}
		    this->index=index;
			this->IsInited=true;
			float temp[3];
            VectBinus(farpoint,nearpoint,temp);
            this->nearestDistance=calMole(temp);
			return false;
		 }
		 return true;
	  }
	  int getIndex(){
	       return index;
	  }	 
	  //返回:以前的物体编号。
	  int set(int index,float point[3]){
		  int tempindex;
		  tempindex=this->index;
		  double distance;
		  float temp[3];
          VectBinus(point,nearpoint,temp);
          distance=calMole(temp);
		  if((distance-nearestDistance)<-0.000001)
		  {
		    nearestDistance=distance;	
			this->index=index;
		  }
		  	return  tempindex;
	  }
};
nearestobject* const nearestobject::theOnlyOne=new nearestobject();
//定义射线求交用的变量,这些变量用来进行拾取
float org[3],dir[3],a[3],b[3],c[3],point[3],end[3];
bool IsFromFront;
bool calculateInterWithTriangle(float a[3],float b[3],float c[3]){
return IsIntersectWithTriangle(org,dir,a,b,c,point,IsFromFront);
}
OpenGL::OpenGL()
{
}
OpenGL::~OpenGL()
{	CleanUp();
}
BOOL OpenGL::SetupPixelFormat(HDC hDC0)//检测安装OpenGL
{	int nPixelFormat;					  // 象素点格式
	hDC=hDC0;
	PIXELFORMATDESCRIPTOR pfd = { 
	    sizeof(PIXELFORMATDESCRIPTOR),    // pfd结构的大小 
	    1,                                // 版本号 
	    PFD_DRAW_TO_WINDOW |              // 支持在窗口中绘图 
	    PFD_SUPPORT_OPENGL |              // 支持 OpenGL 
	    PFD_DOUBLEBUFFER,                 // 双缓存模式 
	    PFD_TYPE_RGBA,                    // RGBA 颜色模式 
	    16,                               // 24 位颜色深度 
	    0, 0, 0, 0, 0, 0,                 // 忽略颜色位 
	    0,                                // 没有非透明度缓存 
	    0,                                // 忽略移位位 
	    0,                                // 无累加缓存 
	    0, 0, 0, 0,                       // 忽略累加位 
	    16,                               // 32 位深度缓存     
	    0,                                // 无模板缓存 
	    0,                                // 无辅助缓存 
	    PFD_MAIN_PLANE,                   // 主层 
	    0,                                // 保留 
	    0, 0, 0                           // 忽略层,可见性和损毁掩模 
	}; 
	if (!(nPixelFormat = ChoosePixelFormat(hDC, &pfd)))
		{ MessageBox(NULL,"没找到合适的显示模式","Error",MB_OK|MB_ICONEXCLAMATION);
	      return FALSE;
		}
	SetPixelFormat(hDC,nPixelFormat,&pfd);//设置当前设备的像素点格式
	//利用hDC创造hRC,这句话使得windows设备句柄转化为opengl支持的设备句柄。
	hRC = wglCreateContext(hDC);          //获取渲染描述句柄
	//得到hRC后,我们激活它,,让它与当前的hDC相关联。
	wglMakeCurrent(hDC, hRC);             //激活渲染描述句柄

		;//cout<<"Init"<<endl;


//	m_baiscobj=new baiscobj();
//	m_baiscobj->light0();
	return TRUE;
}
extern int k;
void OpenGL::init(int Width, int Height)
{  
   glViewport(0,0,Width,Height);			// 设置OpenGL视口大小。	
   glMatrixMode(GL_PROJECTION);			// 设置当前矩阵为投影矩阵。
   glLoadIdentity();						// 重置当前指定的矩阵为单位矩阵
   gluPerspective							// 设置透视图
		( 90.0f,							// 透视角设置为 45 度
		  (GLfloat)Width/(GLfloat)Height,	// 窗口的宽与高比
		  0.1f,								// 视野透视深度:近点1.0f
		  3000.0f							// 视野透视深度:始点0.1f远点1000.0f
		);
	// 这和照象机很类似,第一个参数设置镜头广角度,第二个参数是长宽比,后面是远近剪切。
	glMatrixMode(GL_MODELVIEW);				// 设置当前矩阵为模型视图矩阵
	//glLoadIdentity();						// 重置当前指定的矩阵为单位矩阵
//====================================================
}
	struct point3f//定义一个三维变量结构
	{double x;
	 double y;
	 double z;
	};
	#define MAP_W       32        // size of map along x-axis 32 
	#define MAP_SCALE   24.0f     // the scale of the terrain map
	#define MAP			MAP_W*MAP_SCALE/2
	point3f n_vector;
//	float xyz[3];
 	float	nimh=0,sx,sz;			//上一次3D鼠
	void picter(float x,float y,float z);
	double modelview[16];                           // 定义保存视图矩阵数组
	double projection[16];                          // 定义保存投影矩阵数组
	int    viewport[4]={0,0,800,600};               // 定义保存屏幕尺寸数组
	POINT mouse;
	point3f nearPoint;
	point3f farPoint;
	point3f xyz;

#define FRAND   (((float)rand()-(float)rand())/RAND_MAX)
void OpenGL::Render()//OpenGL图形处理
{ 	
   
	GetCursorPos(&mouse);
	ScreenToClient(hWnd,&mouse);
	//下面对鼠标位置进行编程。
	//首先转化为opengl的视口坐标,视口坐标实际上就是窗口坐标,因为前面已经设定。
	//下面把屏幕坐标转Opengl坐标:
	mouse.x=mouse.x, 
	mouse.y=Height-mouse.y;
	//;//cout<<mouse.x<<endl;
	//;//cout<<mouse.y;
//	;//cout<<mouse.x<<" "<<mouse.y<<endl;
    //下面把屏幕坐标转化为3D坐标
	glGetDoublev(GL_MODELVIEW_MATRIX,modelview);    // 获取视图矩阵
	glGetDoublev(GL_PROJECTION_MATRIX,projection);  // 获取投影矩阵
	glGetIntegerv(GL_VIEWPORT,viewport);            // 获取视口大小
	gluUnProject( (double)mouse.x,                  // 窗口坐标X
				  (double)mouse.y,                  // 窗口坐标Y
				  0.0f,                             // 获取近裁剪面上的交点
                  modelview,                        // 视图矩阵
                  projection,                       // 投影矩阵
                  viewport,                         // 屏幕视区
                  &nearPoint.x,                        // 获得的近点3D坐标值X
				  &nearPoint.y,                        // 获得的近点3D坐标值Y
                  &nearPoint.z                         // 获得的近点3D坐标值Z
				);
	gluUnProject( (double)mouse.x,                  // 窗口坐标X
				  (double)mouse.y,                  // 窗口坐标Y
				  1.0f,                             // 获取近裁剪面上的交点
                  modelview,                        // 视图矩阵
                  projection,                       // 投影矩阵
                  viewport,                         // 屏幕视区
                  &farPoint.x,                        // 获得的近点3D坐标值X
				  &farPoint.y,                        // 获得的近点3D坐标值Y
                  &farPoint.z                         // 获得的近点3D坐标值Z
				);
   //Lbutdown=false;
	dir[0]=n_vector.x=farPoint.x-nearPoint.x;
    dir[1]=n_vector.y=farPoint.y-nearPoint.y;
    dir[2]=n_vector.z=farPoint.z-nearPoint.z;
    org[0]=nearPoint.x;  
    org[1]=nearPoint.y;
	org[2]=nearPoint.z;
	end[0]=farPoint.x;
	end[1]=farPoint.y;
	end[2]=farPoint.z;
	IsFromFront=false;
	nearestobject* pNearest=nearestobject::GetNearestP();
	pNearest->Init(org,end);
	/*
	for(int i=0;i<N;i++)
	{
	 int n_triangle;
	 Triangle* p_nTriangle=object[i].getTriangles(n_triangle);
	 for(int i=0;i<n_triangle;i++)
	 Triangle[i].get(a,b,c);
     calculateInterWithTriangle(,b,c);
	}
	*/
	glClearColor(0.50f, 0.70f, 0.90f, 1.0f);			 // 设置刷新背景色
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);// 刷新背景
	// glLoadIdentity();	
	// 重置当前的模型观察矩阵
	glPushMatrix();//压入堆栈
	glEnable(GL_DEPTH_TEST); 
	glDisable(GL_TEXTURE_2D);
	picter(-15,-25,-40);// 更新窗口
	glEnable(GL_TEXTURE_2D);		//使用纹理
	glTranslatef(0,0,-280);
	glBindTexture(GL_TEXTURE_2D, m_ID);//
  	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  glBegin(GL_QUADS);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-Width/2, -Height/2,  0.0f);// 前
		glTexCoord2f(1.0f, 0.0f); glVertex3f( Width/2,-Height/2,  0.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( Width/2,  Height/2,  0.0f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-Width/2,  Height/2,  0.0f);
  glEnd();
  glPopMatrix();
  
  glFlush();	
  SwapBuffers(hDC);								// 切换缓冲区
}
void OpenGL::CleanUp()
{	 wglMakeCurrent(hDC, NULL);                     //清除OpenGL
	 wglDeleteContext(hRC);                         //清除OpenGL
}
float r=0;

void picter(float x,float y,float z)//组合图形
{   
	BSPTree myTree;
	static int n_iTriangles;
	//TheTreeObect(float *triangle[3][3],int n1)
	float triangle [2][3][3];
	for(int j=0;j<1;j=+2)
	{
		triangle[j][0][0]=0+j;
		triangle[j][0][1]=2+j;
		triangle[j][0][2]=0+j;
		triangle[j][1][0]=0+j;
		triangle[j][1][1]=1+j;
		triangle[j][1][2]=0+j;
		triangle[j][2][0]=0+j;
		triangle[j][2][1]=0+j;
		triangle[j][2][2]=1+j;
		triangle[j+1][0][0]=1+j;
		triangle[j+1][0][1]=0+j;
		triangle[j+1][0][2]=1;
		triangle[j+1][1][0]=0+j;
		triangle[j+1][1][1]=1+j;
		triangle[j+1][1][2]=0+j;
		triangle[j+1][2][0]=-1+j;
		triangle[j+1][2][1]=0+j;
		triangle[j+1][2][2]=0+j;
	}
	TheTreeObect obj(triangle,2);
//	cout<<n_iTriangles++<<endl;
    myTree.UpdateByModels(obj.getTriangles(),obj.getN());
	myTree.addObject(obj);
//	myTree.outPut();
	glPushAttrib(GL_CURRENT_BIT);//保存现有颜色属实性
	glTranslatef(0,0,-30);		//平台的定位
   glPushMatrix();//平台-==============================
	glTranslatef(x,y+0.5f,z);		//平台的定位
	glColor3f(0.0f,1.0f,0.2f);		//绿色
	auxSolidCube(1);				//方台(边长)
	glTranslatef(0.0f,0.8f,0.0f);	//架的位置调整,上升0.8
	glColor3f(0.0f,0.0f,1.0f);		//蓝色
	auxSolidBox(.2f,1.3f,.2f);		//长方架(宽、高、长)
 glPopMatrix();
 glPushMatrix();//雷达==============================
	glTranslatef(x,y+2.5f,z);		//雷达的定位1
	glRotatef(r-90,0.0,1.0,0.0);	//雷达旋转2
	//=======================================
	glColor3f(1.0f,1.0f,1.0f);		//白色
	glRotatef(45, 1.0, 0.0, 0.0);	//盘的角度调整,仰30度
	auxWireCone(1.5,0.6f);			//线园锥盘(底半径、高)
	//=======================================
	glRotatef(180, 1.0, 0.0, 0.0);	//杆的角度调整,反方向转
	glTranslatef(0.0f,0.0f,-0.7f);  //杆的位置调整,缩进一点
	auxWireCone(0.2f,2.0f);			//园锥杆(底半径、高)
	glColor3f(FRAND,0,0);			//随机红色
	glTranslatef(0.0f,0.0f,2.0f);	//杆的位置调整,缩进一点
	auxSolidSphere(0.1f);			//园(半径)
 glPopMatrix();
 glPushMatrix();//火箭=============================
	glTranslatef(x,y+10.0f,z);		//火箭的定位
	glRotatef(r, 0.0, 1.0, 0.0);	//火箭的旋转
	glTranslatef(15,0,0);			//火箭的定位
	//=============================================
	glColor3f(1.0f,0.0f,0.0f);		//红色
	glRotatef(180, 0.0, 1.0, 0.0);	//角度调整,与雷达平行,箭头朝前
	auxSolidCone(.2,0.6);			//园锥(底半径、高)
	//=============================================
	glColor3f(1.0f,1.0f,1.0f);		//白色
	glRotatef(90, 1.0, 0.0, 0.0);	//角度调整,与火箭头对接
	glTranslatef(0.0f,-1.0f,0);		//位置调整,与火箭头对接
	auxSolidCylinder(.2f,1);		//园柱(半径、高)
	glRotatef(-270, 1.0, 0.0, 0.0);
	glColor3f(FRAND+.6f,0.2f,0.0f);	//随机色
	glTranslatef(0.0f,-0.0f,-0.2f); //位置调整,缩进一点
	auxSolidCone(.2,1.5);			//园锥(底半径、高)
 glPopMatrix();
 glPopAttrib();//恢复前一属性
 r+=0.5f;if(r>360) r=0;
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics