3DS多模块连动(机械臂)

现在来实现机械手臂运动,以一个挖掘机为例:


我们把挖机分成几个部分

1、底盘,2、可转车身,3、大臂,4、前臂,5、挖斗。

流程:

1。按名称分层

2。找每层旋转轴

3。计算每个的旋转角度

4。分别绘制每层

第1步。按名称分层:

vector<t3DObject*> obj1vec,obj2vec,obj3vec,obj4vec ,obj5vec; //五层对象名 1、底盘,2、可转车身,3、大臂,4、前臂,5、挖斗。

GLfloat Spin2= 0 ,Spin3= 0,Spin4= 0,Spin5= 0;//可转四层旋转量
//名称分层
void initName()
{
	unsigned int e;
	//第一层对象 底盘(除去所有可动部件)
	for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		e=0;
		if(strcmp(gothicModel.pObject[i].strName,"上车身")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"前臂")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"铲斗")==0)
			e=1;
		...省略...其它可动配件


		if(e==0)
			obj1vec.push_back(&gothicModel.pObject[i]);  
	}
	//

	//第二层对象 上车身周围
	for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		e=0;
		if(strcmp(gothicModel.pObject[i].strName,"上车身")==0)
			e=1;
		.....

		if(e==1)
			obj2vec.push_back(&gothicModel.pObject[i]);  
	}
	//

	//第三层 大臂及配件
	for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		e=0;

		if(strcmp(gothicModel.pObject[i].strName,"大臂")==0)
			e=1;
		...
		if(e==1)
			obj3vec.push_back(&gothicModel.pObject[i]);  
	}

		//第四层 前臂
	for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		e=0;
		if(strcmp(gothicModel.pObject[i].strName,"前臂")==0)
			e=1;

		if(e==1)
			obj4vec.push_back(&gothicModel.pObject[i]);  
	}

			//第五层 挖斗
	for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		e=0;
		if(strcmp(gothicModel.pObject[i].strName,"铲斗")==0)
			e=1;

		if(e==1)
			obj5vec.push_back(&gothicModel.pObject[i]);  
	}

	printf("第一层个数:%d ",obj1vec.size());
	printf("第二层个数:%d ",obj2vec.size());
	printf("第三层个数:%d ",obj3vec.size());
	printf("第四层个数:%d ",obj4vec.size());
	printf("第五层个数:%d ",obj5vec.size());

		printf("总数:%d\n",obj1vec.size()+obj2vec.size()+obj3vec.size());

}

2。找每层旋转轴

	float scaleNum=1.0f;//测距用的单位长
/* 找旋转轴   (辅助用)  */
void huaxyz()
{

	//第一
	//画坐标系

	//xt1=0;//向右 +
	//yt1=scaleNum*20;//向上 + 
	//zt1=scaleNum*19;//向屏幕外 +19

	glTranslatef(xt1,0.0f,0.0f);// x1
	glTranslatef(0.0f,yt1,0.0f);// y轴移动  y1
	glTranslatef(0.0f,0.0f,zt1);// z1
	//
	//  1. 画坐标轴(直线)
    glColor3f(0.0, 0.0, 1.0); // --> 红色  
    GLfloat curSizeLine=5;//线宽
    glLineWidth(curSizeLine); 

   glBegin(GL_LINES);//x轴
   glVertex3f(-1800.0f,0.0f,0.0f);
   glVertex3f(1800.0f,0.0f,0.0f); 
    
    glEnd();

   glBegin(GL_LINES);//y轴
   glVertex3f(0.0f,-1800.0f,0.0f);
   glVertex3f(0.0f,1800.0f,0.0f); 
    
    glEnd();

   glBegin(GL_LINES);//z轴
   glVertex3f(0.0f,0.0f,-1800.0f);
   glVertex3f(0.0f,0.0f,1800.0f); 
    
    glEnd();

	//第二,三,四,省略

}
这里要慢慢调整。


上图就是调整好的轴位置

第3。计算每个的旋转角度

	Spin2+=0.3; 
	if( Spin2 > 360 )
	Spin2 -= 360;
这里只显示一个

第4。分别绘制每层

//显示3ds模型
void drawModel(t3DModel Model,bool touming,bool outTex)
{
	
	...省略见原文
	
	// 遍历模型中所有的对象
	for(int i = 0; i < Model.numOfObjects; i++)
	{

		// 获得当前显示的对象
		t3DObject *pObject ;
		//================================
		int count1 = obj1vec.size();
		int count2 = obj2vec.size();
		int count3 = obj3vec.size();
		int count4 = obj4vec.size();
		int count5 = obj5vec.size();
		if(i<count1)
			pObject = obj1vec.at(i);
		else if(i<count1+count2)
			pObject = obj2vec.at(i-count1);
		else if(i<count1+count2+count3)
				pObject = obj3vec.at(i-count1-count2);
		else if(i<count1+count2+count3+count4)
				pObject = obj4vec.at(i-count1-count2-count3);
		else if(i<count1+count2+count3+count4+count5)
				pObject = obj5vec.at(i-count1-count2-count3-count4);
		
		else
		{
			pObject = &Model.pObject[i];//不出错的话这句是运行不到的

		}

		...省略见原文

		if(i<count1)//底盘
		{
			if(i==0)glPushMatrix();//保存当前位置
		}
		else if(i<count1+count2)//旋转机身
		{
			if(i==count1){
				float xt1=scaleNum*(-4.6);//这里根据前面得
				float yt1=scaleNum*(-92.6);
				float zt1=scaleNum*(-14.6);
				glTranslatef(xt1,yt1,zt1);// 
				glRotatef(Spin,0.0f,1.0f,0.0f);// 绕y轴旋转 
				glTranslatef(-xt1,-yt1,-zt1);// 
			}
		}
		
		else if(i<count1+count2+count3)//大臂
		{
			if(i==count1+count2){

				float xt2=  scaleNum*(-4.6+7.1);//前面再加这里
				float yt2=  scaleNum*(-92.6);
				float zt2=  scaleNum*(-14.6+5.3);

				glTranslatef(xt2,yt2,zt2);// 移动转轴到原点
				glRotatef(-Spin2,1.0f,0.0f,0.0f);// 绕x轴旋转 
				glTranslatef(-xt2,-yt2,-zt2);// 还原
			}
		}
		else if(i<count1+count2+count3+count4)//前臂 和 铲斗 与上面同
		...省略
		}
	}
	...省略见原文
}
运行图:


完整代码:

// 3DS挖掘机动作(有纹理贴图的3ds模型,+光照 +虚拟球旋转)
 

#define  name3DS "Data/3ds/wj.3DS"  //

 
#include "CLoad3DS1.cpp"



vector<t3DObject*> obj1vec,obj2vec,obj3vec,obj4vec ,obj5vec; //五层对象名 1、底盘,2、可转车身,3、大臂,4、前臂,5、挖斗。

GLfloat Spin2= 0 ,Spin3= 0,Spin4= 0,Spin5= 0;//可转四层旋转量

	float scaleNum=1.0f;//测距用的单位长

	GLfloat xt1=0.0,yt1=0.0,zt1=0.0f;//转动轴移动量 
	float rquad=0.0;//转动量
	void huaxyz();

//显示3ds模型
void drawModel(t3DModel Model,bool touming,bool outTex)
{
	
	if( touming ){
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glColor4f(1,1,1,0.5);
	}
	
	// 遍历模型中所有的对象
	for(int i = 0; i < Model.numOfObjects; i++)
	{

		// 获得当前显示的对象
		t3DObject *pObject ;
		//================================
		int count1 = obj1vec.size();
		int count2 = obj2vec.size();
		int count3 = obj3vec.size();
		int count4 = obj4vec.size();
		int count5 = obj5vec.size();
		if(i<count1)
			pObject = obj1vec.at(i);
		else if(i<count1+count2)
			pObject = obj2vec.at(i-count1);
		else if(i<count1+count2+count3)
				pObject = obj3vec.at(i-count1-count2);
		else if(i<count1+count2+count3+count4)
				pObject = obj4vec.at(i-count1-count2-count3);
		else if(i<count1+count2+count3+count4+count5)
				pObject = obj5vec.at(i-count1-count2-count3-count4);
		
		else
		{
			//pObject = &Model.pObject[i];//不出错的话这句是运行不到的

		}

		//================================
		// 判断该对象是否有纹理映射
		if(!outTex) {
			if(pObject->bHasTexture) {
				
				// 打开纹理映射
				glEnable(GL_TEXTURE_2D);
				
				glBindTexture(GL_TEXTURE_2D, Model.texture[pObject->materialID]);
			} else {
				
				// 关闭纹理映射
				glDisable(GL_TEXTURE_2D);
				glColor3ub(255, 255, 255);
			}
		} 
		if(i<count1)//底盘
		{
			if(i==0)glPushMatrix();//保存当前位置
		}
		else if(i<count1+count2)//旋转机身
		{
			if(i==count1){
				float xt1=scaleNum*(-4.6);
				float yt1=scaleNum*(-92.6);
				float zt1=scaleNum*(-14.6);
				glTranslatef(xt1,yt1,zt1);// x1
				glRotatef(Spin3,0.0f,1.0f,0.0f);// 绕y轴旋转 
				glTranslatef(-xt1,-yt1,-zt1);// -x1
			}
		}
		
		else if(i<count1+count2+count3)//大臂
		{
			if(i==count1+count2){

				float xt2=  scaleNum*(-4.6+7.1);
				float yt2=  scaleNum*(-92.6);
				float zt2=  scaleNum*(-14.6+5.3);

				glTranslatef(xt2,yt2,zt2);// 移动转轴到原点
				glRotatef(-Spin3,1.0f,0.0f,0.0f);// 绕x轴旋转 
				glTranslatef(-xt2,-yt2,-zt2);// 还原
			}
		}
		else if(i<count1+count2+count3+count4)//前臂
		{
			if(i==count1+count2+count3){

				float xt2=  scaleNum*(-4.6+7.1);
				float yt2=  scaleNum*(-92.6+35);
				float zt2=  scaleNum*(-14.6+5.3+45);

				glTranslatef(xt2,yt2,zt2);// 移动转轴到原点
				glRotatef(Spin3,1.0f,0.0f,0.0f);// 绕x轴旋转 
				glTranslatef(-xt2,-yt2,-zt2);// 还原
			}
		}
		else //if(i<count1+count2+count3+count4)//铲斗
		{
			if(i==count1+count2+count3+count4){

				float xt2=  scaleNum*(-4.6+7.1);
				float yt2=  scaleNum*(-92.6+35-23);
				float zt2=  scaleNum*(-14.6+5.3+45+16);

				glTranslatef(xt2,yt2,zt2);// 移动转轴到原点
				glRotatef(Spin3,1.0f,0.0f,0.0f);// 绕x轴旋转 
				glTranslatef(-xt2,-yt2,-zt2);// 还原
			}
		}

		//开始以g_ViewMode模式绘制
		glBegin(GL_TRIANGLES);          
		// 遍历所有的面
		for(int j = 0; j < pObject->numOfFaces; j++)
		{
			// 遍历三角形的所有点
			for(int whichVertex = 0; whichVertex < 3; whichVertex++)
			{
				// 获得面对每个点的索引
				int index = pObject->pFaces[j].vertIndex[whichVertex];
				// 给出法向量
				glNormal3f(pObject->pNormals[ index ].x, pObject->pNormals[ index ].y, pObject->pNormals[ index ].z);
				// 如果对象具有纹理
				if(pObject->bHasTexture) {
					
					// 确定是否有UVW纹理坐标
					if(pObject->pTexVerts) { 
						glColor3f(1.0,1.0,1.0);
						glTexCoord2f(pObject->pTexVerts[ index ].x, pObject->pTexVerts[ index ].y);
					}
				} else{
					
					if(Model.pMaterials.size() && pObject->materialID >= 0) 
					{
						BYTE *pColor = Model.pMaterials[pObject->materialID].color;
						glColor3ub(pColor[0], pColor[1], pColor[2]);
					}
				}
				glVertex3f(pObject->pVerts[ index ].x, pObject->pVerts[ index ].y, pObject->pVerts[ index ].z);
			}
			
		}
		
		glEnd();                // 绘制结束
	}
	glPopMatrix();//恢复原来位置

	//huaxyz();

	if( touming )
		glDisable(GL_BLEND);
	
}



#include "ArcBall.cpp"

const GLfloat lightPosition[] = {10.0,-10.0,10.0,0.0};  //光源所在的位置 无限远处+方向
const GLfloat whiteLight[] = {0.8,0.8,0.8,1.0};  
GLfloat matSpecular [] = {0.3,0.3,0.3,1.0};  //镜面反光率(RGBA)
GLfloat matShininess [] = {20.0};  
GLfloat matEmission [] = {0.3,0.3,0.3,1.0};  
GLfloat spin = 0;  
GLint  width = 600;
GLint  height = 480;

CLoad3DS *gothicLoader=new(CLoad3DS);  
t3DModel gothicModel;  
float gothicTrans[10] = {   
    0, 0 , -30 ,     //表示在世界矩阵的位置  
       0 , 0 , 0 ,      //表示xyz放大倍数  
        0 , 0 , 0 , 0  //表示旋转  
};

//初始化,必须用全局变量的方式,不能用new
ArcBallT arcBall(600.0f,400.0f);
ArcBallT*    ArcBall =&arcBall;// new ArcBallT(600.0f,400.0f);//&arcBall;

char * filename3ds=name3DS;


//移动
void move(int x, int y)                         
{
    ArcBall->MousePt.s.X = x;
    ArcBall->MousePt.s.Y = y;
    ArcBall->upstate();
    glutPostRedisplay();
}
//点击
void mouse(int button, int state, int x, int y) 
{
    if(button == GLUT_LEFT_BUTTON && state==GLUT_DOWN){
        ArcBall->isClicked = true;
        move(x,y);
    }
    else if(button == GLUT_LEFT_BUTTON && state==GLUT_UP)
        ArcBall->isClicked = false;
    else if(button == GLUT_RIGHT_BUTTON && state==GLUT_DOWN){
        ArcBall->isRClicked = true;
        move(x,y);
    }
    else if(button == GLUT_RIGHT_BUTTON && state == GLUT_UP)
        ArcBall->isRClicked = false;
    ArcBall->upstate();
    glutPostRedisplay();
}

//把名称分层
void initName()
{
	unsigned int e;
	//第一层对象 底盘(除去所有可动部件)
	for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		e=0;
		if(strcmp(gothicModel.pObject[i].strName,"上车身")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"上车身配件")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"左窗")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"右窗")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"前窗")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标1")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标2")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标3")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标4")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标5")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标6")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标7")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标8")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标9")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标10")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"前臂")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"铲斗")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"连接件1")==0)//液压传动去掉不显示
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"连接件2")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"活塞1")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"活塞2")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"活塞3")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"活塞缸1")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"活塞缸2")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"活塞缸3")==0)
			e=1;

		if(e==0)
			obj1vec.push_back(&gothicModel.pObject[i]);  
	}
	//

	//第二层对象 上车身周围
	for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		e=0;
		if(strcmp(gothicModel.pObject[i].strName,"上车身")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"上车身配件")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"左窗")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"前窗")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"右窗")==0)
			e=1;

		if(e==1)
			obj2vec.push_back(&gothicModel.pObject[i]);  
	}
	//

	//第三层 大臂及配件
	for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		e=0;

		if(strcmp(gothicModel.pObject[i].strName,"大臂")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标1")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标2")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标3")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标4")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标5")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标6")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标7")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标8")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标9")==0)
			e=1;
		if(strcmp(gothicModel.pObject[i].strName,"大臂商标10")==0)
			e=1;

		if(e==1)
			obj3vec.push_back(&gothicModel.pObject[i]);  
	}

		//第四层 前臂
	for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		e=0;
		if(strcmp(gothicModel.pObject[i].strName,"前臂")==0)
			e=1;

		if(e==1)
			obj4vec.push_back(&gothicModel.pObject[i]);  
	}

			//第五层 挖斗
	for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		e=0;
		if(strcmp(gothicModel.pObject[i].strName,"铲斗")==0)
			e=1;

		if(e==1)
			obj5vec.push_back(&gothicModel.pObject[i]);  
	}

	printf("第一层个数:%d ",obj1vec.size());
	printf("第二层个数:%d ",obj2vec.size());
	printf("第三层个数:%d ",obj3vec.size());
	printf("第四层个数:%d ",obj4vec.size());
	printf("第五层个数:%d ",obj5vec.size());

		printf("总数:%d\n",obj1vec.size()+obj2vec.size()+obj3vec.size());

}


//计算模型外框大小,把模型放在屏幕中央
void zhong(GLvoid)
{
	//遍历模型的对象,遍历对象顶点,找到x,y,z的最小,最大值,计算模型外框大小,长,宽,高
	//然后计算xyz放大倍数


	float xmin,xmax,ymin,ymax,zmin,zmax,t;
	xmin=ymin=zmin=9999999.0;//设置一个很大的值
	xmax=ymax=zmax=-9999999.0;//设置一个很小的值

   printf("对象个数:%d\n",gothicModel.numOfObjects);
   //printf("对象vector大小:%d\n",gothicModel.pObject.size());
   //遍历模型中的所有对象
   for(unsigned int i=0;i<gothicModel.pObject.size();i++)
	{
		   //printf("第%d个对象的顶点个数:%d\n",i,gothicModel.pObject[i].numOfVerts);
			NBVector3 *pVerts;      // 对象的顶点
			pVerts=gothicModel.pObject[i].pVerts;
			//遍历对象中的所有顶点
			 for(int j=0;j<gothicModel.pObject[i].numOfVerts;j++)
			 {	
				 //比较大小,留下最小和最大值
				 t=pVerts->x;
				 xmin=(t<xmin)?t:xmin;
				 xmax=(t>xmax)?t:xmax;

				 t=pVerts->y;
				 ymin=(t<ymin)?t:ymin;
				 ymax=(t>ymax)?t:ymax;

				 t=pVerts->z;
				 zmin=(t<zmin)?t:zmin;
				 zmax=(t>zmax)?t:zmax;
				pVerts++;//下一个顶点
			 }
			 //显示对象名称
			printf("对象%d名称:%s\n",i,gothicModel.pObject[i].strName);
	}
	
	//显示最小最大值
   printf("xmin:%f,xmax:%f\n",xmin,xmax);
   printf("ymin:%f,ymax:%f\n",ymin,ymax);
   printf("zmin:%f,xmax:%f\n",zmin,zmax);

      printf("宽度(x差值):%f,\n",xmax-xmin);
      printf("高度(y差值):%f,\n",ymax-ymin);
      printf("深度(z差值):%f,\n",zmax-zmin);
	  float xm,ym,zm,b;
	  xm=xmax-xmin;ym=ymax-ymin;zm=zmax-zmin;
		float max3=max(max(xm,ym),zm);

	  b=1.0/max3;
	  	  scaleNum=max3/100;//100分之一为 1 单位
      printf("放大倍数:%f,\n",b);
      printf("1单位:%f\n",scaleNum);

	gothicTrans[3]=gothicTrans[4]=gothicTrans[5]=b;//设置放大倍数	
	//移到屏幕中央
	gothicTrans[0]=-(xmin+(xmax-xmin)/2)*b;
	gothicTrans[1]=-(ymin+(ymax-ymin)/2)*b;
	gothicTrans[2]=-(zmin+(zmax-zmin)/2)*b-20;


}


void init()  
{  
	gothicLoader->Import3DS(&gothicModel, filename3ds);//导入模型,第二个参数是3ds文件的路径,
	zhong();
	initName();//对模型对象显示层排序


    glClearColor(0.3,0.3,0.3,1.0);  
    glClearDepth(1.0);  


    glShadeModel(GL_SMOOTH);  
    glEnable(GL_LIGHTING);  //打开光照处理功能
    glEnable(GL_LIGHT0);  //使用第0号光照   
    glEnable(GL_DEPTH_TEST); 

    glMatrixMode(GL_MODELVIEW);  //对模型视景矩阵操作  
    glLoadIdentity();  //将坐标原点移到中心 


	gluPerspective(3.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);


    glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);  //光源所在的位置。

	//GL_DIFFUSE:该光源所发出的光,照射到粗糙表面时经过漫反射,所得到的光的强度(颜色)
    glLightfv(GL_LIGHT0,GL_DIFFUSE,whiteLight);  

	//GL_SPECULAR:该光源所发出的光,照射到光滑表面时经过镜面反射,所得到的光的强度(颜色)。
    glLightfv(GL_LIGHT0,GL_SPECULAR,whiteLight);  
}  
void display()  
{     
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //清空颜色和深度缓冲  
    glMatrixMode(GL_PROJECTION);  //对投影矩阵操作  
    glLoadIdentity();;  //将坐标原点移到中心
      
    glMatrixMode(GL_MODELVIEW);  //对模型视景矩阵操作 
    glPushMatrix();  
    glRotatef(spin,0.0,1.0,0.0);  
	//设置材质
    glMaterialfv(GL_FRONT,GL_SPECULAR,matSpecular);  //设置镜面光
    glMaterialfv(GL_FRONT,GL_SHININESS,matShininess);  //镜面指数
    glMaterialfv(GL_FRONT,GL_EMISSION,matEmission);//自发光
	
	changeObject( gothicTrans );  

	//-----轨迹球----------开始
    glScalef(ArcBall->zoomRate, ArcBall->zoomRate, ArcBall->zoomRate);//2. 缩放
    glMultMatrixf(ArcBall->Transform.M);                        //3. 旋转
	//-----轨迹球----------结束

	drawModel(gothicModel,true,false);  
	//huaxyz();
	glPopMatrix();  
    glFlush();  
}  

void keyboardFunc(unsigned char key,int x,int y)  
{  
    switch(key)  
    {  
    case 'a':  
        zt1 +=80;  
        break;  
    case 'd':  
        zt1 -=80;  
        break;  
    }  
	   printf("zt1:%f\n",zt1);

    //if(spin<360)  
    //    spin +=360;  
    //else if(spin>=360)  
    //    spin -=360;  
    //glutPostRedisplay();  
}  

void SpinDisplay()
{
	Spin2+=0.3; 
	if( Spin2 > 360 )
	Spin2 -= 360;

static int Spin3t = 1;//Spin3 方向

	if(Spin3t==1)
		Spin3+=0.3; 
	else
		Spin3-=0.3; 

	if( Spin3 > 60 )
		Spin3t=-1;
	if( Spin3 < 1 )
		Spin3t=1;

	glutPostRedisplay();
}

int main(int argc,char *argv[])  
{     
	if( argc == 2 )
		filename3ds=argv[1];
    glutInit(&argc,argv);  
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGBA|GLUT_DEPTH);  
	glutInitWindowSize(width,height);
    glutInitWindowPosition(150,150);  
    glutCreateWindow("3DS挖机动作演示");  
    glutDisplayFunc(display);  
    //glutKeyboardFunc(keyboardFunc);  
    init();  

    glutMouseFunc(mouse);        //注册鼠标事件。
    glutMotionFunc(move);        //注册移动事件
		glutIdleFunc( SpinDisplay );//注册旋转

    glutMainLoop();  
    return EXIT_SUCCESS;  
}  
 
/* 找旋转轴   (辅助用)  */
void huaxyz()
{

	//第一
	//画坐标系

	float xt1=-scaleNum*4.6;//向右 +
	float yt1=-scaleNum*92.4;//向上 + 
	float zt1=-scaleNum*14.6;//向屏幕外 +

	glTranslatef(xt1,0.0f,0.0f);// x1
	glTranslatef(0.0f,yt1,0.0f);// y轴移动  y1
	glTranslatef(0.0f,0.0f,zt1);// z1
	//
	//  1. 画坐标轴(直线)
    glColor3f(1.0, 0.0, 0.0); // --> 红色  
    GLfloat curSizeLine=5;//线宽
    glLineWidth(curSizeLine); 

   //glBegin(GL_LINES);//x轴
   //glVertex3f(-800.0f,0.0f,0.0f);
   //glVertex3f(800.0f,0.0f,0.0f); 
   // 
   // glEnd();

   glBegin(GL_LINES);//y轴
   glVertex3f(0.0f,-800.0f,0.0f);
   glVertex3f(0.0f,800.0f,0.0f); 
    
    glEnd();

   //glBegin(GL_LINES);//z轴
   //glVertex3f(0.0f,0.0f,-800.0f);
   //glVertex3f(0.0f,0.0f,800.0f); 
   // 
   // glEnd();

	//第二==================================================
				float xt2 = scaleNum*7.1,
					zt2=  scaleNum*5.3;

				glTranslatef(xt2,0.0f,zt2);

	//  2. 画坐标轴(直线)
	glColor3f(0.0, 1.0, 0.0); // --> 绿色  

   glBegin(GL_LINES);//x轴
   glVertex3f(-800.0f,0.0f,0.0f);
   glVertex3f(800.0f,0.0f,0.0f); 
    
    glEnd();

   //glBegin(GL_LINES);//y轴
   //glVertex3f(0.0f,-800.0f,0.0f);
   //glVertex3f(0.0f,800.0f,0.0f); 
   // 
   // glEnd();

   //glBegin(GL_LINES);//z轴
   //glVertex3f(0.0f,0.0f,-800.0f);
   //glVertex3f(0.0f,0.0f,800.0f); 
   // 
   // glEnd();

	第三==================================================
	yt1=scaleNum*35;//向上 + 
	zt1=scaleNum*45;;//向屏幕外 +

	glTranslatef(0.0f,yt1,0.0f);// y轴移动  y1
	glTranslatef(0.0f,0.0f,zt1);// z1

	//  2. 画坐标轴(直线)
	glColor3f(0.0, 0.0, 1.0); // --> 蓝色  

   glBegin(GL_LINES);//x轴
   glVertex3f(-800.0f,0.0f,0.0f);
   glVertex3f(800.0f,0.0f,0.0f); 
    
    glEnd();

   //glBegin(GL_LINES);//y轴
   //glVertex3f(0.0f,-800.0f,0.0f);
   //glVertex3f(0.0f,800.0f,0.0f); 
   // 
   // glEnd();

   //glBegin(GL_LINES);//z轴
   //glVertex3f(0.0f,0.0f,-800.0f);
   //glVertex3f(0.0f,0.0f,800.0f); 
   // 
   // glEnd();

	第四==================================================
	yt1=-scaleNum*23;//向上 + 
	zt1=scaleNum*16;;//向屏幕外 +

	glTranslatef(0.0f,yt1,0.0f);// y轴移动  y1
	glTranslatef(0.0f,0.0f,zt1);// z1

	//  2. 画坐标轴(直线)
	glColor3f(1.0, 0.0, 1.0); // --> 紫色  

   glBegin(GL_LINES);//x轴
   glVertex3f(-800.0f,0.0f,0.0f);
   glVertex3f(800.0f,0.0f,0.0f); 
    
    glEnd();

   //glBegin(GL_LINES);//y轴
   //glVertex3f(0.0f,-800.0f,0.0f);
   //glVertex3f(0.0f,800.0f,0.0f); 
   // 
   // glEnd();

   //glBegin(GL_LINES);//z轴
   //glVertex3f(0.0f,0.0f,-800.0f);
   //glVertex3f(0.0f,0.0f,800.0f); 
   // 
   // glEnd();
}
由于液压传动没有实现,所以在全代码已经除掉这部分不显示了(见上代码中)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值