3DS Max R4.2 Exporter Plugin Texturing Problem
Dear all,
It seems that I am still having problems with my 3D model importer and eignafx''s tip
on drawing all the 3 vertices of all the faces in the model didn''t seem to help. So, if
anybody knows how I can fix the problem, please tell me.
Here is my Max 4.2 exporter code (all source code from here and output at the end):
// Write basic mesh data (excluding bone data) to file.
bool writeMeshData(
INode* ptrINode,
fstream& m_fsOutFile,
ofstream* ofsTextFile
)
{
// If selected node is not valid and is not a mesh.
if ((!ptrINode)||(!IsMesh(ptrINode)))
{
// Return failure.
return false;
}
// Get transformation matrix for the selected mesh.
Matrix3 tm = ptrINode->GetObjectTM(0);
// Get the state of the selected mesh.
ObjectState os = ptrINode->EvalWorldState(0);
int iDummy;
// Get a handle to the mesh.
Mesh& mesh = *(( (GeomObject*) os.obj)->
GetRenderMesh(0,ptrINode,s_nullView,iDummy));
// Gets the current position in file.
long lStartPosition = m_fsOutFile.tellg();
// Skip the mesh header section.
m_fsOutFile.seekg( sizeof(StructS3DMesh), ios::cur);
/////////////////////////////////////////////////////////////////
// Write StructS3DModelVertex
/////////////////////////////////////////////////////////////////
/////
*ofsTextFile << "\n" << "[StructS3DModelVertex Section]" << "\n";
// Create a mesh header.
StructS3DMesh structs3dmeshHeader;
// Allocate memory for the mesh header.
memset(&structs3dmeshHeader, 0, sizeof(StructS3DMesh));
// Get the mesh vertex count.
structs3dmeshHeader.m_iS3dmodelvertexCount = mesh.getNumVerts();
// Get the offset in the file to the StructS3DModelVertex section.
structs3dmeshHeader.m_lS3dmodelvertexOffset = m_fsOutFile.tellg();
// build the normals
mesh.buildNormals();
// Loop through all the vertices
for(
int i = 0;
i < structs3dmeshHeader.m_iS3dmodelvertexCount;
i++
)
{
// Get the vertex coordinates.
// Remember to multiply by Max''s transformation matrix.
Point3 pnt = mesh.getVert(i) * tm;
// Get the vertex normals.
Point3 norm = Normalize(mesh.getNormal(i));
// Get the vertex texture coordinates.
UVVert uvTexCoordinates = getTextureUV(i, &mesh);
// Create temporary StructS3DModelVertex structure.
StructS3DModelVertex structs3dmodelvertexTemp;
// Allocate memory for the vertex structure.
memset(
&structs3dmodelvertexTemp,
0,
sizeof(StructS3DModelVertex)
);
// Store the collected vertex data into
// our structure to be written to file.
structs3dmodelvertexTemp.m_iX = pnt.x;
structs3dmodelvertexTemp.m_iY = pnt.z;
structs3dmodelvertexTemp.m_iZ = pnt.y;
structs3dmodelvertexTemp.m_iNormX = norm.x;
structs3dmodelvertexTemp.m_iNormY = norm.z;
structs3dmodelvertexTemp.m_iNormZ = norm.y;
structs3dmodelvertexTemp.m_iU = uvTexCoordinates.x;
structs3dmodelvertexTemp.m_iV = uvTexCoordinates.y;
// Write StructS3DModelVertex structure to file.
m_fsOutFile.write(
(char*)&structs3dmodelvertexTemp.m_iX,
sizeof(float) * 8
);
/////////
*ofsTextFile << structs3dmodelvertexTemp.m_iX << " "
<< structs3dmodelvertexTemp.m_iY << " "
<< structs3dmodelvertexTemp.m_iZ << " "
<< structs3dmodelvertexTemp.m_iNormX << " "
<< structs3dmodelvertexTemp.m_iNormY << " "
<< structs3dmodelvertexTemp.m_iNormZ << " "
<< structs3dmodelvertexTemp.m_iU << " "
<< structs3dmodelvertexTemp.m_iV << " "
<< "\n";
}
/////////////////////////////////////////////////////////////////
// Write Faces
/////////////////////////////////////////////////////////////////
/////
*ofsTextFile << "\n" << "[Faces Section]" << "\n";
// get the number of faces.
structs3dmeshHeader.m_iFaceCount = mesh.getNumFaces();
// get the offset to the faces.
structs3dmeshHeader.m_lFaceOffset = m_fsOutFile.tellg();
// Loop throuh all the faces.
for(i = 0; i < structs3dmeshHeader.m_iFaceCount; i++)
{
// Create a face header.
StructS3DFace structs3dfaceHeader;
// Allocate memory for the face header.
memset(&structs3dfaceHeader, 0, sizeof(StructS3DFace));
// Get face data.
structs3dfaceHeader.m_usVertexIndex[0] = mesh.faces.v[0];
structs3dfaceHeader.m_usVertexIndex[1] = mesh.faces.v[1];
structs3dfaceHeader.m_usVertexIndex[2] = mesh.faces.v[2];
// Write faces to file.
m_fsOutFile.write(
(char*)&structs3dfaceHeader,
sizeof(StructS3DFace)
);
/////////
*ofsTextFile
<< structs3dfaceHeader.m_usVertexIndex[0] << " "
<< structs3dfaceHeader.m_usVertexIndex[1] << " "
<< structs3dfaceHeader.m_usVertexIndex[2] << " "
<< "\n";
// Create temporary StructS3DModelVertex structure.
StructS3DModelVertex structs3dmodelvertexTemp;
// Allocate memory for the vertex structure.
memset(
&structs3dmodelvertexTemp,
0,
sizeof(StructS3DModelVertex)
);
///////////////////////////////////////////////////////////////////////
// Get the vertex coordinates for the first face vertex.
Point3 pnt =
mesh.getVert(structs3dfaceHeader.m_usVertexIndex[0]) * tm;
// Get the vertex normal.
Point3 norm =
Normalize(mesh.getNormal(
structs3dfaceHeader.m_usVertexIndex[0]));
// Get the texture coordinates.
UVVert& uv = mesh.tVerts[mesh.tvFace.t[0]];
// Fill in our vertex structure to be written to file.
structs3dmodelvertexTemp.m_iX = pnt.x;
structs3dmodelvertexTemp.m_iY = pnt.z;
structs3dmodelvertexTemp.m_iZ = pnt.y;
structs3dmodelvertexTemp.m_iNormX = norm.x;
structs3dmodelvertexTemp.m_iNormY = norm.z;
structs3dmodelvertexTemp.m_iNormZ = norm.y;
structs3dmodelvertexTemp.m_iU = uv.x;
structs3dmodelvertexTemp.m_iV = uv.y;
// Write StructS3DModelVertex structure to file.
m_fsOutFile.write(
(char*)&structs3dmodelvertexTemp.m_iX,
sizeof(float) * 8
);
/////////
*ofsTextFile << structs3dmodelvertexTemp.m_iX << " "
<< structs3dmodelvertexTemp.m_iY << " "
<< structs3dmodelvertexTemp.m_iZ << " "
<< structs3dmodelvertexTemp.m_iNormX << " "
<< structs3dmodelvertexTemp.m_iNormY << " "
<< structs3dmodelvertexTemp.m_iNormZ << " "
<< structs3dmodelvertexTemp.m_iU << " "
<< structs3dmodelvertexTemp.m_iV << " "
<< "\n";
//////////////////////////////////////////////////////////////////////
// Get the vertex coordinates for the second face vertex.
pnt =
mesh.getVert(structs3dfaceHeader.m_usVertexIndex[1]) * tm;
// Get the vertex normal.
norm =
Normalize(mesh.getNormal(
structs3dfaceHeader.m_usVertexIndex[1]));
// Get the texture coordinates.
uv = mesh.tVerts[mesh.tvFace.t[1]];
// Fill in our vertex structure to be written to file.
structs3dmodelvertexTemp.m_iX = pnt.x;
structs3dmodelvertexTemp.m_iY = pnt.z;
structs3dmodelvertexTemp.m_iZ = pnt.y;
structs3dmodelvertexTemp.m_iNormX = norm.x;
structs3dmodelvertexTemp.m_iNormY = norm.z;
structs3dmodelvertexTemp.m_iNormZ = norm.y;
structs3dmodelvertexTemp.m_iU = uv.x;
structs3dmodelvertexTemp.m_iV = uv.y;
// Write StructS3DModelVertex structure to file.
m_fsOutFile.write(
(char*)&structs3dmodelvertexTemp.m_iX,
sizeof(float) * 8
);
/////////
*ofsTextFile << structs3dmodelvertexTemp.m_iX << " "
<< structs3dmodelvertexTemp.m_iY << " "
<< structs3dmodelvertexTemp.m_iZ << " "
<< structs3dmodelvertexTemp.m_iNormX << " "
<< structs3dmodelvertexTemp.m_iNormY << " "
<< structs3dmodelvertexTemp.m_iNormZ << " "
<< structs3dmodelvertexTemp.m_iU << " "
<< structs3dmodelvertexTemp.m_iV << " "
<< "\n";
///////////////////////////////////////////////////////////////////////
// Get the vertex coordinates for the third face vertex.
pnt =
mesh.getVert(structs3dfaceHeader.m_usVertexIndex[2]) * tm;
// Get the vertex normal.
norm =
Normalize(mesh.getNormal(
structs3dfaceHeader.m_usVertexIndex[2]));
// Get the texture coordinates.
uv = mesh.tVerts[mesh.tvFace.t[2]];
// Fill in our vertex structure to be written to file.
structs3dmodelvertexTemp.m_iX = pnt.x;
structs3dmodelvertexTemp.m_iY = pnt.z;
structs3dmodelvertexTemp.m_iZ = pnt.y;
structs3dmodelvertexTemp.m_iNormX = norm.x;
structs3dmodelvertexTemp.m_iNormY = norm.z;
structs3dmodelvertexTemp.m_iNormZ = norm.y;
structs3dmodelvertexTemp.m_iU = uv.x;
structs3dmodelvertexTemp.m_iV = uv.y;
// Write StructS3DModelVertex structure to file.
m_fsOutFile.write(
(char*)&structs3dmodelvertexTemp.m_iX,
sizeof(float) * 8
);
/////////
*ofsTextFile << structs3dmodelvertexTemp.m_iX << " "
<< structs3dmodelvertexTemp.m_iY << " "
<< structs3dmodelvertexTemp.m_iZ << " "
<< structs3dmodelvertexTemp.m_iNormX << " "
<< structs3dmodelvertexTemp.m_iNormY << " "
<< structs3dmodelvertexTemp.m_iNormZ << " "
<< structs3dmodelvertexTemp.m_iU << " "
<< structs3dmodelvertexTemp.m_iV << " "
<< "\n";
}// End loop through all faces.
/////////////////////////////////////////////////////////////////
// Get texture info.
// Get the material for the selected node.
Mtl* curMat = ptrINode->GetMtl();
// Create a texture map slot.
Texmap* texmapSlot = NULL;
// Loop through all the texture maps in the material.
for (i=0; i < curMat->NumSubTexmaps(); i++)
{
// Get the current texture map.
texmapSlot = curMat->GetSubTexmap(i);
// If the there is a valid texture map.
if (texmapSlot)
{
// If the texture map is a bitmap texture.
if (
texmapSlot->ClassID() ==
Class_ID(BMTEX_CLASS_ID, 0x00)
)
{
// Get the entire path name of the bitmap texture.
TSTR tstrMapName =
((BitmapTex *)texmapSlot)->GetMapName();
// Extract file name.
TSTR tstrPathName, tstrFileName;
SplitPathFile( tstrMapName,
&tstrPathName,
&tstrFileName
);
// Copy the file name into our structure to be
// written to file.
_tcscpy(
structs3dmeshHeader.m_strTextureName,
tstrFileName
);
} // End if bitmap texture.
} // End if valid texture map slot.
} // End loop through all texture maps in the material.
//////////////////////////////////////////////////////////////////
// Get the current position in file.
long lEndPosition = m_fsOutFile.tellg();
// Go to start position.
m_fsOutFile.seekg(lStartPosition);
/////
*ofsTextFile << "\n" << "[Mesh Header Section]" << "\n";
// Write mesh header class to file.
m_fsOutFile.write(
(char*)&structs3dmeshHeader,
sizeof(StructS3DMesh)
);
/////////
*ofsTextFile << structs3dmeshHeader.m_iS3dmodelvertexCount << endl
<< structs3dmeshHeader.m_lS3dmodelvertexOffset << endl
<< structs3dmeshHeader.m_iFaceCount << endl
<< structs3dmeshHeader.m_lFaceOffset << endl
<< structs3dmeshHeader.m_strTextureName << endl
<< "\n";
// Go to end position.
m_fsOutFile.seekg(lEndPosition);
// Return success.
return true;
}
// Get texture coordinates from a vertex.
UVVert getTextureUV(int iVertexIndex, Mesh* mesh)
{
UVVert uvTextureCoordinates;
// If mesh has valid vertices and faces
if ( mesh->tVerts && mesh->tvFace )
{
// Loop through all the faces.
for ( int i = 0; i < mesh->numFaces; i++ )
{
// Loop through the 3 vertices of the face.
for ( int j = 0; j < 3; j++ )
{
// If the vertex index passed in matches
// the vertex of the face.
if ( mesh->faces.v[j] == iVertexIndex )
{
// Obtain the texture coordinates for it.
uvTextureCoordinates =
mesh->tVerts[mesh->tvFace.t[j]];
} // End vertex index and face vertex index match
} // End face vertex index loop.
} // End face loop.
// Return the texture coordinates.
return uvTextureCoordinates;
} // End if valid vertices and faces.
// Return failure
return NULL;
}
Here is my importer code:
//ββββββββββββββββββββββββββ
// Name: setModelData()
// Desc: Sets the model data by deciphering from the buffer.
//ββββββββββββββββββββββββββ
bool S3DModel::setModelData( S3DSystem* ptrS3dsystemCapsule )
{
// Create a local pointer to the memory buffer
// containing the 3D model data.
const char* ptrCharModelData = m_ptrCharModelData;
// Obtain the file version by casting.
const unsigned long* ptrUlS3DVersion =
( const unsigned long* ) ptrCharModelData;
// If not the correct file version.
if ( *ptrUlS3DVersion != s_ulS3DVersion )
{
// Notify user.
ptrS3dsystemCapsule->displayMessage(
"Incorrect S3D model file version. Please only use valid *.s3d files."
);
// Return model load failure.
return false;
}
// Skip file version data.
ptrCharModelData += sizeof( s_ulS3DVersion );
// Skip model header data.
ptrCharModelData += sizeof( StructS3DModel );
// Obtain the mesh structure.
m_ptrStructs3dmeshData = ( StructS3DMesh* ) ptrCharModelData;
// Save the texture name.
strcpy(
m_strTextureName,
m_ptrStructs3dmeshData->m_strTextureName
);
// Skip mesh header data.
ptrCharModelData += sizeof( StructS3DMesh );
// Record the current position in the buffer..
const char* ptrCharSavedPosition = ptrCharModelData;
// Skip to face data.
ptrCharModelData = m_ptrCharModelData +
m_ptrStructs3dmeshData->m_lFaceOffset;
// Clear the STL vector to store the indices of our faces.
m_vecUsIndices.clear();
// Clear the STL vector to store the vertices of our face.
m_vecStructs3dmodelvertexContainer.clear();
// Loop through all the face data.
for (
int i = 0;
i < (m_ptrStructs3dmeshData->m_iFaceCount);
i++
)
{
// Create a temporary face structure pointer.
StructS3DFace* ptrStructs3dfaceTemp;
// Obtain the face data by casting.
ptrStructs3dfaceTemp =
( StructS3DFace* ) ptrCharModelData;
//cout << ptrStructs3dfaceTemp->m_usVertexIndex[0] << " ";
//cout << ptrStructs3dfaceTemp->m_usVertexIndex[1] << " ";
//cout << ptrStructs3dfaceTemp->m_usVertexIndex[2] << " ";
// Store the face data.
m_vecUsIndices.
push_back( ptrStructs3dfaceTemp->m_usVertexIndex[0] );
m_vecUsIndices.
push_back( ptrStructs3dfaceTemp->m_usVertexIndex[1] );
m_vecUsIndices.
push_back( ptrStructs3dfaceTemp->m_usVertexIndex[2] );
// Skip this particular face structure.
ptrCharModelData += sizeof( StructS3DFace );
// Loop through all the 3 vertices of the face.
for (
int j = 0;
j < 3;
++j
)
{
// Create a temporary model vertex structure pointer.
StructS3DModelVertex* ptrStructs3dmodelvertexTemp;
// Obtain the model vertex data by casting.
ptrStructs3dmodelvertexTemp =
( StructS3DModelVertex* ) ptrCharModelData;
// Create a temporary model vertex structure.
StructS3DModelVertex structs3dmodelvertexTemp;
// Fill in the data of the model vertex structure.
structs3dmodelvertexTemp.m_iX =
ptrStructs3dmodelvertexTemp->m_iX;
structs3dmodelvertexTemp.m_iY =
ptrStructs3dmodelvertexTemp->m_iY;
structs3dmodelvertexTemp.m_iZ =
ptrStructs3dmodelvertexTemp->m_iZ;
structs3dmodelvertexTemp.m_iNormX =
ptrStructs3dmodelvertexTemp->m_iNormX;
structs3dmodelvertexTemp.m_iNormY =
ptrStructs3dmodelvertexTemp->m_iNormY;
structs3dmodelvertexTemp.m_iNormZ =
ptrStructs3dmodelvertexTemp->m_iNormZ;
structs3dmodelvertexTemp.m_iU =
ptrStructs3dmodelvertexTemp->m_iU;
structs3dmodelvertexTemp.m_iV =
1 - ptrStructs3dmodelvertexTemp->m_iV;
//cout << ptrStructs3dmodelvertexTemp->m_iNormZ << " ";
// Store the vertex data.
m_vecStructs3dmodelvertexContainer.
push_back( structs3dmodelvertexTemp );
// Skip this particular model vertex structure.
ptrCharModelData += sizeof( StructS3DModelVertex );
}
} // End loop through faces.
//cout << m_vecStructs3dmodelvertexContainer[4484].m_iU;
//cout << m_vecStructs3dmodelvertexContainer.size() << " ";
// Create iterators.
std::vector::iterator itrStructs3dmodelvertex =
m_vecStructs3dmodelvertexContainer.begin();
// Create vertex buffer.
ptrS3dsystemCapsule->createVertexBuffer(
sizeof(StructS3DModelVertex)
* m_vecStructs3dmodelvertexContainer.size(),
sizeof(StructS3DModelVertex),
m_ptrStructs3dmeshData->m_iFaceCount,
itrStructs3dmodelvertex
);
// return success.
return true;
}
//ββββββββββββββββββββββββββ
// Name: renderModel()
// Desc: Renders the loaded model.
//ββββββββββββββββββββββββββ
void S3DModel::renderModel(
float fX, float fY, float fZ,
S3DSystem* ptrS3dsystemCapsule,
S3DRender* ptrS3drenderModule
)
{
// Ensure position is the one directly infront of camera
// by adjusting the view matrix. The size of the fonts
// are also scaled.
S3DMath::S3DMatrix s3dmatrixView;
s3dmatrixView.identity();
s3dmatrixView[0][0] = 0.3f;
s3dmatrixView[1][1] = 0.3f;
s3dmatrixView[2][2] = 0.3f;
s3dmatrixView[3][0] = fX;
s3dmatrixView[3][1] = fY;
s3dmatrixView[3][2] = fZ;
// Invoke setTransforms, which will eventually set our
// 3D API''s view matrix.
ptrS3drenderModule->setTransforms(
ptrS3dsystemCapsule,
VIEW_TRANSFORM,
&s3dmatrixView
);
// Create iterators.
std::vector::iterator itrInt = m_vecUsIndices.begin();
std::vector::iterator itrStructs3dmodelvertex =
m_vecStructs3dmodelvertexContainer.begin();
// Invoke the render function.
ptrS3drenderModule->renderNonIndexed(
ptrS3dsystemCapsule,
0,
sizeof(StructS3DModelVertex),
m_ptrStructs3dmeshData->m_iFaceCount
);
/* ptrS3drenderModule->render(
ptrS3dsystemCapsule,
0,
m_ptrStructs3dmeshData->m_iS3dmodelvertexCount,
m_ptrStructs3dmeshData->m_iFaceCount,
itrInt,
itrStructs3dmodelvertex,
sizeof(StructS3DModelVertex)
);
*/
}
Here is my output:
www.Sherman3D.com/sherman/error2.jpg
Ummm, anybody knows what I am doing wrong? Thanks! ^_^
Best regards,
Sherman </i>
_________________ Best regards, Sherman Chin Director Sherman3D (Malaysia) Sdn Bhd www.Sherman3D.com www.AlphaKimori.com
you are in the incorrect group, because it is a artist group not programmer :-(
-----------------------------------------------
"Cuando se es peon, la unica salida es la revoluciΓ³n"
-----------------------------------------------
"Cuando se es peon, la unica salida es la revoluciΓ³n"
-----------------------------------------------"Cuando se es peon, la unica salida es la revoluciΓ³n"
Dear eng3D,
Thanks for your reply. Just trying my luck since my post in the 3D Graphics Programming
forum yielded no replies. ;_;
Best regards,
Sherman
http://www.Sherman3D.com
Thanks for your reply. Just trying my luck since my post in the 3D Graphics Programming
forum yielded no replies. ;_;
Best regards,
Sherman
http://www.Sherman3D.com
_________________ Best regards, Sherman Chin Director Sherman3D (Malaysia) Sdn Bhd www.Sherman3D.com www.AlphaKimori.com
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement