//-------------------------------------------------------------------------
FKCW_3D_Mesh* CreateConeMesh(float r,float h,int nSlice,int nStack,bool isHaveBottom,
							const FKCW_3D_Vector4&headColor,const FKCW_3D_Vector4&bottomColor)
	//why cone need nStack ? because even a plane need subdivision to achieve better specular effect
{
	float dA=360.0f/nSlice;
	const float PIDIV180= static_cast<float>(M_PI/180.0f);
	vector<FKCW_3D_Vector4> positionList;
	vector<FKCW_3D_Vector2> texCoordList;
	vector<FKCW_3D_Vector4> normalList;
	vector<FKCW_3D_Vector4> colorList;
	vector<FKCW_3D_IDTriangle> IDtriList;
	//----generate side
	//generate positionList, texCoordList, normalList, colorList
	for(int i=0;i<=nStack;i++){
		float y=i*h/nStack;
		for (int j=0; j<=nSlice; j++) {
			float A=j*dA;
			float R=r-i*r/nStack;
			float cosA=cosf(A*PIDIV180);
			float sinA=sinf(A*PIDIV180);
			float x=R*cosA;
			float z=R*sinA;
			FKCW_3D_Vector4 position(x,y,z,1);
			float s=(float)j/nSlice+0.25f;
			float t=1-(float)i/nStack;
			FKCW_3D_Vector2 texCoord(s,t);
			float ny=r/sqrtf(FKCW_Square(h)+FKCW_Square(r));
			float nx,nz;//nx*nx+ny*ny+nz*nz=1 and nx:nz=cosA:sinA => k=sqrt((1-ny*ny)/(cosA*cosA+sinA*sinA)), nx=cosA*k, nz=sinA*k
			float k=sqrtf((1-ny*ny)/(cosA*cosA+sinA*sinA));
			nx=cosA*k;
			nz=sinA*k;
			FKCW_3D_Vector4 normal=normalize(FKCW_3D_Vector4(nx,ny,nz,0));
			FKCW_3D_Vector4 color=bottomColor*(1-(float)i/nStack)+headColor*((float)i/nStack);
			positionList.push_back(position);
			texCoordList.push_back(texCoord);
			normalList.push_back(normal);
			colorList.push_back(color);
		}
	}
	//generate IDtriList
	for(int i=0;i<nStack;i++){
		for(int j=0;j<nSlice;j++){
			int vID_ld=(nSlice+1)*i+j;
			int vID_rd=vID_ld+1;
			int vID_ru=vID_rd+(nSlice+1);
			int vID_lu=vID_ru-1;
			FKCW_3D_IDTriangle IDtri0(vID_ld,vID_rd,vID_ru);
			FKCW_3D_IDTriangle IDtri1(vID_ld,vID_ru,vID_lu);
			IDtriList.push_back(IDtri0);
			IDtriList.push_back(IDtri1);
		}
	}

	//----generate bottom
	if(isHaveBottom){
		vector<FKCW_3D_Vector4> _positionList=positionList;
		vector<FKCW_3D_Vector2> _texCoordList=texCoordList;
		vector<FKCW_3D_Vector4> _normalList=normalList;
		vector<FKCW_3D_Vector4> _colorList=colorList;
		vector<FKCW_3D_IDTriangle> _IDtriList=IDtriList;
		//all postion in _positionList set y to zero
		int _nPosition=(int)_positionList.size();
		for(int i=0;i<_nPosition;i++){
			FKCW_3D_Vector4&position=_positionList[i];
			position.sety(0);
		}
		//all normal in _normalList set to (0,-1,0,0)
		int _nNormal=(int)_normalList.size();
		for(int i=0;i<_nNormal;i++){
			FKCW_3D_Vector4&normal=_normalList[i];
			normal=FKCW_3D_Vector4(0, -1, 0, 0);
		}
		//all index in _IDtriList should be plus offset=(int)positionList.size()
		const int offset=(int)positionList.size();
		int _nIDtri=(int)_IDtriList.size();
		for(int i=0;i<_nIDtri;i++){
			FKCW_3D_IDTriangle&IDtri=_IDtriList[i];
			int ID0=IDtri.vID(0);
			int ID1=IDtri.vID(1);
			int ID2=IDtri.vID(2);
			IDtri.init(ID0+offset, ID1+offset, ID2+offset);
		}
		//connect side and bottom
		positionList=connectList(positionList,_positionList);
		texCoordList=connectList(texCoordList,_texCoordList);
		normalList=connectList(normalList,_normalList);
		colorList=connectList(colorList,_colorList);
		IDtriList=connectList(IDtriList,_IDtriList);
	}

	//----create mesh
	FKCW_3D_SubMeshData*subMeshData=new FKCW_3D_SubMeshData();
	subMeshData->autorelease();
	subMeshData->init();
	subMeshData->initPositionList(positionList);
	subMeshData->initTexCoordList(texCoordList);
	subMeshData->initNormalList(normalList);
	subMeshData->initColorList(colorList);
	subMeshData->initIDtriList(IDtriList);
	FKCW_3D_SubMesh* subMesh=new FKCW_3D_SubMesh();
	subMesh->autorelease();
	subMesh->init();
	subMesh->setSubMeshData(subMeshData);
	FKCW_3D_Mesh* mesh=new FKCW_3D_Mesh();
	mesh->autorelease();
	mesh->init();
	mesh->addSubMesh(subMesh);
	return mesh;
}
예제 #2
0
void Cball::makeBall(float r,int nSlice,int nStack,string texFilePath){
	
	//make ball
	float dA=360.0/nSlice;
    float dB=180.0/nStack;
    const float PIDIV180=c3d_PI/180;
    vector<Cc3dVector4> positionList;
    vector<Cc3dVector2> texCoordList;
    vector<Cc3dVector4> normalList;
    vector<Cc3dIDTriangle> IDtriList;
    //generate positionList, texCoordList, normalList, colorList
    for(int i=0;i<=nStack;i++){
        float B=-90+i*dB;
        float y=r*sinf(B*PIDIV180);
        float cosB=cosf(B*PIDIV180);
        for (int j=0; j<=nSlice; j++) {
            float A=j*dA;
            float R=r*cosB;
            float x=R*cosf(A*PIDIV180);
            float z=R*sinf(A*PIDIV180);
            Cc3dVector4 position(x,y,z,1);
            float s=(float)j/nSlice+0.25;
            float t=1-(float)i/nStack;
            Cc3dVector2 texCoord(s,t);
            Cc3dVector4 normal=normalize(cc3dv4(position.x(), position.y(), position.z(), 0));
            positionList.push_back(position);
            texCoordList.push_back(texCoord);
            normalList.push_back(normal);
        }
    }
    //generate IDtriList
    for(int i=0;i<nStack;i++){
        for(int j=0;j<nSlice;j++){
            int vID_ld=(nSlice+1)*i+j;
            int vID_rd=vID_ld+1;
            int vID_ru=vID_rd+(nSlice+1);
            int vID_lu=vID_ru-1;
            Cc3dIDTriangle IDtri0(vID_ld,vID_rd,vID_ru);
            Cc3dIDTriangle IDtri1(vID_ld,vID_ru,vID_lu);
            IDtriList.push_back(IDtri0);
            IDtriList.push_back(IDtri1);
        }
    }
    Cc3dSubMesh*subMesh=new Cc3dSubMesh();
	subMesh->autorelease();
	int nPos=(int)positionList.size();
	for(int i=0;i<nPos;i++){
		Cc3dVector4&pos=positionList[i];
		Cc3dVector2&texCoord=texCoordList[i];
		Cc3dVector4&norm=normalList[i];
		subMesh->addVertex(Cc3dVertex(pos,texCoord,norm));
	}
	int nIDtri=(int)IDtriList.size();
	for(int i=0;i<nIDtri;i++){
		Cc3dIDTriangle&IDtri=IDtriList[i];
		subMesh->addIDtri(IDtri);
	}


	//--texture
	if(texFilePath.empty()==false){
		Cc3dTexture*texture=Cc3dTextureCache::sharedTextureCache()->addImage(texFilePath,GL_CLAMP_TO_EDGE,GL_CLAMP_TO_EDGE);
		subMesh->setTexture(texture);
	}

	//----mesh
	Cc3dMesh*mesh=new Cc3dMesh();
	mesh->autorelease();
	mesh->addSubMesh(subMesh);
	//----model
	this->addMesh(mesh);
}
//-------------------------------------------------------------------------
FKCW_3D_Mesh* CreateBallMesh(float r,int nSlice,int nStack,
							const FKCW_3D_Vector4&northPoleColor,const FKCW_3D_Vector4&southPoleColor)
{
	float dA=360.0f/nSlice;
	float dB=180.0f/nStack;
	const float PIDIV180=static_cast<float>(M_PI/180.0f);
	vector<FKCW_3D_Vector4> positionList;
	vector<FKCW_3D_Vector2> texCoordList;
	vector<FKCW_3D_Vector4> normalList;
	vector<FKCW_3D_Vector4> colorList;
	vector<FKCW_3D_IDTriangle> IDtriList;
	//generate positionList, texCoordList, normalList, colorList
	for(int i=0;i<=nStack;i++){
		float B=-90+i*dB;
		float y=r*sinf(B*PIDIV180);
		float cosB=cosf(B*PIDIV180);
		for (int j=0; j<=nSlice; j++) {
			float A=j*dA;
			float R=r*cosB;
			float x=R*cosf(A*PIDIV180);
			float z=R*sinf(A*PIDIV180);
			FKCW_3D_Vector4 position(x,y,z,1);
			float s=(float)j/nSlice+0.25f;
			float t=1-(float)i/nStack;
			FKCW_3D_Vector2 texCoord(s,t);
			FKCW_3D_Vector4 normal=normalize(FKCW_3D_Vector4(position.x(), position.y(), position.z(), 0));
			FKCW_3D_Vector4 color=southPoleColor*(1-(float)i/nStack)+northPoleColor*((float)i/nStack);
			positionList.push_back(position);
			texCoordList.push_back(texCoord);
			normalList.push_back(normal);
			colorList.push_back(color);
		}
	}
	//generate IDtriList
	for(int i=0;i<nStack;i++){
		for(int j=0;j<nSlice;j++){
			int vID_ld=(nSlice+1)*i+j;
			int vID_rd=vID_ld+1;
			int vID_ru=vID_rd+(nSlice+1);
			int vID_lu=vID_ru-1;
			FKCW_3D_IDTriangle IDtri0(vID_ld,vID_rd,vID_ru);
			FKCW_3D_IDTriangle IDtri1(vID_ld,vID_ru,vID_lu);
			IDtriList.push_back(IDtri0);
			IDtriList.push_back(IDtri1);
		}
	}
	FKCW_3D_SubMeshData*subMeshData=new FKCW_3D_SubMeshData();
	subMeshData->autorelease();
	subMeshData->init();
	subMeshData->initPositionList(positionList);
	subMeshData->initTexCoordList(texCoordList);
	subMeshData->initNormalList(normalList);
	subMeshData->initColorList(colorList);
	subMeshData->initIDtriList(IDtriList);
	FKCW_3D_SubMesh* subMesh=new FKCW_3D_SubMesh();
	subMesh->autorelease();
	subMesh->init();
	subMesh->setSubMeshData(subMeshData);
	FKCW_3D_Mesh* mesh=new FKCW_3D_Mesh();
	mesh->autorelease();
	mesh->init();
	mesh->addSubMesh(subMesh);
	return mesh;
}