First pass of Collada ZAE support

Reads the manifest and loads the DAE
Does not yet load embedded textures
pull/2545/head
RichardTea 2019-07-12 11:29:35 +01:00
parent 2c7f607e7c
commit d64e1bde13
6 changed files with 1852 additions and 1721 deletions

View File

@ -60,6 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <assimp/SkeletonMeshBuilder.h> #include <assimp/SkeletonMeshBuilder.h>
#include <assimp/CreateAnimMesh.h> #include <assimp/CreateAnimMesh.h>
#include <assimp/ZipArchiveIOSystem.h>
#include "time.h" #include "time.h"
#include "math.h" #include "math.h"
@ -75,12 +76,12 @@ static const aiImporterDesc desc = {
"", "",
"", "",
"http://collada.org", "http://collada.org",
aiImporterFlags_SupportTextFlavour, aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportCompressedFlavour,
1, 1,
3, 3,
1, 1,
5, 5,
"dae" "dae zae"
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -114,9 +115,20 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
// check file extension // check file extension
std::string extension = GetExtension(pFile); std::string extension = GetExtension(pFile);
if (extension == "dae") { bool readSig = checkSig && (pIOHandler != nullptr);
if (!readSig) {
if (extension == "dae" || extension == "zae") {
return true; return true;
} }
}
if (readSig) {
// Look for a DAE file inside, but don't extract it
ZipArchiveIOSystem zip_archive(pIOHandler, pFile);
if (zip_archive.isOpen())
return !ColladaParser::ReadZaeManifest(zip_archive).empty();
}
// XML - too generic, we need to open the file and search for typical keywords // XML - too generic, we need to open the file and search for typical keywords
if (extension == "xml" || !extension.length() || checkSig) { if (extension == "xml" || !extension.length() || checkSig) {
@ -357,7 +369,8 @@ void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Coll
if (out->mType == aiLightSource_AMBIENT) { if (out->mType == aiLightSource_AMBIENT) {
out->mColorDiffuse = out->mColorSpecular = aiColor3D(0, 0, 0); out->mColorDiffuse = out->mColorSpecular = aiColor3D(0, 0, 0);
out->mColorAmbient = srcLight->mColor*srcLight->mIntensity; out->mColorAmbient = srcLight->mColor*srcLight->mIntensity;
} else { }
else {
// collada doesn't differentiate between these color types // collada doesn't differentiate between these color types
out->mColorDiffuse = out->mColorSpecular = srcLight->mColor*srcLight->mIntensity; out->mColorDiffuse = out->mColorSpecular = srcLight->mColor*srcLight->mIntensity;
out->mColorAmbient = aiColor3D(0, 0, 0); out->mColorAmbient = aiColor3D(0, 0, 0);
@ -375,12 +388,14 @@ void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Coll
// epsilon chosen to be 0.1 // epsilon chosen to be 0.1
out->mAngleOuterCone = std::acos(std::pow(0.1f, 1.f / srcLight->mFalloffExponent)) + out->mAngleOuterCone = std::acos(std::pow(0.1f, 1.f / srcLight->mFalloffExponent)) +
out->mAngleInnerCone; out->mAngleInnerCone;
} else { }
else {
out->mAngleOuterCone = out->mAngleInnerCone + AI_DEG_TO_RAD(srcLight->mPenumbraAngle); out->mAngleOuterCone = out->mAngleInnerCone + AI_DEG_TO_RAD(srcLight->mPenumbraAngle);
if (out->mAngleOuterCone < out->mAngleInnerCone) if (out->mAngleOuterCone < out->mAngleInnerCone)
std::swap(out->mAngleInnerCone, out->mAngleOuterCone); std::swap(out->mAngleInnerCone, out->mAngleOuterCone);
} }
} else { }
else {
out->mAngleOuterCone = AI_DEG_TO_RAD(srcLight->mOuterAngle); out->mAngleOuterCone = AI_DEG_TO_RAD(srcLight->mOuterAngle);
} }
} }
@ -474,7 +489,8 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
ASSIMP_LOG_WARN_F("Collada: Unable to find geometry for ID \"", mid.mMeshOrController, "\". Skipping."); ASSIMP_LOG_WARN_F("Collada: Unable to find geometry for ID \"", mid.mMeshOrController, "\". Skipping.");
continue; continue;
} }
} else { }
else {
// ID found in the mesh library -> direct reference to an unskinned mesh // ID found in the mesh library -> direct reference to an unskinned mesh
srcMesh = srcMeshIt->second; srcMesh = srcMeshIt->second;
} }
@ -495,7 +511,8 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
if (meshMatIt != mid.mMaterials.end()) { if (meshMatIt != mid.mMaterials.end()) {
table = &meshMatIt->second; table = &meshMatIt->second;
meshMaterial = table->mMatName; meshMaterial = table->mMatName;
} else { }
else {
ASSIMP_LOG_WARN_F("Collada: No material specified for subgroup <", submesh.mMaterial, "> in geometry <", ASSIMP_LOG_WARN_F("Collada: No material specified for subgroup <", submesh.mMaterial, "> in geometry <",
mid.mMeshOrController, ">."); mid.mMeshOrController, ">.");
if (!mid.mMaterials.empty()) { if (!mid.mMaterials.empty()) {
@ -531,7 +548,8 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
std::map<ColladaMeshIndex, size_t>::const_iterator dstMeshIt = mMeshIndexByID.find(index); std::map<ColladaMeshIndex, size_t>::const_iterator dstMeshIt = mMeshIndexByID.find(index);
if (dstMeshIt != mMeshIndexByID.end()) { if (dstMeshIt != mMeshIndexByID.end()) {
newMeshRefs.push_back(dstMeshIt->second); newMeshRefs.push_back(dstMeshIt->second);
} else { }
else {
// else we have to add the mesh to the collection and store its newly assigned index at the node // else we have to add the mesh to the collection and store its newly assigned index at the node
aiMesh* dstMesh = CreateMesh(pParser, srcMesh, submesh, srcController, vertexStart, faceStart); aiMesh* dstMesh = CreateMesh(pParser, srcMesh, submesh, srcController, vertexStart, faceStart);
@ -1056,7 +1074,8 @@ void insertMorphTimeValue(std::vector<MorphTimeValues> &values, float time, floa
{ {
values[i].mKeys.push_back(k); values[i].mKeys.push_back(k);
return; return;
} else if (time > values[i].mTime && time < values[i+1].mTime) }
else if (time > values[i].mTime && time < values[i + 1].mTime)
{ {
MorphTimeValues val; MorphTimeValues val;
val.mTime = time; val.mTime = time;
@ -1158,7 +1177,8 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
entry.mSubElement = 2; entry.mSubElement = 2;
else else
ASSIMP_LOG_WARN_F("Unknown anim subelement <", subElement, ">. Ignoring"); ASSIMP_LOG_WARN_F("Unknown anim subelement <", subElement, ">. Ignoring");
} else { }
else {
// no subelement following, transformId is remaining string // no subelement following, transformId is remaining string
entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1); entry.mTransformId = srcChannel.mTarget.substr(slashPos + 1);
} }
@ -1216,7 +1236,8 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
{ {
entry.mTargetId = entry.mTransformId; entry.mTargetId = entry.mTransformId;
entry.mTransformId = ""; entry.mTransformId = "";
} else }
else
continue; continue;
} }
@ -1385,7 +1406,8 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
} }
anims.push_back(dstAnim); anims.push_back(dstAnim);
} else }
else
{ {
ASSIMP_LOG_WARN("Collada loader: found empty animation channel, ignored. Please check your exporter."); ASSIMP_LOG_WARN("Collada loader: found empty animation channel, ignored. Please check your exporter.");
} }
@ -1623,7 +1645,8 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
effect.mTransparent.a = 1.f; effect.mTransparent.a = 1.f;
mat.AddProperty(&effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT); mat.AddProperty(&effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT);
} else { }
else {
effect.mTransparency *= effect.mTransparent.a; effect.mTransparency *= effect.mTransparent.a;
} }
@ -1821,7 +1844,8 @@ void ColladaLoader::ConvertPath (aiString& ss)
size_t nbr = strtoul16(mychar); size_t nbr = strtoul16(mychar);
it += 3; it += 3;
*out++ = (char)(nbr & 0xFF); *out++ = (char)(nbr & 0xFF);
} else }
else
{ {
*out++ = *it++; *out++ = *it++;
} }
@ -1905,7 +1929,8 @@ std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode)
{ {
if (!pNode->mName.empty()) { if (!pNode->mName.empty()) {
return pNode->mName; return pNode->mName;
} else { }
else {
return format() << "$ColladaAutoName$_" << mNodeNameCounter++; return format() << "$ColladaAutoName$_" << mNodeNameCounter++;
} }
} }

View File

@ -94,7 +94,7 @@ public:
public: public:
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */ * See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const; bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
protected: protected:
/** Return importer meta information. /** Return importer meta information.

View File

@ -57,6 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/light.h> #include <assimp/light.h>
#include <assimp/TinyFormatter.h> #include <assimp/TinyFormatter.h>
#include <assimp/ZipArchiveIOSystem.h>
#include <memory> #include <memory>
@ -90,21 +91,49 @@ ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
throw DeadlyImportError("IOSystem is NULL."); throw DeadlyImportError("IOSystem is NULL.");
} }
// open the file std::unique_ptr<IOStream> daefile;
std::unique_ptr<IOStream> file( pIOHandler->Open(pFile ) ); std::unique_ptr<ZipArchiveIOSystem> zip_archive;
if (file.get() == nullptr) {
throw DeadlyImportError( "Failed to open file " + pFile + "." ); // Determine type
std::string extension = BaseImporter::GetExtension(pFile);
if (extension != "dae") {
zip_archive.reset(new ZipArchiveIOSystem(pIOHandler, pFile));
}
if (zip_archive && zip_archive->isOpen()) {
std::string dae_filename = ReadZaeManifest(*zip_archive);
if (dae_filename.empty()) {
ThrowException(std::string("Invalid ZAE"));
}
daefile.reset(zip_archive->Open(dae_filename.c_str()));
if (daefile == nullptr) {
ThrowException(std::string("Invalid ZAE manifest: '") + std::string(dae_filename) + std::string("' is missing"));
}
}
else {
// attempt to open the file directly
daefile.reset(pIOHandler->Open(pFile));
if (daefile.get() == nullptr) {
throw DeadlyImportError("Failed to open file '" + pFile + "'.");
}
} }
// generate a XML reader for it // generate a XML reader for it
std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get())); std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(daefile.get()));
mReader = irr::io::createIrrXMLReader(mIOWrapper.get()); mReader = irr::io::createIrrXMLReader(mIOWrapper.get());
if (!mReader) { if (!mReader) {
ThrowException("Collada: Unable to open file."); ThrowException("Unable to read file, malformed XML");
} }
// start reading // start reading
ReadContents(); ReadContents();
// read embedded textures
if (zip_archive && zip_archive->isOpen()) {
// TODO
}
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -118,6 +147,49 @@ ColladaParser::~ColladaParser()
delete it->second; delete it->second;
} }
// ------------------------------------------------------------------------------------------------
// Read a ZAE manifest and return the filename to attempt to open
std::string ColladaParser::ReadZaeManifest(ZipArchiveIOSystem &zip_archive) {
// Open the manifest
std::unique_ptr<IOStream> manifestfile(zip_archive.Open("manifest.xml"));
if (manifestfile == nullptr)
{
// No manifest, hope there is only one .DAE inside
std::vector<std::string> file_list;
zip_archive.getFileListExtension(file_list, "dae");
if (file_list.empty())
return std::string();
return file_list.front();
}
std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(manifestfile.get()));
irr::io::IrrXMLReader* manifest_reader = irr::io::createIrrXMLReader(mIOWrapper.get());
while (manifest_reader->read())
{
// find the manifest "dae_root" element
if (manifest_reader->getNodeType() == irr::io::EXN_ELEMENT)
{
if (::strcmp(manifest_reader->getNodeName(), "dae_root") == 0)
{
if (!manifest_reader->read())
return std::string();
if (manifest_reader->getNodeType() != irr::io::EXN_TEXT && manifest_reader->getNodeType() != irr::io::EXN_CDATA)
return std::string();
const char* filepath = manifest_reader->getNodeData();
if (filepath == nullptr)
return std::string();
return std::string(filepath);
}
}
}
return std::string();
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Read bool from text contents of current element // Read bool from text contents of current element
bool ColladaParser::ReadBoolFromTextContent() bool ColladaParser::ReadBoolFromTextContent()
@ -165,12 +237,14 @@ void ColladaParser::ReadContents()
} }
ReadStructure(); ReadStructure();
} else }
else
{ {
ASSIMP_LOG_DEBUG_F("Ignoring global element <", mReader->getNodeName(), ">."); ASSIMP_LOG_DEBUG_F("Ignoring global element <", mReader->getNodeName(), ">.");
SkipElement(); SkipElement();
} }
} else }
else
{ {
// skip everything else silently // skip everything else silently
} }
@ -506,7 +580,8 @@ void ColladaParser::ReadAnimationLibrary()
{ {
// delegate the reading. Depending on the inner elements it will be a container or a anim channel // delegate the reading. Depending on the inner elements it will be a container or a anim channel
ReadAnimation(&mAnims); ReadAnimation(&mAnims);
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -722,7 +797,8 @@ void ColladaParser::ReadControllerLibrary()
// read on from there // read on from there
ReadController(mControllerLibrary[id]); ReadController(mControllerLibrary[id]);
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -816,7 +892,8 @@ void ColladaParser::ReadController( Collada::Controller& pController)
pController.mMorphWeight = source + 1; pController.mMorphWeight = source + 1;
} }
} }
} else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) { }
else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
if (strcmp(mReader->getNodeName(), "targets") == 0) if (strcmp(mReader->getNodeName(), "targets") == 0)
break; break;
else else
@ -1008,7 +1085,8 @@ void ColladaParser::ReadImageLibrary()
// read on from there // read on from there
ReadImage(mImageLibrary[id]); ReadImage(mImageLibrary[id]);
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -1158,7 +1236,8 @@ void ColladaParser::ReadMaterialLibrary()
} }
ReadMaterial(mMaterialLibrary[id]); ReadMaterial(mMaterialLibrary[id]);
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -1193,7 +1272,8 @@ void ColladaParser::ReadLightLibrary()
// create an entry and store it in the library under its ID // create an entry and store it in the library under its ID
ReadLight(mLightLibrary[id] = Light()); ReadLight(mLightLibrary[id] = Light());
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -1232,7 +1312,8 @@ void ColladaParser::ReadCameraLibrary()
ReadCamera(cam); ReadCamera(cam);
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -1268,7 +1349,8 @@ void ColladaParser::ReadMaterial( Collada::Material& pMaterial)
pMaterial.mEffect = url + 1; pMaterial.mEffect = url + 1;
SkipElement(); SkipElement();
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -1439,7 +1521,8 @@ void ColladaParser::ReadEffectLibrary()
mEffectLibrary[id] = Effect(); mEffectLibrary[id] = Effect();
// read on from there // read on from there
ReadEffect(mEffectLibrary[id]); ReadEffect(mEffectLibrary[id]);
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -1779,7 +1862,8 @@ void ColladaParser::ReadEffectFloat( ai_real& pFloat)
SkipSpacesAndLineEnd(&content); SkipSpacesAndLineEnd(&content);
TestClosing("float"); TestClosing("float");
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -1834,7 +1918,8 @@ void ColladaParser::ReadEffectParam( Collada::EffectParam& pParam)
pParam.mType = Param_Sampler; pParam.mType = Param_Sampler;
pParam.mReference = url; pParam.mReference = url;
SkipElement("sampler2D"); SkipElement("sampler2D");
} else }
else
{ {
// ignore unknown element // ignore unknown element
SkipElement(); SkipElement();
@ -1879,7 +1964,8 @@ void ColladaParser::ReadGeometryLibrary()
// read on from there // read on from there
ReadGeometry(mesh); ReadGeometry(mesh);
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -1910,7 +1996,8 @@ void ColladaParser::ReadGeometry( Collada::Mesh* pMesh)
{ {
// read on from there // read on from there
ReadMesh(pMesh); ReadMesh(pMesh);
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -1952,7 +2039,8 @@ void ColladaParser::ReadMesh( Mesh* pMesh)
{ {
// read per-index mesh data and faces setup // read per-index mesh data and faces setup
ReadIndexData(pMesh); ReadIndexData(pMesh);
} else }
else
{ {
// ignore the restf // ignore the restf
SkipElement(); SkipElement();
@ -1968,7 +2056,8 @@ void ColladaParser::ReadMesh( Mesh* pMesh)
{ {
// end of <mesh> element - we're done here // end of <mesh> element - we're done here
break; break;
} else }
else
{ {
// everything else should be punished // everything else should be punished
ThrowException("Expected end of <mesh> element."); ThrowException("Expected end of <mesh> element.");
@ -1999,7 +2088,8 @@ void ColladaParser::ReadSource()
else if (IsElement("accessor")) else if (IsElement("accessor"))
{ {
ReadAccessor(sourceID); ReadAccessor(sourceID);
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -2015,7 +2105,8 @@ void ColladaParser::ReadSource()
else if (strcmp(mReader->getNodeName(), "technique_common") == 0) else if (strcmp(mReader->getNodeName(), "technique_common") == 0)
{ {
// end of another meaningless element - read over it // end of another meaningless element - read over it
} else }
else
{ {
// everything else should be punished // everything else should be punished
ThrowException("Expected end of <source> element."); ThrowException("Expected end of <source> element.");
@ -2064,7 +2155,8 @@ void ColladaParser::ReadDataArray()
SkipSpacesAndLineEnd(&content); SkipSpacesAndLineEnd(&content);
} }
} else }
else
{ {
data.mValues.reserve(count); data.mValues.reserve(count);
@ -2176,7 +2268,8 @@ void ColladaParser::ReadAccessor( const std::string& pID)
// skip remaining stuff of this element, if any // skip remaining stuff of this element, if any
SkipElement(); SkipElement();
} else }
else
{ {
ThrowException(format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <accessor>"); ThrowException(format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <accessor>");
} }
@ -2206,7 +2299,8 @@ void ColladaParser::ReadVertexData( Mesh* pMesh)
if (IsElement("input")) if (IsElement("input"))
{ {
ReadInputChannel(pMesh->mPerVertexData); ReadInputChannel(pMesh->mPerVertexData);
} else }
else
{ {
ThrowException(format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <vertices>"); ThrowException(format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <vertices>");
} }
@ -2304,9 +2398,11 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
else if (IsElement("extra")) else if (IsElement("extra"))
{ {
SkipElement("extra"); SkipElement("extra");
} else if ( IsElement("ph")) { }
else if (IsElement("ph")) {
SkipElement("ph"); SkipElement("ph");
} else { }
else {
ThrowException(format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <" << elementName << ">"); ThrowException(format() << "Unexpected sub element <" << mReader->getNodeName() << "> in tag <" << elementName << ">");
} }
} }
@ -2436,10 +2532,12 @@ size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pP
// HACK: We just fix this number since SketchUp 15.3.331 writes the wrong 'count' for 'lines' // HACK: We just fix this number since SketchUp 15.3.331 writes the wrong 'count' for 'lines'
ReportWarning("Expected different index count in <p> element, %zu instead of %zu.", indices.size(), expectedPointCount * numOffsets); ReportWarning("Expected different index count in <p> element, %zu instead of %zu.", indices.size(), expectedPointCount * numOffsets);
pNumPrimitives = (indices.size() / numOffsets) / 2; pNumPrimitives = (indices.size() / numOffsets) / 2;
} else }
else
ThrowException("Expected different index count in <p> element."); ThrowException("Expected different index count in <p> element.");
} else if( expectedPointCount == 0 && (indices.size() % numOffsets) != 0) }
else if (expectedPointCount == 0 && (indices.size() % numOffsets) != 0)
ThrowException("Expected different index count in <p> element."); ThrowException("Expected different index count in <p> element.");
// find the data for all sources // find the data for all sources
@ -2660,7 +2758,8 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
pMesh->mTexCoords[pInput.mIndex].push_back(aiVector3D(obj[0], obj[1], obj[2])); pMesh->mTexCoords[pInput.mIndex].push_back(aiVector3D(obj[0], obj[1], obj[2]));
if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */ if (0 != acc.mSubOffset[2] || 0 != acc.mSubOffset[3]) /* hack ... consider cleaner solution */
pMesh->mNumUVComponents[pInput.mIndex] = 3; pMesh->mNumUVComponents[pInput.mIndex] = 3;
} else }
else
{ {
ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping."); ASSIMP_LOG_ERROR("Collada: too many texture coordinate sets. Skipping.");
} }
@ -2680,7 +2779,8 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
result[static_cast<unsigned int>(i)] = obj[pInput.mResolved->mSubOffset[i]]; result[static_cast<unsigned int>(i)] = obj[pInput.mResolved->mSubOffset[i]];
} }
pMesh->mColors[pInput.mIndex].push_back(result); pMesh->mColors[pInput.mIndex].push_back(result);
} else }
else
{ {
ASSIMP_LOG_ERROR("Collada: too many vertex color sets. Skipping."); ASSIMP_LOG_ERROR("Collada: too many vertex color sets. Skipping.");
} }
@ -2723,7 +2823,8 @@ void ColladaParser::ReadSceneLibrary()
mNodeLibrary[node->mID] = node; mNodeLibrary[node->mID] = node;
ReadSceneNode(node); ReadSceneNode(node);
} else }
else
{ {
// ignore the rest // ignore the rest
SkipElement(); SkipElement();
@ -3036,7 +3137,8 @@ void ColladaParser::ReadScene()
if (sit == mNodeLibrary.end()) if (sit == mNodeLibrary.end())
ThrowException("Unable to resolve visual_scene reference \"" + std::string(url) + "\" in <instance_visual_scene> element."); ThrowException("Unable to resolve visual_scene reference \"" + std::string(url) + "\" in <instance_visual_scene> element.");
mRootNode = sit->second; mRootNode = sit->second;
} else { }
else {
SkipElement(); SkipElement();
} }
} }

View File

@ -54,6 +54,7 @@
namespace Assimp namespace Assimp
{ {
class ZipArchiveIOSystem;
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
/** Parser helper class for the Collada loader. /** Parser helper class for the Collada loader.
@ -75,6 +76,9 @@ namespace Assimp
/** Destructor */ /** Destructor */
~ColladaParser(); ~ColladaParser();
/** Attempts to read the ZAE manifest and returns the DAE to open */
static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
/** Reads the contents of the file */ /** Reads the contents of the file */
void ReadContents(); void ReadContents();

Binary file not shown.

Binary file not shown.