Added support for cones and cylinders to NFF (the code to generate these primitives is hosted in StandardShapes.cpp).

Fixed some minor material bugs in NFF.
Added some more test NFF files, refactored and commented the old ones.
Added FromToMatrix function to aiMatrix4x4
Temporarily disabled animation support in SMD and fixed some minor bugs. Static models should load correctly in every case.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@254 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
This commit is contained in:
aramis_acg
2008-11-28 23:02:27 +00:00
parent 5639220859
commit be864ce4a0
22 changed files with 601 additions and 305 deletions

View File

@@ -665,32 +665,66 @@ void NFFImporter::InternReadFile( const std::string& pFile,
// 'tpp' - texture polygon patch primitive
if ('t' == line[0])
{
if (meshesWithUVCoords.empty())
currentMeshWithUVCoords = NULL;
for (std::vector<MeshInfo>::iterator it = meshesWithUVCoords.begin(), end = meshesWithUVCoords.end();
it != end;++it)
{
if ((*it).shader == s)
{
currentMeshWithUVCoords = &(*it);
break;
}
}
if (!currentMeshWithUVCoords)
{
meshesWithUVCoords.push_back(MeshInfo(PatchType_UVAndNormals));
currentMeshWithUVCoords = &meshesWithUVCoords.back();
currentMeshWithUVCoords->shader = s;
}
out = currentMeshWithUVCoords;
}
// 'pp' - polygon patch primitive
else if ('p' == line[1])
{
if (meshesWithNormals.empty())
currentMeshWithNormals = NULL;
for (std::vector<MeshInfo>::iterator it = meshesWithNormals.begin(), end = meshesWithNormals.end();
it != end;++it)
{
if ((*it).shader == s)
{
currentMeshWithNormals = &(*it);
break;
}
}
if (!currentMeshWithNormals)
{
meshesWithNormals.push_back(MeshInfo(PatchType_Normals));
currentMeshWithNormals = &meshesWithNormals.back();
currentMeshWithNormals->shader = s;
}
sz = &line[2];out = currentMeshWithNormals;
}
// 'p' - polygon primitive
else
{
if (meshes.empty())
currentMesh = NULL;
for (std::vector<MeshInfo>::iterator it = meshes.begin(), end = meshes.end();
it != end;++it)
{
if ((*it).shader == s)
{
currentMesh = &(*it);
break;
}
}
if (!currentMesh)
{
meshes.push_back(MeshInfo(PatchType_Simple));
currentMesh = &meshes.back();
currentMesh->shader = s;
}
sz = &line[1];out = currentMesh;
}
@@ -711,7 +745,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
{
if(!GetNextLine(buffer,line))
{
DefaultLogger::get()->error("NFF: Unexpected EOF was encountered");
DefaultLogger::get()->error("NFF: Unexpected EOF was encountered. Patch definition incomplete");
continue;
}
@@ -764,7 +798,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
// NFF2 uses full colors here so we need to use them too
// although NFF uses simple scaling factors
s.diffuse.g = s.diffuse.b = s.diffuse.r;
s.diffuse.g = s.diffuse.b = s.diffuse.r;
s.specular.g = s.specular.b = s.specular.r;
// if the next one is NOT a number we assume it is a texture file name
@@ -787,58 +821,14 @@ void NFFImporter::InternReadFile( const std::string& pFile,
{
AI_NFF_PARSE_FLOAT(s.ambient); // optional
}
// check whether we have this material already -
// although we have the RRM-Step, this is necessary here.
// otherwise we would generate hundreds of small meshes
// with just a few faces - this is surely never wanted.
currentMesh = currentMeshWithNormals = currentMeshWithUVCoords = NULL;
for (std::vector<MeshInfo>::iterator it = meshes.begin(), end = meshes.end();
it != end;++it)
{
if ((*it).bLocked)continue;
if ((*it).shader == s)
{
switch ((*it).pType)
{
case PatchType_Normals:
currentMeshWithNormals = &(*it);
break;
case PatchType_Simple:
currentMesh = &(*it);
break;
default:
currentMeshWithUVCoords = &(*it);
break;
};
}
}
if (!currentMesh)
{
meshes.push_back(MeshInfo(PatchType_Simple));
currentMesh = &meshes.back();
currentMesh->shader = s;
}
if (!currentMeshWithNormals)
{
meshesWithNormals.push_back(MeshInfo(PatchType_Normals));
currentMeshWithNormals = &meshesWithNormals.back();
currentMeshWithNormals->shader = s;
}
if (!currentMeshWithUVCoords)
{
meshesWithUVCoords.push_back(MeshInfo(PatchType_UVAndNormals));
currentMeshWithUVCoords = &meshesWithUVCoords.back();
currentMeshWithUVCoords->shader = s;
}
}
// 'shader' - other way to specify a texture
else if (TokenMatch(sz,"shader",6))
{
// todo
SkipSpaces(&sz);
const char* old = sz;
while (!IsSpaceOrNewLine(*sz))++sz;
s.texFile = std::string(old, (uintptr_t)sz - (uintptr_t)old);
}
// 'l' - light source
else if (TokenMatch(sz,"l",1))
@@ -856,7 +846,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
MeshInfo& currentMesh = meshesLocked.back();
currentMesh.shader = s;
s.mapping = aiTextureMapping_SPHERE;
currentMesh.shader.mapping = aiTextureMapping_SPHERE;
AI_NFF_PARSE_SHAPE_INFORMATION();
@@ -873,7 +863,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
MeshInfo& currentMesh = meshesLocked.back();
currentMesh.shader = s;
s.mapping = aiTextureMapping_SPHERE;
currentMesh.shader.mapping = aiTextureMapping_SPHERE;
AI_NFF_PARSE_SHAPE_INFORMATION();
@@ -891,7 +881,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
MeshInfo& currentMesh = meshesLocked.back();
currentMesh.shader = s;
s.mapping = aiTextureMapping_SPHERE;
currentMesh.shader.mapping = aiTextureMapping_SPHERE;
AI_NFF_PARSE_SHAPE_INFORMATION();
@@ -909,7 +899,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
MeshInfo& currentMesh = meshesLocked.back();
currentMesh.shader = s;
s.mapping = aiTextureMapping_SPHERE;
currentMesh.shader.mapping = aiTextureMapping_SPHERE;
AI_NFF_PARSE_SHAPE_INFORMATION();
@@ -927,7 +917,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
MeshInfo& currentMesh = meshesLocked.back();
currentMesh.shader = s;
s.mapping = aiTextureMapping_SPHERE;
currentMesh.shader.mapping = aiTextureMapping_BOX;
AI_NFF_PARSE_SHAPE_INFORMATION();
@@ -942,26 +932,54 @@ void NFFImporter::InternReadFile( const std::string& pFile,
else if (TokenMatch(sz,"c",1))
{
meshesLocked.push_back(MeshInfo(PatchType_Simple,true));
MeshInfo& currentMesh = meshes.back();
MeshInfo& currentMesh = meshesLocked.back();
currentMesh.shader = s;
s.mapping = aiTextureMapping_CYLINDER;
currentMesh.shader.mapping = aiTextureMapping_CYLINDER;
if(!GetNextLine(buffer,line))
{
DefaultLogger::get()->error("NFF: Unexpected end of file (cone definition not complete)");
break;
}
sz = line;
// read the two center points and the respective radii
aiVector3D center1, center2; float radius1, radius2;
AI_NFF_PARSE_TRIPLE(center1);
AI_NFF_PARSE_FLOAT(radius1);
if(!GetNextLine(buffer,line))
{
DefaultLogger::get()->error("NFF: Unexpected end of file (cone definition not complete)");
break;
}
sz = line;
AI_NFF_PARSE_TRIPLE(center2);
AI_NFF_PARSE_FLOAT(radius2);
// compute the center point of the cone/cylinder
center2 = (center2-center1)/2.f;
currentMesh.center = center1+center2;
center1 = -center2;
// compute the center point of the cone/cylinder -
// it is its local transformation origin
currentMesh.dir = center2-center1;
currentMesh.center = center1+currentMesh.dir/2.f;
float f;
if (( f = currentMesh.dir.Length()) < 10e-3f )
{
DefaultLogger::get()->error("NFF: Cone height is close to zero");
continue;
}
currentMesh.dir /= f; // normalize
// generate the cone - it consists of simple triangles
StandardShapes::MakeCone(center1, radius1, center2, radius2, iTesselation, currentMesh.vertices);
StandardShapes::MakeCone(f, radius1, radius2,
integer_pow(4, iTesselation), currentMesh.vertices);
// MakeCone() returns tris
currentMesh.faces.resize(currentMesh.vertices.size()/3,3);
// generate a name for the mesh
// generate a name for the mesh. 'cone' if it a cone,
// 'cylinder' if it is a cylinder. Funny, isn't it?
if (radius1 != radius2)
::sprintf(currentMesh.name,"cone_%i",cone++);
else ::sprintf(currentMesh.name,"cylinder_%i",cylinder++);
@@ -1125,13 +1143,16 @@ void NFFImporter::InternReadFile( const std::string& pFile,
node->mName.Set(src.name);
// setup the transformation matrix of the node
node->mTransformation.a4 = src.center.x;
node->mTransformation.b4 = src.center.y;
node->mTransformation.c4 = src.center.z;
aiMatrix4x4::FromToMatrix(aiVector3D(0.f,1.f,0.f),
src.dir,node->mTransformation);
node->mTransformation.a1 = src.radius.x;
node->mTransformation.b2 = src.radius.y;
node->mTransformation.c3 = src.radius.z;
aiMatrix4x4& mat = node->mTransformation;
mat.a1 *= src.radius.x; mat.b1 *= src.radius.x; mat.c1 *= src.radius.x;
mat.a2 *= src.radius.y; mat.b2 *= src.radius.y; mat.c2 *= src.radius.y;
mat.a3 *= src.radius.z; mat.b3 *= src.radius.z; mat.c3 *= src.radius.z;
mat.a4 = src.center.x;
mat.b4 = src.center.y;
mat.c4 = src.center.z;
++ppcChildren;
}
@@ -1194,7 +1215,8 @@ void NFFImporter::InternReadFile( const std::string& pFile,
s.Set(AI_DEFAULT_MATERIAL_NAME);
pcMat->AddProperty(&s, AI_MATKEY_NAME);
aiColor3D c = src.shader.color * src.shader.diffuse;
// FIX: Ignore diffuse == 0
aiColor3D c = src.shader.color * (src.shader.diffuse.r ? src.shader.diffuse : aiColor3D(1.f,1.f,1.f));
pcMat->AddProperty(&c,1,AI_MATKEY_COLOR_DIFFUSE);
c = src.shader.color * src.shader.specular;
pcMat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);
@@ -1209,6 +1231,9 @@ void NFFImporter::InternReadFile( const std::string& pFile,
{
s.Set(src.shader.texFile);
pcMat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
if (aiTextureMapping_UV != src.shader.mapping)
pcMat->AddProperty((int*)&src.shader.mapping, 1,AI_MATKEY_MAPPING_DIFFUSE(0));
}
// setup the name of the material
@@ -1218,11 +1243,6 @@ void NFFImporter::InternReadFile( const std::string& pFile,
pcMat->AddProperty(&s,AI_MATKEY_NAME);
}
if (aiTextureMapping_UV != src.shader.mapping)
{
pcMat->AddProperty((int*)&src.shader.mapping, 1,AI_MATKEY_MAPPING_DIFFUSE(0));
}
// setup some more material properties that are specific to NFF2
int i;
if (src.shader.twoSided)