📄 ase.cpp
字号:
///////////////////////////////// READ OBJECT INFO \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function reads in the information about the object, but not the data
/////
///////////////////////////////// READ OBJECT INFO \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CLoadASE::ReadObjectInfo(t3DObject *pObject, int desiredObject)
{
char strWord[255] = {0};
// In this function we position the file pointer to the object we want
// to read in, then we read until we find the associated tags, then read the info.
// Go to the desired object to read from in the file
MoveToObject(desiredObject);
// While we are not at the end of the file
while (!feof(m_FilePointer))
{
// Read in each word from the file to check against
fscanf(m_FilePointer, "%s", &strWord);
// If we hit the number of vertices tag
if (!strcmp(strWord, NUM_VERTEX))
{
// Read in the number of vertices for this object
fscanf(m_FilePointer, "%d", &pObject->numOfVerts);
// Allocate enough memory to hold the vertices
pObject->pVerts = new CVector3 [pObject->numOfVerts];
}
// If we hit the number of faces tag
else if (!strcmp(strWord, NUM_FACES))
{
// Read in the number of faces for this object
fscanf(m_FilePointer, "%d", &pObject->numOfFaces);
// Allocate enough memory to hold the faces
pObject->pFaces = new tFace [pObject->numOfFaces];
}
// If we hit the number of texture vertices tag
else if (!strcmp(strWord, NUM_TVERTEX))
{
// Read in the number of texture coordinates for this object
fscanf(m_FilePointer, "%d", &pObject->numTexVertex);
// Allocate enough memory for the UV coordinates
pObject->pTexVerts = new CVector2 [pObject->numTexVertex];
}
// If we hit the object tag we want to stop cause we went to far
else if (!strcmp(strWord, OBJECT))
{
// Return if we get to the next object
return;
}
else
{
// We didn't find anything we want to check for so we read to the next line
fgets(strWord, 100, m_FilePointer);
}
}
}
///////////////////////////////// GET TEXTURE NAME \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function reads in the file name of the texture assigned to the object
/////
///////////////////////////////// GET TEXTURE NAME \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CLoadASE::GetTextureName(tMaterialInfo *pTexture)
{
// Read in the texture's file name
fscanf (m_FilePointer, " \"%s", &(pTexture->strFile));
// Put a NULL character at the end of the string
pTexture->strFile[strlen (pTexture->strFile) - 1] = '\0';
}
///////////////////////////////// GET MATERIAL NAME \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function reads in the material name of the object
/////
///////////////////////////////// GET MATERIAL NAME \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CLoadASE::GetMaterialName(tMaterialInfo *pTexture)
{
// Read in the material's name (Make sure this is just one word or it won't work well)
fscanf (m_FilePointer, " \"%s", &(pTexture->strName));
// Put a NULL character at the end of the string just in case
pTexture->strName[strlen (pTexture->strName)] = '\0';
}
///////////////////////////////// READ OBJECT DATA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function calls the functions that query and read in the desired data
/////
///////////////////////////////// READ OBJECT DATA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CLoadASE::ReadObjectData(t3DModel *pModel, t3DObject *pObject, int desiredObject)
{
// This will go through the file every time for each data tag and
// read in the data for that tag. We pass in the desired object to read it from.
// This isn't the fastest way in the world, but it works fine. The best way
// for reading models in from this format would be to create a program that
// converts the data to binary so you don't have to query, but load it in straightway.
// Load the material ID for this object
GetData(pModel, pObject, MATERIAL_ID, desiredObject);
// Load the vertices for this object
GetData(pModel, pObject, VERTEX, desiredObject);
// Load the texture coordinates for this object
GetData(pModel, pObject, TVERTEX, desiredObject);
// Load the vertex faces list for this object
GetData(pModel, pObject, FACE, desiredObject);
// Load the texture face list for this object
GetData(pModel, pObject, TFACE, desiredObject);
// Load the texture for this object
GetData(pModel, pObject, TEXTURE, desiredObject);
// Load the U tile for this object
GetData(pModel, pObject, UTILE, desiredObject);
// Load the V tile for this object
GetData(pModel, pObject, VTILE, desiredObject);
}
///////////////////////////////// GET DATA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function is the loop for reading in the object data
/////
///////////////////////////////// GET DATA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CLoadASE::GetData(t3DModel *pModel, t3DObject *pObject, char *strDesiredData, int desiredObject)
{
char strWord[255] = {0};
// In here, we move the file pointer to the desired object we want to read in,
// then we query all the tags that are being read in. If we find a valid tag,
// then we need to check if that's the tag that we want to read in. If so,
// then we read it in.
// Move the file pointer to the desired object
MoveToObject(desiredObject);
// Go through the file until we reach the end
while(!feof(m_FilePointer))
{
// Read in every word to check it against tags
fscanf(m_FilePointer, "%s", &strWord);
// If we reached an object tag, stop read because we went to far
if(!strcmp(strWord, OBJECT))
{
// Stop reading because we are done with the current object
return;
}
// If we hit a vertex tag
else if(!strcmp(strWord, VERTEX))
{
// Make sure that is the data that we want to read in
if(!strcmp(strDesiredData, VERTEX))
{
// Read in a vertex
ReadVertex(pObject);
}
}
// If we hit a texture vertex
else if(!strcmp(strWord, TVERTEX))
{
// Make sure that is the data that we want to read in
if(!strcmp(strDesiredData, TVERTEX))
{
// Read in a texture vertex
ReadTextureVertex(pObject, pModel->pMaterials[pObject->materialID]);
}
}
// If we hit a vertice index to a face
else if(!strcmp(strWord, FACE))
{
// Make sure that is the data that we want to read in
if(!strcmp(strDesiredData, FACE))
{
// Read in a face
ReadFace(pObject);
}
}
// If we hit a texture index to a face
else if(!strcmp(strWord, TFACE))
{
// Make sure that is the data that we want to read in
if(!strcmp(strDesiredData, TFACE))
{
// Read in a texture indice for a face
ReadTextureFace(pObject);
}
}
// If we hit the material ID to the object
else if(!strcmp(strWord, MATERIAL_ID))
{
// Make sure that is the data that we want to read in
if(!strcmp(strDesiredData, MATERIAL_ID))
{
// Read in the material ID assigned to this object
pObject->materialID = (int)ReadFloat();
return;
}
}
else
{
// We must not care about this tag read so read past the whole line
fgets(strWord, 100, m_FilePointer);
}
}
}
///////////////////////////////// READ VERTEX \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function reads in the vertices for the object
/////
///////////////////////////////// READ VERTEX \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CLoadASE::ReadVertex(t3DObject *pObject)
{
int index = 0;
// Read past the vertex index
fscanf(m_FilePointer, "%d", &index);
// Here we read in the vertice's (X, Y, Z). Since 3D Studio Max has Z pointing
// up, we are going to swap the Y and Z to make it normal. Otherwise we would need
// to rotate it around the X axis by -90 degrees: glRotatef(-90, 1.0f, 0.0f, 0.0f);
fscanf(m_FilePointer, "%f %f %f", &pObject->pVerts[index].x,
&pObject->pVerts[index].z,
&pObject->pVerts[index].y);
// Also in 3D studio max the Z goes out of the screen so we want to swap that too.
// We do that by negating the Z value of each vertex.
pObject->pVerts[index].z = -pObject->pVerts[index].z;
}
///////////////////////////////// READ TEXTURE VERTEX \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function reads in the texture coordinates
/////
///////////////////////////////// READ TEXTURE VERTEX \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CLoadASE::ReadTextureVertex(t3DObject *pObject, tMaterialInfo texture)
{
int index = 0;
// Here we read past the index of the texture coordinate
fscanf(m_FilePointer, "%d", &index);
// Next, we read in the (U, V) texture coordinates.
fscanf(m_FilePointer, "%f %f", &(pObject->pTexVerts[index].x), &(pObject->pTexVerts[index].y));
// What is being done here is we are multiplying a X and Y tile factor
// to the UV coordinate. Usually the uTile and vTile is 1, but if it depends on
// your UVW map. If you made the texture tile more along the object, these would change.
pObject->pTexVerts[index].x *= texture.uTile;
pObject->pTexVerts[index].y *= texture.vTile;
// We know this object has a texture so let's set this true
pObject->bHasTexture = true;
}
///////////////////////////////// READ FACE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function reads in the indices to the array of vertices
/////
///////////////////////////////// READ FACE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CLoadASE::ReadFace(t3DObject *pObject)
{
int index = 0;
// Read past the index of this Face
fscanf(m_FilePointer, "%d:", &index);
// Now we read in the actual vertex indices; One index for each point in the triangle.
// These indices will index into the vertex array pVerts[].
fscanf(m_FilePointer, "\tA:\t%d B:\t%d C:\t%d", &(pObject->pFaces[index].vertIndex[0]),
&(pObject->pFaces[index].vertIndex[1]),
&(pObject->pFaces[index].vertIndex[2]));
}
///////////////////////////////// READ TEXTURE FACE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function reads in the indices to the texture coordinate array
/////
///////////////////////////////// READ TEXTURE FACE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void CLoadASE::ReadTextureFace(t3DObject *pObject)
{
int index = 0;
// Read past the index for this texture coordinate
fscanf(m_FilePointer, "%d:", &index);
// Now we read in the UV coordinate index for the current face.
// This will be an index into pTexCoords[] for each point in the face.
fscanf(m_FilePointer, "%d %d %d", &pObject->pFaces[index].coordIndex[0],
&pObject->pFaces[index].coordIndex[1],
&pObject->pFaces[index].coordIndex[2]);
}
// Below are some math functions for calculating vertex normals. We want vertex normals
// because it makes the lighting look really smooth and life like. You probably already
// have these functions in the rest of your engine, so you can delete these and call
// your own. I wanted to add them so I could show how to calculate vertex normals.
////////////////////////////// Math Functions ////////////////////////////////*
// This computes the magnitude of a normal. (magnitude = sqrt(x^2 + y^2 + z^2)
#define Mag(Normal) (sqrt(Normal.x*Normal.x + Normal.y*Normal.y + Normal.z*Normal.z))
// This calculates a vector between 2 points and returns the result
CVector3 Vector(CVector3 vPoint1, CVector3 vPoint2)
{
CVector3 vVector; // The variable to hold the resultant vector
vVector.x = vPoint1.x - vPoint2.x; // Subtract point1 and point2 x's
vVector.y = vPoint1.y - vPoint2.y; // Subtract point1 and point2 y's
vVector.z = vPoint1.z - vPoint2.z; // Subtract point1 and point2 z's
return vVector; // Return the resultant vector
}
// This adds 2 vectors together and returns the result
CVector3 AddVector(CVector3 vVector1, CVector3 vVector2)
{
CVector3 vResult; // The variable to hold the resultant vector
vResult.x = vVector2.x + vVector1.x; // Add Vector1 and Vector2 x's
vResult.y = vVector2.y + vVector1.y; // Add Vector1 and Vector2 y's
vResult.z = vVector2.z + vVector1.z; // Add Vector1 and Vector2 z's
return vResult; // Return the resultant vector
}
// This divides a vector by a single number (scalar) and returns the result
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -