Merge branch 'master' of github.com:assimp/assimp
commit
fdbfa572ab
|
@ -235,9 +235,13 @@ void ColladaExporter::WriteMaterials()
|
||||||
if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS )
|
if( mat->Get( AI_MATKEY_NAME, name) != aiReturn_SUCCESS )
|
||||||
name = "mat";
|
name = "mat";
|
||||||
materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (a) + name.C_Str();
|
materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (a) + name.C_Str();
|
||||||
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it )
|
for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) {
|
||||||
if( !isalnum( *it) )
|
// isalnum on MSVC asserts for code points in [0,255]. Thus prevent unwanted promotion
|
||||||
|
// of char to signed int and take the unsigned char value.
|
||||||
|
if( !isalnum( static_cast<uint8_t>(*it) ) ) {
|
||||||
*it = '_';
|
*it = '_';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ReadMaterialSurface( materials[a].ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT);
|
ReadMaterialSurface( materials[a].ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT);
|
||||||
if( !materials[a].ambient.texture.empty() ) numTextures++;
|
if( !materials[a].ambient.texture.empty() ) numTextures++;
|
||||||
|
|
|
@ -199,6 +199,7 @@ void ObjExporter :: WriteGeometryFile()
|
||||||
AddNode(pScene->mRootNode,mBase);
|
AddNode(pScene->mRootNode,mBase);
|
||||||
|
|
||||||
// write vertex positions
|
// write vertex positions
|
||||||
|
vpMap.getVectors(vp);
|
||||||
mOutput << "# " << vp.size() << " vertex positions" << endl;
|
mOutput << "# " << vp.size() << " vertex positions" << endl;
|
||||||
BOOST_FOREACH(const aiVector3D& v, vp) {
|
BOOST_FOREACH(const aiVector3D& v, vp) {
|
||||||
mOutput << "v " << v.x << " " << v.y << " " << v.z << endl;
|
mOutput << "v " << v.x << " " << v.y << " " << v.z << endl;
|
||||||
|
@ -206,6 +207,7 @@ void ObjExporter :: WriteGeometryFile()
|
||||||
mOutput << endl;
|
mOutput << endl;
|
||||||
|
|
||||||
// write uv coordinates
|
// write uv coordinates
|
||||||
|
vtMap.getVectors(vt);
|
||||||
mOutput << "# " << vt.size() << " UV coordinates" << endl;
|
mOutput << "# " << vt.size() << " UV coordinates" << endl;
|
||||||
BOOST_FOREACH(const aiVector3D& v, vt) {
|
BOOST_FOREACH(const aiVector3D& v, vt) {
|
||||||
mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
|
mOutput << "vt " << v.x << " " << v.y << " " << v.z << endl;
|
||||||
|
@ -213,6 +215,7 @@ void ObjExporter :: WriteGeometryFile()
|
||||||
mOutput << endl;
|
mOutput << endl;
|
||||||
|
|
||||||
// write vertex normals
|
// write vertex normals
|
||||||
|
vnMap.getVectors(vn);
|
||||||
mOutput << "# " << vn.size() << " vertex normals" << endl;
|
mOutput << "# " << vn.size() << " vertex normals" << endl;
|
||||||
BOOST_FOREACH(const aiVector3D& v, vn) {
|
BOOST_FOREACH(const aiVector3D& v, vn) {
|
||||||
mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
|
mOutput << "vn " << v.x << " " << v.y << " " << v.z << endl;
|
||||||
|
@ -252,6 +255,31 @@ void ObjExporter :: WriteGeometryFile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int ObjExporter::vecIndexMap::getIndex(const aiVector3D& vec)
|
||||||
|
{
|
||||||
|
vecIndexMap::dataType::iterator vertIt = vecMap.find(vec);
|
||||||
|
if(vertIt != vecMap.end()){// vertex already exists, so reference it
|
||||||
|
return vertIt->second;
|
||||||
|
}
|
||||||
|
vecMap[vec] = mNextIndex;
|
||||||
|
int ret = mNextIndex;
|
||||||
|
mNextIndex++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjExporter::vecIndexMap::getVectors( std::vector<aiVector3D>& vecs )
|
||||||
|
{
|
||||||
|
vecs.resize(vecMap.size());
|
||||||
|
for(vecIndexMap::dataType::iterator it = vecMap.begin(); it != vecMap.end(); it++){
|
||||||
|
vecs[it->second-1] = it->first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat)
|
void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatrix4x4& mat)
|
||||||
{
|
{
|
||||||
|
@ -262,6 +290,7 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri
|
||||||
mesh.matname = GetMaterialName(m->mMaterialIndex);
|
mesh.matname = GetMaterialName(m->mMaterialIndex);
|
||||||
|
|
||||||
mesh.faces.resize(m->mNumFaces);
|
mesh.faces.resize(m->mNumFaces);
|
||||||
|
|
||||||
for(unsigned int i = 0; i < m->mNumFaces; ++i) {
|
for(unsigned int i = 0; i < m->mNumFaces; ++i) {
|
||||||
const aiFace& f = m->mFaces[i];
|
const aiFace& f = m->mFaces[i];
|
||||||
|
|
||||||
|
@ -281,21 +310,22 @@ void ObjExporter :: AddMesh(const aiString& name, const aiMesh* m, const aiMatri
|
||||||
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||||
const unsigned int idx = f.mIndices[a];
|
const unsigned int idx = f.mIndices[a];
|
||||||
|
|
||||||
// XXX need a way to check if this is an unique vertex or if we had it already,
|
aiVector3D vert = mat * m->mVertices[idx];
|
||||||
// in which case we should instead reference the previous occurrence.
|
face.indices[a].vp = vpMap.getIndex(vert);
|
||||||
ai_assert(m->mVertices);
|
|
||||||
vp.push_back( mat * m->mVertices[idx] );
|
|
||||||
face.indices[a].vp = vp.size();
|
|
||||||
|
|
||||||
if (m->mNormals) {
|
if (m->mNormals) {
|
||||||
vn.push_back( m->mNormals[idx] );
|
face.indices[a].vn = vnMap.getIndex(m->mNormals[idx]);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
face.indices[a].vn = 0;
|
||||||
}
|
}
|
||||||
face.indices[a].vn = vn.size();
|
|
||||||
|
|
||||||
if (m->mTextureCoords[0]) {
|
if (m->mTextureCoords[0]) {
|
||||||
vt.push_back( m->mTextureCoords[0][idx] );
|
face.indices[a].vt = vtMap.getIndex(m->mTextureCoords[0][idx]);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
face.indices[a].vt = 0;
|
||||||
}
|
}
|
||||||
face.indices[a].vt = vt.size();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,6 +112,36 @@ private:
|
||||||
const aiScene* const pScene;
|
const aiScene* const pScene;
|
||||||
|
|
||||||
std::vector<aiVector3D> vp, vn, vt;
|
std::vector<aiVector3D> vp, vn, vt;
|
||||||
|
|
||||||
|
|
||||||
|
struct aiVectorCompare
|
||||||
|
{
|
||||||
|
bool operator() (const aiVector3D& a, const aiVector3D& b) const
|
||||||
|
{
|
||||||
|
if(a.x < b.x) return true;
|
||||||
|
if(a.x > b.x) return false;
|
||||||
|
if(a.y < b.y) return true;
|
||||||
|
if(a.y > b.y) return false;
|
||||||
|
if(a.z < b.z) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class vecIndexMap
|
||||||
|
{
|
||||||
|
int mNextIndex;
|
||||||
|
typedef std::map<aiVector3D, int, aiVectorCompare> dataType;
|
||||||
|
dataType vecMap;
|
||||||
|
public:
|
||||||
|
|
||||||
|
vecIndexMap():mNextIndex(1)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int getIndex(const aiVector3D& vec);
|
||||||
|
void getVectors( std::vector<aiVector3D>& vecs );
|
||||||
|
};
|
||||||
|
|
||||||
|
vecIndexMap vpMap, vnMap, vtMap;
|
||||||
std::vector<MeshInstance> meshes;
|
std::vector<MeshInstance> meshes;
|
||||||
|
|
||||||
// this endl() doesn't flush() the stream
|
// this endl() doesn't flush() the stream
|
||||||
|
|
|
@ -112,7 +112,7 @@ void ObjFileParser::parseFile()
|
||||||
case 'v': // Parse a vertex texture coordinate
|
case 'v': // Parse a vertex texture coordinate
|
||||||
{
|
{
|
||||||
++m_DataIt;
|
++m_DataIt;
|
||||||
if (*m_DataIt == ' ')
|
if (*m_DataIt == ' ' || *m_DataIt == '\t')
|
||||||
{
|
{
|
||||||
// Read in vertex definition
|
// Read in vertex definition
|
||||||
getVector3(m_pModel->m_Vertices);
|
getVector3(m_pModel->m_Vertices);
|
||||||
|
@ -290,6 +290,10 @@ void ObjFileParser::getFace(aiPrimitiveType type)
|
||||||
std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
|
std::vector<unsigned int> *pNormalID = new std::vector<unsigned int>;
|
||||||
bool hasNormal = false;
|
bool hasNormal = false;
|
||||||
|
|
||||||
|
const int vSize = m_pModel->m_Vertices.size();
|
||||||
|
const int vtSize = m_pModel->m_TextureCoord.size();
|
||||||
|
const int vnSize = m_pModel->m_Normals.size();
|
||||||
|
|
||||||
const bool vt = (!m_pModel->m_TextureCoord.empty());
|
const bool vt = (!m_pModel->m_TextureCoord.empty());
|
||||||
const bool vn = (!m_pModel->m_Normals.empty());
|
const bool vn = (!m_pModel->m_Normals.empty());
|
||||||
int iStep = 0, iPos = 0;
|
int iStep = 0, iPos = 0;
|
||||||
|
@ -323,7 +327,11 @@ void ObjFileParser::getFace(aiPrimitiveType type)
|
||||||
{
|
{
|
||||||
//OBJ USES 1 Base ARRAYS!!!!
|
//OBJ USES 1 Base ARRAYS!!!!
|
||||||
const int iVal = atoi( pPtr );
|
const int iVal = atoi( pPtr );
|
||||||
|
|
||||||
|
// increment iStep position based off of the sign and # of digits
|
||||||
int tmp = iVal;
|
int tmp = iVal;
|
||||||
|
if (iVal < 0)
|
||||||
|
++iStep;
|
||||||
while ( ( tmp = tmp / 10 )!=0 )
|
while ( ( tmp = tmp / 10 )!=0 )
|
||||||
++iStep;
|
++iStep;
|
||||||
|
|
||||||
|
@ -348,6 +356,27 @@ void ObjFileParser::getFace(aiPrimitiveType type)
|
||||||
reportErrorTokenInFace();
|
reportErrorTokenInFace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ( iVal < 0 )
|
||||||
|
{
|
||||||
|
// Store relatively index
|
||||||
|
if ( 0 == iPos )
|
||||||
|
{
|
||||||
|
pIndices->push_back( vSize + iVal );
|
||||||
|
}
|
||||||
|
else if ( 1 == iPos )
|
||||||
|
{
|
||||||
|
pTexID->push_back( vtSize + iVal );
|
||||||
|
}
|
||||||
|
else if ( 2 == iPos )
|
||||||
|
{
|
||||||
|
pNormalID->push_back( vnSize + iVal );
|
||||||
|
hasNormal = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reportErrorTokenInFace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pPtr += iStep;
|
pPtr += iStep;
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,12 @@ bool IsAsciiSTL(const char* buffer, unsigned int fileSize) {
|
||||||
if (IsBinarySTL(buffer, fileSize))
|
if (IsBinarySTL(buffer, fileSize))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (fileSize < 5)
|
const char* bufferEnd = buffer + fileSize;
|
||||||
|
|
||||||
|
if (!SkipSpaces(&buffer))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (buffer + 5 >= bufferEnd)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return strncmp(buffer, "solid", 5) == 0;
|
return strncmp(buffer, "solid", 5) == 0;
|
||||||
|
@ -209,7 +214,11 @@ void STLImporter::LoadASCIIFile()
|
||||||
{
|
{
|
||||||
aiMesh* pMesh = pScene->mMeshes[0];
|
aiMesh* pMesh = pScene->mMeshes[0];
|
||||||
|
|
||||||
const char* sz = mBuffer + 5; // skip the "solid"
|
const char* sz = mBuffer;
|
||||||
|
SkipSpaces(&sz);
|
||||||
|
ai_assert(!IsLineEnd(sz));
|
||||||
|
|
||||||
|
sz += 5; // skip the "solid"
|
||||||
SkipSpaces(&sz);
|
SkipSpaces(&sz);
|
||||||
const char* szMe = sz;
|
const char* szMe = sz;
|
||||||
while (!::IsSpaceOrNewLine(*sz)) {
|
while (!::IsSpaceOrNewLine(*sz)) {
|
||||||
|
|
Loading…
Reference in New Issue