Collada ZAE import must convert manifest and image paths
Moved ConvertPath into ColladaParser and use it when reading all filenames from the XML Added more EXPECTS to the Collada testspull/2711/head
parent
14f8877a2c
commit
ce5c71d2e7
|
@ -583,7 +583,7 @@ struct Image
|
|||
/** Embedded image data */
|
||||
std::vector<uint8_t> mImageData;
|
||||
|
||||
/** File format hint ofembedded image data */
|
||||
/** File format hint of embedded image data */
|
||||
std::string mEmbeddedFormat;
|
||||
};
|
||||
|
||||
|
|
|
@ -1735,6 +1735,7 @@ void ColladaLoader::BuildMaterials(ColladaParser& pParser, aiScene* /*pScene*/)
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Resolves the texture name for the given effect texture entry
|
||||
// and loads the texture data
|
||||
aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser& pParser,
|
||||
const Collada::Effect& pEffect, const std::string& pName)
|
||||
{
|
||||
|
@ -1762,7 +1763,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser& pParse
|
|||
|
||||
//set default texture file name
|
||||
result.Set(name + ".jpg");
|
||||
ConvertPath(result);
|
||||
ColladaParser::ConvertPath(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1781,7 +1782,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser& pParse
|
|||
|
||||
|
||||
// setup format hint
|
||||
if (imIt->second.mEmbeddedFormat.length() > 3) {
|
||||
if (imIt->second.mEmbeddedFormat.length() >= HINTMAXTEXTURELEN) {
|
||||
ASSIMP_LOG_WARN("Collada: texture format hint is too long, truncating to 3 characters");
|
||||
}
|
||||
strncpy(tex->achFormatHint, imIt->second.mEmbeddedFormat.c_str(), 3);
|
||||
|
@ -1802,61 +1803,10 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser& pParse
|
|||
}
|
||||
|
||||
result.Set(imIt->second.mFileName);
|
||||
ConvertPath(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Convert a path read from a collada file to the usual representation
|
||||
void ColladaLoader::ConvertPath(aiString& ss)
|
||||
{
|
||||
// TODO: collada spec, p 22. Handle URI correctly.
|
||||
// For the moment we're just stripping the file:// away to make it work.
|
||||
// Windows doesn't seem to be able to find stuff like
|
||||
// 'file://..\LWO\LWO2\MappingModes\earthSpherical.jpg'
|
||||
if (0 == strncmp(ss.data, "file://", 7))
|
||||
{
|
||||
ss.length -= 7;
|
||||
memmove(ss.data, ss.data + 7, ss.length);
|
||||
ss.data[ss.length] = '\0';
|
||||
}
|
||||
|
||||
// Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
|
||||
// I need to filter it without destroying linux paths starting with "/somewhere"
|
||||
#if defined( _MSC_VER )
|
||||
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
|
||||
#else
|
||||
if (ss.data[0] == '/' && isalpha(ss.data[1]) && ss.data[2] == ':') {
|
||||
#endif
|
||||
--ss.length;
|
||||
::memmove(ss.data, ss.data + 1, ss.length);
|
||||
ss.data[ss.length] = 0;
|
||||
}
|
||||
|
||||
// find and convert all %xy special chars
|
||||
char* out = ss.data;
|
||||
for (const char* it = ss.data; it != ss.data + ss.length; /**/)
|
||||
{
|
||||
if (*it == '%' && (it + 3) < ss.data + ss.length)
|
||||
{
|
||||
// separate the number to avoid dragging in chars from behind into the parsing
|
||||
char mychar[3] = { it[1], it[2], 0 };
|
||||
size_t nbr = strtoul16(mychar);
|
||||
it += 3;
|
||||
*out++ = (char)(nbr & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
*out++ = *it++;
|
||||
}
|
||||
}
|
||||
|
||||
// adjust length and terminator of the shortened string
|
||||
*out = 0;
|
||||
ss.length = (ptrdiff_t)(out - ss.data);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a float value from an accessor and its data array.
|
||||
ai_real ColladaLoader::ReadFloat(const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const
|
||||
|
|
|
@ -94,7 +94,7 @@ public:
|
|||
public:
|
||||
/** Returns whether the class can handle the format of the given file.
|
||||
* See BaseImporter::CanRead() for details. */
|
||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
|
||||
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
|
||||
|
||||
protected:
|
||||
/** Return importer meta information.
|
||||
|
@ -184,9 +184,6 @@ protected:
|
|||
aiString FindFilenameForEffectTexture( const ColladaParser& pParser,
|
||||
const Collada::Effect& pEffect, const std::string& pName);
|
||||
|
||||
/** Converts a path read from a collada file to the usual representation */
|
||||
void ConvertPath( aiString& ss);
|
||||
|
||||
/** Reads a float value from an accessor and its data array.
|
||||
* @param pAccessor The accessor to use for reading
|
||||
* @param pData The data array to read from
|
||||
|
|
|
@ -183,13 +183,66 @@ std::string ColladaParser::ReadZaeManifest(ZipArchiveIOSystem &zip_archive) {
|
|||
if (filepath == nullptr)
|
||||
return std::string();
|
||||
|
||||
return std::string(filepath);
|
||||
aiString ai_str(filepath);
|
||||
ConvertPath(ai_str);
|
||||
|
||||
return std::string(ai_str.C_Str());
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Convert a path read from a collada file to the usual representation
|
||||
void ColladaParser::ConvertPath(aiString& ss)
|
||||
{
|
||||
// TODO: collada spec, p 22. Handle URI correctly.
|
||||
// For the moment we're just stripping the file:// away to make it work.
|
||||
// Windows doesn't seem to be able to find stuff like
|
||||
// 'file://..\LWO\LWO2\MappingModes\earthSpherical.jpg'
|
||||
if (0 == strncmp(ss.data, "file://", 7))
|
||||
{
|
||||
ss.length -= 7;
|
||||
memmove(ss.data, ss.data + 7, ss.length);
|
||||
ss.data[ss.length] = '\0';
|
||||
}
|
||||
|
||||
// Maxon Cinema Collada Export writes "file:///C:\andsoon" with three slashes...
|
||||
// I need to filter it without destroying linux paths starting with "/somewhere"
|
||||
#if defined( _MSC_VER )
|
||||
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
|
||||
#else
|
||||
if (ss.data[0] == '/' && isalpha(ss.data[1]) && ss.data[2] == ':') {
|
||||
#endif
|
||||
--ss.length;
|
||||
::memmove(ss.data, ss.data + 1, ss.length);
|
||||
ss.data[ss.length] = 0;
|
||||
}
|
||||
|
||||
// find and convert all %xy special chars
|
||||
char* out = ss.data;
|
||||
for (const char* it = ss.data; it != ss.data + ss.length; /**/)
|
||||
{
|
||||
if (*it == '%' && (it + 3) < ss.data + ss.length)
|
||||
{
|
||||
// separate the number to avoid dragging in chars from behind into the parsing
|
||||
char mychar[3] = { it[1], it[2], 0 };
|
||||
size_t nbr = strtoul16(mychar);
|
||||
it += 3;
|
||||
*out++ = (char)(nbr & 0xFF);
|
||||
}
|
||||
else
|
||||
{
|
||||
*out++ = *it++;
|
||||
}
|
||||
}
|
||||
|
||||
// adjust length and terminator of the shortened string
|
||||
*out = 0;
|
||||
ss.length = (ptrdiff_t)(out - ss.data);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Read bool from text contents of current element
|
||||
bool ColladaParser::ReadBoolFromTextContent()
|
||||
|
@ -1120,7 +1173,12 @@ void ColladaParser::ReadImage(Collada::Image& pImage)
|
|||
if (!mReader->isEmptyElement()) {
|
||||
// element content is filename - hopefully
|
||||
const char* sz = TestTextContent();
|
||||
if (sz)pImage.mFileName = sz;
|
||||
if (sz)
|
||||
{
|
||||
aiString filepath(sz);
|
||||
ConvertPath(filepath);
|
||||
pImage.mFileName = filepath.C_Str();
|
||||
}
|
||||
TestClosing("init_from");
|
||||
}
|
||||
if (!pImage.mFileName.length()) {
|
||||
|
@ -1153,7 +1211,12 @@ void ColladaParser::ReadImage(Collada::Image& pImage)
|
|||
{
|
||||
// element content is filename - hopefully
|
||||
const char* sz = TestTextContent();
|
||||
if (sz)pImage.mFileName = sz;
|
||||
if (sz)
|
||||
{
|
||||
aiString filepath(sz);
|
||||
ConvertPath(filepath);
|
||||
pImage.mFileName = filepath.C_Str();
|
||||
}
|
||||
TestClosing("ref");
|
||||
}
|
||||
else if (IsElement("hex") && !pImage.mFileName.length())
|
||||
|
|
|
@ -66,12 +66,15 @@ namespace Assimp
|
|||
{
|
||||
friend class ColladaLoader;
|
||||
|
||||
/** Converts a path read from a collada file to the usual representation */
|
||||
static void ConvertPath(aiString& ss);
|
||||
|
||||
protected:
|
||||
/** Map for generic metadata as aiString */
|
||||
typedef std::map<std::string, aiString> StringMetaData;
|
||||
|
||||
/** Constructor from XML file */
|
||||
ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
|
||||
ColladaParser(IOSystem* pIOHandler, const std::string& pFile);
|
||||
|
||||
/** Destructor */
|
||||
~ColladaParser();
|
||||
|
|
|
@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "AbstractImportExportBase.h"
|
||||
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
using namespace Assimp;
|
||||
|
@ -53,7 +54,18 @@ public:
|
|||
virtual bool importerTest() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/Collada/duck.dae", aiProcess_ValidateDataStructure );
|
||||
return nullptr != scene;
|
||||
if (scene == nullptr)
|
||||
return false;
|
||||
|
||||
// Expected number of items
|
||||
EXPECT_EQ(scene->mNumMeshes, 1);
|
||||
EXPECT_EQ(scene->mNumMaterials, 1);
|
||||
EXPECT_EQ(scene->mNumAnimations, 0);
|
||||
EXPECT_EQ(scene->mNumTextures, 0);
|
||||
EXPECT_EQ(scene->mNumLights, 1);
|
||||
EXPECT_EQ(scene->mNumCameras, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -66,7 +78,18 @@ public:
|
|||
virtual bool importerTest() {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck.zae", aiProcess_ValidateDataStructure);
|
||||
return nullptr != scene;
|
||||
if (scene == nullptr)
|
||||
return false;
|
||||
|
||||
// Expected number of items
|
||||
EXPECT_EQ(scene->mNumMeshes, 1);
|
||||
EXPECT_EQ(scene->mNumMaterials, 1);
|
||||
EXPECT_EQ(scene->mNumAnimations, 0);
|
||||
EXPECT_EQ(scene->mNumTextures, 1);
|
||||
EXPECT_EQ(scene->mNumLights, 1);
|
||||
EXPECT_EQ(scene->mNumCameras, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue