Ejemplo n.º 1
0
Archivo: Ase.cpp Proyecto: RinM/CGA
void CLoadASE::ComputeNormals(t3DModel *pModel)
{
	CVector3 vVector1, vVector2, vNormal, vPoly[3];

	if(pModel->numOfObjects <= 0)
		return;

	for(int index = 0; index < pModel->numOfObjects; index++)
	{
		t3DObject *pObject = &(pModel->pObject[index]);

		CVector3 *pNormals		= new CVector3 [pObject->numOfFaces];
		CVector3 *pTempNormals	= new CVector3 [pObject->numOfFaces];
		pObject->pNormals		= new CVector3 [pObject->numOfVerts];

		for(int i=0; i < pObject->numOfFaces; i++)
		{												
			vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]];
			vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]];
			vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]];

			vVector1 = Vector(vPoly[0], vPoly[2]);
			vVector2 = Vector(vPoly[2], vPoly[1]);

			vNormal  = Cross(vVector1, vVector2);
			pTempNormals[i] = vNormal;			
			vNormal  = Normalize(vNormal);
			pObject->pFaces[i].Normal=MultiplieVectorByScaler(vNormal,-1.0f);
			pNormals[i] = vNormal;
		}

		CVector3 vSum = {0.0, 0.0, 0.0};
		CVector3 vZero = vSum;
		int shared=0;

		for(int i = 0; i < pObject->numOfVerts; i++)
		{
			for (int j = 0; j < pObject->numOfFaces; j++)
			{											
				if (pObject->pFaces[j].vertIndex[0] == i || 
					pObject->pFaces[j].vertIndex[1] == i || 
					pObject->pFaces[j].vertIndex[2] == i)
				{
					vSum = AddVector(vSum, pTempNormals[j]);
					shared++;								
				}
			}      
			
			pObject->pNormals[i] = DivideVectorByScaler(vSum, float(-shared));

			pObject->pNormals[i] = Normalize(pObject->pNormals[i]);	

			vSum = vZero;									
			shared = 0;										
		}
	
		delete [] pTempNormals;
		delete [] pNormals;
	}
}
Ejemplo n.º 2
0
//  下面的函数用于计算对象的法向量
void CLoad3DS::ComputeNormals(t3DModel *pModel)
{ 
	CVector3 vVector1, vVector2, vNormal, vPoly[3];
	// 如果模型中没有对象,则返回
	if(pModel->numOfObjects <= 0)
		return;
	// 遍历模型中所有的对象
	for(int index = 0; index < pModel->numOfObjects; index++)
	{
		// 获得当前的对象
		t3DObject *pObject = &(pModel->pObject[index]);
		// 分配需要的存储空间
		CVector3 *pNormals  = new CVector3 [pObject->numOfFaces];
		CVector3 *pTempNormals = new CVector3 [pObject->numOfFaces];
		pObject->pNormals  = new CVector3 [pObject->numOfVerts];
		// 遍历对象的所有面
		for(int i=0; i < pObject->numOfFaces; i++)
		{
			vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]];
			vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]];
			vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]];
			// 计算面的法向量
			vVector1 = Vector(vPoly[0], vPoly[2]);  // 获得多边形的矢量
			vVector2 = Vector(vPoly[2], vPoly[1]);  // 获得多边形的第二个矢量
			vNormal  = Cross(vVector1, vVector2);  // 获得两个矢量的叉积
			pTempNormals[i] = vNormal;     // 保存非规范化法向量
			vNormal  = Normalize(vNormal);    // 规范化获得的叉积
			pNormals[i] = vNormal;      // 将法向量添加到法向量列表中
		}
		//  下面求顶点法向量
		CVector3 vSum = {0.0, 0.0, 0.0};
		CVector3 vZero = vSum;
		int shared=0;
		// 遍历所有的顶点
		for (int i = 0; i < pObject->numOfVerts; i++)   
		{ 
			for (int j = 0; j < pObject->numOfFaces; j++) // 遍历所有的三角形面
			{            // 判断该点是否与其它的面共享
				if (pObject->pFaces[j].vertIndex[0] == i || 
					pObject->pFaces[j].vertIndex[1] == i || 
					pObject->pFaces[j].vertIndex[2] == i)
				{ vSum = AddVector(vSum, pTempNormals[j]);
				shared++;        
				}
			}      
			pObject->pNormals[i] = DivideVectorByScaler(vSum, float(-shared));
			// 规范化最后的顶点法向
			pObject->pNormals[i] = Normalize(pObject->pNormals[i]); 
			vSum = vZero;        
			shared = 0;          
		}
		// 释放存储空间,开始下一个对象
		delete [] pTempNormals;
		delete [] pNormals;
	}
}
Ejemplo n.º 3
0
void CLoad3DS::ComputeNormals(t3DModel *pModel)
{
	CVector3 vVector1, vVector2, vNormal, vPoly[3];

	// If there are no objects, we can skip this part
	if(pModel->numOfObjects <= 0)
		return;

	// What are vertex normals?  And how are they different from other normals?
	// Well, if you find the normal to a triangle, you are finding a "Face Normal".
	// If you give OpenGL a face normal for lighting, it will make your object look
	// really flat and not very round.  If we find the normal for each vertex, it makes
	// the smooth lighting look.  This also covers up blocky looking objects and they appear
	// to have more polygons than they do.    Basically, what you do is first
	// calculate the face normals, then you take the average of all the normals around each
	// vertex.  It's just averaging.  That way you get a better approximation for that vertex.

	// Go through each of the objects to calculate their normals
	for(int index = 0; index < pModel->numOfObjects; index++)
	{
		// Get the current object
		t3DObject *pObject = &(pModel->pObject[index]);

		// Here we allocate all the memory we need to calculate the normals
		CVector3 *pNormals		= new CVector3 [pObject->numOfFaces];
		CVector3 *pTempNormals	= new CVector3 [pObject->numOfFaces];
		pObject->pNormals		= new CVector3 [pObject->numOfVerts];

		// Go though all of the faces of this object
		for(int i=0; i < pObject->numOfFaces; i++)
		{												
			// To cut down LARGE code, we extract the 3 points of this face
			vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]];
			vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]];
			vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]];

			// Now let's calculate the face normals (Get 2 vectors and find the cross product of those 2)

			vVector1 = Vector(vPoly[0], vPoly[2]);		// Get the vector of the polygon (we just need 2 sides for the normal)
			vVector2 = Vector(vPoly[2], vPoly[1]);		// Get a second vector of the polygon

			vNormal  = Cross(vVector1, vVector2);		// Return the cross product of the 2 vectors (normalize vector, but not a unit vector)
			pTempNormals[i] = vNormal;					// Save the un-normalized normal for the vertex normals
			vNormal  = Normalize(vNormal);				// Normalize the cross product to give us the polygons normal

			pNormals[i] = vNormal;						// Assign the normal to the list of normals
		}

		//////////////// Now Get The Vertex Normals /////////////////

		CVector3 vSum = {0.0, 0.0, 0.0};
		CVector3 vZero = vSum;
		int shared=0;

		for (int i = 0; i < pObject->numOfVerts; i++)			// Go through all of the vertices
		{
			for (int j = 0; j < pObject->numOfFaces; j++)	// Go through all of the triangles
			{												// Check if the vertex is shared by another face
				if (pObject->pFaces[j].vertIndex[0] == i || 
					pObject->pFaces[j].vertIndex[1] == i || 
					pObject->pFaces[j].vertIndex[2] == i)
				{
					vSum = AddVector(vSum, pTempNormals[j]);// Add the un-normalized normal of the shared face
					shared++;								// Increase the number of shared triangles
				}
			}      
			
			// Get the normal by dividing the sum by the shared.  We negate the shared so it has the normals pointing out.
			pObject->pNormals[i] = DivideVectorByScaler(vSum, float(-shared));

			// Normalize the normal for the final vertex normal
			pObject->pNormals[i] = Normalize(pObject->pNormals[i]);	

			vSum = vZero;									// Reset the sum
			shared = 0;										// Reset the shared
		}
	
		// Free our memory and start over on the next object
		delete [] pTempNormals;
		delete [] pNormals;
	}
}
Ejemplo n.º 4
0
/** computes the normals and vertex normals of the objects */
void Obj::computeNormals(tOBJModel *pmodel)
{
  Vec3 vVector1, vVector2, vNormal, vPoly[3];

  if (pmodel->numOfObjects <= 0) return; // if there are no objects, we can skip

  for (int index = 0; index < pmodel->numOfObjects; index++) { // for each of the objects
    tOBJObject *pobject = &(pmodel->pObject[index]); // get the current object

    Vec3 *pNormals     = new Vec3 [pobject->numOfFaces];
    Vec3 *pTempNormals = new Vec3 [pobject->numOfFaces];
    pobject->pNormals  = new Vec3 [pobject->numOfVerts];

    for (int i=0; i < pobject->numOfFaces; i++) { // go though all of the faces
      // we extract the 3 points of this face
      int vx = pobject->pFaces[i].vertIndex[0];
      int vy = pobject->pFaces[i].vertIndex[1];
      int vz = pobject->pFaces[i].vertIndex[2];
      int vc = pobject->numOfVerts;
      if (vx > vc || vy > vc || vz > vc) {
        error("Obj: vx=%d vy=%d vz=%d vc=%d", vx, vy, vz, vc);
        continue;	//dax BUG: segfault
      }
      vPoly[0] = pobject->pVerts[pobject->pFaces[i].vertIndex[0]];
      vPoly[1] = pobject->pVerts[pobject->pFaces[i].vertIndex[1]];
      vPoly[2] = pobject->pVerts[pobject->pFaces[i].vertIndex[2]];

      // let's calculate the face normals (get 2 vectors and find the cross product of those 2)
      vVector1 = Vector(vPoly[0], vPoly[2]); // get the vector of the polygon (we just need 2 sides)
      vVector2 = Vector(vPoly[2], vPoly[1]); // get a second vector of the polygon
      vNormal  = Cross(vVector1, vVector2);  // return the cross product of the 2 vectors
      pTempNormals[i] = vNormal;     // save the un-normalized normal for the vertex normals
      vNormal = Normalize(vNormal);  // normalize the cross product to give us the polygons normal
      pNormals[i] = vNormal;         // assign the normal to the list of normals
    }

    Vec3 vSum = {0.0, 0.0, 0.0};
    Vec3 vZero = vSum;
    int shared=0;

    // get the vertex normals
    for (int i=0; i < pobject->numOfVerts; i++) {  // go through all of the vertices
      for (int j=0; j < pobject->numOfFaces; j++) {// go through all of the triangles
        // check if the vertex is shared by another face
        if (pobject->pFaces[j].vertIndex[0] == i ||
            pobject->pFaces[j].vertIndex[1] == i ||
            pobject->pFaces[j].vertIndex[2] == i) {
          vSum = AddVector(vSum, pTempNormals[j]); // add the unnormalized normal of the shared face
          shared++;                // increase the number of shared triangles
        }
      }
      // get the normal by dividing the sum by the shared. we negate so normals pointing out.
      pobject->pNormals[i] = DivideVectorByScaler(vSum, float(-shared));

      // normalize the normal for the final vertex normal
      pobject->pNormals[i] = Normalize(pobject->pNormals[i]);
      vSum = vZero;                  // reset the sum
      shared = 0;                    // reset the shared
    }
    if (pTempNormals) delete[] pTempNormals;
    if (pNormals) delete[] pNormals;
  }
}
Ejemplo n.º 5
0
Archivo: Ase.cpp Proyecto: RinM/CGA
void CLoadASE::ComputeTangents(t3DModel *pModel)
{
	CVector3 vVector1, vVector2, vTangent, vBinormal, vPoly[3];
	float vVector1s, vVector1t, vVector2s, vVector2t;
	float v1s, v1t, v2s, v2t, v3s, v3t;

	CVector3 vSum = {0.0, 0.0, 0.0};
	CVector3 vZero = vSum;
	int shared=0;

	if(pModel->numOfObjects <= 0)
		return;

	for(int index = 0; index < pModel->numOfObjects; index++)
	{
		t3DObject *pObject = &(pModel->pObject[index]);

		CVector3 *pTangents		= new CVector3 [pObject->numOfFaces];
		CVector3 *pTempTangents	= new CVector3 [pObject->numOfFaces];
		pObject->pTangents		= new CVector3 [pObject->numOfVerts];
	
		CVector3 *pBinormals	 = new CVector3 [pObject->numOfFaces];
		CVector3 *pTempBinormals = new CVector3 [pObject->numOfFaces];
		pObject->pBinormals		 = new CVector3 [pObject->numOfVerts];
		
		for(int i=0; i < pObject->numOfFaces; i++)
		{												
			vPoly[0] = pObject->pVerts[pObject->pFaces[i].vertIndex[0]];
			vPoly[1] = pObject->pVerts[pObject->pFaces[i].vertIndex[1]];
			vPoly[2] = pObject->pVerts[pObject->pFaces[i].vertIndex[2]];

			v1s = pObject->pTexVerts[pObject->pFaces[i].coordIndex[0]].x;
			v1t = pObject->pTexVerts[pObject->pFaces[i].coordIndex[0]].y;

			v2s = pObject->pTexVerts[pObject->pFaces[i].coordIndex[1]].x;
			v2t = pObject->pTexVerts[pObject->pFaces[i].coordIndex[1]].y;

			v3s = pObject->pTexVerts[pObject->pFaces[i].coordIndex[2]].x;
			v3t = pObject->pTexVerts[pObject->pFaces[i].coordIndex[2]].y;

			vVector1 = Vector(vPoly[1], vPoly[0]);
			vVector2 = Vector(vPoly[2], vPoly[0]);

			vVector1s = v2s-v1s;
			vVector1t = v2t-v1t;

			vVector2s = v3s-v1s;
			vVector2t = v3t-v1t;

			float denominator = vVector1s * vVector2t - vVector2s * vVector1t;

			if(denominator < 0.0001f && denominator > -0.0001f)
			{
				vTangent.x = 1.0f;
				vTangent.y = 0.0f;
				vTangent.z = 0.0f;

				vBinormal.x = 0.0f;
				vBinormal.y = 1.0f;
				vBinormal.z = 0.0f;

				pTempTangents[i] = vTangent;
				pTempBinormals[i] = vBinormal;
			}
			else
			{
				float scale = 1.0f / denominator;

				CVector3 T, B, N;

				T.x = (vVector2t * vVector1.x - vVector1t * vVector2.x) * scale;
				T.y = (vVector2t * vVector1.y - vVector1t * vVector2.y) * scale;
				T.z = (vVector2t * vVector1.z - vVector1t * vVector2.z) * scale;

				B.x = (-vVector2s * vVector1.x + vVector1s * vVector2.x) * scale;
				B.y = (-vVector2s * vVector1.y + vVector1s * vVector2.y) * scale;
				B.z = (-vVector2s * vVector1.z + vVector1s * vVector2.z) * scale;

				N = pObject->pFaces[i].Normal;

				float scale2 = 1.0f / ((T.x * B.y * N.z - T.z * B.y * N.x) + 
									   (B.x * N.y * T.z - B.z * N.y * T.x) + 
									   (N.x * T.y * B.z - N.z * T.y * B.x));

				vTangent.x =  Cross(B, N).x * scale2;
				vTangent.y = -Cross(N, T).x * scale2;
				vTangent.z =  Cross(T, B).x * scale2;
				pTempTangents[i] = vTangent;
				vTangent=Normalize(vTangent);

				vBinormal.x = -Cross(B, N).y * scale2;
				vBinormal.y =  Cross(N, T).y * scale2;
				vBinormal.z = -Cross(T, B).y * scale2;
				pTempBinormals[i] = vBinormal;
				vBinormal=Normalize(vBinormal);
	
			}
					
		}
		
		vZero = vSum;
		shared=0;

		for(int i = 0; i < pObject->numOfVerts; i++)
		{
			for (int j = 0; j < pObject->numOfFaces; j++)
			{			
				if (pObject->pFaces[j].vertIndex[0] == i || 
					pObject->pFaces[j].vertIndex[1] == i || 
					pObject->pFaces[j].vertIndex[2] == i)
				{
					vSum = AddVector(vSum, pTempTangents[j]);
					shared++;
				}
			}      
			
			pObject->pTangents[i] = DivideVectorByScaler(vSum, float(shared));
			pObject->pTangents[i] = Normalize(pObject->pTangents[i]);	

			vSum = vZero;
			shared = 0;
		}
	
		delete [] pTempTangents;
		delete [] pTangents;

		vZero = vSum;
		shared=0;

		for(int i = 0; i < pObject->numOfVerts; i++)
		{
			for (int j = 0; j < pObject->numOfFaces; j++)
			{											
				if (pObject->pFaces[j].vertIndex[0] == i || 
					pObject->pFaces[j].vertIndex[1] == i || 
					pObject->pFaces[j].vertIndex[2] == i)
				{
					vSum = AddVector(vSum, pTempBinormals[j]);
					shared++;
				}
			}      
			
			pObject->pBinormals[i] = DivideVectorByScaler(vSum, float(-shared));
			pObject->pBinormals[i] = Normalize(pObject->pBinormals[i]);	

			vSum = vZero;
			shared = 0;
		}
	
		delete [] pTempBinormals;
		delete [] pBinormals;
		
	}
	
}
Ejemplo n.º 6
0
void ComputeNormals(Loader3ds *pt3ds) 
{ 
 int i,j,index; 
 int shared=0; 
	float	v1x=0.0,v1y=0.0,v1z=0.0, 
			v2x=0.0,v2y=0.0,v2z=0.0, 
			vnx=0.0,vny=0.0,vnz=0.0, 
			vp0x=0.0,vp0y=0.0,vp0z=0.0, 
			vp1x=0.0,vp1y=0.0,vp1z=0.0, 
			vp2x=0.0,vp2y=0.0,vp2z=0.0, 
			*pNormals=NULL, 
			*pTempNormals=NULL, 
			vSumx = 0.0,vSumy = 0.0,vSumz = 0.0;	 
 	Objects *cur_obj; 

	// If there are no objects, we can skip this part 
	if(pt3ds->NBobjects <= 0) 
		return; 
 
	// Go through each of the objects to calculate their normals 
	cur_obj = pt3ds->objects; 
	for(index = 0; index < pt3ds->NBobjects; index++) 
	{ 
		pNormals		= (float*)malloc(sizeof(float) *(3*cur_obj->NBFaces)); 
		pTempNormals	= (float*)malloc(sizeof(float) * (3*cur_obj->NBFaces)); 
		cur_obj->Normal = (float*)malloc(sizeof(float) * (3*cur_obj->NBvert)); 
 
 
		// Go though all of the faces of this object 
		for(i=0; i < cur_obj->NBFaces; i++) 
		  {
			vp0x=cur_obj->vert[0+3*cur_obj->Faces[i*3]]; 
			vp0y=cur_obj->vert[1+3*cur_obj->Faces[i*3]]; 
			vp0z=cur_obj->vert[2+3*cur_obj->Faces[i*3]]; 
 
			vp1x=cur_obj->vert[0+3*cur_obj->Faces[i*3+1]]; 
			vp1y=cur_obj->vert[1+3*cur_obj->Faces[i*3+1]]; 
			vp1z=cur_obj->vert[2+3*cur_obj->Faces[i*3+1]]; 
 
			vp2x=cur_obj->vert[0+3*cur_obj->Faces[i*3+2]]; 
			vp2y=cur_obj->vert[1+3*cur_obj->Faces[i*3+2]]; 
			vp2z=cur_obj->vert[2+3*cur_obj->Faces[i*3+2]]; 
  
			Vector(	vp0x,vp0y,vp0z, 
					vp2x,vp2y,vp2z, 
					&v1x,&v1y,&v1z);		// Get the vector of the polygon (we just need 2 sides for the normal) 
 
			Vector(	vp2x,vp2y,vp2z, 
					vp1x,vp1y,vp1z, 
					&v2x,&v2y,&v2z);		// Get a second vector of the polygon 
			 
			Cross(	v1x,v1y,v1z, 
					v2x,v2y,v2z, 
					&vnx,&vny,&vnz);		// Return the cross product of the 2 vectors (normalize vector, but not a unit vector) 
 
			pTempNormals[3*i] = vnx;					// Save the un-normalized normal for the vertex normals 
			pTempNormals[3*i+1] = vny;					// Save the un-normalized normal for the vertex normals 
			pTempNormals[3*i+2] = vnz;					// Save the un-normalized normal for the vertex normals 
 
			Normalize(&vnx,&vny,&vnz);				// Normalize the cross product to give us the polygons normal 
 
			pNormals[3*i] = vnx;						// Assign the normal to the list of normals 
			pNormals[3*i+1] = vny;						// Assign the normal to the list of normals 
			pNormals[3*i+2] = vnz;						// Assign the normal to the list of normals 
		} 
 
		//////////////// Now Get The Vertex Normals ///////////////// 
 
		vSumx = 0.0;vSumy = 0.0;vSumz = 0.0;		 
		shared=0; 
 
		for (i = 0; i < cur_obj->NBvert; i++)			// Go through all of the vertices 
		{ 
			for (j = 0; j < cur_obj->NBFaces; j++)	// Go through all of the triangles 
			{												// Check if the vertex is shared by another face 
				if (cur_obj->Faces[j*3]   == i ||  
					cur_obj->Faces[j*3+1] == i ||  
					cur_obj->Faces[j*3+2] == i) 
				{ 
					AddVector(	vSumx,vSumy,vSumz, 
								pTempNormals[j*3],pTempNormals[j*3+1],pTempNormals[j*3+2], 
								&vSumx,&vSumy,&vSumz);// Add the un-normalized normal of the shared face 
					shared++;								// Increase the number of shared triangles 
				} 
			}       
			 
			// Get the normal by dividing the sum by the shared.  We negate the shared so it has the normals pointing out. 
			 DivideVectorByScaler(	vSumx,vSumy,vSumz, 
									&(cur_obj->Normal[i*3]), 
									&(cur_obj->Normal[i*3+1]), 
									&(cur_obj->Normal[i*3+2]), 
									-(float)shared); 
 
			// Normalize the normal for the final vertex normal 
			Normalize(	&(cur_obj->Normal[i*3]), 
						&(cur_obj->Normal[i*3+1]), 
						&(cur_obj->Normal[i*3+2]));	 
 
			vSumx = 0.0;vSumy = 0.0;vSumz = 0.0;			// Reset the sum 
			shared = 0;										// Reset the shared 
		} 
		 
	if (pNormals) free(pNormals); 
	if (pTempNormals) free(pTempNormals); 
	cur_obj=cur_obj->next; 
	}//end for index 
}