⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ase.cpp

📁 Zodspark is a Car racing simulation game built on VC++ using opengl library
💻 CPP
📖 第 1 页 / 共 3 页
字号:
CVector3 DivideVectorByScaler(CVector3 vVector1, float Scaler)
{
	CVector3 vResult;							// The variable to hold the resultant vector
	
	vResult.x = vVector1.x / Scaler;			// Divide Vector1's x value by the scaler
	vResult.y = vVector1.y / Scaler;			// Divide Vector1's y value by the scaler
	vResult.z = vVector1.z / Scaler;			// Divide Vector1's z value by the scaler

	return vResult;								// Return the resultant vector
}

// This returns the cross product between 2 vectors
CVector3 Cross(CVector3 vVector1, CVector3 vVector2)
{
	CVector3 vCross;								// The vector to hold the cross product
												// Get the X value
	vCross.x = ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y));
												// Get the Y value
	vCross.y = ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z));
												// Get the Z value
	vCross.z = ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x));

	return vCross;								// Return the cross product
}

// This returns the normal of a vector
CVector3 Normalize(CVector3 vNormal)
{
	double Magnitude;							// This holds the magnitude			

	Magnitude = Mag(vNormal);					// Get the magnitude

	vNormal.x /= (float)Magnitude;				// Divide the vector's X by the magnitude
	vNormal.y /= (float)Magnitude;				// Divide the vector's Y by the magnitude
	vNormal.z /= (float)Magnitude;				// Divide the vector's Z by the magnitude

	return vNormal;								// Return the normal
}

///////////////////////////////// COMPUTER NORMALS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function computes the normals and vertex normals of the objects
/////
///////////////////////////////// COMPUTER NORMALS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void CLoadASE::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;
	}
}


/////////////////////////////////////////////////////////////////////////////////
//
// * QUICK NOTES * 
//
// This tutorial shows how to load a .Ase file.  An ASE file is a 3D Studio Max
// ASCII file that saves all the information in a text file instead of in binary.
// The good thing about this is that it's easy to read in, as well as easy
// to change without having the software.  The bad thing is that it's a HUGE
// file size, it takes a lot longer to read in, no other programs support it
// and it can't even be imported back into 3D Studio Max.  I would recommend
// looking at this tutorial before you look at the 3DS tutorial though.  That
// way you can see what is actually being read in.
//
// Let me mention that the math functions above are not so important and don't
// need to be in this file.  I wanted to show how to calculate vertex normals so your
// models would have some excellent lighting.  You most likely have functions already
// that do the basics so I encourage you to just use those.  This will cut down the code
// significantly.
// 
// * What's An STL (Standard Template Library) Vector? *
// Let me quickly explain the STL vector for those of you who are not familiar with them.
// To use a vector you must include <vector> and use the std namespace: using namespace std;
// A vector is an array based link list.  It allows you to dynamically add and remove nodes.
// This is a template class so it can be a list of ANY type.  To create a vector of type
// "int" you would say:  vector<int> myIntList;
// Now you can add a integer to the dynamic array by saying: myIntList.push_back(10);
// or you can say:  myIntList.push_back(num);.  The more you push back, the larger
// your array gets.  You can index the vector like an array.  myIntList[0] = 0;
// To get rid of a node you use the pop_back() function.  To clear the vector use clear().
// It frees itself so you don't need to worry about it, except if you have data
// structures that need information freed from inside them, like our objects.
//
// Let's go over some of the format of the .Ase file.  I will only address the
// information that we really care about for object loading.  The rest is Scene stuff.
// I created a single box around the origin that had a texture map over it to show
// the simplest and smallest amount of data.
// 
// This next block is the material block.  This holds all the info on the materials.
//
//	*MATERIAL_LIST {			// This is the tag for the start of the material info
//	*MATERIAL_COUNT 1			// This tells us how many materials there are
//	*MATERIAL 0 {				// This is the material ID that the next data is refering too.
//		*MATERIAL_NAME "Material #1"	// The material name
//		*MATERIAL_CLASS "Standard"
//		*MATERIAL_AMBIENT 0.1791	0.0654	0.0654
//		*MATERIAL_DIFFUSE 0.5373	0.1961	0.1961	// The color of the object
//		*MATERIAL_SPECULAR 0.9000	0.9000	0.9000
//		*MATERIAL_SHINE 0.2500
//		*MATERIAL_SHINESTRENGTH 0.0500
//		*MATERIAL_TRANSPARENCY 0.0000
//		*MATERIAL_WIRESIZE 1.0000
//		*MATERIAL_SHADING Blinn
//		*MATERIAL_XP_FALLOFF 0.0000
//		*MATERIAL_SELFILLUM 0.0000
//		*MATERIAL_FALLOFF In
//		*MATERIAL_XP_TYPE Filter
//		*MAP_DIFFUSE {
//			*MAP_NAME "Map #1"
//			*MAP_CLASS "Bitmap"
//			*MAP_SUBNO 1
//			*MAP_AMOUNT 1.0000
//			*BITMAP "texture.bmp"		// This is the file name for the texture
//			*MAP_TYPE Screen
//			*UVW_U_OFFSET 0.0000		// This is the U offset for the tile
//			*UVW_V_OFFSET 0.0000		// This is the V offset for the tile
//			*UVW_U_TILING 1.0000		// This is the U tiling ratio (1 is standard)
//			*UVW_V_TILING 1.0000		// This is the V tiling ratio (1 is standard)
//			*UVW_ANGLE 0.0000
//			*UVW_BLUR 1.0000
//			*UVW_BLUR_OFFSET 0.0000
//			*UVW_NOUSE_AMT 1.0000
//			*UVW_NOISE_SIZE 1.0000
//			*UVW_NOISE_LEVEL 1
//			*UVW_NOISE_PHASE 0.0000
//			*BITMAP_FILTER Pyramidal
//		}
//    }
// }
//
//
//
//*GEOMOBJECT {							// This tag let's us know that objects are next
//	*NODE_NAME "Box01"					// This is the object name
//	*NODE_TM {
//		*NODE_NAME "Box01"				// Once again, this is the objects name
//		*INHERIT_POS 0 0 0
//		*INHERIT_ROT 0 0 0
//		*INHERIT_SCL 0 0 0
//		*TM_ROW0 1.0000	0.0000	0.0000
//		*TM_ROW1 0.0000	1.0000	0.0000
//		*TM_ROW2 0.0000	0.0000	1.0000
//		*TM_ROW3 0.0000	0.0000	0.0000
//		*TM_POS 0.0000	0.0000	0.0000
//		*TM_ROTAXIS 0.0000	0.0000	0.0000
//		*TM_ROTANGLE 0.0000
//		*TM_SCALE 1.0000	1.0000	1.0000
//		*TM_SCALEAXIS 0.0000	0.0000	0.0000
//		*TM_SCALEAXISANG 0.0000
//	}
//	*MESH {								// This tells us an objects data is next
//		*TIMEVALUE 0					
//		*MESH_NUMVERTEX 8				// This holds the number of vertices for this object
//		*MESH_NUMFACES 12				// This is the number of faces in this object
//		*MESH_VERTEX_LIST {				// The tag for the start of the vertex list
//			*MESH_VERTEX    0	-1.5000	-1.5000	0.0000	// These next 8 are the vertices.
//			*MESH_VERTEX    1	1.5000	-1.5000	0.0000	// The first number is the index
//			*MESH_VERTEX    2	-1.5000	1.5000	0.0000  // and the next 3 are the (X, Y, Z)
//			*MESH_VERTEX    3	1.5000	1.5000	0.0000  // ...
//			*MESH_VERTEX    4	-1.5000	-1.5000	3.0000
//			*MESH_VERTEX    5	1.5000	-1.5000	3.0000
//			*MESH_VERTEX    6	-1.5000	1.5000	3.0000
//			*MESH_VERTEX    7	1.5000	1.5000	3.0000
//		}
//
//		// Below is the tag for the face list.  We have a list of vertices and texture coordinates.
//		// Each of these vertices and coordinates are unique.  This cuts down memory.
//      // We then have a structure that holds index's into the vertex and UV array.
//		// After *MESH_FACE it has the index, then the A B and C values.  These values
//		// are for point1 point2 and point3 indices into the vertex array. The rest can
//      // be ignored.  They have to do with visibility issues.
//
//		*MESH_FACE_LIST {				
//			*MESH_FACE    0:    A:    0 B:    2 C:    3 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 2 	*MESH_MTLID 1
//			*MESH_FACE    1:    A:    3 B:    1 C:    0 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 2 	*MESH_MTLID 1
//			*MESH_FACE    2:    A:    4 B:    5 C:    7 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 3 	*MESH_MTLID 0
//			*MESH_FACE    3:    A:    7 B:    6 C:    4 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 3 	*MESH_MTLID 0
//			*MESH_FACE    4:    A:    0 B:    1 C:    5 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 4 	*MESH_MTLID 4
//			*MESH_FACE    5:    A:    5 B:    4 C:    0 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 4 	*MESH_MTLID 4
//			*MESH_FACE    6:    A:    1 B:    3 C:    7 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 5 	*MESH_MTLID 3
//			*MESH_FACE    7:    A:    7 B:    5 C:    1 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 5 	*MESH_MTLID 3
//			*MESH_FACE    8:    A:    3 B:    2 C:    6 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 6 	*MESH_MTLID 5
//			*MESH_FACE    9:    A:    6 B:    7 C:    3 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 6 	*MESH_MTLID 5
//			*MESH_FACE   10:    A:    2 B:    0 C:    4 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 7 	*MESH_MTLID 2
//			*MESH_FACE   11:    A:    4 B:    6 C:    2 AB:    1 BC:    1 CA:    0	 *MESH_SMOOTHING 7 	*MESH_MTLID 2
//		}
//		*MESH_NUMTVERTEX 36					// This is the number of texture coordinates for this object
//
//		// The next block is the texture coordinates.  The first value after *MESH_TVERT
//      // is the index and the next 2 values are the ones we care about.  The third is ignored.
//      // The 2 we care about are the U and V values for the vertices.
//
//		*MESH_TVERTLIST {					// The tag to let us know there are UV coordiantes
//			*MESH_TVERT 0	0.9995	0.0005	0.0005 // Format: Index   U  V   Ignore
//			*MESH_TVERT 1	0.0005	0.0005	0.9995
//			*MESH_TVERT 2	0.0005	0.0005	0.0005
//			*MESH_TVERT 3	0.0005	0.0005	0.9995
//			*MESH_TVERT 4	0.9995	0.9995	0.0005
//			*MESH_TVERT 5	0.0005	0.9995	0.9995
//			*MESH_TVERT 6	0.0005	0.9995	0.0005
//			*MESH_TVERT 7	0.0005	0.9995	0.9995
//			*MESH_TVERT 8	0.9995	0.0005	0.0005
//			*MESH_TVERT 9	0.9995	0.9995	0.0005
//			*MESH_TVERT 10	0.0005	0.9995	0.0005
//			*MESH_TVERT 11	0.0005	0.9995	0.0005
//			*MESH_TVERT 12	0.0005	0.0005	0.0005
//			*MESH_TVERT 13	0.9995	0.0005	0.0005
//			*MESH_TVERT 14	0.0005	0.0005	0.9995
//			*MESH_TVERT 15	0.9995	0.0005	0.9995
//			*MESH_TVERT 16	0.9995	0.9995	0.9995
//			*MESH_TVERT 17	0.9995	0.9995	0.9995
//			*MESH_TVERT 18	0.0005	0.9995	0.9995
//			*MESH_TVERT 19	0.0005	0.0005	0.9995
//			*MESH_TVERT 20	0.0005	0.0005	0.0005
//			*MESH_TVERT 21	0.9995	0.0005	0.0005
//			*MESH_TVERT 22	0.9995	0.9995	0.0005
//			*MESH_TVERT 23	0.9995	0.9995	0.0005
//			*MESH_TVERT 24	0.0005	0.9995	0.0005
//			*MESH_TVERT 25	0.0005	0.0005	0.0005
//			*MESH_TVERT 26	0.0005	0.0005	0.9995
//			*MESH_TVERT 27	0.9995	0.0005	0.9995
//			*MESH_TVERT 28	0.9995	0.9995	0.9995
//			*MESH_TVERT 29	0.9995	0.9995	0.9995
//			*MESH_TVERT 30	0.0005	0.0005	0.9995
//			*MESH_TVERT 31	0.9995	0.0005	0.9995
//			*MESH_TVERT 32	0.9995	0.9995	0.9995
//			*MESH_TVERT 33	0.9995	0.9995	0.9995
//			*MESH_TVERT 34	0.0005	0.0005	0.0005
//			*MESH_TVERT 35	0.9995	0.9995	0.0005
//		}
//
//		// This next block is the indices for the faces into the texture coordinate array.
//      // Just like the vertex indices with the A B and C values, these do work the same.
//		// We use the 3 values to index the UV coordinates in the texture coordinate array.
//		// The format after the *MESH_TFACE is:  The face index, then the 3 indices into the array.
//      // For example, the top line below has a 0 for the index (not read in)
//      // the next is an 8, which will be used to index the 8th texture coordinate in the
//      // array.  Like so:  int coordIndex = pObject->pFaces[j].coordIndex[whichVertex];
//		// If j was zero and whichVertex was zero, coordIndex would be 8.  Get it?
//
//		*MESH_NUMTVFACES 12				// This is the number of textured faces
//		*MESH_TFACELIST {				// This tag tells us the UV indices are next
//			*MESH_TFACE 0	8	9	10	// Format: faceIndex UVIndex1  UVIndex2  UVIndex3
//			*MESH_TFACE 1	11	12	13  // ...
//			*MESH_TFACE 2	14	15	16
//			*MESH_TFACE 3	17	18	19
//			*MESH_TFACE 4	20	21	22
//			*MESH_TFACE 5	23	24	25
//			*MESH_TFACE 6	26	27	28
//			*MESH_TFACE 7	29	5	1
//			*MESH_TFACE 8	30	31	32
//			*MESH_TFACE 9	33	7	3
//			*MESH_TFACE 10	34	0	35
//			*MESH_TFACE 11	4	6	2
//		}
//	}
//	
// So that's the main stuff.  There is more things like animation and normals but
// I prefer to calculate my own normals, because not all formats have vertex normals
// and animation is a huge topic not to be discussed in a file format tutorial :)
// For those of you who don't know what vertex normals are, it means you have a normal
// for not just every polygon, but for every vertex.  That makes lighting more real looking.
// Also it makes the models look more smooth.
//
// *Note* - Remember after saving your .Ase file, to delete the path in front
// of the texture name.  You want: "texture.bmp" verses "C:\MyStuff\Pictures\texture.bmp"
// That way you can just stick the bitmap in the same folder as the program and not be
// dependant on paths.
//
// I hope this helped someone out.  Let us know at GameTutorials.com what you do with
// this.  We are always interested.  Eventually there will probably be an animation
// tutorial for this format so stay in touch.
//
// Ben Humphrey (DigiBen)
// Game Programmer
// DigiBen@GameTutorials.com
// Co-Web Host of www.GameTutorials.com
// 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -