예제 #1
0
void MD5_GenerateLightingInfo (md5_mesh_t* mesh)
{
	int verticesCounter;
	int weightCounter;
	//User for tangent space generation
	vec3_t v1,v2,normal;
	
	vec3_t* normalAccumulator;
	vec3_t* normalWeightAccumulator;

	vec3_t tangent;
	float coef;
	vec3_t jointSpaceTangent;
	vec2_t st1,st2;
	vec3_t* tangentAccumulator;
	vec3_t* tangentWeightAccumulator;

	
	vertex_t* currentVertex = NULL;
	md5_vertex_t* md5Vertex;
	int facesCounter;
	
	md5_weight_t* weight;
	md5_bone_t* bone;
	md5_triangle_t* currentFace;
	
	vec3_t jointSpaceNormal;
	
	normalAccumulator		=	calloc(mesh->numVertices, sizeof(vec3_t));
	normalWeightAccumulator =	calloc(mesh->numWeights, sizeof(vec3_t));

	tangentAccumulator		=	calloc(mesh->numVertices, sizeof(vec3_t));
	tangentWeightAccumulator=	calloc(mesh->numWeights, sizeof(vec3_t));

	
	//printf("\nGenerating normal and tangents.\n");

	
	//Generate the normal and tangent per face
	currentFace = mesh->triangles;
	for(facesCounter = 0; facesCounter < mesh->numTriangles ; facesCounter++,currentFace++)
	{
		
		// Normal part
		vectorSubtract(mesh->vertexArray[currentFace->index[2]].pos , mesh->vertexArray[currentFace->index[0]].pos, v1);
		vectorSubtract(mesh->vertexArray[currentFace->index[1]].pos , mesh->vertexArray[currentFace->index[0]].pos, v2);
		vectorCrossProduct(v2,v1,normal);
		
		normalize(normal);
		
		vectorAdd(normalAccumulator[currentFace->index[0]],normal,normalAccumulator[currentFace->index[0]]);
		vectorAdd(normalAccumulator[currentFace->index[1]],normal,normalAccumulator[currentFace->index[1]]);
		vectorAdd(normalAccumulator[currentFace->index[2]],normal,normalAccumulator[currentFace->index[2]]);
		
		
		// The following part is from "Mathematic for 3D programming" by Eric Lengyel
		// Tangent part
		


		vector2Subtract(mesh->vertexArray[currentFace->index[2]].text,mesh->vertexArray[currentFace->index[0]].text,st1);
		vector2Subtract(mesh->vertexArray[currentFace->index[1]].text,mesh->vertexArray[currentFace->index[0]].text,st2);
		
		vector2Scale(st1,1/(float)32767,st1);
		vector2Scale(st2,1/(float)32767,st2);
		
		if (st1[0] == 0.0f && st2[0] == 0.0f)
		{
			st1[0] = 0.1f ; 
			st2[0] = 0.1f;
		}
		
		if (st1[1] == 0.0f && st2[1] == 0.0f)
		{
			st1[1] = 0.1f ;
			st2[1] = 0.1f;
		}
		
		
		coef = 1/ (st1[0] * st2[1] - st2[0] * st1[1]);
		
		
		
		tangent[0] = coef * (v1[0] * st2[1]  + v2[0] * -st1[1]);
		tangent[1] = coef * (v1[1] * st2[1]  + v2[1] * -st1[1]);
		tangent[2] = coef * (v1[2] * st2[1]  + v2[2] * -st1[1]);
		
		normalize(tangent);		
		
		
		vectorAdd(tangentAccumulator[currentFace->index[0]],tangent,tangentAccumulator[currentFace->index[0]]);
		vectorAdd(tangentAccumulator[currentFace->index[1]],tangent,tangentAccumulator[currentFace->index[1]]);
		vectorAdd(tangentAccumulator[currentFace->index[2]],tangent,tangentAccumulator[currentFace->index[2]]);
		
		
		
	}
	
	//Normalize accumulated normal and tangent
	for(verticesCounter=0 ; verticesCounter < mesh->numVertices ; verticesCounter++,currentVertex++)
	{
		
		
		normalize(normalAccumulator[verticesCounter]);
//		printf("normalized accumulated normal [%d][%.2f,%.2f,%.2f]\n",verticesCounter,normalAccumulator[verticesCounter][0],normalAccumulator[verticesCounter][1],normalAccumulator[verticesCounter][2]);
		normalize(tangentAccumulator[verticesCounter]);
//		printf("normalized accumulated tangent [%d][%.2f,%.2f,%.2f]\n",verticesCounter,tangentAccumulator[verticesCounter][0],tangentAccumulator[verticesCounter][1],tangentAccumulator[verticesCounter][2]);
	}
	
	//Now we have all the normal for this model, but need to transform them in bone space for re-usage
	// Translating the normal orientation from object to joint space and Store normals inside weights, 
	md5Vertex = mesh->vertices;
	currentVertex = mesh->vertexArray;
	for(verticesCounter=0 ; verticesCounter < mesh->numVertices ; verticesCounter++,md5Vertex++)
	{
		for (weightCounter = 0; weightCounter < md5Vertex->count; weightCounter++)
		{
			weight = &mesh->weights[md5Vertex->start + weightCounter];
			bone  = &mesh->bones[weight->boneId];
			
			multiplyByInvertQuaternion(normalAccumulator[verticesCounter],bone->orientation,jointSpaceNormal);
			vectorAdd(normalWeightAccumulator[md5Vertex->start + weightCounter],jointSpaceNormal,normalWeightAccumulator[md5Vertex->start + weightCounter]);
					
			multiplyByInvertQuaternion(tangentAccumulator[verticesCounter],bone->orientation,jointSpaceTangent);
			vectorAdd(tangentWeightAccumulator[md5Vertex->start + weightCounter],jointSpaceTangent,tangentWeightAccumulator[md5Vertex->start + weightCounter]);			
		}
		
	}
	
	weight = mesh->weights;
	for (weightCounter = 0; weightCounter < mesh->numWeights; weightCounter++,weight++)
	{
		normalize(normalWeightAccumulator[weightCounter]);
		vectorScale(normalWeightAccumulator[weightCounter],32767,weight->boneSpaceNormal);
		
		normalize(tangentWeightAccumulator[weightCounter]);
		vectorScale(tangentWeightAccumulator[weightCounter],32767,weight->boneSpaceTangent);
			
	}
	
	free(normalAccumulator);
	free(normalWeightAccumulator);

	free(tangentAccumulator);
	free(tangentWeightAccumulator);

}
예제 #2
0
void GenerateLightingInfo (const md5_mesh_t *mesh, md5_joint_t *skeleton)
{

	int verticesCounter;
	int weightCounter;
	//User for tangent space generation
	vec3_t v1,v2,normal;
	
	vec3_t* normalAccumulator;
	vec3_t* normalWeightAccumulator;
	#ifdef TANGENT_ENABLED
	vec3_t tangent;
	float coef;
	vec3_t jointSpaceTangent;
	vec2_t st1,st2;
	vec3_t* tangentAccumulator;
	vec3_t* tangentWeightAccumulator;
	#endif
	
	vertex_t* currentVertex = NULL;
	md5_vertex_t* md5Vertex;
	int facesCounter;
	
	md5_weight_t* weight;
	md5_joint_t* joint;
	md5_triangle_t* currentFace;
	
	vec3_t jointSpaceNormal;
	
	normalAccumulator = calloc(mesh->num_verts, sizeof(vec3_t));
	normalWeightAccumulator = calloc(mesh->num_weights, sizeof(vec3_t));
 	#ifdef TANGENT_ENABLED
	tangentAccumulator = calloc(mesh->num_verts, sizeof(vec3_t));
	tangentWeightAccumulator  = calloc(mesh->num_weights, sizeof(vec3_t));
	#endif
	
	//Set all textures coordinate once for all.
	currentVertex = mesh->vertexArray;
	for(verticesCounter=0 ; verticesCounter < mesh->num_verts ; verticesCounter++,currentVertex++)
	{
		currentVertex->text[0] = mesh->vertices[verticesCounter].st[0];
		currentVertex->text[1] = mesh->vertices[verticesCounter].st[1];
	}
	
	currentFace = mesh->triangles;
	for(facesCounter = 0; facesCounter < mesh->num_tris ; facesCounter++,currentFace++)
	{
		
		// Normal part
		vectorSubtract(mesh->vertexArray[currentFace->index[2]].pos , mesh->vertexArray[currentFace->index[0]].pos, v1);
		vectorSubtract(mesh->vertexArray[currentFace->index[1]].pos , mesh->vertexArray[currentFace->index[0]].pos, v2);
		vectorCrossProduct(v2,v1,normal);
		
		vectorAdd(normalAccumulator[currentFace->index[0]],normal,normalAccumulator[currentFace->index[0]]);
		vectorAdd(normalAccumulator[currentFace->index[1]],normal,normalAccumulator[currentFace->index[1]]);
		vectorAdd(normalAccumulator[currentFace->index[2]],normal,normalAccumulator[currentFace->index[2]]);
		
		
		// The following part is from "Mathematic for 3D programming" by Eric Lengyel
		// Tangent part
		#ifdef TANGENT_ENABLED
		vector2Subtract(mesh->vertexArray[currentFace->index[2]].text,mesh->vertexArray[currentFace->index[0]].text,st1);
		vector2Subtract(mesh->vertexArray[currentFace->index[1]].text,mesh->vertexArray[currentFace->index[0]].text,st2);
		
		coef = 1/ (st1[0] * st2[1] - st2[0] * st1[1]);
		
		tangent[0] = coef * (v1[0] * st2[1]  + v2[0] * -st1[1]);
		tangent[1] = coef * (v1[1] * st2[1]  + v2[1] * -st1[1]);
		tangent[2] = coef * (v1[2] * st2[1]  + v2[2] * -st1[1]);
		
		vectorAdd(tangentAccumulator[currentFace->index[0]],tangent,tangentAccumulator[currentFace->index[0]]);
		vectorAdd(tangentAccumulator[currentFace->index[1]],tangent,tangentAccumulator[currentFace->index[1]]);
		vectorAdd(tangentAccumulator[currentFace->index[2]],tangent,tangentAccumulator[currentFace->index[2]]);
						
		#endif
	}
	
	
	for(verticesCounter=0 ; verticesCounter < mesh->num_verts ; verticesCounter++,currentVertex++)
	{
		normalize(normalAccumulator[verticesCounter]);
		#ifdef TANGENT_ENABLED			
		normalize(tangentAccumulator[verticesCounter]);
		#endif
	}
	
	//Now we have all the normal for this model, but need to transform them in bone space for re-usage
	// Translating the normal orientation from object to joint space and Store normals inside weights, 
	md5Vertex = mesh->vertices;
	currentVertex = mesh->vertexArray;
	for(verticesCounter=0 ; verticesCounter < mesh->num_verts ; verticesCounter++,md5Vertex++)
	{
		for (weightCounter = 0; weightCounter < md5Vertex->count; weightCounter++)
		{
			weight = &mesh->weights[md5Vertex->start + weightCounter];
			joint  = &skeleton[weight->joint];
			
			multiplyByInvertQuaternion(normalAccumulator[verticesCounter],joint->orient,jointSpaceNormal);
			vectorAdd(normalWeightAccumulator[md5Vertex->start + weightCounter],jointSpaceNormal,normalWeightAccumulator[md5Vertex->start + weightCounter]);
						
			#ifdef TANGENT_ENABLED			
			multiplyByInvertQuaternion(tangentAccumulator[verticesCounter],joint->orient,jointSpaceTangent);
			vectorAdd(tangentWeightAccumulator[md5Vertex->start + weightCounter],jointSpaceTangent,tangentWeightAccumulator[md5Vertex->start + weightCounter]);
			#endif
						
		}
		
	}
	
	weight = mesh->weights;
	for (weightCounter = 0; weightCounter < mesh->num_weights; weightCounter++,weight++)
	{
		normalize(normalWeightAccumulator[weightCounter]);
		vectorScale(normalWeightAccumulator[weightCounter],32767,weight->normal);
		#ifdef TANGENT_ENABLED			
			normalize(tangentWeightAccumulator[weightCounter]);
		vectorScale(tangentWeightAccumulator[weightCounter],32767,weight->tangent);
		#endif			
	}
	
	free(normalAccumulator);
	free(normalWeightAccumulator);
	#ifdef TANGENT_ENABLED	
	free(tangentAccumulator);
	free(tangentWeightAccumulator);
	#endif	
}