- cleaned up doc, made section on face winding clearer 

MD3 
 - fixed coordinate system 
 - changed default face order for .shader files 

MD2 
 - fixed coordinate system 
 - fixed face order 



git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@367 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2009-03-18 22:01:11 +00:00
parent c2d8881549
commit 93ab7383da
6 changed files with 59 additions and 56 deletions

View File

@ -310,8 +310,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
DefaultLogger::get()->warn("Texture file name has zero length. It will be skipped.");
}
}
else
{
else {
// apply a default material
aiColor3D clr;
clr.b = clr.g = clr.r = 0.6f;
@ -338,8 +337,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
unsigned int iCurrent = 0;
float fDivisorU = 1.0f,fDivisorV = 1.0f;
if (m_pcHeader->numTexCoords)
{
if (m_pcHeader->numTexCoords) {
// allocate storage for texture coordinates, too
pcMesh->mTextureCoords[0] = new aiVector3D[pcMesh->mNumVertices];
pcMesh->mNumUVComponents[0] = 2;
@ -356,8 +354,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
else fDivisorV = (float)m_pcHeader->skinHeight;
}
for (unsigned int i = 0; i < (unsigned int)m_pcHeader->numTriangles;++i)
{
for (unsigned int i = 0; i < (unsigned int)m_pcHeader->numTriangles;++i) {
// Allocate the face
pScene->mMeshes[0]->mFaces[i].mIndices = new unsigned int[3];
pScene->mMeshes[0]->mFaces[i].mNumIndices = 3;
@ -365,12 +362,11 @@ void MD2Importer::InternReadFile( const std::string& pFile,
// copy texture coordinates
// check whether they are different from the previous value at this index.
// In this case, create a full separate set of vertices/normals/texcoords
for (unsigned int c = 0; c < 3;++c,++iCurrent)
{
for (unsigned int c = 0; c < 3;++c,++iCurrent) {
// validate vertex indices
register unsigned int iIndex = (unsigned int)pcTriangles[i].vertexIndices[c];
if (iIndex >= m_pcHeader->numVertices)
{
if (iIndex >= m_pcHeader->numVertices) {
DefaultLogger::get()->error("MD2: Vertex index is outside the allowed range");
iIndex = m_pcHeader->numVertices-1;
}
@ -391,9 +387,9 @@ void MD2Importer::InternReadFile( const std::string& pFile,
aiVector3D& vNormal = pcMesh->mNormals[iCurrent];
LookupNormalIndex(pcVerts[iIndex].lightNormalIndex,vNormal);
// invert z for proper output coordinate system
vNormal.z *= -1.0f;
vec.z *= -1.0f;
// flip z and y to become right-handed
std::swap((float&)vNormal.z,(float&)vNormal.y);
std::swap((float&)vec.z,(float&)vec.y);
if (m_pcHeader->numTexCoords) {
// validate texture coordinates

View File

@ -531,7 +531,7 @@ bool MD3Importer::ReadMultipartFile()
aiNode* tag_torso, *tag_head;
std::vector<AttachmentInfo> attach;
DefaultLogger::get()->info("Multi-part MD3 player model: lower, upper and head parts are joined");
DefaultLogger::get()->info("Multi part MD3 player model: lower, upper and head parts are joined");
// ensure we won't try to load ourselves recursively
BatchLoader::PropertyMap props;
@ -552,21 +552,21 @@ bool MD3Importer::ReadMultipartFile()
// ... and get them. We need all of them.
scene_lower = batch.GetImport(_lower);
if (!scene_lower) {
DefaultLogger::get()->error("M3D: Failed to read multipart model, lower.md3 fails to load");
DefaultLogger::get()->error("M3D: Failed to read multi part model, lower.md3 fails to load");
failure = "lower";
goto error_cleanup;
}
scene_upper = batch.GetImport(_upper);
if (!scene_upper) {
DefaultLogger::get()->error("M3D: Failed to read multipart model, upper.md3 fails to load");
DefaultLogger::get()->error("M3D: Failed to read multi part model, upper.md3 fails to load");
failure = "upper";
goto error_cleanup;
}
scene_head = batch.GetImport(_head);
if (!scene_head) {
DefaultLogger::get()->error("M3D: Failed to read multipart model, head.md3 fails to load");
DefaultLogger::get()->error("M3D: Failed to read multi part model, head.md3 fails to load");
failure = "head";
goto error_cleanup;
}
@ -580,7 +580,7 @@ bool MD3Importer::ReadMultipartFile()
// tag_torso
tag_torso = scene_lower->mRootNode->FindNode("tag_torso");
if (!tag_torso) {
DefaultLogger::get()->error("M3D: Failed to find attachment tag for multipart model: tag_torso expected");
DefaultLogger::get()->error("M3D: Failed to find attachment tag for multi part model: tag_torso expected");
goto error_cleanup;
}
scene_upper->mRootNode->mName.Set("upper");
@ -589,7 +589,7 @@ bool MD3Importer::ReadMultipartFile()
// tag_head
tag_head = scene_upper->mRootNode->FindNode("tag_head");
if (!tag_head) {
DefaultLogger::get()->error("M3D: Failed to find attachment tag for multipart model: tag_head expected");
DefaultLogger::get()->error("M3D: Failed to find attachment tag for multi part model: tag_head expected");
goto error_cleanup;
}
scene_head->mRootNode->mName.Set("head");
@ -601,6 +601,12 @@ bool MD3Importer::ReadMultipartFile()
RemoveSingleNodeFromList (scene_upper->mRootNode->FindNode("tag_torso"));
RemoveSingleNodeFromList (scene_head-> mRootNode->FindNode("tag_head" ));
// Undo the rotations which we applied to the coordinate systems. We're
// working in global Quake space here
scene_head->mRootNode->mTransformation = aiMatrix4x4();
scene_lower->mRootNode->mTransformation = aiMatrix4x4();
scene_upper->mRootNode->mTransformation = aiMatrix4x4();
// and merge the scenes
SceneCombiner::MergeScenes(&mScene,master, attach,
AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES |
@ -608,6 +614,10 @@ bool MD3Importer::ReadMultipartFile()
AI_INT_MERGE_SCENE_RESOLVE_CROSS_ATTACHMENTS |
(!configSpeedFlag ? AI_INT_MERGE_SCENE_GEN_UNIQUE_NAMES_IF_NECESSARY : 0));
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
mScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
return true;
error_cleanup:
@ -673,10 +683,7 @@ void MD3Importer::InternReadFile( const std::string& pFile,
// get base path and file name
// todo ... move to PathConverter
std::string::size_type s = mFile.find_last_of('/');
if (s == std::string::npos) {
s = mFile.find_last_of('\\');
}
std::string::size_type s = mFile.find_last_of("/\\");
if (s == std::string::npos) {
s = 0;
}
@ -907,8 +914,7 @@ void MD3Importer::InternReadFile( const std::string& pFile,
// Ensure correct endianess
#ifdef AI_BUILD_BIG_ENDIAN
for (uint32_t i = 0; i < pcSurfaces->NUM_VERTICES;++i)
{
for (uint32_t i = 0; i < pcSurfaces->NUM_VERTICES;++i) {
AI_SWAP2( pcVertices[i].NORMAL );
AI_SWAP2( pcVertices[i].X );
AI_SWAP2( pcVertices[i].Y );
@ -917,8 +923,7 @@ void MD3Importer::InternReadFile( const std::string& pFile,
AI_SWAP4( pcUVs[i].U );
AI_SWAP4( pcUVs[i].U );
}
for (uint32_t i = 0; i < pcSurfaces->NUM_TRIANGLES;++i)
{
for (uint32_t i = 0; i < pcSurfaces->NUM_TRIANGLES;++i) {
AI_SWAP4(pcTriangles[i].INDEXES[0]);
AI_SWAP4(pcTriangles[i].INDEXES[1]);
AI_SWAP4(pcTriangles[i].INDEXES[2]);
@ -939,34 +944,31 @@ void MD3Importer::InternReadFile( const std::string& pFile,
// Fill in all triangles
unsigned int iCurrent = 0;
for (unsigned int i = 0; i < (unsigned int)pcSurfaces->NUM_TRIANGLES;++i)
{
for (unsigned int i = 0; i < (unsigned int)pcSurfaces->NUM_TRIANGLES;++i) {
pcMesh->mFaces[i].mIndices = new unsigned int[3];
pcMesh->mFaces[i].mNumIndices = 3;
unsigned int iTemp = iCurrent;
for (unsigned int c = 0; c < 3;++c,++iCurrent)
{
for (unsigned int c = 0; c < 3;++c,++iCurrent) {
pcMesh->mFaces[i].mIndices[c] = iCurrent;
// Read vertices
pcMesh->mVertices[iCurrent].x = pcVertices[ pcTriangles->INDEXES[c]].X*AI_MD3_XYZ_SCALE;
pcMesh->mVertices[iCurrent].y = pcVertices[ pcTriangles->INDEXES[c]].Y*AI_MD3_XYZ_SCALE;
pcMesh->mVertices[iCurrent].z = pcVertices[ pcTriangles->INDEXES[c]].Z*AI_MD3_XYZ_SCALE;
aiVector3D& vec = pcMesh->mVertices[iCurrent];
vec.x = pcVertices[ pcTriangles->INDEXES[c]].X*AI_MD3_XYZ_SCALE;
vec.y = pcVertices[ pcTriangles->INDEXES[c]].Y*AI_MD3_XYZ_SCALE;
vec.z = pcVertices[ pcTriangles->INDEXES[c]].Z*AI_MD3_XYZ_SCALE;
// Convert the normal vector to uncompressed float3 format
LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL,
(float*)&pcMesh->mNormals[iCurrent]);
aiVector3D& nor = pcMesh->mNormals[iCurrent];
LatLngNormalToVec3(pcVertices[pcTriangles->INDEXES[c]].NORMAL,(float*)&nor);
// Read texture coordinates
pcMesh->mTextureCoords[0][iCurrent].x = pcUVs[ pcTriangles->INDEXES[c]].U;
pcMesh->mTextureCoords[0][iCurrent].y = 1.0f-pcUVs[ pcTriangles->INDEXES[c]].V;
}
// Flip face order if necessary
if (!shader || shader->cull == Q3Shader::CULL_CCW) {
pcMesh->mFaces[i].mIndices[0] = iTemp+2;
pcMesh->mFaces[i].mIndices[1] = iTemp+1;
pcMesh->mFaces[i].mIndices[2] = iTemp+0;
if (!shader || shader->cull == Q3Shader::CULL_CW) {
std::swap(pcMesh->mFaces[i].mIndices[2],pcMesh->mFaces[i].mIndices[1]);
}
pcTriangles++;
}
@ -1008,7 +1010,7 @@ void MD3Importer::InternReadFile( const std::string& pFile,
AI_SWAP4(pcTags->origin.y);
AI_SWAP4(pcTags->origin.z);
// Copy local origin
// Copy local origin, again flip z,y
nd->mTransformation.a4 = pcTags->origin.x;
nd->mTransformation.b4 = pcTags->origin.y;
nd->mTransformation.c4 = pcTags->origin.z;
@ -1025,6 +1027,10 @@ void MD3Importer::InternReadFile( const std::string& pFile,
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
pScene->mRootNode->mMeshes[i] = i;
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
}
#endif // !! ASSIMP_BUILD_NO_MD3_IMPORTER

View File

@ -145,7 +145,7 @@ struct ShaderMapBlock
struct ShaderDataBlock
{
ShaderDataBlock()
: cull (CULL_CCW)
: cull (CULL_CW)
{}
//! Name of referenced data element

View File

@ -551,12 +551,12 @@ By contrast, some other environments use left-handed coordinate systems, a promi
DirectX. If you need the imported data to be in a left-handed coordinate system, supply the
#aiProcess_MakeLeftHanded flag to the ReadFile() function call.
The output face winding is counter-clockwise. Use #aiProcess_FlipWindingOrder to get CW data.
The output face winding is clockwise. Use #aiProcess_FlipWindingOrder to get CCW data.
@code
x0
x2
x1
x2
@endcode
The output UV coordinate system has its origin in the lower-left corner:

View File

@ -63,12 +63,14 @@ extern "C" {
* a special post-processing step which splits meshes with *different*
* primitive types mixed up (e.g. lines and triangles) in several, 'clean'
* submeshes. Furthermore there is a configuration option,
* AI_CONFIG_PP_SBP_REMOVE, to force SortByPType to remove specific primitive
* types from the scene - completely. In most cases you'll propably want to
* set this config to
* #AI_CONFIG_PP_SBP_REMOVE, to force #aiProcess_SortByPType to remove
* specific primitive types from the imported scene - completely. In most cases
* you'll probably want to set this setting to
* @code
* aiPrimitiveType_LINE|aiPrimitiveType_POINT
* @endcode
* @note Take a look at the @link data Data Structures page @endlink for
* more information on the layout and winding order of a face.
*/
struct aiFace
{

View File

@ -436,14 +436,14 @@ enum aiPostProcessSteps
aiProcess_FlipUVs = 0x80000000, /* don't change */
// -------------------------------------------------------------------------
/** <hr>This step adjusts the output face winding order to be clock-wise.
/** <hr>This step adjusts the output face winding order to be ccw.
*
* The default face winding order is counter-clockwise.
* The default face winding order is clockwise.
* <br><b>Output face order:</b>
* @code
* x0
*
* x1
*
* x0
* x2
* @endcode
*/
@ -461,10 +461,9 @@ enum aiPostProcessSteps
/** @def aiProcess_ConvertToLeftHanded
* @brief Shortcut flag for Direct3D-based applications.
*
* Supersedes the #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
* #aiProcess_FlipWindingOrder flags. The output data matches Direct3D's conventions:
* left-handed geometry, upper-left origin for UV coordinates and finally clockwise
* face order, suitable for CCW culling.
* Supersedes the #aiProcess_MakeLeftHanded and #aiProcess_FlipUVs and
* The output data matches Direct3D's conventions: left-handed geometry, upper-left
* origin for UV coordinates and finally clockwise face order, suitable for CCW culling.
*
* @deprecated
*/