Merge branch 'master' into master

pull/3195/head
Kim Kulling 2020-05-16 20:41:05 +02:00 committed by GitHub
commit d7e8fefed7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
152 changed files with 5096 additions and 22141 deletions

100
INSTALL
View File

@ -1,50 +1,50 @@
======================================================================== ========================================================================
Open Asset Import Library (assimp) INSTALL Open Asset Import Library (assimp) INSTALL
======================================================================== ========================================================================
------------------------------ ------------------------------
Getting the documentation Getting the documentation
------------------------------ ------------------------------
A regularly-updated copy is available at A regularly-updated copy is available at
http://assimp.sourceforge.net/lib_html/index.html http://assimp.sourceforge.net/lib_html/index.html
A CHM file is included in the SVN repos: ./doc/AssimpDoc_Html/AssimpDoc.chm. A CHM file is included in the SVN repos: ./doc/AssimpDoc_Html/AssimpDoc.chm.
To build the doxygen documentation on your own, follow these steps: To build the doxygen documentation on your own, follow these steps:
a) download & install latest doxygen a) download & install latest doxygen
b) make sure doxygen is in the executable search path b) make sure doxygen is in the executable search path
c) navigate to ./doc c) navigate to ./doc
d) and run 'doxygen' d) and run 'doxygen'
Open the generated HTML (AssimpDoc_Html/index.html) in the browser of your choice. Open the generated HTML (AssimpDoc_Html/index.html) in the browser of your choice.
Windows only: To generate the CHM doc, install 'Microsoft HTML Workshop' Windows only: To generate the CHM doc, install 'Microsoft HTML Workshop'
and configure the path to it in the DOXYFILE first. and configure the path to it in the DOXYFILE first.
------------------------------ ------------------------------
Building Assimp Building Assimp
------------------------------ ------------------------------
More detailed build instructions can be found in the documentation, More detailed build instructions can be found in the documentation,
this section is just for the inpatient among you. this section is just for the inpatient among you.
CMake is the preferred build system for Assimp. The minimum required version CMake is the preferred build system for Assimp. The minimum required version
is 2.6. If you don't have it yet, downloads for CMake can be found on is 2.6. If you don't have it yet, downloads for CMake can be found on
http://www.cmake.org/. http://www.cmake.org/.
For Unix: For Unix:
1. mkdir build && cd build 1. mkdir build && cd build
2. cmake .. -G 'Unix Makefiles' 2. cmake .. -G 'Unix Makefiles'
3. make -j4 3. make -j4
For Windows: For Windows:
1. Open a command prompt 1. Open a command prompt
2. mkdir build 2. mkdir build
3. cd build 3. cd build
4. cmake .. 4. cmake ..
5. cmake --build . 5. cmake --build .
For iOS: For iOS:
Just check the following project, which deploys a compiler toolchain for different iOS-versions: https://github.com/assimp/assimp/tree/master/port/iOS Just check the following project, which deploys a compiler toolchain for different iOS-versions: https://github.com/assimp/assimp/tree/master/port/iOS

View File

@ -1,4 +1,4 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -44,8 +44,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER #ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
#include "ColladaExporter.h" #include "ColladaExporter.h"
#include <assimp/Bitmap.h> #include <assimp/Bitmap.h>
#include <assimp/ColladaMetaData.h>
#include <assimp/DefaultIOSystem.h> #include <assimp/DefaultIOSystem.h>
#include <assimp/Exceptional.h>
#include <assimp/MathFunctions.h> #include <assimp/MathFunctions.h>
#include <assimp/SceneCombiner.h> #include <assimp/SceneCombiner.h>
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
@ -56,15 +59,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Exporter.hpp> #include <assimp/Exporter.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
#include <assimp/Exceptional.h>
#include <ctime> #include <ctime>
#include <iostream>
#include <memory> #include <memory>
#include <set>
#include <vector>
using namespace Assimp;
namespace Assimp { namespace Assimp {
@ -91,8 +87,6 @@ void ExportSceneCollada(const char *pFile, IOSystem *pIOSystem, const aiScene *p
outfile->Write(iDoTheExportThing.mOutput.str().c_str(), static_cast<size_t>(iDoTheExportThing.mOutput.tellp()), 1); outfile->Write(iDoTheExportThing.mOutput.str().c_str(), static_cast<size_t>(iDoTheExportThing.mOutput.tellp()), 1);
} }
} // end of namespace Assimp
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Encodes a string into a valid XML ID using the xsd:ID schema qualifications. // Encodes a string into a valid XML ID using the xsd:ID schema qualifications.
static const std::string XMLIDEncode(const std::string &name) { static const std::string XMLIDEncode(const std::string &name) {
@ -115,7 +109,7 @@ static const std::string XMLIDEncode(const std::string &name) {
if (strchr(XML_ID_CHARS, *it) != nullptr) { if (strchr(XML_ID_CHARS, *it) != nullptr) {
idEncoded << *it; idEncoded << *it;
} else { } else {
// Select placeholder character based on invalid character to prevent name collisions // Select placeholder character based on invalid character to reduce ID collisions
idEncoded << XML_ID_CHARS[(*it) % XML_ID_CHARS_COUNT]; idEncoded << XML_ID_CHARS[(*it) % XML_ID_CHARS_COUNT];
} }
} }
@ -126,7 +120,9 @@ static const std::string XMLIDEncode(const std::string &name) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor for a specific scene to export // Constructor for a specific scene to export
ColladaExporter::ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file) : ColladaExporter::ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file) :
mIOSystem(pIOSystem), mPath(path), mFile(file) { mIOSystem(pIOSystem),
mPath(path),
mFile(file) {
// make sure that all formatting happens using the standard, C locale and not the user's current locale // make sure that all formatting happens using the standard, C locale and not the user's current locale
mOutput.imbue(std::locale("C")); mOutput.imbue(std::locale("C"));
mOutput.precision(ASSIMP_AI_REAL_TEXT_PRECISION); mOutput.precision(ASSIMP_AI_REAL_TEXT_PRECISION);
@ -161,6 +157,9 @@ void ColladaExporter::WriteFile() {
WriteTextures(); WriteTextures();
WriteHeader(); WriteHeader();
// Add node names to the unique id database first so they are most likely to use their names as unique ids
CreateNodeIds(mScene->mRootNode);
WriteCamerasLibrary(); WriteCamerasLibrary();
WriteLightsLibrary(); WriteLightsLibrary();
WriteMaterials(); WriteMaterials();
@ -175,7 +174,7 @@ void ColladaExporter::WriteFile() {
// useless Collada fu at the end, just in case we haven't had enough indirections, yet. // useless Collada fu at the end, just in case we haven't had enough indirections, yet.
mOutput << startstr << "<scene>" << endstr; mOutput << startstr << "<scene>" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<instance_visual_scene url=\"#" + XMLIDEncode(mScene->mRootNode->mName.C_Str()) + "\" />" << endstr; mOutput << startstr << "<instance_visual_scene url=\"#" + GetNodeUniqueId(mScene->mRootNode) + "\" />" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</scene>" << endstr; mOutput << startstr << "</scene>" << endstr;
PopTag(); PopTag();
@ -201,7 +200,7 @@ void ColladaExporter::WriteHeader() {
static const unsigned int date_nb_chars = 20; static const unsigned int date_nb_chars = 20;
char date_str[date_nb_chars]; char date_str[date_nb_chars];
std::time_t date = std::time(NULL); std::time_t date = std::time(nullptr);
std::strftime(date_str, date_nb_chars, "%Y-%m-%dT%H:%M:%S", std::localtime(&date)); std::strftime(date_str, date_nb_chars, "%Y-%m-%dT%H:%M:%S", std::localtime(&date));
aiVector3D scaling; aiVector3D scaling;
@ -352,7 +351,7 @@ void ColladaExporter::WriteTextures() {
std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char *)texture->achFormatHint); std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char *)texture->achFormatHint);
std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + mIOSystem->getOsSeparator() + name, "wb")); std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + mIOSystem->getOsSeparator() + name, "wb"));
if (outfile == NULL) { if (outfile == nullptr) {
throw DeadlyExportError("could not open output texture file: " + mPath + name); throw DeadlyExportError("could not open output texture file: " + mPath + name);
} }
@ -388,10 +387,10 @@ void ColladaExporter::WriteCamerasLibrary() {
void ColladaExporter::WriteCamera(size_t pIndex) { void ColladaExporter::WriteCamera(size_t pIndex) {
const aiCamera *cam = mScene->mCameras[pIndex]; const aiCamera *cam = mScene->mCameras[pIndex];
const std::string cameraName = XMLEscape(cam->mName.C_Str()); const std::string cameraId = GetObjectUniqueId(AiObjectType::Camera, pIndex);
const std::string cameraId = XMLIDEncode(cam->mName.C_Str()); const std::string cameraName = GetObjectName(AiObjectType::Camera, pIndex);
mOutput << startstr << "<camera id=\"" << cameraId << "-camera\" name=\"" << cameraName << "\" >" << endstr; mOutput << startstr << "<camera id=\"" << cameraId << "\" name=\"" << cameraName << "\" >" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<optics>" << endstr; mOutput << startstr << "<optics>" << endstr;
PushTag(); PushTag();
@ -441,10 +440,10 @@ void ColladaExporter::WriteLightsLibrary() {
void ColladaExporter::WriteLight(size_t pIndex) { void ColladaExporter::WriteLight(size_t pIndex) {
const aiLight *light = mScene->mLights[pIndex]; const aiLight *light = mScene->mLights[pIndex];
const std::string lightName = XMLEscape(light->mName.C_Str()); const std::string lightId = GetObjectUniqueId(AiObjectType::Light, pIndex);
const std::string lightId = XMLIDEncode(light->mName.C_Str()); const std::string lightName = GetObjectName(AiObjectType::Light, pIndex);
mOutput << startstr << "<light id=\"" << lightId << "-light\" name=\"" mOutput << startstr << "<light id=\"" << lightId << "\" name=\""
<< lightName << "\" >" << endstr; << lightName << "\" >" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<technique_common>" << endstr; mOutput << startstr << "<technique_common>" << endstr;
@ -561,12 +560,11 @@ void ColladaExporter::WriteAmbienttLight(const aiLight *const light) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Reads a single surface entry from the given material keys // Reads a single surface entry from the given material keys
void ColladaExporter::ReadMaterialSurface(Surface &poSurface, const aiMaterial *pSrcMat, bool ColladaExporter::ReadMaterialSurface(Surface &poSurface, const aiMaterial &pSrcMat, aiTextureType pTexture, const char *pKey, size_t pType, size_t pIndex) {
aiTextureType pTexture, const char *pKey, size_t pType, size_t pIndex) { if (pSrcMat.GetTextureCount(pTexture) > 0) {
if (pSrcMat->GetTextureCount(pTexture) > 0) {
aiString texfile; aiString texfile;
unsigned int uvChannel = 0; unsigned int uvChannel = 0;
pSrcMat->GetTexture(pTexture, 0, &texfile, NULL, &uvChannel); pSrcMat.GetTexture(pTexture, 0, &texfile, nullptr, &uvChannel);
std::string index_str(texfile.C_Str()); std::string index_str(texfile.C_Str());
@ -596,8 +594,9 @@ void ColladaExporter::ReadMaterialSurface(Surface &poSurface, const aiMaterial *
poSurface.exist = true; poSurface.exist = true;
} else { } else {
if (pKey) if (pKey)
poSurface.exist = pSrcMat->Get(pKey, static_cast<unsigned int>(pType), static_cast<unsigned int>(pIndex), poSurface.color) == aiReturn_SUCCESS; poSurface.exist = pSrcMat.Get(pKey, static_cast<unsigned int>(pType), static_cast<unsigned int>(pIndex), poSurface.color) == aiReturn_SUCCESS;
} }
return poSurface.exist;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -608,9 +607,9 @@ static bool isalnum_C(char c) {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Writes an image entry for the given surface // Writes an image entry for the given surface
void ColladaExporter::WriteImageEntry(const Surface &pSurface, const std::string &pNameAdd) { void ColladaExporter::WriteImageEntry(const Surface &pSurface, const std::string &imageId) {
if (!pSurface.texture.empty()) { if (!pSurface.texture.empty()) {
mOutput << startstr << "<image id=\"" << XMLIDEncode(pNameAdd) << "\">" << endstr; mOutput << startstr << "<image id=\"" << imageId << "\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<init_from>"; mOutput << startstr << "<init_from>";
@ -631,14 +630,14 @@ void ColladaExporter::WriteImageEntry(const Surface &pSurface, const std::string
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Writes a color-or-texture entry into an effect definition // Writes a color-or-texture entry into an effect definition
void ColladaExporter::WriteTextureColorEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &pImageName) { void ColladaExporter::WriteTextureColorEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &imageId) {
if (pSurface.exist) { if (pSurface.exist) {
mOutput << startstr << "<" << pTypeName << ">" << endstr; mOutput << startstr << "<" << pTypeName << ">" << endstr;
PushTag(); PushTag();
if (pSurface.texture.empty()) { if (pSurface.texture.empty()) {
mOutput << startstr << "<color sid=\"" << pTypeName << "\">" << pSurface.color.r << " " << pSurface.color.g << " " << pSurface.color.b << " " << pSurface.color.a << "</color>" << endstr; mOutput << startstr << "<color sid=\"" << pTypeName << "\">" << pSurface.color.r << " " << pSurface.color.g << " " << pSurface.color.b << " " << pSurface.color.a << "</color>" << endstr;
} else { } else {
mOutput << startstr << "<texture texture=\"" << XMLIDEncode(pImageName) << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr; mOutput << startstr << "<texture texture=\"" << imageId << "\" texcoord=\"CHANNEL" << pSurface.channel << "\" />" << endstr;
} }
PopTag(); PopTag();
mOutput << startstr << "</" << pTypeName << ">" << endstr; mOutput << startstr << "</" << pTypeName << ">" << endstr;
@ -647,24 +646,24 @@ void ColladaExporter::WriteTextureColorEntry(const Surface &pSurface, const std:
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Writes the two parameters necessary for referencing a texture in an effect entry // Writes the two parameters necessary for referencing a texture in an effect entry
void ColladaExporter::WriteTextureParamEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &pMatName) { void ColladaExporter::WriteTextureParamEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &materialId) {
// if surface is a texture, write out the sampler and the surface parameters necessary to reference the texture // if surface is a texture, write out the sampler and the surface parameters necessary to reference the texture
if (!pSurface.texture.empty()) { if (!pSurface.texture.empty()) {
mOutput << startstr << "<newparam sid=\"" << XMLIDEncode(pMatName) << "-" << pTypeName << "-surface\">" << endstr; mOutput << startstr << "<newparam sid=\"" << materialId << "-" << pTypeName << "-surface\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<surface type=\"2D\">" << endstr; mOutput << startstr << "<surface type=\"2D\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<init_from>" << XMLIDEncode(pMatName) << "-" << pTypeName << "-image</init_from>" << endstr; mOutput << startstr << "<init_from>" << materialId << "-" << pTypeName << "-image</init_from>" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</surface>" << endstr; mOutput << startstr << "</surface>" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</newparam>" << endstr; mOutput << startstr << "</newparam>" << endstr;
mOutput << startstr << "<newparam sid=\"" << XMLIDEncode(pMatName) << "-" << pTypeName << "-sampler\">" << endstr; mOutput << startstr << "<newparam sid=\"" << materialId << "-" << pTypeName << "-sampler\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<sampler2D>" << endstr; mOutput << startstr << "<sampler2D>" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<source>" << XMLIDEncode(pMatName) << "-" << pTypeName << "-surface</source>" << endstr; mOutput << startstr << "<source>" << materialId << "-" << pTypeName << "-surface</source>" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</sampler2D>" << endstr; mOutput << startstr << "</sampler2D>" << endstr;
PopTag(); PopTag();
@ -687,80 +686,63 @@ void ColladaExporter::WriteFloatEntry(const Property &pProperty, const std::stri
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Writes the material setup // Writes the material setup
void ColladaExporter::WriteMaterials() { void ColladaExporter::WriteMaterials() {
std::vector<Material> materials;
materials.resize(mScene->mNumMaterials); materials.resize(mScene->mNumMaterials);
/// collect all materials from the scene /// collect all materials from the scene
size_t numTextures = 0; size_t numTextures = 0;
for (size_t a = 0; a < mScene->mNumMaterials; ++a) { for (size_t a = 0; a < mScene->mNumMaterials; ++a) {
const aiMaterial *mat = mScene->mMaterials[a]; Material &material = materials[a];
material.id = GetObjectUniqueId(AiObjectType::Material, a);
aiString name; material.name = GetObjectName(AiObjectType::Material, a);
if (mat->Get(AI_MATKEY_NAME, name) != aiReturn_SUCCESS) {
name = "mat";
materials[a].name = std::string("m") + to_string(a) + name.C_Str();
} else {
// try to use the material's name if no other material has already taken it, else append #
std::string testName = name.C_Str();
size_t materialCountWithThisName = 0;
for (size_t i = 0; i < a; i++) {
if (materials[i].name == testName) {
materialCountWithThisName++;
}
}
if (materialCountWithThisName == 0) {
materials[a].name = name.C_Str();
} else {
materials[a].name = std::string(name.C_Str()) + to_string(materialCountWithThisName);
}
}
const aiMaterial &mat = *(mScene->mMaterials[a]);
aiShadingMode shading = aiShadingMode_Flat; aiShadingMode shading = aiShadingMode_Flat;
materials[a].shading_model = "phong"; material.shading_model = "phong";
if (mat->Get(AI_MATKEY_SHADING_MODEL, shading) == aiReturn_SUCCESS) { if (mat.Get(AI_MATKEY_SHADING_MODEL, shading) == aiReturn_SUCCESS) {
if (shading == aiShadingMode_Phong) { if (shading == aiShadingMode_Phong) {
materials[a].shading_model = "phong"; material.shading_model = "phong";
} else if (shading == aiShadingMode_Blinn) { } else if (shading == aiShadingMode_Blinn) {
materials[a].shading_model = "blinn"; material.shading_model = "blinn";
} else if (shading == aiShadingMode_NoShading) { } else if (shading == aiShadingMode_NoShading) {
materials[a].shading_model = "constant"; material.shading_model = "constant";
} else if (shading == aiShadingMode_Gouraud) { } else if (shading == aiShadingMode_Gouraud) {
materials[a].shading_model = "lambert"; material.shading_model = "lambert";
} }
} }
ReadMaterialSurface(materials[a].ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT); if (ReadMaterialSurface(material.ambient, mat, aiTextureType_AMBIENT, AI_MATKEY_COLOR_AMBIENT))
if (!materials[a].ambient.texture.empty()) numTextures++; ++numTextures;
ReadMaterialSurface(materials[a].diffuse, mat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE); if (ReadMaterialSurface(material.diffuse, mat, aiTextureType_DIFFUSE, AI_MATKEY_COLOR_DIFFUSE))
if (!materials[a].diffuse.texture.empty()) numTextures++; ++numTextures;
ReadMaterialSurface(materials[a].specular, mat, aiTextureType_SPECULAR, AI_MATKEY_COLOR_SPECULAR); if (ReadMaterialSurface(material.specular, mat, aiTextureType_SPECULAR, AI_MATKEY_COLOR_SPECULAR))
if (!materials[a].specular.texture.empty()) numTextures++; ++numTextures;
ReadMaterialSurface(materials[a].emissive, mat, aiTextureType_EMISSIVE, AI_MATKEY_COLOR_EMISSIVE); if (ReadMaterialSurface(material.emissive, mat, aiTextureType_EMISSIVE, AI_MATKEY_COLOR_EMISSIVE))
if (!materials[a].emissive.texture.empty()) numTextures++; ++numTextures;
ReadMaterialSurface(materials[a].reflective, mat, aiTextureType_REFLECTION, AI_MATKEY_COLOR_REFLECTIVE); if (ReadMaterialSurface(material.reflective, mat, aiTextureType_REFLECTION, AI_MATKEY_COLOR_REFLECTIVE))
if (!materials[a].reflective.texture.empty()) numTextures++; ++numTextures;
ReadMaterialSurface(materials[a].transparent, mat, aiTextureType_OPACITY, AI_MATKEY_COLOR_TRANSPARENT); if (ReadMaterialSurface(material.transparent, mat, aiTextureType_OPACITY, AI_MATKEY_COLOR_TRANSPARENT))
if (!materials[a].transparent.texture.empty()) numTextures++; ++numTextures;
ReadMaterialSurface(materials[a].normal, mat, aiTextureType_NORMALS, NULL, 0, 0); if (ReadMaterialSurface(material.normal, mat, aiTextureType_NORMALS, nullptr, 0, 0))
if (!materials[a].normal.texture.empty()) numTextures++; ++numTextures;
materials[a].shininess.exist = mat->Get(AI_MATKEY_SHININESS, materials[a].shininess.value) == aiReturn_SUCCESS; material.shininess.exist = mat.Get(AI_MATKEY_SHININESS, material.shininess.value) == aiReturn_SUCCESS;
materials[a].transparency.exist = mat->Get(AI_MATKEY_OPACITY, materials[a].transparency.value) == aiReturn_SUCCESS; material.transparency.exist = mat.Get(AI_MATKEY_OPACITY, material.transparency.value) == aiReturn_SUCCESS;
materials[a].index_refraction.exist = mat->Get(AI_MATKEY_REFRACTI, materials[a].index_refraction.value) == aiReturn_SUCCESS; material.index_refraction.exist = mat.Get(AI_MATKEY_REFRACTI, material.index_refraction.value) == aiReturn_SUCCESS;
} }
// output textures if present // output textures if present
if (numTextures > 0) { if (numTextures > 0) {
mOutput << startstr << "<library_images>" << endstr; mOutput << startstr << "<library_images>" << endstr;
PushTag(); PushTag();
for (std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it) { for (const Material &mat : materials) {
const Material &mat = *it; WriteImageEntry(mat.ambient, mat.id + "-ambient-image");
WriteImageEntry(mat.ambient, mat.name + "-ambient-image"); WriteImageEntry(mat.diffuse, mat.id + "-diffuse-image");
WriteImageEntry(mat.diffuse, mat.name + "-diffuse-image"); WriteImageEntry(mat.specular, mat.id + "-specular-image");
WriteImageEntry(mat.specular, mat.name + "-specular-image"); WriteImageEntry(mat.emissive, mat.id + "-emission-image");
WriteImageEntry(mat.emissive, mat.name + "-emission-image"); WriteImageEntry(mat.reflective, mat.id + "-reflective-image");
WriteImageEntry(mat.reflective, mat.name + "-reflective-image"); WriteImageEntry(mat.transparent, mat.id + "-transparent-image");
WriteImageEntry(mat.transparent, mat.name + "-transparent-image"); WriteImageEntry(mat.normal, mat.id + "-normal-image");
WriteImageEntry(mat.normal, mat.name + "-normal-image");
} }
PopTag(); PopTag();
mOutput << startstr << "</library_images>" << endstr; mOutput << startstr << "</library_images>" << endstr;
@ -770,40 +752,39 @@ void ColladaExporter::WriteMaterials() {
if (!materials.empty()) { if (!materials.empty()) {
mOutput << startstr << "<library_effects>" << endstr; mOutput << startstr << "<library_effects>" << endstr;
PushTag(); PushTag();
for (std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it) { for (const Material &mat : materials) {
const Material &mat = *it;
// this is so ridiculous it must be right // this is so ridiculous it must be right
mOutput << startstr << "<effect id=\"" << XMLIDEncode(mat.name) << "-fx\" name=\"" << XMLEscape(mat.name) << "\">" << endstr; mOutput << startstr << "<effect id=\"" << mat.id << "-fx\" name=\"" << mat.name << "\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<profile_COMMON>" << endstr; mOutput << startstr << "<profile_COMMON>" << endstr;
PushTag(); PushTag();
// write sampler- and surface params for the texture entries // write sampler- and surface params for the texture entries
WriteTextureParamEntry(mat.emissive, "emission", mat.name); WriteTextureParamEntry(mat.emissive, "emission", mat.id);
WriteTextureParamEntry(mat.ambient, "ambient", mat.name); WriteTextureParamEntry(mat.ambient, "ambient", mat.id);
WriteTextureParamEntry(mat.diffuse, "diffuse", mat.name); WriteTextureParamEntry(mat.diffuse, "diffuse", mat.id);
WriteTextureParamEntry(mat.specular, "specular", mat.name); WriteTextureParamEntry(mat.specular, "specular", mat.id);
WriteTextureParamEntry(mat.reflective, "reflective", mat.name); WriteTextureParamEntry(mat.reflective, "reflective", mat.id);
WriteTextureParamEntry(mat.transparent, "transparent", mat.name); WriteTextureParamEntry(mat.transparent, "transparent", mat.id);
WriteTextureParamEntry(mat.normal, "normal", mat.name); WriteTextureParamEntry(mat.normal, "normal", mat.id);
mOutput << startstr << "<technique sid=\"standard\">" << endstr; mOutput << startstr << "<technique sid=\"standard\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<" << mat.shading_model << ">" << endstr; mOutput << startstr << "<" << mat.shading_model << ">" << endstr;
PushTag(); PushTag();
WriteTextureColorEntry(mat.emissive, "emission", mat.name + "-emission-sampler"); WriteTextureColorEntry(mat.emissive, "emission", mat.id + "-emission-sampler");
WriteTextureColorEntry(mat.ambient, "ambient", mat.name + "-ambient-sampler"); WriteTextureColorEntry(mat.ambient, "ambient", mat.id + "-ambient-sampler");
WriteTextureColorEntry(mat.diffuse, "diffuse", mat.name + "-diffuse-sampler"); WriteTextureColorEntry(mat.diffuse, "diffuse", mat.id + "-diffuse-sampler");
WriteTextureColorEntry(mat.specular, "specular", mat.name + "-specular-sampler"); WriteTextureColorEntry(mat.specular, "specular", mat.id + "-specular-sampler");
WriteFloatEntry(mat.shininess, "shininess"); WriteFloatEntry(mat.shininess, "shininess");
WriteTextureColorEntry(mat.reflective, "reflective", mat.name + "-reflective-sampler"); WriteTextureColorEntry(mat.reflective, "reflective", mat.id + "-reflective-sampler");
WriteTextureColorEntry(mat.transparent, "transparent", mat.name + "-transparent-sampler"); WriteTextureColorEntry(mat.transparent, "transparent", mat.id + "-transparent-sampler");
WriteFloatEntry(mat.transparency, "transparency"); WriteFloatEntry(mat.transparency, "transparency");
WriteFloatEntry(mat.index_refraction, "index_of_refraction"); WriteFloatEntry(mat.index_refraction, "index_of_refraction");
if (!mat.normal.texture.empty()) { if (!mat.normal.texture.empty()) {
WriteTextureColorEntry(mat.normal, "bump", mat.name + "-normal-sampler"); WriteTextureColorEntry(mat.normal, "bump", mat.id + "-normal-sampler");
} }
PopTag(); PopTag();
@ -823,9 +804,9 @@ void ColladaExporter::WriteMaterials() {
PushTag(); PushTag();
for (std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it) { for (std::vector<Material>::const_iterator it = materials.begin(); it != materials.end(); ++it) {
const Material &mat = *it; const Material &mat = *it;
mOutput << startstr << "<material id=\"" << XMLIDEncode(mat.name) << "\" name=\"" << XMLEscape(mat.name) << "\">" << endstr; mOutput << startstr << "<material id=\"" << mat.id << "\" name=\"" << mat.name << "\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<instance_effect url=\"#" << XMLIDEncode(mat.name) << "-fx\"/>" << endstr; mOutput << startstr << "<instance_effect url=\"#" << mat.id << "-fx\"/>" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</material>" << endstr; mOutput << startstr << "</material>" << endstr;
} }
@ -852,20 +833,18 @@ void ColladaExporter::WriteControllerLibrary() {
// Writes a skin controller of the given mesh // Writes a skin controller of the given mesh
void ColladaExporter::WriteController(size_t pIndex) { void ColladaExporter::WriteController(size_t pIndex) {
const aiMesh *mesh = mScene->mMeshes[pIndex]; const aiMesh *mesh = mScene->mMeshes[pIndex];
const std::string idstr = mesh->mName.length == 0 ? GetMeshId(pIndex) : mesh->mName.C_Str(); // Is there a skin controller?
const std::string idstrEscaped = XMLIDEncode(idstr); if (mesh->mNumBones == 0 || mesh->mNumFaces == 0 || mesh->mNumVertices == 0)
if (mesh->mNumFaces == 0 || mesh->mNumVertices == 0)
return; return;
if (mesh->mNumBones == 0) const std::string idstr = GetObjectUniqueId(AiObjectType::Mesh, pIndex);
return; const std::string namestr = GetObjectName(AiObjectType::Mesh, pIndex);
mOutput << startstr << "<controller id=\"" << idstrEscaped << "-skin\" "; mOutput << startstr << "<controller id=\"" << idstr << "-skin\" ";
mOutput << "name=\"skinCluster" << pIndex << "\">" << endstr; mOutput << "name=\"skinCluster" << pIndex << "\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<skin source=\"#" << idstrEscaped << "\">" << endstr; mOutput << startstr << "<skin source=\"#" << idstr << "\">" << endstr;
PushTag(); PushTag();
// bind pose matrix // bind pose matrix
@ -882,20 +861,20 @@ void ColladaExporter::WriteController(size_t pIndex) {
PopTag(); PopTag();
mOutput << startstr << "</bind_shape_matrix>" << endstr; mOutput << startstr << "</bind_shape_matrix>" << endstr;
mOutput << startstr << "<source id=\"" << idstrEscaped << "-skin-joints\" name=\"" << idstrEscaped << "-skin-joints\">" << endstr; mOutput << startstr << "<source id=\"" << idstr << "-skin-joints\" name=\"" << namestr << "-skin-joints\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<Name_array id=\"" << idstrEscaped << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\">"; mOutput << startstr << "<Name_array id=\"" << idstr << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\">";
for (size_t i = 0; i < mesh->mNumBones; ++i) for (size_t i = 0; i < mesh->mNumBones; ++i)
mOutput << XMLIDEncode(mesh->mBones[i]->mName.C_Str()) << " "; mOutput << GetBoneUniqueId(mesh->mBones[i]) << ' ';
mOutput << "</Name_array>" << endstr; mOutput << "</Name_array>" << endstr;
mOutput << startstr << "<technique_common>" << endstr; mOutput << startstr << "<technique_common>" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<accessor source=\"#" << idstrEscaped << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\" stride=\"" << 1 << "\">" << endstr; mOutput << startstr << "<accessor source=\"#" << idstr << "-skin-joints-array\" count=\"" << mesh->mNumBones << "\" stride=\"" << 1 << "\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<param name=\"JOINT\" type=\"Name\"></param>" << endstr; mOutput << startstr << "<param name=\"JOINT\" type=\"Name\"></param>" << endstr;
@ -932,8 +911,8 @@ void ColladaExporter::WriteController(size_t pIndex) {
mOutput << startstr << "<joints>" << endstr; mOutput << startstr << "<joints>" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<input semantic=\"JOINT\" source=\"#" << idstrEscaped << "-skin-joints\"></input>" << endstr; mOutput << startstr << "<input semantic=\"JOINT\" source=\"#" << idstr << "-skin-joints\"></input>" << endstr;
mOutput << startstr << "<input semantic=\"INV_BIND_MATRIX\" source=\"#" << idstrEscaped << "-skin-bind_poses\"></input>" << endstr; mOutput << startstr << "<input semantic=\"INV_BIND_MATRIX\" source=\"#" << idstr << "-skin-bind_poses\"></input>" << endstr;
PopTag(); PopTag();
mOutput << startstr << "</joints>" << endstr; mOutput << startstr << "</joints>" << endstr;
@ -941,8 +920,8 @@ void ColladaExporter::WriteController(size_t pIndex) {
mOutput << startstr << "<vertex_weights count=\"" << mesh->mNumVertices << "\">" << endstr; mOutput << startstr << "<vertex_weights count=\"" << mesh->mNumVertices << "\">" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<input semantic=\"JOINT\" source=\"#" << idstrEscaped << "-skin-joints\" offset=\"0\"></input>" << endstr; mOutput << startstr << "<input semantic=\"JOINT\" source=\"#" << idstr << "-skin-joints\" offset=\"0\"></input>" << endstr;
mOutput << startstr << "<input semantic=\"WEIGHT\" source=\"#" << idstrEscaped << "-skin-weights\" offset=\"1\"></input>" << endstr; mOutput << startstr << "<input semantic=\"WEIGHT\" source=\"#" << idstr << "-skin-weights\" offset=\"1\"></input>" << endstr;
mOutput << startstr << "<vcount>"; mOutput << startstr << "<vcount>";
@ -1017,9 +996,8 @@ void ColladaExporter::WriteGeometryLibrary() {
// Writes the given mesh // Writes the given mesh
void ColladaExporter::WriteGeometry(size_t pIndex) { void ColladaExporter::WriteGeometry(size_t pIndex) {
const aiMesh *mesh = mScene->mMeshes[pIndex]; const aiMesh *mesh = mScene->mMeshes[pIndex];
const std::string idstr = mesh->mName.length == 0 ? GetMeshId(pIndex) : mesh->mName.C_Str(); const std::string geometryId = GetObjectUniqueId(AiObjectType::Mesh, pIndex);
const std::string geometryName = XMLEscape(idstr); const std::string geometryName = GetObjectName(AiObjectType::Mesh, pIndex);
const std::string geometryId = XMLIDEncode(idstr);
if (mesh->mNumFaces == 0 || mesh->mNumVertices == 0) if (mesh->mNumFaces == 0 || mesh->mNumVertices == 0)
return; return;
@ -1032,15 +1010,15 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
PushTag(); PushTag();
// Positions // Positions
WriteFloatArray(idstr + "-positions", FloatType_Vector, (ai_real *)mesh->mVertices, mesh->mNumVertices); WriteFloatArray(geometryId + "-positions", FloatType_Vector, (ai_real *)mesh->mVertices, mesh->mNumVertices);
// Normals, if any // Normals, if any
if (mesh->HasNormals()) if (mesh->HasNormals())
WriteFloatArray(idstr + "-normals", FloatType_Vector, (ai_real *)mesh->mNormals, mesh->mNumVertices); WriteFloatArray(geometryId + "-normals", FloatType_Vector, (ai_real *)mesh->mNormals, mesh->mNumVertices);
// texture coords // texture coords
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) { for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (mesh->HasTextureCoords(static_cast<unsigned int>(a))) { if (mesh->HasTextureCoords(static_cast<unsigned int>(a))) {
WriteFloatArray(idstr + "-tex" + to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2, WriteFloatArray(geometryId + "-tex" + to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2,
(ai_real *)mesh->mTextureCoords[a], mesh->mNumVertices); (ai_real *)mesh->mTextureCoords[a], mesh->mNumVertices);
} }
} }
@ -1048,7 +1026,7 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
// vertex colors // vertex colors
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) { for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (mesh->HasVertexColors(static_cast<unsigned int>(a))) if (mesh->HasVertexColors(static_cast<unsigned int>(a)))
WriteFloatArray(idstr + "-color" + to_string(a), FloatType_Color, (ai_real *)mesh->mColors[a], mesh->mNumVertices); WriteFloatArray(geometryId + "-color" + to_string(a), FloatType_Color, (ai_real *)mesh->mColors[a], mesh->mNumVertices);
} }
// assemble vertex structure // assemble vertex structure
@ -1248,8 +1226,8 @@ void ColladaExporter::WriteFloatArray(const std::string &pIdString, FloatDataTyp
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Writes the scene library // Writes the scene library
void ColladaExporter::WriteSceneLibrary() { void ColladaExporter::WriteSceneLibrary() {
const std::string sceneName = XMLEscape(mScene->mRootNode->mName.C_Str()); const std::string sceneId = GetNodeUniqueId(mScene->mRootNode);
const std::string sceneId = XMLIDEncode(mScene->mRootNode->mName.C_Str()); const std::string sceneName = GetNodeName(mScene->mRootNode);
mOutput << startstr << "<library_visual_scenes>" << endstr; mOutput << startstr << "<library_visual_scenes>" << endstr;
PushTag(); PushTag();
@ -1258,7 +1236,7 @@ void ColladaExporter::WriteSceneLibrary() {
// start recursive write at the root node // start recursive write at the root node
for (size_t a = 0; a < mScene->mRootNode->mNumChildren; ++a) for (size_t a = 0; a < mScene->mRootNode->mNumChildren; ++a)
WriteNode(mScene, mScene->mRootNode->mChildren[a]); WriteNode(mScene->mRootNode->mChildren[a]);
PopTag(); PopTag();
mOutput << startstr << "</visual_scene>" << endstr; mOutput << startstr << "</visual_scene>" << endstr;
@ -1272,20 +1250,10 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex) {
if (anim->mNumChannels == 0 && anim->mNumMeshChannels == 0 && anim->mNumMorphMeshChannels == 0) if (anim->mNumChannels == 0 && anim->mNumMeshChannels == 0 && anim->mNumMorphMeshChannels == 0)
return; return;
const std::string animation_name_escaped = XMLEscape(anim->mName.C_Str()); const std::string animationNameEscaped = GetObjectName(AiObjectType::Animation, pIndex);
std::string idstr = anim->mName.C_Str(); const std::string idstrEscaped = GetObjectUniqueId(AiObjectType::Animation, pIndex);
std::string ending = std::string("AnimId") + to_string(pIndex);
if (idstr.length() >= ending.length()) {
if (0 != idstr.compare(idstr.length() - ending.length(), ending.length(), ending)) {
idstr = idstr + ending;
}
} else {
idstr = idstr + ending;
}
const std::string idstrEscaped = XMLIDEncode(idstr); mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animationNameEscaped + "\">" << endstr;
mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
PushTag(); PushTag();
std::string cur_node_idstr; std::string cur_node_idstr;
@ -1435,20 +1403,21 @@ void ColladaExporter::WriteAnimationsLibrary() {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Helper to find a bone by name in the scene // Helper to find a bone by name in the scene
aiBone *findBone(const aiScene *scene, const char *name) { aiBone *findBone(const aiScene *scene, const aiString &name) {
for (size_t m = 0; m < scene->mNumMeshes; m++) { for (size_t m = 0; m < scene->mNumMeshes; m++) {
aiMesh *mesh = scene->mMeshes[m]; aiMesh *mesh = scene->mMeshes[m];
for (size_t b = 0; b < mesh->mNumBones; b++) { for (size_t b = 0; b < mesh->mNumBones; b++) {
aiBone *bone = mesh->mBones[b]; aiBone *bone = mesh->mBones[b];
if (0 == strcmp(name, bone->mName.C_Str())) { if (name == bone->mName) {
return bone; return bone;
} }
} }
} }
return NULL; return nullptr;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Helper to find the node associated with a bone in the scene
const aiNode *findBoneNode(const aiNode *aNode, const aiBone *bone) { const aiNode *findBoneNode(const aiNode *aNode, const aiBone *bone) {
if (aNode && bone && aNode->mName == bone->mName) { if (aNode && bone && aNode->mName == bone->mName) {
return aNode; return aNode;
@ -1457,15 +1426,17 @@ const aiNode *findBoneNode(const aiNode *aNode, const aiBone *bone) {
if (aNode && bone) { if (aNode && bone) {
for (unsigned int i = 0; i < aNode->mNumChildren; ++i) { for (unsigned int i = 0; i < aNode->mNumChildren; ++i) {
aiNode *aChild = aNode->mChildren[i]; aiNode *aChild = aNode->mChildren[i];
const aiNode *foundFromChild = 0; const aiNode *foundFromChild = nullptr;
if (aChild) { if (aChild) {
foundFromChild = findBoneNode(aChild, bone); foundFromChild = findBoneNode(aChild, bone);
if (foundFromChild) return foundFromChild; if (foundFromChild) {
return foundFromChild;
}
} }
} }
} }
return NULL; return nullptr;
} }
const aiNode *findSkeletonRootNode(const aiScene *scene, const aiMesh *mesh) { const aiNode *findSkeletonRootNode(const aiScene *scene, const aiMesh *mesh) {
@ -1476,7 +1447,7 @@ const aiNode *findSkeletonRootNode(const aiScene *scene, const aiMesh *mesh) {
const aiNode *node = findBoneNode(scene->mRootNode, bone); const aiNode *node = findBoneNode(scene->mRootNode, bone);
if (node) { if (node) {
while (node->mParent && findBone(scene, node->mParent->mName.C_Str()) != 0) { while (node->mParent && findBone(scene, node->mParent->mName) != nullptr) {
node = node->mParent; node = node->mParent;
} }
topParentBoneNodes.insert(node); topParentBoneNodes.insert(node);
@ -1496,45 +1467,39 @@ const aiNode *findSkeletonRootNode(const aiScene *scene, const aiMesh *mesh) {
} }
} }
return NULL; return nullptr;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursively writes the given node // Recursively writes the given node
void ColladaExporter::WriteNode(const aiScene *pScene, aiNode *pNode) { void ColladaExporter::WriteNode(const aiNode *pNode) {
// the node must have a name
if (pNode->mName.length == 0) {
std::stringstream ss;
ss << "Node_" << pNode;
pNode->mName.Set(ss.str());
}
// If the node is associated with a bone, it is a joint node (JOINT) // If the node is associated with a bone, it is a joint node (JOINT)
// otherwise it is a normal node (NODE) // otherwise it is a normal node (NODE)
// Assimp-specific: nodes with no name cannot be associated with bones
const char *node_type; const char *node_type;
bool is_joint, is_skeleton_root = false; bool is_joint, is_skeleton_root = false;
if (nullptr == findBone(pScene, pNode->mName.C_Str())) { if (pNode->mName.length == 0 || nullptr == findBone(mScene, pNode->mName)) {
node_type = "NODE"; node_type = "NODE";
is_joint = false; is_joint = false;
} else { } else {
node_type = "JOINT"; node_type = "JOINT";
is_joint = true; is_joint = true;
if (!pNode->mParent || nullptr == findBone(pScene, pNode->mParent->mName.C_Str())) { if (!pNode->mParent || nullptr == findBone(mScene, pNode->mParent->mName)) {
is_skeleton_root = true; is_skeleton_root = true;
} }
} }
const std::string node_id = XMLIDEncode(pNode->mName.data); const std::string node_id = GetNodeUniqueId(pNode);
const std::string node_name = XMLEscape(pNode->mName.data); const std::string node_name = GetNodeName(pNode);
mOutput << startstr << "<node "; mOutput << startstr << "<node ";
if (is_skeleton_root) { if (is_skeleton_root) {
mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id + "\"" : ""); // For now, only support one skeleton in a scene. mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id + "\" " : ""); // For now, only support one skeleton in a scene.
mFoundSkeletonRootNodeID = node_id; mFoundSkeletonRootNodeID = node_id;
} else { } else {
mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id + "\"" : ""); mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id + "\" " : "");
} }
mOutput << " name=\"" << node_name mOutput << "name=\"" << node_name
<< "\" type=\"" << node_type << "\" type=\"" << node_type
<< "\">" << endstr; << "\">" << endstr;
PushTag(); PushTag();
@ -1573,14 +1538,14 @@ void ColladaExporter::WriteNode(const aiScene *pScene, aiNode *pNode) {
//check if it is a camera node //check if it is a camera node
for (size_t i = 0; i < mScene->mNumCameras; i++) { for (size_t i = 0; i < mScene->mNumCameras; i++) {
if (mScene->mCameras[i]->mName == pNode->mName) { if (mScene->mCameras[i]->mName == pNode->mName) {
mOutput << startstr << "<instance_camera url=\"#" << node_id << "-camera\"/>" << endstr; mOutput << startstr << "<instance_camera url=\"#" << GetObjectUniqueId(AiObjectType::Camera, i) << "\"/>" << endstr;
break; break;
} }
} }
//check if it is a light node //check if it is a light node
for (size_t i = 0; i < mScene->mNumLights; i++) { for (size_t i = 0; i < mScene->mNumLights; i++) {
if (mScene->mLights[i]->mName == pNode->mName) { if (mScene->mLights[i]->mName == pNode->mName) {
mOutput << startstr << "<instance_light url=\"#" << node_id << "-light\"/>" << endstr; mOutput << startstr << "<instance_light url=\"#" << GetObjectUniqueId(AiObjectType::Light, i) << "\"/>" << endstr;
break; break;
} }
} }
@ -1593,22 +1558,22 @@ void ColladaExporter::WriteNode(const aiScene *pScene, aiNode *pNode) {
if (mesh->mNumFaces == 0 || mesh->mNumVertices == 0) if (mesh->mNumFaces == 0 || mesh->mNumVertices == 0)
continue; continue;
const std::string meshName = mesh->mName.length == 0 ? GetMeshId(pNode->mMeshes[a]) : mesh->mName.C_Str(); const std::string meshId = GetObjectUniqueId(AiObjectType::Mesh, pNode->mMeshes[a]);
if (mesh->mNumBones == 0) { if (mesh->mNumBones == 0) {
mOutput << startstr << "<instance_geometry url=\"#" << XMLIDEncode(meshName) << "\">" << endstr; mOutput << startstr << "<instance_geometry url=\"#" << meshId << "\">" << endstr;
PushTag(); PushTag();
} else { } else {
mOutput << startstr mOutput << startstr
<< "<instance_controller url=\"#" << XMLIDEncode(meshName) << "-skin\">" << "<instance_controller url=\"#" << meshId << "-skin\">"
<< endstr; << endstr;
PushTag(); PushTag();
// note! this mFoundSkeletonRootNodeID some how affects animation, it makes the mesh attaches to armature skeleton root node. // note! this mFoundSkeletonRootNodeID some how affects animation, it makes the mesh attaches to armature skeleton root node.
// use the first bone to find skeleton root // use the first bone to find skeleton root
const aiNode *skeletonRootBoneNode = findSkeletonRootNode(pScene, mesh); const aiNode *skeletonRootBoneNode = findSkeletonRootNode(mScene, mesh);
if (skeletonRootBoneNode) { if (skeletonRootBoneNode) {
mFoundSkeletonRootNodeID = XMLIDEncode(skeletonRootBoneNode->mName.C_Str()); mFoundSkeletonRootNodeID = GetNodeUniqueId(skeletonRootBoneNode);
} }
mOutput << startstr << "<skeleton>#" << mFoundSkeletonRootNodeID << "</skeleton>" << endstr; mOutput << startstr << "<skeleton>#" << mFoundSkeletonRootNodeID << "</skeleton>" << endstr;
} }
@ -1616,7 +1581,7 @@ void ColladaExporter::WriteNode(const aiScene *pScene, aiNode *pNode) {
PushTag(); PushTag();
mOutput << startstr << "<technique_common>" << endstr; mOutput << startstr << "<technique_common>" << endstr;
PushTag(); PushTag();
mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << XMLIDEncode(materials[mesh->mMaterialIndex].name) << "\">" << endstr; mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << GetObjectUniqueId(AiObjectType::Material, mesh->mMaterialIndex) << "\">" << endstr;
PushTag(); PushTag();
for (size_t aa = 0; aa < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++aa) { for (size_t aa = 0; aa < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++aa) {
if (mesh->HasTextureCoords(static_cast<unsigned int>(aa))) if (mesh->HasTextureCoords(static_cast<unsigned int>(aa)))
@ -1641,11 +1606,152 @@ void ColladaExporter::WriteNode(const aiScene *pScene, aiNode *pNode) {
// recurse into subnodes // recurse into subnodes
for (size_t a = 0; a < pNode->mNumChildren; ++a) for (size_t a = 0; a < pNode->mNumChildren; ++a)
WriteNode(pScene, pNode->mChildren[a]); WriteNode(pNode->mChildren[a]);
PopTag(); PopTag();
mOutput << startstr << "</node>" << endstr; mOutput << startstr << "</node>" << endstr;
} }
inline bool IsUniqueId(const std::unordered_set<std::string> &idSet, const std::string &idStr) {
return (idSet.find(idStr) == idSet.end());
}
inline std::string MakeUniqueId(const std::unordered_set<std::string> &idSet, const std::string &idPrefix, const std::string &postfix) {
std::string result(idPrefix + postfix);
if (!IsUniqueId(idSet, result)) {
// Select a number to append
size_t idnum = 1;
do {
result = idPrefix + '_' + to_string(idnum) + postfix;
++idnum;
} while (!IsUniqueId(idSet, result));
}
return result;
}
void ColladaExporter::CreateNodeIds(const aiNode *node) {
GetNodeUniqueId(node);
for (size_t a = 0; a < node->mNumChildren; ++a)
CreateNodeIds(node->mChildren[a]);
}
std::string ColladaExporter::GetNodeUniqueId(const aiNode *node) {
// Use the pointer as the key. This is safe because the scene is immutable.
auto idIt = mNodeIdMap.find(node);
if (idIt != mNodeIdMap.cend())
return idIt->second;
// Prefer the requested Collada Id if extant
std::string idStr;
aiString origId;
if (node->mMetaData && node->mMetaData->Get(AI_METADATA_COLLADA_ID, origId)) {
idStr = origId.C_Str();
} else {
idStr = node->mName.C_Str();
}
// Make sure the requested id is valid
if (idStr.empty())
idStr = "node";
else
idStr = XMLIDEncode(idStr);
// Ensure it's unique
idStr = MakeUniqueId(mUniqueIds, idStr, std::string());
mUniqueIds.insert(idStr);
mNodeIdMap.insert(std::make_pair(node, idStr));
return idStr;
}
std::string ColladaExporter::GetNodeName(const aiNode *node) {
return XMLEscape(node->mName.C_Str());
}
std::string ColladaExporter::GetBoneUniqueId(const aiBone *bone) {
// Find the Node that is this Bone
const aiNode *boneNode = findBoneNode(mScene->mRootNode, bone);
if (boneNode == nullptr)
return std::string();
return GetNodeUniqueId(boneNode);
}
std::string ColladaExporter::GetObjectUniqueId(AiObjectType type, size_t pIndex) {
auto idIt = GetObjectIdMap(type).find(pIndex);
if (idIt != GetObjectIdMap(type).cend())
return idIt->second;
// Not seen this object before, create and add
NameIdPair result = AddObjectIndexToMaps(type, pIndex);
return result.second;
}
std::string ColladaExporter::GetObjectName(AiObjectType type, size_t pIndex) {
auto objectName = GetObjectNameMap(type).find(pIndex);
if (objectName != GetObjectNameMap(type).cend())
return objectName->second;
// Not seen this object before, create and add
NameIdPair result = AddObjectIndexToMaps(type, pIndex);
return result.first;
}
// Determine unique id and add the name and id to the maps
// @param type object type
// @param index object index
// @param name in/out. Caller to set the original name if known.
// @param idStr in/out. Caller to set the preferred id if known.
ColladaExporter::NameIdPair ColladaExporter::AddObjectIndexToMaps(AiObjectType type, size_t index) {
std::string name;
std::string idStr;
std::string idPostfix;
// Get the name and id postfix
switch (type) {
case AiObjectType::Mesh: name = mScene->mMeshes[index]->mName.C_Str(); break;
case AiObjectType::Material: name = mScene->mMaterials[index]->GetName().C_Str(); break;
case AiObjectType::Animation: name = mScene->mAnimations[index]->mName.C_Str(); break;
case AiObjectType::Light:
name = mScene->mLights[index]->mName.C_Str();
idPostfix = "-light";
break;
case AiObjectType::Camera:
name = mScene->mCameras[index]->mName.C_Str();
idPostfix = "-camera";
break;
case AiObjectType::Count: throw std::logic_error("ColladaExporter::AiObjectType::Count is not an object type");
}
if (name.empty()) {
// Default ids if empty name
switch (type) {
case AiObjectType::Mesh: idStr = std::string("mesh_"); break;
case AiObjectType::Material: idStr = std::string("material_"); break; // This one should never happen
case AiObjectType::Animation: idStr = std::string("animation_"); break;
case AiObjectType::Light: idStr = std::string("light_"); break;
case AiObjectType::Camera: idStr = std::string("camera_"); break;
case AiObjectType::Count: throw std::logic_error("ColladaExporter::AiObjectType::Count is not an object type");
}
idStr.append(to_string(index));
} else {
idStr = XMLIDEncode(name);
}
if (!name.empty())
name = XMLEscape(name);
idStr = MakeUniqueId(mUniqueIds, idStr, idPostfix);
// Add to maps
mUniqueIds.insert(idStr);
GetObjectIdMap(type).insert(std::make_pair(index, idStr));
GetObjectNameMap(type).insert(std::make_pair(index, name));
return std::make_pair(name, idStr);
}
} // end of namespace Assimp
#endif #endif
#endif #endif

View File

@ -48,28 +48,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/material.h> #include <assimp/material.h>
#include <assimp/mesh.h>
#include <assimp/light.h>
#include <assimp/Exporter.hpp>
#include <sstream>
#include <vector>
#include <map>
#include <assimp/StringUtils.h> #include <array>
#include <map>
#include <sstream>
#include <unordered_set>
#include <vector>
struct aiScene; struct aiScene;
struct aiNode; struct aiNode;
struct aiLight;
struct aiBone;
namespace Assimp namespace Assimp {
{
class IOSystem;
/// Helper class to export a given scene to a Collada file. Just for my personal /// Helper class to export a given scene to a Collada file. Just for my personal
/// comfort when implementing it. /// comfort when implementing it.
class ColladaExporter class ColladaExporter {
{
public: public:
/// Constructor for a specific scene to export /// Constructor for a specific scene to export
ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file); ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, const std::string &path, const std::string &file);
/// Destructor /// Destructor
virtual ~ColladaExporter(); virtual ~ColladaExporter();
@ -107,51 +107,87 @@ protected:
void WriteControllerLibrary(); void WriteControllerLibrary();
/// Writes a skin controller of the given mesh /// Writes a skin controller of the given mesh
void WriteController( size_t pIndex); void WriteController(size_t pIndex);
/// Writes the geometry library /// Writes the geometry library
void WriteGeometryLibrary(); void WriteGeometryLibrary();
/// Writes the given mesh /// Writes the given mesh
void WriteGeometry( size_t pIndex); void WriteGeometry(size_t pIndex);
//enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight }; //enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight };
// customized to add animation related type // customized to add animation related type
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight, FloatType_Time }; enum FloatDataType { FloatType_Vector,
FloatType_TexCoord2,
FloatType_TexCoord3,
FloatType_Color,
FloatType_Mat4x4,
FloatType_Weight,
FloatType_Time };
/// Writes a float array of the given type /// Writes a float array of the given type
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const ai_real* pData, size_t pElementCount); void WriteFloatArray(const std::string &pIdString, FloatDataType pType, const ai_real *pData, size_t pElementCount);
/// Writes the scene library /// Writes the scene library
void WriteSceneLibrary(); void WriteSceneLibrary();
// customized, Writes the animation library // customized, Writes the animation library
void WriteAnimationsLibrary(); void WriteAnimationsLibrary();
void WriteAnimationLibrary( size_t pIndex); void WriteAnimationLibrary(size_t pIndex);
std::string mFoundSkeletonRootNodeID = "skeleton_root"; // will be replaced by found node id in the WriteNode call. std::string mFoundSkeletonRootNodeID = "skeleton_root"; // will be replaced by found node id in the WriteNode call.
/// Recursively writes the given node /// Recursively writes the given node
void WriteNode( const aiScene* scene, aiNode* pNode); void WriteNode(const aiNode *pNode);
/// Enters a new xml element, which increases the indentation /// Enters a new xml element, which increases the indentation
void PushTag() { startstr.append( " "); } void PushTag() { startstr.append(" "); }
/// Leaves an element, decreasing the indentation /// Leaves an element, decreasing the indentation
void PopTag() { void PopTag() {
ai_assert( startstr.length() > 1); ai_assert(startstr.length() > 1);
startstr.erase( startstr.length() - 2); startstr.erase(startstr.length() - 2);
} }
/// Creates a mesh ID for the given mesh void CreateNodeIds(const aiNode *node);
std::string GetMeshId( size_t pIndex) const {
return std::string( "meshId" ) + to_string(pIndex); /// Get or Create a unique Node ID string for the given Node
} std::string GetNodeUniqueId(const aiNode *node);
std::string GetNodeName(const aiNode *node);
std::string GetBoneUniqueId(const aiBone *bone);
enum class AiObjectType {
Mesh,
Material,
Animation,
Light,
Camera,
Count,
};
/// Get or Create a unique ID string for the given scene object index
std::string GetObjectUniqueId(AiObjectType type, size_t pIndex);
/// Get or Create a name string for the given scene object index
std::string GetObjectName(AiObjectType type, size_t pIndex);
typedef std::map<size_t, std::string> IndexIdMap;
typedef std::pair<std::string, std::string> NameIdPair;
NameIdPair AddObjectIndexToMaps(AiObjectType type, size_t pIndex);
// Helpers
inline IndexIdMap &GetObjectIdMap(AiObjectType type) { return mObjectIdMap[static_cast<size_t>(type)]; }
inline IndexIdMap &GetObjectNameMap(AiObjectType type) { return mObjectNameMap[static_cast<size_t>(type)]; }
private:
std::unordered_set<std::string> mUniqueIds; // Cache of used unique ids
std::map<const void *, std::string> mNodeIdMap; // Cache of encoded node and bone ids
std::array<IndexIdMap, static_cast<size_t>(AiObjectType::Count)> mObjectIdMap; // Cache of encoded unique IDs
std::array<IndexIdMap, static_cast<size_t>(AiObjectType::Count)> mObjectNameMap; // Cache of encoded names
public: public:
/// Stringstream to write all output into /// Stringstream to write all output into
std::stringstream mOutput; std::stringstream mOutput;
/// The IOSystem for output /// The IOSystem for output
IOSystem* mIOSystem; IOSystem *mIOSystem;
/// Path of the directory where the scene will be exported /// Path of the directory where the scene will be exported
const std::string mPath; const std::string mPath;
@ -160,7 +196,7 @@ public:
const std::string mFile; const std::string mFile;
/// The scene to be written /// The scene to be written
const aiScene* mScene; const aiScene *mScene;
bool mSceneOwned; bool mSceneOwned;
/// current line start string, contains the current indentation for simple stream insertion /// current line start string, contains the current indentation for simple stream insertion
@ -168,55 +204,53 @@ public:
/// current line end string for simple stream insertion /// current line end string for simple stream insertion
std::string endstr; std::string endstr;
// pair of color and texture - texture precedences color // pair of color and texture - texture precedences color
struct Surface struct Surface {
{ bool exist;
bool exist; aiColor4D color;
aiColor4D color; std::string texture;
std::string texture; size_t channel;
size_t channel; Surface() {
Surface() { exist = false; channel = 0; } exist = false;
}; channel = 0;
}
};
struct Property struct Property {
{ bool exist;
bool exist; ai_real value;
ai_real value; Property() :
Property() exist(false),
: exist(false) value(0.0) {}
, value(0.0) };
{}
};
// summarize a material in an convenient way. // summarize a material in an convenient way.
struct Material struct Material {
{ std::string id;
std::string name; std::string name;
std::string shading_model; std::string shading_model;
Surface ambient, diffuse, specular, emissive, reflective, transparent, normal; Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
Property shininess, transparency, index_refraction; Property shininess, transparency, index_refraction;
Material() {} Material() {}
}; };
std::vector<Material> materials; std::map<unsigned int, std::string> textures;
std::map<unsigned int, std::string> textures;
public: public:
/// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions /// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions
/// Reads a single surface entry from the given material keys /// Reads a single surface entry from the given material keys
void ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex); bool ReadMaterialSurface(Surface &poSurface, const aiMaterial &pSrcMat, aiTextureType pTexture, const char *pKey, size_t pType, size_t pIndex);
/// Writes an image entry for the given surface /// Writes an image entry for the given surface
void WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd); void WriteImageEntry(const Surface &pSurface, const std::string &imageId);
/// Writes the two parameters necessary for referencing a texture in an effect entry /// Writes the two parameters necessary for referencing a texture in an effect entry
void WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName); void WriteTextureParamEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &materialId);
/// Writes a color-or-texture entry into an effect definition /// Writes a color-or-texture entry into an effect definition
void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName); void WriteTextureColorEntry(const Surface &pSurface, const std::string &pTypeName, const std::string &imageId);
/// Writes a scalar property /// Writes a scalar property
void WriteFloatEntry( const Property& pProperty, const std::string& pTypeName); void WriteFloatEntry(const Property &pProperty, const std::string &pTypeName);
}; };
} } // namespace Assimp
#endif // !! AI_COLLADAEXPORTER_H_INC #endif // !! AI_COLLADAEXPORTER_H_INC

View File

@ -43,8 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ColladaHelper.h" #include "ColladaHelper.h"
#include <assimp/commonMetaData.h>
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <assimp/commonMetaData.h>
namespace Assimp { namespace Assimp {
namespace Collada { namespace Collada {
@ -63,42 +63,35 @@ const MetaKeyPairVector &GetColladaAssimpMetaKeys() {
const MetaKeyPairVector MakeColladaAssimpMetaKeysCamelCase() { const MetaKeyPairVector MakeColladaAssimpMetaKeysCamelCase() {
MetaKeyPairVector result = MakeColladaAssimpMetaKeys(); MetaKeyPairVector result = MakeColladaAssimpMetaKeys();
for (auto &val : result) for (auto &val : result) {
{
ToCamelCase(val.first); ToCamelCase(val.first);
} }
return result; return result;
}; };
const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase() const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase() {
{
static const MetaKeyPairVector result = MakeColladaAssimpMetaKeysCamelCase(); static const MetaKeyPairVector result = MakeColladaAssimpMetaKeysCamelCase();
return result; return result;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Convert underscore_separated to CamelCase: "authoring_tool" becomes "AuthoringTool" // Convert underscore_separated to CamelCase: "authoring_tool" becomes "AuthoringTool"
void ToCamelCase(std::string &text) void ToCamelCase(std::string &text) {
{
if (text.empty()) if (text.empty())
return; return;
// Capitalise first character // Capitalise first character
auto it = text.begin(); auto it = text.begin();
(*it) = ToUpper(*it); (*it) = ToUpper(*it);
++it; ++it;
for (/*started above*/ ; it != text.end(); /*iterated below*/) for (/*started above*/; it != text.end(); /*iterated below*/) {
{ if ((*it) == '_') {
if ((*it) == '_')
{
it = text.erase(it); it = text.erase(it);
if (it != text.end()) if (it != text.end())
(*it) = ToUpper(*it); (*it) = ToUpper(*it);
} } else {
else
{
// Make lower case // Make lower case
(*it) = ToLower(*it); (*it) = ToLower(*it);
++it; ++it;
} }
} }
} }

View File

@ -45,31 +45,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_COLLADAHELPER_H_INC #ifndef AI_COLLADAHELPER_H_INC
#define AI_COLLADAHELPER_H_INC #define AI_COLLADAHELPER_H_INC
#include <map>
#include <vector>
#include <set>
#include <stdint.h>
#include <assimp/light.h> #include <assimp/light.h>
#include <assimp/mesh.h>
#include <assimp/material.h> #include <assimp/material.h>
#include <assimp/mesh.h>
#include <stdint.h>
#include <map>
#include <set>
#include <vector>
struct aiMaterial; struct aiMaterial;
namespace Assimp { namespace Assimp {
namespace Collada { namespace Collada {
/** Collada file versions which evolved during the years ... */ /** Collada file versions which evolved during the years ... */
enum FormatVersion enum FormatVersion {
{
FV_1_5_n, FV_1_5_n,
FV_1_4_n, FV_1_4_n,
FV_1_3_n FV_1_3_n
}; };
/** Transformation types that can be applied to a node */ /** Transformation types that can be applied to a node */
enum TransformType enum TransformType {
{
TF_LOOKAT, TF_LOOKAT,
TF_ROTATE, TF_ROTATE,
TF_TRANSLATE, TF_TRANSLATE,
@ -79,10 +76,9 @@ enum TransformType
}; };
/** Different types of input data to a vertex or face */ /** Different types of input data to a vertex or face */
enum InputType enum InputType {
{
IT_Invalid, IT_Invalid,
IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data. IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data.
IT_Position, IT_Position,
IT_Normal, IT_Normal,
IT_Texcoord, IT_Texcoord,
@ -92,15 +88,13 @@ enum InputType
}; };
/** Supported controller types */ /** Supported controller types */
enum ControllerType enum ControllerType {
{
Skin, Skin,
Morph Morph
}; };
/** Supported morph methods */ /** Supported morph methods */
enum MorphMethod enum MorphMethod {
{
Normalized, Normalized,
Relative Relative
}; };
@ -118,24 +112,21 @@ const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase();
void ToCamelCase(std::string &text); void ToCamelCase(std::string &text);
/** Contains all data for one of the different transformation types */ /** Contains all data for one of the different transformation types */
struct Transform struct Transform {
{ std::string mID; ///< SID of the transform step, by which anim channels address their target node
std::string mID; ///< SID of the transform step, by which anim channels address their target node
TransformType mType; TransformType mType;
ai_real f[16]; ///< Interpretation of data depends on the type of the transformation ai_real f[16]; ///< Interpretation of data depends on the type of the transformation
}; };
/** A collada camera. */ /** A collada camera. */
struct Camera struct Camera {
{ Camera() :
Camera() mOrtho(false),
: mOrtho (false) mHorFov(10e10f),
, mHorFov (10e10f) mVerFov(10e10f),
, mVerFov (10e10f) mAspect(10e10f),
, mAspect (10e10f) mZNear(0.1f),
, mZNear (0.1f) mZFar(1000.f) {}
, mZFar (1000.f)
{}
// Name of camera // Name of camera
std::string mName; std::string mName;
@ -159,19 +150,17 @@ struct Camera
#define ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET 1e9f #define ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET 1e9f
/** A collada light source. */ /** A collada light source. */
struct Light struct Light {
{ Light() :
Light() mType(aiLightSource_UNDEFINED),
: mType (aiLightSource_UNDEFINED) mAttConstant(1.f),
, mAttConstant (1.f) mAttLinear(0.f),
, mAttLinear (0.f) mAttQuadratic(0.f),
, mAttQuadratic (0.f) mFalloffAngle(180.f),
, mFalloffAngle (180.f) mFalloffExponent(0.f),
, mFalloffExponent (0.f) mPenumbraAngle(ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET),
, mPenumbraAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET) mOuterAngle(ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET),
, mOuterAngle (ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET) mIntensity(1.f) {}
, mIntensity (1.f)
{}
//! Type of the light source aiLightSourceType + ambient //! Type of the light source aiLightSourceType + ambient
unsigned int mType; unsigned int mType;
@ -180,7 +169,7 @@ struct Light
aiColor3D mColor; aiColor3D mColor;
//! Light attenuation //! Light attenuation
ai_real mAttConstant,mAttLinear,mAttQuadratic; ai_real mAttConstant, mAttLinear, mAttQuadratic;
//! Spot light falloff //! Spot light falloff
ai_real mFalloffAngle; ai_real mFalloffAngle;
@ -198,12 +187,10 @@ struct Light
}; };
/** Short vertex index description */ /** Short vertex index description */
struct InputSemanticMapEntry struct InputSemanticMapEntry {
{ InputSemanticMapEntry() :
InputSemanticMapEntry() mSet(0),
: mSet(0) mType(IT_Invalid) {}
, mType(IT_Invalid)
{}
//! Index of set, optional //! Index of set, optional
unsigned int mSet; unsigned int mSet;
@ -213,8 +200,7 @@ struct InputSemanticMapEntry
}; };
/** Table to map from effect to vertex input semantics */ /** Table to map from effect to vertex input semantics */
struct SemanticMappingTable struct SemanticMappingTable {
{
//! Name of material //! Name of material
std::string mMatName; std::string mMatName;
@ -222,7 +208,7 @@ struct SemanticMappingTable
std::map<std::string, InputSemanticMapEntry> mMap; std::map<std::string, InputSemanticMapEntry> mMap;
//! For std::find //! For std::find
bool operator == (const std::string& s) const { bool operator==(const std::string &s) const {
return s == mMatName; return s == mMatName;
} }
}; };
@ -230,8 +216,7 @@ struct SemanticMappingTable
/** A reference to a mesh inside a node, including materials assigned to the various subgroups. /** A reference to a mesh inside a node, including materials assigned to the various subgroups.
* The ID refers to either a mesh or a controller which specifies the mesh * The ID refers to either a mesh or a controller which specifies the mesh
*/ */
struct MeshInstance struct MeshInstance {
{
///< ID of the mesh or controller to be instanced ///< ID of the mesh or controller to be instanced
std::string mMeshOrController; std::string mMeshOrController;
@ -240,34 +225,30 @@ struct MeshInstance
}; };
/** A reference to a camera inside a node*/ /** A reference to a camera inside a node*/
struct CameraInstance struct CameraInstance {
{ ///< ID of the camera
///< ID of the camera
std::string mCamera; std::string mCamera;
}; };
/** A reference to a light inside a node*/ /** A reference to a light inside a node*/
struct LightInstance struct LightInstance {
{ ///< ID of the camera
///< ID of the camera
std::string mLight; std::string mLight;
}; };
/** A reference to a node inside a node*/ /** A reference to a node inside a node*/
struct NodeInstance struct NodeInstance {
{ ///< ID of the node
///< ID of the node
std::string mNode; std::string mNode;
}; };
/** A node in a scene hierarchy */ /** A node in a scene hierarchy */
struct Node struct Node {
{
std::string mName; std::string mName;
std::string mID; std::string mID;
std::string mSID; std::string mSID;
Node* mParent; Node *mParent;
std::vector<Node*> mChildren; std::vector<Node *> mChildren;
/** Operations in order to calculate the resulting transformation to parent. */ /** Operations in order to calculate the resulting transformation to parent. */
std::vector<Transform> mTransforms; std::vector<Transform> mTransforms;
@ -288,80 +269,83 @@ struct Node
std::string mPrimaryCamera; std::string mPrimaryCamera;
//! Constructor. Begin with a zero parent //! Constructor. Begin with a zero parent
Node() Node() :
: mParent( nullptr ){ mParent(nullptr) {
// empty // empty
} }
//! Destructor: delete all children subsequently //! Destructor: delete all children subsequently
~Node() { ~Node() {
for( std::vector<Node*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) for (std::vector<Node *>::iterator it = mChildren.begin(); it != mChildren.end(); ++it)
delete *it; delete *it;
} }
}; };
/** Data source array: either floats or strings */ /** Data source array: either floats or strings */
struct Data struct Data {
{
bool mIsStringArray; bool mIsStringArray;
std::vector<ai_real> mValues; std::vector<ai_real> mValues;
std::vector<std::string> mStrings; std::vector<std::string> mStrings;
}; };
/** Accessor to a data array */ /** Accessor to a data array */
struct Accessor struct Accessor {
{ size_t mCount; // in number of objects
size_t mCount; // in number of objects size_t mSize; // size of an object, in elements (floats or strings, mostly 1)
size_t mSize; // size of an object, in elements (floats or strings, mostly 1) size_t mOffset; // in number of values
size_t mOffset; // in number of values size_t mStride; // Stride in number of values
size_t mStride; // Stride in number of values
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore. std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on. size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on.
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component. // For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
std::string mSource; // URL of the source array std::string mSource; // URL of the source array
mutable const Data* mData; // Pointer to the source array, if resolved. NULL else mutable const Data *mData; // Pointer to the source array, if resolved. NULL else
Accessor() Accessor() {
{ mCount = 0;
mCount = 0; mSize = 0; mOffset = 0; mStride = 0; mData = NULL; mSize = 0;
mOffset = 0;
mStride = 0;
mData = NULL;
mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0; mSubOffset[0] = mSubOffset[1] = mSubOffset[2] = mSubOffset[3] = 0;
} }
}; };
/** A single face in a mesh */ /** A single face in a mesh */
struct Face struct Face {
{
std::vector<size_t> mIndices; std::vector<size_t> mIndices;
}; };
/** An input channel for mesh data, referring to a single accessor */ /** An input channel for mesh data, referring to a single accessor */
struct InputChannel struct InputChannel {
{ InputType mType; // Type of the data
InputType mType; // Type of the data size_t mIndex; // Optional index, if multiple sets of the same data type are given
size_t mIndex; // Optional index, if multiple sets of the same data type are given size_t mOffset; // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better.
size_t mOffset; // Index offset in the indices array of per-face indices. Don't ask, can't explain that any better.
std::string mAccessor; // ID of the accessor where to read the actual values from. std::string mAccessor; // ID of the accessor where to read the actual values from.
mutable const Accessor* mResolved; // Pointer to the accessor, if resolved. NULL else mutable const Accessor *mResolved; // Pointer to the accessor, if resolved. NULL else
InputChannel() { mType = IT_Invalid; mIndex = 0; mOffset = 0; mResolved = NULL; } InputChannel() {
mType = IT_Invalid;
mIndex = 0;
mOffset = 0;
mResolved = NULL;
}
}; };
/** Subset of a mesh with a certain material */ /** Subset of a mesh with a certain material */
struct SubMesh struct SubMesh {
{
std::string mMaterial; ///< subgroup identifier std::string mMaterial; ///< subgroup identifier
size_t mNumFaces; ///< number of faces in this submesh size_t mNumFaces; ///< number of faces in this submesh
}; };
/** Contains data for a single mesh */ /** Contains data for a single mesh */
struct Mesh struct Mesh {
{ Mesh(const std::string &id) :
Mesh() mId(id) {
{ for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i)
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
mNumUVComponents[i] = 2; mNumUVComponents[i] = 2;
} }
const std::string mId;
std::string mName; std::string mName;
// just to check if there's some sophisticated addressing involved... // just to check if there's some sophisticated addressing involved...
@ -377,7 +361,7 @@ struct Mesh
std::vector<aiVector3D> mTangents; std::vector<aiVector3D> mTangents;
std::vector<aiVector3D> mBitangents; std::vector<aiVector3D> mBitangents;
std::vector<aiVector3D> mTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS]; std::vector<aiVector3D> mTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
std::vector<aiColor4D> mColors[AI_MAX_NUMBER_OF_COLOR_SETS]; std::vector<aiColor4D> mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS]; unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
@ -394,8 +378,7 @@ struct Mesh
}; };
/** Which type of primitives the ReadPrimitives() function is going to read */ /** Which type of primitives the ReadPrimitives() function is going to read */
enum PrimitiveType enum PrimitiveType {
{
Prim_Invalid, Prim_Invalid,
Prim_Lines, Prim_Lines,
Prim_LineStrip, Prim_LineStrip,
@ -407,8 +390,7 @@ enum PrimitiveType
}; };
/** A skeleton controller to deform a mesh with the use of joints */ /** A skeleton controller to deform a mesh with the use of joints */
struct Controller struct Controller {
{
// controller type // controller type
ControllerType mType; ControllerType mType;
@ -436,36 +418,32 @@ struct Controller
std::vector<size_t> mWeightCounts; std::vector<size_t> mWeightCounts;
// JointIndex-WeightIndex pairs for all vertices // JointIndex-WeightIndex pairs for all vertices
std::vector< std::pair<size_t, size_t> > mWeights; std::vector<std::pair<size_t, size_t>> mWeights;
std::string mMorphTarget; std::string mMorphTarget;
std::string mMorphWeight; std::string mMorphWeight;
}; };
/** A collada material. Pretty much the only member is a reference to an effect. */ /** A collada material. Pretty much the only member is a reference to an effect. */
struct Material struct Material {
{
std::string mName; std::string mName;
std::string mEffect; std::string mEffect;
}; };
/** Type of the effect param */ /** Type of the effect param */
enum ParamType enum ParamType {
{
Param_Sampler, Param_Sampler,
Param_Surface Param_Surface
}; };
/** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */ /** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */
struct EffectParam struct EffectParam {
{
ParamType mType; ParamType mType;
std::string mReference; // to which other thing the param is referring to. std::string mReference; // to which other thing the param is referring to.
}; };
/** Shading type supported by the standard effect spec of Collada */ /** Shading type supported by the standard effect spec of Collada */
enum ShadeType enum ShadeType {
{
Shade_Invalid, Shade_Invalid,
Shade_Constant, Shade_Constant,
Shade_Lambert, Shade_Lambert,
@ -474,18 +452,16 @@ enum ShadeType
}; };
/** Represents a texture sampler in collada */ /** Represents a texture sampler in collada */
struct Sampler struct Sampler {
{ Sampler() :
Sampler() mWrapU(true),
: mWrapU (true) mWrapV(true),
, mWrapV (true) mMirrorU(),
, mMirrorU () mMirrorV(),
, mMirrorV () mOp(aiTextureOp_Multiply),
, mOp (aiTextureOp_Multiply) mUVId(UINT_MAX),
, mUVId (UINT_MAX) mWeighting(1.f),
, mWeighting (1.f) mMixWithPrevious(1.f) {}
, mMixWithPrevious (1.f)
{}
/** Name of image reference /** Name of image reference
*/ */
@ -537,18 +513,17 @@ struct Sampler
/** A collada effect. Can contain about anything according to the Collada spec, /** A collada effect. Can contain about anything according to the Collada spec,
but we limit our version to a reasonable subset. */ but we limit our version to a reasonable subset. */
struct Effect struct Effect {
{
// Shading mode // Shading mode
ShadeType mShadeType; ShadeType mShadeType;
// Colors // Colors
aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular, aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular,
mTransparent, mReflective; mTransparent, mReflective;
// Textures // Textures
Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular, Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular,
mTexTransparent, mTexBump, mTexReflective; mTexTransparent, mTexBump, mTexReflective;
// Scalar factory // Scalar factory
ai_real mShininess, mRefractIndex, mReflectivity; ai_real mShininess, mRefractIndex, mReflectivity;
@ -566,30 +541,28 @@ struct Effect
// Double-sided? // Double-sided?
bool mDoubleSided, mWireframe, mFaceted; bool mDoubleSided, mWireframe, mFaceted;
Effect() Effect() :
: mShadeType (Shade_Phong) mShadeType(Shade_Phong),
, mEmissive ( 0, 0, 0, 1) mEmissive(0, 0, 0, 1),
, mAmbient ( 0.1f, 0.1f, 0.1f, 1) mAmbient(0.1f, 0.1f, 0.1f, 1),
, mDiffuse ( 0.6f, 0.6f, 0.6f, 1) mDiffuse(0.6f, 0.6f, 0.6f, 1),
, mSpecular ( 0.4f, 0.4f, 0.4f, 1) mSpecular(0.4f, 0.4f, 0.4f, 1),
, mTransparent ( 0, 0, 0, 1) mTransparent(0, 0, 0, 1),
, mShininess (10.0f) mShininess(10.0f),
, mRefractIndex (1.f) mRefractIndex(1.f),
, mReflectivity (0.f) mReflectivity(0.f),
, mTransparency (1.f) mTransparency(1.f),
, mHasTransparency (false) mHasTransparency(false),
, mRGBTransparency(false) mRGBTransparency(false),
, mInvertTransparency(false) mInvertTransparency(false),
, mDoubleSided (false) mDoubleSided(false),
, mWireframe (false) mWireframe(false),
, mFaceted (false) mFaceted(false) {
{
} }
}; };
/** An image, meaning texture */ /** An image, meaning texture */
struct Image struct Image {
{
std::string mFileName; std::string mFileName;
/** Embedded image data */ /** Embedded image data */
@ -600,8 +573,7 @@ struct Image
}; };
/** An animation channel. */ /** An animation channel. */
struct AnimationChannel struct AnimationChannel {
{
/** URL of the data to animate. Could be about anything, but we support only the /** URL of the data to animate. Could be about anything, but we support only the
* "NodeID/TransformID.SubElement" notation * "NodeID/TransformID.SubElement" notation
*/ */
@ -620,8 +592,7 @@ struct AnimationChannel
}; };
/** An animation. Container for 0-x animation channels or 0-x animations */ /** An animation. Container for 0-x animation channels or 0-x animations */
struct Animation struct Animation {
{
/** Anim name */ /** Anim name */
std::string mName; std::string mName;
@ -629,96 +600,86 @@ struct Animation
std::vector<AnimationChannel> mChannels; std::vector<AnimationChannel> mChannels;
/** the sub-animations, if any */ /** the sub-animations, if any */
std::vector<Animation*> mSubAnims; std::vector<Animation *> mSubAnims;
/** Destructor */ /** Destructor */
~Animation() ~Animation() {
{ for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
for( std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
delete *it; delete *it;
} }
/** Collect all channels in the animation hierarchy into a single channel list. */ /** Collect all channels in the animation hierarchy into a single channel list. */
void CollectChannelsRecursively(std::vector<AnimationChannel> &channels) void CollectChannelsRecursively(std::vector<AnimationChannel> &channels) {
{ channels.insert(channels.end(), mChannels.begin(), mChannels.end());
channels.insert(channels.end(), mChannels.begin(), mChannels.end());
for (std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) {
{ Animation *pAnim = (*it);
Animation *pAnim = (*it);
pAnim->CollectChannelsRecursively(channels); pAnim->CollectChannelsRecursively(channels);
} }
} }
/** Combine all single-channel animations' channel into the same (parent) animation channel list. */ /** Combine all single-channel animations' channel into the same (parent) animation channel list. */
void CombineSingleChannelAnimations() void CombineSingleChannelAnimations() {
{ CombineSingleChannelAnimationsRecursively(this);
CombineSingleChannelAnimationsRecursively(this); }
}
void CombineSingleChannelAnimationsRecursively(Animation *pParent) void CombineSingleChannelAnimationsRecursively(Animation *pParent) {
{ std::set<std::string> childrenTargets;
std::set<std::string> childrenTargets; bool childrenAnimationsHaveDifferentChannels = true;
bool childrenAnimationsHaveDifferentChannels = true;
for (std::vector<Animation*>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();) for (std::vector<Animation *>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();) {
{ Animation *anim = *it;
Animation *anim = *it; CombineSingleChannelAnimationsRecursively(anim);
CombineSingleChannelAnimationsRecursively(anim);
if (childrenAnimationsHaveDifferentChannels && anim->mChannels.size() == 1 && if (childrenAnimationsHaveDifferentChannels && anim->mChannels.size() == 1 &&
childrenTargets.find(anim->mChannels[0].mTarget) == childrenTargets.end()) { childrenTargets.find(anim->mChannels[0].mTarget) == childrenTargets.end()) {
childrenTargets.insert(anim->mChannels[0].mTarget); childrenTargets.insert(anim->mChannels[0].mTarget);
} else { } else {
childrenAnimationsHaveDifferentChannels = false; childrenAnimationsHaveDifferentChannels = false;
} }
++it; ++it;
} }
// We only want to combine animations if they have different channels // We only want to combine animations if they have different channels
if (childrenAnimationsHaveDifferentChannels) if (childrenAnimationsHaveDifferentChannels) {
{ for (std::vector<Animation *>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();) {
for (std::vector<Animation*>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();) Animation *anim = *it;
{
Animation *anim = *it;
pParent->mChannels.push_back(anim->mChannels[0]); pParent->mChannels.push_back(anim->mChannels[0]);
it = pParent->mSubAnims.erase(it); it = pParent->mSubAnims.erase(it);
delete anim; delete anim;
continue; continue;
} }
} }
} }
}; };
/** Description of a collada animation channel which has been determined to affect the current node */ /** Description of a collada animation channel which has been determined to affect the current node */
struct ChannelEntry struct ChannelEntry {
{ const Collada::AnimationChannel *mChannel; ///> the source channel
const Collada::AnimationChannel* mChannel; ///> the source channel
std::string mTargetId; std::string mTargetId;
std::string mTransformId; // the ID of the transformation step of the node which is influenced std::string mTransformId; // the ID of the transformation step of the node which is influenced
size_t mTransformIndex; // Index into the node's transform chain to apply the channel to size_t mTransformIndex; // Index into the node's transform chain to apply the channel to
size_t mSubElement; // starting index inside the transform data size_t mSubElement; // starting index inside the transform data
// resolved data references // resolved data references
const Collada::Accessor* mTimeAccessor; ///> Collada accessor to the time values const Collada::Accessor *mTimeAccessor; ///> Collada accessor to the time values
const Collada::Data* mTimeData; ///> Source data array for the time values const Collada::Data *mTimeData; ///> Source data array for the time values
const Collada::Accessor* mValueAccessor; ///> Collada accessor to the key value values const Collada::Accessor *mValueAccessor; ///> Collada accessor to the key value values
const Collada::Data* mValueData; ///> Source datat array for the key value values const Collada::Data *mValueData; ///> Source datat array for the key value values
ChannelEntry() ChannelEntry() :
: mChannel() mChannel(),
, mTransformIndex() mTransformIndex(),
, mSubElement() mSubElement(),
, mTimeAccessor() mTimeAccessor(),
, mTimeData() mTimeData(),
, mValueAccessor() mValueAccessor(),
, mValueData() mValueData() {}
{}
}; };
} // end of namespace Collada } // end of namespace Collada

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -47,346 +47,345 @@
#ifndef AI_COLLADAPARSER_H_INC #ifndef AI_COLLADAPARSER_H_INC
#define AI_COLLADAPARSER_H_INC #define AI_COLLADAPARSER_H_INC
#include <assimp/irrXMLWrapper.h>
#include "ColladaHelper.h" #include "ColladaHelper.h"
#include <assimp/ai_assert.h>
#include <assimp/TinyFormatter.h> #include <assimp/TinyFormatter.h>
#include <assimp/ai_assert.h>
#include <assimp/irrXMLWrapper.h>
namespace Assimp namespace Assimp {
{ class ZipArchiveIOSystem;
class ZipArchiveIOSystem;
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
/** Parser helper class for the Collada loader. /** Parser helper class for the Collada loader.
* *
* Does all the XML reading and builds internal data structures from it, * Does all the XML reading and builds internal data structures from it,
* but leaves the resolving of all the references to the loader. * but leaves the resolving of all the references to the loader.
*/ */
class ColladaParser class ColladaParser {
{ friend class ColladaLoader;
friend class ColladaLoader;
/** Converts a path read from a collada file to the usual representation */ /** Converts a path read from a collada file to the usual representation */
static void UriDecodePath(aiString& ss); static void UriDecodePath(aiString &ss);
protected: protected:
/** Map for generic metadata as aiString */ /** Map for generic metadata as aiString */
typedef std::map<std::string, aiString> StringMetaData; typedef std::map<std::string, aiString> StringMetaData;
/** Constructor from XML file */ /** Constructor from XML file */
ColladaParser(IOSystem* pIOHandler, const std::string& pFile); ColladaParser(IOSystem *pIOHandler, const std::string &pFile);
/** Destructor */ /** Destructor */
~ColladaParser(); ~ColladaParser();
/** Attempts to read the ZAE manifest and returns the DAE to open */ /** Attempts to read the ZAE manifest and returns the DAE to open */
static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive); static std::string ReadZaeManifest(ZipArchiveIOSystem &zip_archive);
/** Reads the contents of the file */ /** Reads the contents of the file */
void ReadContents(); void ReadContents();
/** Reads the structure of the file */ /** Reads the structure of the file */
void ReadStructure(); void ReadStructure();
/** Reads asset information such as coordinate system information and legal blah */ /** Reads asset information such as coordinate system information and legal blah */
void ReadAssetInfo(); void ReadAssetInfo();
/** Reads contributor information such as author and legal blah */ /** Reads contributor information such as author and legal blah */
void ReadContributorInfo(); void ReadContributorInfo();
/** Reads generic metadata into provided map and renames keys for Assimp */ /** Reads generic metadata into provided map and renames keys for Assimp */
void ReadMetaDataItem(StringMetaData &metadata); void ReadMetaDataItem(StringMetaData &metadata);
/** Reads the animation library */ /** Reads the animation library */
void ReadAnimationLibrary(); void ReadAnimationLibrary();
/** Reads the animation clip library */ /** Reads the animation clip library */
void ReadAnimationClipLibrary(); void ReadAnimationClipLibrary();
/** Unwrap controllers dependency hierarchy */ /** Unwrap controllers dependency hierarchy */
void PostProcessControllers(); void PostProcessControllers();
/** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
void PostProcessRootAnimations();
/** Reads an animation into the given parent structure */ /** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
void ReadAnimation( Collada::Animation* pParent); void PostProcessRootAnimations();
/** Reads an animation sampler into the given anim channel */ /** Reads an animation into the given parent structure */
void ReadAnimationSampler( Collada::AnimationChannel& pChannel); void ReadAnimation(Collada::Animation *pParent);
/** Reads the skeleton controller library */ /** Reads an animation sampler into the given anim channel */
void ReadControllerLibrary(); void ReadAnimationSampler(Collada::AnimationChannel &pChannel);
/** Reads a controller into the given mesh structure */ /** Reads the skeleton controller library */
void ReadController( Collada::Controller& pController); void ReadControllerLibrary();
/** Reads the joint definitions for the given controller */ /** Reads a controller into the given mesh structure */
void ReadControllerJoints( Collada::Controller& pController); void ReadController(Collada::Controller &pController);
/** Reads the joint weights for the given controller */ /** Reads the joint definitions for the given controller */
void ReadControllerWeights( Collada::Controller& pController); void ReadControllerJoints(Collada::Controller &pController);
/** Reads the image library contents */ /** Reads the joint weights for the given controller */
void ReadImageLibrary(); void ReadControllerWeights(Collada::Controller &pController);
/** Reads an image entry into the given image */ /** Reads the image library contents */
void ReadImage( Collada::Image& pImage); void ReadImageLibrary();
/** Reads the material library */ /** Reads an image entry into the given image */
void ReadMaterialLibrary(); void ReadImage(Collada::Image &pImage);
/** Reads a material entry into the given material */ /** Reads the material library */
void ReadMaterial( Collada::Material& pMaterial); void ReadMaterialLibrary();
/** Reads the camera library */ /** Reads a material entry into the given material */
void ReadCameraLibrary(); void ReadMaterial(Collada::Material &pMaterial);
/** Reads a camera entry into the given camera */ /** Reads the camera library */
void ReadCamera( Collada::Camera& pCamera); void ReadCameraLibrary();
/** Reads the light library */ /** Reads a camera entry into the given camera */
void ReadLightLibrary(); void ReadCamera(Collada::Camera &pCamera);
/** Reads a light entry into the given light */ /** Reads the light library */
void ReadLight( Collada::Light& pLight); void ReadLightLibrary();
/** Reads the effect library */ /** Reads a light entry into the given light */
void ReadEffectLibrary(); void ReadLight(Collada::Light &pLight);
/** Reads an effect entry into the given effect*/ /** Reads the effect library */
void ReadEffect( Collada::Effect& pEffect); void ReadEffectLibrary();
/** Reads an COMMON effect profile */ /** Reads an effect entry into the given effect*/
void ReadEffectProfileCommon( Collada::Effect& pEffect); void ReadEffect(Collada::Effect &pEffect);
/** Read sampler properties */ /** Reads an COMMON effect profile */
void ReadSamplerProperties( Collada::Sampler& pSampler); void ReadEffectProfileCommon(Collada::Effect &pEffect);
/** Reads an effect entry containing a color or a texture defining that color */ /** Read sampler properties */
void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler); void ReadSamplerProperties(Collada::Sampler &pSampler);
/** Reads an effect entry containing a float */ /** Reads an effect entry containing a color or a texture defining that color */
void ReadEffectFloat( ai_real& pFloat); void ReadEffectColor(aiColor4D &pColor, Collada::Sampler &pSampler);
/** Reads an effect parameter specification of any kind */ /** Reads an effect entry containing a float */
void ReadEffectParam( Collada::EffectParam& pParam); void ReadEffectFloat(ai_real &pFloat);
/** Reads the geometry library contents */ /** Reads an effect parameter specification of any kind */
void ReadGeometryLibrary(); void ReadEffectParam(Collada::EffectParam &pParam);
/** Reads a geometry from the geometry library. */ /** Reads the geometry library contents */
void ReadGeometry( Collada::Mesh* pMesh); void ReadGeometryLibrary();
/** Reads a mesh from the geometry library */ /** Reads a geometry from the geometry library. */
void ReadMesh( Collada::Mesh* pMesh); void ReadGeometry(Collada::Mesh &pMesh);
/** Reads a source element - a combination of raw data and an accessor defining /** Reads a mesh from the geometry library */
void ReadMesh(Collada::Mesh &pMesh);
/** Reads a source element - a combination of raw data and an accessor defining
* things that should not be redefinable. Yes, that's another rant. * things that should not be redefinable. Yes, that's another rant.
*/ */
void ReadSource(); void ReadSource();
/** Reads a data array holding a number of elements, and stores it in the global library. /** Reads a data array holding a number of elements, and stores it in the global library.
* Currently supported are array of floats and arrays of strings. * Currently supported are array of floats and arrays of strings.
*/ */
void ReadDataArray(); void ReadDataArray();
/** Reads an accessor and stores it in the global library under the given ID - /** Reads an accessor and stores it in the global library under the given ID -
* accessors use the ID of the parent <source> element * accessors use the ID of the parent <source> element
*/ */
void ReadAccessor( const std::string& pID); void ReadAccessor(const std::string &pID);
/** Reads input declarations of per-vertex mesh data into the given mesh */ /** Reads input declarations of per-vertex mesh data into the given mesh */
void ReadVertexData( Collada::Mesh* pMesh); void ReadVertexData(Collada::Mesh &pMesh);
/** Reads input declarations of per-index mesh data into the given mesh */ /** Reads input declarations of per-index mesh data into the given mesh */
void ReadIndexData( Collada::Mesh* pMesh); void ReadIndexData(Collada::Mesh &pMesh);
/** Reads a single input channel element and stores it in the given array, if valid */ /** Reads a single input channel element and stores it in the given array, if valid */
void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels); void ReadInputChannel(std::vector<Collada::InputChannel> &poChannels);
/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */ /** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels, size_t ReadPrimitives(Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType); size_t pNumPrimitives, const std::vector<size_t> &pVCount, Collada::PrimitiveType pPrimType);
/** Copies the data for a single primitive into the mesh, based on the InputChannels */ /** Copies the data for a single primitive into the mesh, based on the InputChannels */
void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels, Collada::Mesh &pMesh, std::vector<Collada::InputChannel> &pPerIndexChannels,
size_t currentPrimitive, const std::vector<size_t>& indices); size_t currentPrimitive, const std::vector<size_t> &indices);
/** Reads one triangle of a tristrip into the mesh */ /** Reads one triangle of a tristrip into the mesh */
void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh, void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh &pMesh,
std::vector<Collada::InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices); std::vector<Collada::InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices);
/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */ /** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh); void ExtractDataObjectFromChannel(const Collada::InputChannel &pInput, size_t pLocalIndex, Collada::Mesh &pMesh);
/** Reads the library of node hierarchies and scene parts */ /** Reads the library of node hierarchies and scene parts */
void ReadSceneLibrary(); void ReadSceneLibrary();
/** Reads a scene node's contents including children and stores it in the given node */ /** Reads a scene node's contents including children and stores it in the given node */
void ReadSceneNode( Collada::Node* pNode); void ReadSceneNode(Collada::Node *pNode);
/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */ /** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType); void ReadNodeTransformation(Collada::Node *pNode, Collada::TransformType pType);
/** Reads a mesh reference in a node and adds it to the node's mesh list */ /** Reads a mesh reference in a node and adds it to the node's mesh list */
void ReadNodeGeometry( Collada::Node* pNode); void ReadNodeGeometry(Collada::Node *pNode);
/** Reads the collada scene */ /** Reads the collada scene */
void ReadScene(); void ReadScene();
// Processes bind_vertex_input and bind elements // Processes bind_vertex_input and bind elements
void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl); void ReadMaterialVertexInputBinding(Collada::SemanticMappingTable &tbl);
/** Reads embedded textures from a ZAE archive*/ /** Reads embedded textures from a ZAE archive*/
void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive); void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
protected: protected:
/** Aborts the file reading with an exception */ /** Aborts the file reading with an exception */
AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN void ThrowException(const std::string &pError) const AI_WONT_RETURN_SUFFIX;
void ReportWarning(const char* msg,...); void ReportWarning(const char *msg, ...);
/** Skips all data until the end node of the current element */ /** Skips all data until the end node of the current element */
void SkipElement(); void SkipElement();
/** Skips all data until the end node of the given element */ /** Skips all data until the end node of the given element */
void SkipElement( const char* pElement); void SkipElement(const char *pElement);
/** Compares the current xml element name to the given string and returns true if equal */ /** Compares the current xml element name to the given string and returns true if equal */
bool IsElement( const char* pName) const; bool IsElement(const char *pName) const;
/** Tests for the opening tag of the given element, throws an exception if not found */ /** Tests for the opening tag of the given element, throws an exception if not found */
void TestOpening( const char* pName); void TestOpening(const char *pName);
/** Tests for the closing tag of the given element, throws an exception if not found */ /** Tests for the closing tag of the given element, throws an exception if not found */
void TestClosing( const char* pName); void TestClosing(const char *pName);
/** Checks the present element for the presence of the attribute, returns its index /** Checks the present element for the presence of the attribute, returns its index
or throws an exception if not found */ or throws an exception if not found */
int GetAttribute( const char* pAttr) const; int GetAttribute(const char *pAttr) const;
/** Returns the index of the named attribute or -1 if not found. Does not throw, /** Returns the index of the named attribute or -1 if not found. Does not throw,
therefore useful for optional attributes */ therefore useful for optional attributes */
int TestAttribute( const char* pAttr) const; int TestAttribute(const char *pAttr) const;
/** Reads the text contents of an element, throws an exception if not given. /** Reads the text contents of an element, throws an exception if not given.
Skips leading whitespace. */ Skips leading whitespace. */
const char* GetTextContent(); const char *GetTextContent();
/** Reads the text contents of an element, returns NULL if not given. /** Reads the text contents of an element, returns NULL if not given.
Skips leading whitespace. */ Skips leading whitespace. */
const char* TestTextContent(); const char *TestTextContent();
/** Reads a single bool from current text content */ /** Reads a single bool from current text content */
bool ReadBoolFromTextContent(); bool ReadBoolFromTextContent();
/** Reads a single float from current text content */ /** Reads a single float from current text content */
ai_real ReadFloatFromTextContent(); ai_real ReadFloatFromTextContent();
/** Calculates the resulting transformation from all the given transform steps */ /** Calculates the resulting transformation from all the given transform steps */
aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const; aiMatrix4x4 CalculateResultTransform(const std::vector<Collada::Transform> &pTransforms) const;
/** Determines the input data type for the given semantic string */ /** Determines the input data type for the given semantic string */
Collada::InputType GetTypeForSemantic( const std::string& pSemantic); Collada::InputType GetTypeForSemantic(const std::string &pSemantic);
/** Finds the item in the given library by its reference, throws if not found */ /** Finds the item in the given library by its reference, throws if not found */
template <typename Type> const Type& ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
protected:
/** Filename, for a verbose error message */
std::string mFileName;
/** XML reader, member for everyday use */
irr::io::IrrXMLReader* mReader;
/** All data arrays found in the file by ID. Might be referred to by actually
everyone. Collada, you are a steaming pile of indirection. */
typedef std::map<std::string, Collada::Data> DataLibrary;
DataLibrary mDataLibrary;
/** Same for accessors which define how the data in a data array is accessed. */
typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
AccessorLibrary mAccessorLibrary;
/** Mesh library: mesh by ID */
typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
MeshLibrary mMeshLibrary;
/** node library: root node of the hierarchy part by ID */
typedef std::map<std::string, Collada::Node*> NodeLibrary;
NodeLibrary mNodeLibrary;
/** Image library: stores texture properties by ID */
typedef std::map<std::string, Collada::Image> ImageLibrary;
ImageLibrary mImageLibrary;
/** Effect library: surface attributes by ID */
typedef std::map<std::string, Collada::Effect> EffectLibrary;
EffectLibrary mEffectLibrary;
/** Material library: surface material by ID */
typedef std::map<std::string, Collada::Material> MaterialLibrary;
MaterialLibrary mMaterialLibrary;
/** Light library: surface light by ID */
typedef std::map<std::string, Collada::Light> LightLibrary;
LightLibrary mLightLibrary;
/** Camera library: surface material by ID */
typedef std::map<std::string, Collada::Camera> CameraLibrary;
CameraLibrary mCameraLibrary;
/** Controller library: joint controllers by ID */
typedef std::map<std::string, Collada::Controller> ControllerLibrary;
ControllerLibrary mControllerLibrary;
/** Animation library: animation references by ID */
typedef std::map<std::string, Collada::Animation*> AnimationLibrary;
AnimationLibrary mAnimationLibrary;
/** Animation clip library: clip animation references by ID */
typedef std::vector<std::pair<std::string, std::vector<std::string> > > AnimationClipLibrary;
AnimationClipLibrary mAnimationClipLibrary;
/** Pointer to the root node. Don't delete, it just points to one of
the nodes in the node library. */
Collada::Node* mRootNode;
/** Root animation container */
Collada::Animation mAnims;
/** Size unit: how large compared to a meter */
ai_real mUnitSize;
/** Which is the up vector */
enum { UP_X, UP_Y, UP_Z } mUpDirection;
/** Asset metadata (global for scene) */
StringMetaData mAssetMetaData;
/** Collada file format version */
Collada::FormatVersion mFormat;
};
// ------------------------------------------------------------------------------------------------
// Check for element match
inline bool ColladaParser::IsElement( const char* pName) const
{
ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT);
return ::strcmp( mReader->getNodeName(), pName) == 0;
}
// ------------------------------------------------------------------------------------------------
// Finds the item in the given library by its reference, throws if not found
template <typename Type> template <typename Type>
const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const const Type &ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const;
{
typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL); protected:
if( it == pLibrary.end()) /** Filename, for a verbose error message */
ThrowException( Formatter::format() << "Unable to resolve library reference \"" << pURL << "\"." ); std::string mFileName;
return it->second;
} /** XML reader, member for everyday use */
irr::io::IrrXMLReader *mReader;
/** All data arrays found in the file by ID. Might be referred to by actually
everyone. Collada, you are a steaming pile of indirection. */
typedef std::map<std::string, Collada::Data> DataLibrary;
DataLibrary mDataLibrary;
/** Same for accessors which define how the data in a data array is accessed. */
typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
AccessorLibrary mAccessorLibrary;
/** Mesh library: mesh by ID */
typedef std::map<std::string, Collada::Mesh *> MeshLibrary;
MeshLibrary mMeshLibrary;
/** node library: root node of the hierarchy part by ID */
typedef std::map<std::string, Collada::Node *> NodeLibrary;
NodeLibrary mNodeLibrary;
/** Image library: stores texture properties by ID */
typedef std::map<std::string, Collada::Image> ImageLibrary;
ImageLibrary mImageLibrary;
/** Effect library: surface attributes by ID */
typedef std::map<std::string, Collada::Effect> EffectLibrary;
EffectLibrary mEffectLibrary;
/** Material library: surface material by ID */
typedef std::map<std::string, Collada::Material> MaterialLibrary;
MaterialLibrary mMaterialLibrary;
/** Light library: surface light by ID */
typedef std::map<std::string, Collada::Light> LightLibrary;
LightLibrary mLightLibrary;
/** Camera library: surface material by ID */
typedef std::map<std::string, Collada::Camera> CameraLibrary;
CameraLibrary mCameraLibrary;
/** Controller library: joint controllers by ID */
typedef std::map<std::string, Collada::Controller> ControllerLibrary;
ControllerLibrary mControllerLibrary;
/** Animation library: animation references by ID */
typedef std::map<std::string, Collada::Animation *> AnimationLibrary;
AnimationLibrary mAnimationLibrary;
/** Animation clip library: clip animation references by ID */
typedef std::vector<std::pair<std::string, std::vector<std::string>>> AnimationClipLibrary;
AnimationClipLibrary mAnimationClipLibrary;
/** Pointer to the root node. Don't delete, it just points to one of
the nodes in the node library. */
Collada::Node *mRootNode;
/** Root animation container */
Collada::Animation mAnims;
/** Size unit: how large compared to a meter */
ai_real mUnitSize;
/** Which is the up vector */
enum { UP_X,
UP_Y,
UP_Z } mUpDirection;
/** Asset metadata (global for scene) */
StringMetaData mAssetMetaData;
/** Collada file format version */
Collada::FormatVersion mFormat;
};
// ------------------------------------------------------------------------------------------------
// Check for element match
inline bool ColladaParser::IsElement(const char *pName) const {
ai_assert(mReader->getNodeType() == irr::io::EXN_ELEMENT);
return ::strcmp(mReader->getNodeName(), pName) == 0;
}
// ------------------------------------------------------------------------------------------------
// Finds the item in the given library by its reference, throws if not found
template <typename Type>
const Type &ColladaParser::ResolveLibraryReference(const std::map<std::string, Type> &pLibrary, const std::string &pURL) const {
typename std::map<std::string, Type>::const_iterator it = pLibrary.find(pURL);
if (it == pLibrary.end())
ThrowException(Formatter::format() << "Unable to resolve library reference \"" << pURL << "\".");
return it->second;
}
} // end of namespace Assimp } // end of namespace Assimp

View File

@ -3315,6 +3315,7 @@ void FBXConverter::InterpolateKeys(aiQuatKey *valOut, const KeyTimeList &keys, c
// http://www.3dkingdoms.com/weekly/weekly.php?a=36 // http://www.3dkingdoms.com/weekly/weekly.php?a=36
if (quat.x * lastq.x + quat.y * lastq.y + quat.z * lastq.z + quat.w * lastq.w < 0) { if (quat.x * lastq.x + quat.y * lastq.y + quat.z * lastq.z + quat.w * lastq.w < 0) {
quat.Conjugate(); quat.Conjugate();
quat.w = -quat.w;
} }
lastq = quat; lastq = quat;

View File

@ -93,4 +93,4 @@ private:
} // Namespace Assimp } // Namespace Assimp
#endif #endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,114 +0,0 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
#include "StepFileImporter.h"
#include "../../Importer/STEPParser/STEPFileReader.h"
#include <assimp/importerdesc.h>
#include <assimp/DefaultIOSystem.h>
namespace Assimp {
namespace StepFile {
using namespace STEP;
static const aiImporterDesc desc = { "StepFile Importer",
"",
"",
"",
0,
0,
0,
0,
0,
"stp" };
StepFileImporter::StepFileImporter()
: BaseImporter() {
}
StepFileImporter::~StepFileImporter() {
}
bool StepFileImporter::CanRead(const std::string& file, IOSystem* pIOHandler, bool checkSig) const {
const std::string &extension = GetExtension(file);
if ( extension == "stp" || extension == "step" ) {
return true;
} else if ((!extension.length() || checkSig) && pIOHandler) {
const char* tokens[] = { "ISO-10303-21" };
const bool found(SearchFileHeaderForToken(pIOHandler, file, tokens, 1));
return found;
}
return false;
}
const aiImporterDesc *StepFileImporter::GetInfo() const {
return &desc;
}
static const std::string mode = "rb";
static const std::string StepFileSchema = "CONFIG_CONTROL_DESIGN";
void StepFileImporter::InternReadFile(const std::string &file, aiScene*, IOSystem* pIOHandler) {
// Read file into memory
std::shared_ptr<IOStream> fileStream(pIOHandler->Open(file, mode));
if (!fileStream.get()) {
throw DeadlyImportError("Failed to open file " + file + ".");
}
std::unique_ptr<STEP::DB> db(STEP::ReadFileHeader(fileStream));
const STEP::HeaderInfo& head = static_cast<const STEP::DB&>(*db).GetHeader();
if (!head.fileSchema.size() || head.fileSchema != StepFileSchema) {
DeadlyImportError("Unrecognized file schema: " + head.fileSchema);
}
}
} // Namespace StepFile
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_STEP_IMPORTER

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------

View File

@ -363,20 +363,44 @@ struct Object {
// Classes for each glTF top-level object type // Classes for each glTF top-level object type
// //
//! Base class for types that access binary data from a BufferView, such as accessors
//! or sparse accessors' indices.
//! N.B. not a virtual class. All owned pointers to BufferViewClient instances should
//! be to their most derived types (which may of course be just BufferViewClient).
struct BufferViewClient : public Object {
Ref<BufferView> bufferView; //!< The ID of the bufferView. (required)
size_t byteOffset; //!< The offset relative to the start of the bufferView in bytes. (required)
inline uint8_t *GetPointer();
void Read(Value &obj, Asset &r);
};
//! BufferViewClient with component type information.
//! N.B. not a virtual class. All owned pointers to ComponentTypedBufferViewClient
//! instances should be to their most derived types (which may of course be just
//! ComponentTypedBufferViewClient).
struct ComponentTypedBufferViewClient : public BufferViewClient {
ComponentType componentType; //!< The datatype of components in the attribute. (required)
unsigned int GetBytesPerComponent();
void Read(Value &obj, Asset &r);
};
//! A typed view into a BufferView. A BufferView contains raw binary data. //! A typed view into a BufferView. A BufferView contains raw binary data.
//! An accessor provides a typed view into a BufferView or a subset of a BufferView //! An accessor provides a typed view into a BufferView or a subset of a BufferView
//! similar to how WebGL's vertexAttribPointer() defines an attribute in a buffer. //! similar to how WebGL's vertexAttribPointer() defines an attribute in a buffer.
struct Accessor : public Object { struct Accessor : public ComponentTypedBufferViewClient {
Ref<BufferView> bufferView; //!< The ID of the bufferView. (required) struct Sparse;
size_t byteOffset; //!< The offset relative to the start of the bufferView in bytes. (required)
ComponentType componentType; //!< The datatype of components in the attribute. (required)
size_t count; //!< The number of attributes referenced by this accessor. (required) size_t count; //!< The number of attributes referenced by this accessor. (required)
AttribType::Value type; //!< Specifies if the attribute is a scalar, vector, or matrix. (required) AttribType::Value type; //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
std::vector<double> max; //!< Maximum value of each component in this attribute. std::vector<double> max; //!< Maximum value of each component in this attribute.
std::vector<double> min; //!< Minimum value of each component in this attribute. std::vector<double> min; //!< Minimum value of each component in this attribute.
std::unique_ptr<Sparse> sparse; //!< Sparse accessor information
unsigned int GetNumComponents(); unsigned int GetNumComponents();
unsigned int GetBytesPerComponent();
unsigned int GetElementSize(); unsigned int GetElementSize();
inline uint8_t *GetPointer(); inline uint8_t *GetPointer();
@ -417,11 +441,61 @@ struct Accessor : public Object {
} }
}; };
//! Sparse accessor information
struct Sparse {
size_t count;
ComponentTypedBufferViewClient indices;
BufferViewClient values;
std::vector<uint8_t> data; //!< Actual data, which may be defaulted to an array of zeros or the original data, with the sparse buffer view applied on top of it.
inline void PopulateData(size_t numBytes, uint8_t *bytes) {
if (bytes) {
data.assign(bytes, bytes + numBytes);
} else {
data.resize(numBytes, 0x00);
}
}
inline void PatchData(unsigned int elementSize)
{
uint8_t *pIndices = indices.GetPointer();
const unsigned int indexSize = indices.GetBytesPerComponent();
uint8_t *indicesEnd = pIndices + count * indexSize;
uint8_t *pValues = values.GetPointer();
while (pIndices != indicesEnd) {
size_t offset;
switch (indices.componentType) {
case ComponentType_UNSIGNED_BYTE:
offset = *pIndices;
break;
case ComponentType_UNSIGNED_SHORT:
offset = *reinterpret_cast<uint16_t *>(pIndices);
break;
case ComponentType_UNSIGNED_INT:
offset = *reinterpret_cast<uint32_t *>(pIndices);
break;
default:
// have fun with float and negative values from signed types as indices.
throw DeadlyImportError("Unsupported component type in index.");
}
offset *= elementSize;
std::memcpy(data.data() + offset, pValues, elementSize);
pValues += elementSize;
pIndices += indexSize;
}
}
};
inline Indexer GetIndexer() { inline Indexer GetIndexer() {
return Indexer(*this); return Indexer(*this);
} }
Accessor() {} Accessor() {}
void Read(Value &obj, Asset &r); void Read(Value &obj, Asset &r);
}; };

View File

@ -551,36 +551,10 @@ inline void BufferView::Read(Value &obj, Asset &r) {
} }
// //
// struct Accessor // struct BufferViewClient
// //
inline void Accessor::Read(Value &obj, Asset &r) { inline uint8_t *BufferViewClient::GetPointer() {
if (Value *bufferViewVal = FindUInt(obj, "bufferView")) {
bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
}
byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0));
componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
count = MemberOrDefault(obj, "count", size_t(0));
const char *typestr;
type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
}
inline unsigned int Accessor::GetNumComponents() {
return AttribType::GetNumComponents(type);
}
inline unsigned int Accessor::GetBytesPerComponent() {
return int(ComponentTypeSize(componentType));
}
inline unsigned int Accessor::GetElementSize() {
return GetNumComponents() * GetBytesPerComponent();
}
inline uint8_t *Accessor::GetPointer() {
if (!bufferView || !bufferView->buffer) return 0; if (!bufferView || !bufferView->buffer) return 0;
uint8_t *basePtr = bufferView->buffer->GetPointer(); uint8_t *basePtr = bufferView->buffer->GetPointer();
if (!basePtr) return 0; if (!basePtr) return 0;
@ -599,6 +573,76 @@ inline uint8_t *Accessor::GetPointer() {
return basePtr + offset; return basePtr + offset;
} }
inline void BufferViewClient::Read(Value &obj, Asset &r) {
if (Value *bufferViewVal = FindUInt(obj, "bufferView")) {
bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
}
byteOffset = MemberOrDefault(obj, "byteOffset", size_t(0));
}
//
// struct ComponentTypedBufferViewClient
//
inline unsigned int ComponentTypedBufferViewClient::GetBytesPerComponent() {
return int(ComponentTypeSize(componentType));
}
inline void ComponentTypedBufferViewClient::Read(Value &obj, Asset &r) {
BufferViewClient::Read(obj, r);
componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
}
//
// struct Accessor
//
inline uint8_t *Accessor::GetPointer() {
if (!sparse) return BufferViewClient::GetPointer();
return sparse->data.data();
}
inline void Accessor::Read(Value &obj, Asset &r) {
ComponentTypedBufferViewClient::Read(obj, r);
count = MemberOrDefault(obj, "count", size_t(0));
const char *typestr;
type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
if (Value *sparseValue = FindObject(obj, "sparse")) {
sparse.reset(new Sparse);
ReadMember(*sparseValue, "count", sparse->count);
if (Value *indicesValue = FindObject(*sparseValue, "indices")) {
sparse->indices.Read(*indicesValue, r);
}
if (Value *valuesValue = FindObject(*sparseValue, "values")) {
sparse->values.Read(*valuesValue, r);
}
const unsigned int elementSize = GetElementSize();
const size_t dataSize = count * elementSize;
sparse->PopulateData(dataSize, BufferViewClient::GetPointer());
sparse->PatchData(elementSize);
}
}
inline unsigned int Accessor::GetNumComponents() {
return AttribType::GetNumComponents(type);
}
inline unsigned int Accessor::GetElementSize() {
return GetNumComponents() * GetBytesPerComponent();
}
namespace { namespace {
inline void CopyData(size_t count, inline void CopyData(size_t count,
const uint8_t *src, size_t src_stride, const uint8_t *src, size_t src_stride,
@ -635,7 +679,7 @@ void Accessor::ExtractData(T *&outData)
const size_t targetElemSize = sizeof(T); const size_t targetElemSize = sizeof(T);
ai_assert(elemSize <= targetElemSize); ai_assert(elemSize <= targetElemSize);
ai_assert(count * stride <= bufferView->byteLength); ai_assert(count * stride <= (bufferView ? bufferView->byteLength : sparse->data.size()));
outData = new T[count]; outData = new T[count];
if (stride == elemSize && targetElemSize == elemSize) { if (stride == elemSize && targetElemSize == elemSize) {
@ -1002,7 +1046,7 @@ inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) {
// Valid attribute semantics include POSITION, NORMAL, TANGENT // Valid attribute semantics include POSITION, NORMAL, TANGENT
int undPos = 0; int undPos = 0;
Mesh::AccessorList *vec = 0; Mesh::AccessorList *vec = 0;
if (GetAttribTargetVector(prim, i, attr, vec, undPos)) { if (GetAttribTargetVector(prim, j, attr, vec, undPos)) {
size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0; size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
if ((*vec).size() <= idx) { if ((*vec).size() <= idx) {
(*vec).resize(idx + 1); (*vec).resize(idx + 1);
@ -1067,10 +1111,10 @@ inline void Camera::Read(Value &obj, Asset & /*r*/) {
cameraProperties.perspective.zfar = MemberOrDefault(*it, "zfar", 100.f); cameraProperties.perspective.zfar = MemberOrDefault(*it, "zfar", 100.f);
cameraProperties.perspective.znear = MemberOrDefault(*it, "znear", 0.01f); cameraProperties.perspective.znear = MemberOrDefault(*it, "znear", 0.01f);
} else { } else {
cameraProperties.ortographic.xmag = MemberOrDefault(obj, "xmag", 1.f); cameraProperties.ortographic.xmag = MemberOrDefault(*it, "xmag", 1.f);
cameraProperties.ortographic.ymag = MemberOrDefault(obj, "ymag", 1.f); cameraProperties.ortographic.ymag = MemberOrDefault(*it, "ymag", 1.f);
cameraProperties.ortographic.zfar = MemberOrDefault(obj, "zfar", 100.f); cameraProperties.ortographic.zfar = MemberOrDefault(*it, "zfar", 100.f);
cameraProperties.ortographic.znear = MemberOrDefault(obj, "znear", 0.01f); cameraProperties.ortographic.znear = MemberOrDefault(*it, "znear", 0.01f);
} }
} }

View File

@ -1,4 +1,4 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------

View File

@ -45,10 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "CInterfaceIOWrapper.h" #include "CInterfaceIOWrapper.h"
namespace Assimp { namespace Assimp {
CIOStreamWrapper::~CIOStreamWrapper(void) CIOStreamWrapper::~CIOStreamWrapper(void) {
{
/* Various places depend on this destructor to close the file */ /* Various places depend on this destructor to close the file */
if (mFile) { if (mFile) {
mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile); mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile);
@ -57,28 +56,25 @@ CIOStreamWrapper::~CIOStreamWrapper(void)
} }
// ................................................................... // ...................................................................
size_t CIOStreamWrapper::Read(void* pvBuffer, size_t CIOStreamWrapper::Read(void *pvBuffer,
size_t pSize, size_t pSize,
size_t pCount size_t pCount) {
){
// need to typecast here as C has no void* // need to typecast here as C has no void*
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount); return mFile->ReadProc(mFile, (char *)pvBuffer, pSize, pCount);
} }
// ................................................................... // ...................................................................
size_t CIOStreamWrapper::Write(const void* pvBuffer, size_t CIOStreamWrapper::Write(const void *pvBuffer,
size_t pSize, size_t pSize,
size_t pCount size_t pCount) {
){
// need to typecast here as C has no void* // need to typecast here as C has no void*
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount); return mFile->WriteProc(mFile, (const char *)pvBuffer, pSize, pCount);
} }
// ................................................................... // ...................................................................
aiReturn CIOStreamWrapper::Seek(size_t pOffset, aiReturn CIOStreamWrapper::Seek(size_t pOffset,
aiOrigin pOrigin aiOrigin pOrigin) {
){ return mFile->SeekProc(mFile, pOffset, pOrigin);
return mFile->SeekProc(mFile,pOffset,pOrigin);
} }
// ................................................................... // ...................................................................
@ -92,16 +88,16 @@ size_t CIOStreamWrapper::FileSize() const {
} }
// ................................................................... // ...................................................................
void CIOStreamWrapper::Flush () { void CIOStreamWrapper::Flush() {
return mFile->FlushProc(mFile); return mFile->FlushProc(mFile);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API // Custom IOStream implementation for the C-API
bool CIOSystemWrapper::Exists( const char* pFile) const { bool CIOSystemWrapper::Exists(const char *pFile) const {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb"); aiFile *p = mFileSystem->OpenProc(mFileSystem, pFile, "rb");
if (p){ if (p) {
mFileSystem->CloseProc(mFileSystem,p); mFileSystem->CloseProc(mFileSystem, p);
return true; return true;
} }
return false; return false;
@ -117,8 +113,8 @@ char CIOSystemWrapper::getOsSeparator() const {
} }
// ................................................................... // ...................................................................
IOStream* CIOSystemWrapper::Open(const char* pFile,const char* pMode) { IOStream *CIOSystemWrapper::Open(const char *pFile, const char *pMode) {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode); aiFile *p = mFileSystem->OpenProc(mFileSystem, pFile, pMode);
if (!p) { if (!p) {
return NULL; return NULL;
} }
@ -126,11 +122,11 @@ IOStream* CIOSystemWrapper::Open(const char* pFile,const char* pMode) {
} }
// ................................................................... // ...................................................................
void CIOSystemWrapper::Close( IOStream* pFile) { void CIOSystemWrapper::Close(IOStream *pFile) {
if (!pFile) { if (!pFile) {
return; return;
} }
delete pFile; delete pFile;
} }
} } // namespace Assimp

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -50,50 +48,47 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/IOStream.hpp> #include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp> #include <assimp/IOSystem.hpp>
namespace Assimp { namespace Assimp {
class CIOSystemWrapper; class CIOSystemWrapper;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API // Custom IOStream implementation for the C-API
class CIOStreamWrapper : public IOStream class CIOStreamWrapper : public IOStream {
{
public: public:
explicit CIOStreamWrapper(aiFile* pFile, CIOSystemWrapper* io) explicit CIOStreamWrapper(aiFile *pFile, CIOSystemWrapper *io) :
: mFile(pFile), mFile(pFile),
mIO(io) mIO(io) {}
{}
~CIOStreamWrapper(void); ~CIOStreamWrapper(void);
size_t Read(void* pvBuffer, size_t pSize, size_t pCount); size_t Read(void *pvBuffer, size_t pSize, size_t pCount);
size_t Write(const void* pvBuffer, size_t pSize, size_t pCount); size_t Write(const void *pvBuffer, size_t pSize, size_t pCount);
aiReturn Seek(size_t pOffset, aiOrigin pOrigin); aiReturn Seek(size_t pOffset, aiOrigin pOrigin);
size_t Tell(void) const; size_t Tell(void) const;
size_t FileSize() const; size_t FileSize() const;
void Flush(); void Flush();
private: private:
aiFile* mFile; aiFile *mFile;
CIOSystemWrapper* mIO; CIOSystemWrapper *mIO;
}; };
class CIOSystemWrapper : public IOSystem class CIOSystemWrapper : public IOSystem {
{
friend class CIOStreamWrapper; friend class CIOStreamWrapper;
public:
explicit CIOSystemWrapper(aiFileIO* pFile)
: mFileSystem(pFile)
{}
bool Exists( const char* pFile) const; public:
explicit CIOSystemWrapper(aiFileIO *pFile) :
mFileSystem(pFile) {}
bool Exists(const char *pFile) const;
char getOsSeparator() const; char getOsSeparator() const;
IOStream* Open(const char* pFile,const char* pMode = "rb"); IOStream *Open(const char *pFile, const char *pMode = "rb");
void Close( IOStream* pFile); void Close(IOStream *pFile);
private: private:
aiFileIO* mFileSystem; aiFileIO *mFileSystem;
}; };
} } // namespace Assimp
#endif #endif

View File

@ -66,6 +66,7 @@ SET( PUBLIC_HEADERS
${HEADER_PATH}/color4.h ${HEADER_PATH}/color4.h
${HEADER_PATH}/color4.inl ${HEADER_PATH}/color4.inl
${CMAKE_CURRENT_BINARY_DIR}/../include/assimp/config.h ${CMAKE_CURRENT_BINARY_DIR}/../include/assimp/config.h
${HEADER_PATH}/ColladaMetaData.h
${HEADER_PATH}/commonMetaData.h ${HEADER_PATH}/commonMetaData.h
${HEADER_PATH}/defs.h ${HEADER_PATH}/defs.h
${HEADER_PATH}/Defines.h ${HEADER_PATH}/Defines.h
@ -1232,7 +1233,7 @@ if (APPLE)
# add ./Compiler/*.h to assimp.framework via copy command # add ./Compiler/*.h to assimp.framework via copy command
ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_directory COMMAND "${CMAKE_COMMAND}" -E copy_directory
"../${HEADER_PATH}/Compiler" "${HEADER_PATH}/Compiler"
assimp.framework/Headers/Compiler assimp.framework/Headers/Compiler
COMMENT "Copying public ./Compiler/ header files to framework bundle's Headers/Compiler/") COMMENT "Copying public ./Compiler/ header files to framework bundle's Headers/Compiler/")
ENDIF() ENDIF()

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -109,4 +109,4 @@ public:
} // Namespace Assimp } // Namespace Assimp
#endif // SCALE_PROCESS_H_ #endif // SCALE_PROCESS_H_

View File

@ -94,4 +94,4 @@ private:
} // Namespace Assimp } // Namespace Assimp
#endif // SCALE_PROCESS_H_ #endif // SCALE_PROCESS_H_

View File

@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits> #include <limits>
#include <assimp/TinyFormatter.h> #include <assimp/TinyFormatter.h>
#include <assimp/Exceptional.h> #include <assimp/Exceptional.h>
#include <set>
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
@ -172,7 +173,15 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
const aiBone* bone = pMesh->mBones[a]; const aiBone* bone = pMesh->mBones[a];
for( unsigned int b = 0; b < bone->mNumWeights; ++b) for( unsigned int b = 0; b < bone->mNumWeights; ++b)
{ {
vertexBones[ bone->mWeights[b].mVertexId ].push_back( BoneWeight( a, bone->mWeights[b].mWeight)); if (bone->mWeights[b].mWeight > 0.0f)
{
int vertexId = bone->mWeights[b].mVertexId;
vertexBones[vertexId].push_back( BoneWeight( a, bone->mWeights[b].mWeight));
if (vertexBones[vertexId].size() > mMaxBoneCount)
{
throw DeadlyImportError("SplitByBoneCountProcess: Single face requires more bones than specified max bone count!");
}
}
} }
} }
@ -188,9 +197,6 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
subMeshFaces.reserve( pMesh->mNumFaces); subMeshFaces.reserve( pMesh->mNumFaces);
// accumulated vertex count of all the faces in this submesh // accumulated vertex count of all the faces in this submesh
unsigned int numSubMeshVertices = 0; unsigned int numSubMeshVertices = 0;
// a small local array of new bones for the current face. State of all used bones for that face
// can only be updated AFTER the face is completely analysed. Thanks to imre for the fix.
std::vector<unsigned int> newBonesAtCurrentFace;
// add faces to the new submesh as long as all bones affecting the faces' vertices fit in the limit // add faces to the new submesh as long as all bones affecting the faces' vertices fit in the limit
for( unsigned int a = 0; a < pMesh->mNumFaces; ++a) for( unsigned int a = 0; a < pMesh->mNumFaces; ++a)
@ -200,33 +206,25 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
{ {
continue; continue;
} }
// a small local set of new bones for the current face. State of all used bones for that face
// can only be updated AFTER the face is completely analysed. Thanks to imre for the fix.
std::set<unsigned int> newBonesAtCurrentFace;
const aiFace& face = pMesh->mFaces[a]; const aiFace& face = pMesh->mFaces[a];
// check every vertex if its bones would still fit into the current submesh // check every vertex if its bones would still fit into the current submesh
for( unsigned int b = 0; b < face.mNumIndices; ++b ) for( unsigned int b = 0; b < face.mNumIndices; ++b )
{ {
const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]]; const std::vector<BoneWeight>& vb = vertexBones[face.mIndices[b]];
for( unsigned int c = 0; c < vb.size(); ++c) for( unsigned int c = 0; c < vb.size(); ++c)
{
unsigned int boneIndex = vb[c].first;
if( !isBoneUsed[boneIndex] )
{ {
unsigned int boneIndex = vb[c].first; newBonesAtCurrentFace.insert(boneIndex);
// if the bone is already used in this submesh, it's ok }
if( isBoneUsed[boneIndex] ) }
{
continue;
}
// if it's not used, yet, we would need to add it. Store its bone index
if( std::find( newBonesAtCurrentFace.begin(), newBonesAtCurrentFace.end(), boneIndex) == newBonesAtCurrentFace.end() )
{
newBonesAtCurrentFace.push_back( boneIndex);
}
}
} }
if (newBonesAtCurrentFace.size() > mMaxBoneCount)
{
throw DeadlyImportError("SplitByBoneCountProcess: Single face requires more bones than specified max bone count!");
}
// leave out the face if the new bones required for this face don't fit the bone count limit anymore // leave out the face if the new bones required for this face don't fit the bone count limit anymore
if( numBones + newBonesAtCurrentFace.size() > mMaxBoneCount ) if( numBones + newBonesAtCurrentFace.size() > mMaxBoneCount )
{ {
@ -234,17 +232,13 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
} }
// mark all new bones as necessary // mark all new bones as necessary
while( !newBonesAtCurrentFace.empty() ) for (std::set<unsigned int>::iterator it = newBonesAtCurrentFace.begin(); it != newBonesAtCurrentFace.end(); ++it)
{ {
unsigned int newIndex = newBonesAtCurrentFace.back(); if (!isBoneUsed[*it])
newBonesAtCurrentFace.pop_back(); // this also avoids the deallocation which comes with a clear() {
if( isBoneUsed[newIndex] ) isBoneUsed[*it] = true;
{
continue;
}
isBoneUsed[newIndex] = true;
numBones++; numBones++;
}
} }
// store the face index and the vertex count // store the face index and the vertex count

View File

@ -1,4 +1,4 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -1,4 +1,4 @@
/* /*
Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc. Copyright (c) 2013 Khaled Mammou - Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy

View File

@ -237,4 +237,4 @@ The _android-cmake_ should correctly handle projects with assembler sources (`*.
## Copying ## Copying
_android-cmake_ is distributed under the terms of [BSD 3-Clause License](http://opensource.org/licenses/BSD-3-Clause) _android-cmake_ is distributed under the terms of [BSD 3-Clause License](http://opensource.org/licenses/BSD-3-Clause)

View File

@ -11,4 +11,4 @@ documentation for that specific version instead.**
To contribute code to Google Test, read: To contribute code to Google Test, read:
* [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch.
* [PumpManual](PumpManual.md) -- how we generate some of Google Test's source files. * [PumpManual](PumpManual.md) -- how we generate some of Google Test's source files.

View File

@ -9,4 +9,4 @@ This page lists all official documentation wiki pages for Google Test **1.5.0**
To contribute code to Google Test, read: To contribute code to Google Test, read:
* DevGuide -- read this _before_ writing your first patch. * DevGuide -- read this _before_ writing your first patch.
* [PumpManual](V1_5_PumpManual.md) -- how we generate some of Google Test's source files. * [PumpManual](V1_5_PumpManual.md) -- how we generate some of Google Test's source files.

View File

@ -174,4 +174,4 @@ You can find real-world applications of Pump in [Google Test](http://www.google.
## Tips ## ## Tips ##
* If a meta variable is followed by a letter or digit, you can separate them using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper` generate `Foo1Helper` when `j` is 1. * If a meta variable is followed by a letter or digit, you can separate them using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper` generate `Foo1Helper` when `j` is 1.
* To avoid extra-long Pump source lines, you can break a line anywhere you want by inserting `[[]]` followed by a new line. Since any new-line character next to `[[` or `]]` is ignored, the generated code won't contain this new line. * To avoid extra-long Pump source lines, you can break a line anywhere you want by inserting `[[]]` followed by a new line. Since any new-line character next to `[[` or `]]` is ignored, the generated code won't contain this new line.

View File

@ -90,4 +90,4 @@ The Debugger has exited with status 0.
# Summary # # Summary #
Unit testing is a valuable way to ensure your data model stays valid even during rapid development or refactoring. The Google Testing Framework is a great unit testing framework for C and C++ which integrates well with an Xcode development environment. Unit testing is a valuable way to ensure your data model stays valid even during rapid development or refactoring. The Google Testing Framework is a great unit testing framework for C and C++ which integrates well with an Xcode development environment.

View File

@ -11,4 +11,4 @@ documentation for that specific version instead.**
To contribute code to Google Test, read: To contribute code to Google Test, read:
* [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch.
* [PumpManual](V1_6_PumpManual.md) -- how we generate some of Google Test's source files. * [PumpManual](V1_6_PumpManual.md) -- how we generate some of Google Test's source files.

View File

@ -90,4 +90,4 @@ The Debugger has exited with status 0.
# Summary # # Summary #
Unit testing is a valuable way to ensure your data model stays valid even during rapid development or refactoring. The Google Testing Framework is a great unit testing framework for C and C++ which integrates well with an Xcode development environment. Unit testing is a valuable way to ensure your data model stays valid even during rapid development or refactoring. The Google Testing Framework is a great unit testing framework for C and C++ which integrates well with an Xcode development environment.

View File

@ -11,4 +11,4 @@ documentation for that specific version instead.**
To contribute code to Google Test, read: To contribute code to Google Test, read:
* [DevGuide](DevGuide.md) -- read this _before_ writing your first patch. * [DevGuide](DevGuide.md) -- read this _before_ writing your first patch.
* [PumpManual](V1_7_PumpManual.md) -- how we generate some of Google Test's source files. * [PumpManual](V1_7_PumpManual.md) -- how we generate some of Google Test's source files.

View File

@ -90,4 +90,4 @@ The Debugger has exited with status 0.
# Summary # # Summary #
Unit testing is a valuable way to ensure your data model stays valid even during rapid development or refactoring. The Google Testing Framework is a great unit testing framework for C and C++ which integrates well with an Xcode development environment. Unit testing is a valuable way to ensure your data model stays valid even during rapid development or refactoring. The Google Testing Framework is a great unit testing framework for C and C++ which integrates well with an Xcode development environment.

View File

@ -90,4 +90,4 @@ The Debugger has exited with status 0.
# Summary # # Summary #
Unit testing is a valuable way to ensure your data model stays valid even during rapid development or refactoring. The Google Testing Framework is a great unit testing framework for C and C++ which integrates well with an Xcode development environment. Unit testing is a valuable way to ensure your data model stays valid even during rapid development or refactoring. The Google Testing Framework is a great unit testing framework for C and C++ which integrates well with an Xcode development environment.

View File

@ -1,4 +1,4 @@
================== ==================
INSTALLATION GUIDE INSTALLATION GUIDE
================== ==================
@ -48,4 +48,4 @@ Examples:
./p2t nazca_monkey.dat 0 0 9 ./p2t nazca_monkey.dat 0 0 9
./p2t random 10 100 5.0 ./p2t random 10 100 5.0
./p2t random 1000 20000 0.025 ./p2t random 1000 20000 0.025

View File

@ -362,4 +362,4 @@ void Triangle::DebugPrint()
cout << points_[2]->x << "," << points_[2]->y << endl; cout << points_[2]->x << "," << points_[2]->y << endl;
} }
} }

View File

@ -324,4 +324,4 @@ inline void Triangle::IsInterior(bool b)
} }
#endif #endif

View File

@ -35,4 +35,4 @@
#include "common/shapes.h" #include "common/shapes.h"
#include "sweep/cdt.h" #include "sweep/cdt.h"
#endif #endif

View File

@ -105,4 +105,4 @@ AdvancingFront::~AdvancingFront()
{ {
} }
} }

View File

@ -115,4 +115,4 @@ inline void AdvancingFront::set_search(Node* node)
} }
#endif #endif

View File

@ -68,4 +68,4 @@ CDT::~CDT()
delete sweep_; delete sweep_;
} }
} }

View File

@ -102,4 +102,4 @@ public:
} }
#endif #endif

View File

@ -282,4 +282,4 @@ private:
} }
#endif #endif

View File

@ -7459,4 +7459,4 @@ AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
*/ */

View File

@ -15,4 +15,4 @@ else
make -j 8 make -j 8
make install make install
ASAN_OPTIONS=detect_leaks=0 LSAN_OPTIONS=verbosity=1:log_threads=1 ctest -V ASAN_OPTIONS=detect_leaks=0 LSAN_OPTIONS=verbosity=1:log_threads=1 ctest -V
fi fi

View File

@ -19,4 +19,4 @@ after_success:
- make - make
- make test - make test
# Uploading report to CodeCov # Uploading report to CodeCov
- bash <(curl -s https://codecov.io/bash) - bash <(curl -s https://codecov.io/bash)

View File

@ -196,10 +196,7 @@ if(MINGW)
set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
endif(MINGW) endif(MINGW)
add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
set_target_properties(zlib PROPERTIES SOVERSION 1)
INSTALL( TARGETS zlibstatic INSTALL( TARGETS zlibstatic
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR} LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}

View File

@ -1 +1 @@
AIAIAIAIAIAIA AIAIAIAIAIAIA

View File

@ -20,4 +20,4 @@ FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE. DEALINGS IN THE SOFTWARE.

View File

@ -7,4 +7,4 @@ copy to a directory file from :
- contrib/masmx64 - contrib/masmx64
- contrib/vstudio/vc7 - contrib/vstudio/vc7
and open testzlib8.sln and open testzlib8.sln

View File

@ -8,4 +8,4 @@ This is a heavily modified and shrinked version of zlib 1.2.3
Assimp itself does not use the compression part yet, so Assimp itself does not use the compression part yet, so
it needn't be compiled (trees.c, deflate.c, compress.c). it needn't be compiled (trees.c, deflate.c, compress.c).
Currently these units are just used by assimp_cmd. Currently these units are just used by assimp_cmd.

View File

@ -351,4 +351,4 @@ BI8AxOURXedNEuG6jMiRPHKQsuuS4BGAuDzS0NCQlZV18JFlRI7qkRRdlwSPAHzCIynKaa5LgkcA
ETwCgEfwCAAewSMAeASP4BEAPIJHAPAIHgFItrEBsYNHAD7BK4gZPAKAR/AIAB7BIwCQBvwfU/j0 ETwCgEfwCAAewSMAeASP4BEAPIJHAPAIHgFItrEBsYNHAD7BK4gZPAKAR/AIAB7BIwCQBvwfU/j0
jy2hMWgAAAAASUVORK5C" /> jy2hMWgAAAAASUVORK5C" />
</BODY> </BODY>
</HTML> </HTML>

View File

@ -645,4 +645,4 @@ tQ2gtkFtg9oGQG2jtkFtA6C2UduA2gZQ26C2QW0DoLZR26C2AVDbqG1AbQMoKg8CahvUNgBqG7UN
ahsAtY3aBtQ2AGobtQ1qGwC1jdoGtQ2A2kZtA2obALWN2ga1DUA1igr2o7ZBbQPw0/wD+/DsALUN ahsAtY3aBtQ2AGobtQ1qGwC1jdoGtQ2A2kZtA2obALWN2ga1DUA1igr2o7ZBbQPw0/wD+/DsALUN
gNpGbYPaBkBto7ZBbQMAAD/R/wDNluGGIxSgmAAAAABJRU5ErkJg" /> gNpGbYPaBkBto7ZBbQMAAD/R/wDNluGGIxSgmAAAAABJRU5ErkJg" />
</BODY> </BODY>
</HTML> </HTML>

View File

@ -104,4 +104,4 @@ tfMWuhaZfgHUw0Q32sDAwIcPH4I/C1fbaJVKRX0GBwft4RA5hXdkNepJqndpKD2R7TlrjeqmxkKh
oLOf5O8VrfC7XlrtOvYCO77PYocddthhhx122GGHHXbYYYcddthhhx122GGHHXbYYYdd29q1c83s oLOf5O8VrfC7XlrtOvYCO77PYocddthhhx122GGHHXbYYYcddthhhx122GGHHXbYYYdd29q1c83s
I9m5B21Yuxg77FJtRzQV/wEjVLA5JUDyfgAAAABJRU5ErkJg" /> I9m5B21Yuxg77FJtRzQV/wEjVLA5JUDyfgAAAABJRU5ErkJg" />
</BODY> </BODY>
</HTML> </HTML>

View File

@ -872,4 +872,4 @@ DYMQQgghNAxCCCGEEBoGIYQQQmgYhBBCCKFhEEIIIYTQMAghhBBCwyCEEEIIDYMQQgghNAxCCCGE
EBoGIYQQQmgYhBBCCKFhEEIIIYTQMAghhBBCwyCEEEJI/PP/A0zci3P89Qf2AAAAAElFTkSuQmCC EBoGIYQQQmgYhBBCCKFhEEIIIYTQMAghhBBCwyCEEEJI/PP/A0zci3P89Qf2AAAAAElFTkSuQmCC
" /> " />
</BODY> </BODY>
</HTML> </HTML>

View File

@ -334,4 +334,4 @@ CQCsyZpgTQCsyZpgTQCsyZpgTQCsyZpgTQCsCdZkTQBgTdZkTQBgTdZkTQBgTdYEawJgTdYEawJg
TdYEawJgTbAmawIAa7ImawIAa7ImawIAa7ImWBMAa7ImWBMAa7ImWBPAvDIByoc1WRMA/uU3lI1q TdYEawJgTbAmawIAa7ImawIAa7ImawIAa7ImWBMAa7ImWBMAa7ImWBPAvDIByoc1WRMA/uU3lI1q
YU0ArAnWZE0AYE3WZE0AABY4/wVVY1WTrOVxIAAAAABJRU5ErkJg" /> YU0ArAnWZE0AYE3WZE0AABY4/wVVY1WTrOVxIAAAAABJRU5ErkJg" />
</BODY> </BODY>
</HTML> </HTML>

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team Copyright (c) 2006-2020, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -40,30 +38,19 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
#include <assimp/cimport.h>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#pragma once extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataSize) {
aiLogStream stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
aiAttachLogStream(&stream);
#ifndef ASSIMP_BUILD_NO_STEP_IMPORTER Importer importer;
const aiScene *sc = importer.ReadFileFromMemory(data, dataSize,
aiProcessPreset_TargetRealtime_Quality, nullptr );
#include <assimp/BaseImporter.h> aiDetachLogStream(&stream);
namespace Assimp { return 0;
namespace StepFile { }
class StepFileImporter : public BaseImporter {
public:
StepFileImporter();
~StepFileImporter();
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const override;
const aiImporterDesc* GetInfo() const override;
protected:
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler ) override;
private:
};
} // Namespace StepFile
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_STEP_IMPORTER

View File

@ -0,0 +1,53 @@
/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file ColladaMetaData.h
* Declares common metadata constants used by Collada files
*/
#pragma once
#ifndef AI_COLLADAMETADATA_H_INC
#define AI_COLLADAMETADATA_H_INC
#define AI_METADATA_COLLADA_ID "Collada_id"
#define AI_METADATA_COLLADA_SID "Collada_sid"
#endif

View File

@ -1030,10 +1030,10 @@ enum aiComponent
#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION" #define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** @brief Specifies whether the Collada loader should use Collada names as node names. /** @brief Specifies whether the Collada loader should use Collada names.
* *
* If this property is set to true, the Collada names will be used as the * If this property is set to true, the Collada names will be used as the node and
* node name. The default is to use the id tag (resp. sid tag, if no id tag is present) * mesh names. The default is to use the id tag (resp. sid tag, if no id tag is present)
* instead. * instead.
* Property type: Bool. Default value: false. * Property type: Bool. Default value: false.
*/ */

View File

@ -1,4 +1,4 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

View File

@ -1,8 +1,6 @@
Project home page: Project home page:
http://assimp.sourceforge.net http://assimp.sourceforge.net
Sourceforge.net project page: Sourceforge.net project page:
http://www.sourceforge.net/projects/assimp http://www.sourceforge.net/projects/assimp

View File

@ -29,4 +29,4 @@ Reinstall Microsoft Visual C++ 2005 SP1 Redistributable (x86 or x64, depending o
Add it to PATH. That's not a bug, the installer does not alter the PATH. Add it to PATH. That's not a bug, the installer does not alter the PATH.
4. Crashes immediately 4. Crashes immediately
You CPU lacks SSE2 support. Build Assimp from scratch to suit your CPU, sorry. You CPU lacks SSE2 support. Build Assimp from scratch to suit your CPU, sorry.

View File

@ -26,4 +26,4 @@ Install the latest DirectX runtime or grab the file from somewhere (that's evil
(Re)install Microsoft Visual C++ 2005 SP1 Redistributable (x86 or x64, depending on your system) (Re)install Microsoft Visual C++ 2005 SP1 Redistributable (x86 or x64, depending on your system)
3. Crashes immediately 3. Crashes immediately
You CPU lacks SSE2 support. Build Assimp from scratch to suit your CPU, sorry. You CPU lacks SSE2 support. Build Assimp from scratch to suit your CPU, sorry.

View File

@ -1,11 +1,11 @@
#-*- coding: UTF-8 -*- #-*- coding: UTF-8 -*-
""" """
All possible errors. All possible errors.
""" """
class AssimpError(BaseException): class AssimpError(BaseException):
""" """
If an internal error occurs. If an internal error occurs.
""" """
pass pass

View File

@ -172,4 +172,4 @@ public final class AiAnimation {
public List<AiMeshAnim> getMeshChannels() { public List<AiMeshAnim> getMeshChannels() {
throw new UnsupportedOperationException("not implemented yet"); throw new UnsupportedOperationException("not implemented yet");
} }
} }

View File

@ -114,4 +114,4 @@ public enum AiBlendMode {
* The mapped c/c++ integer enum value. * The mapped c/c++ integer enum value.
*/ */
private final int m_rawValue; private final int m_rawValue;
} }

View File

@ -300,4 +300,4 @@ public final class AiCamera {
* Aspect ratio. * Aspect ratio.
*/ */
private final float m_aspect; private final float m_aspect;
} }

View File

@ -43,4 +43,4 @@ package jassimp;
public interface AiProgressHandler public interface AiProgressHandler
{ {
boolean update(float percentage); boolean update(float percentage);
} }

View File

@ -162,4 +162,4 @@ public final class AiQuaternion {
return "[" + getX() + ", " + getY() + ", " + getZ() + ", " + return "[" + getX() + ", " + getY() + ", " + getZ() + ", " +
getW() + "]"; getW() + "]";
} }
} }

View File

@ -209,4 +209,4 @@ public enum AiTextureType {
* The mapped c/c++ integer enum value. * The mapped c/c++ integer enum value.
*/ */
private final int m_rawValue; private final int m_rawValue;
} }

View File

@ -1 +1 @@
The interface files are by no means complete yet and only work with the not-yet-released D SWIG backend, although adding support for other languages should not be too much of problem via #ifdefs. The interface files are by no means complete yet and only work with the not-yet-released D SWIG backend, although adding support for other languages should not be too much of problem via #ifdefs.

View File

@ -19,4 +19,4 @@ Troubleshooting:
- OSX workspaces are not updated too frequently, so same files may be missing. - OSX workspaces are not updated too frequently, so same files may be missing.
If you have any problems which you can't solve on your own, If you have any problems which you can't solve on your own,
please report them on the thread above. please report them on the thread above.

View File

@ -1,4 +1,4 @@
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Simple Assimp Directx11 Sample // Simple Assimp Directx11 Sample
// This is a very basic sample and only reads diffuse texture // This is a very basic sample and only reads diffuse texture
// but this can load both embedded textures in fbx and non-embedded textures // but this can load both embedded textures in fbx and non-embedded textures

View File

@ -124,8 +124,7 @@ SET( IMPORTERS
unit/utBlendImportMaterials.cpp unit/utBlendImportMaterials.cpp
unit/utBlenderWork.cpp unit/utBlenderWork.cpp
unit/utBVHImportExport.cpp unit/utBVHImportExport.cpp
unit/utColladaExportCamera.cpp unit/utColladaExport.cpp
unit/utColladaExportLight.cpp
unit/utColladaImportExport.cpp unit/utColladaImportExport.cpp
unit/utCSMImportExport.cpp unit/utCSMImportExport.cpp
unit/utB3DImportExport.cpp unit/utB3DImportExport.cpp

View File

@ -12,4 +12,4 @@ http://xu1productions.com/3dstudio/index.html - 3D Game Resources
http://www.psionicdesign.com - My Main 2D/3D Digital Art site http://www.psionicdesign.com - My Main 2D/3D Digital Art site
Psionic 2002 Psionic 2002

View File

@ -9,4 +9,4 @@ http://www.elektrobar.com/lux/
or mail to: or mail to:
lux@elektrobar.com lux@elektrobar.com
have fun.....VIRLUX have fun.....VIRLUX

View File

@ -22,4 +22,4 @@ tutorials.
INFO INFO
==== ====
CONVERTED FROM 3DS TO ASE WITH AC3D CONVERTED FROM 3DS TO ASE WITH AC3D

View File

@ -21,4 +21,4 @@ tutorials.
INFO INFO
==== ====
CONVERTED FROM 3DS TO ASE WITH AC3D CONVERTED FROM 3DS TO ASE WITH AC3D

View File

@ -8,4 +8,4 @@ RESTRICTIONS:
This model pack is available for use in freeware, shareware, commercial games/software with the following restrictions:- This model pack is available for use in freeware, shareware, commercial games/software with the following restrictions:-
**You may not sell/re-sell this model pack or claim it as your own. **You may not sell/re-sell this model pack or claim it as your own.
***You may not redistribute this pack in some other model pack through a website or on a compilation CD of any kind, without my written consent. ***You may not redistribute this pack in some other model pack through a website or on a compilation CD of any kind, without my written consent.

View File

@ -20,4 +20,4 @@ tutorials.
INFO INFO
==== ====
COnverted from 3ds to DXF with Ac3D COnverted from 3ds to DXF with Ac3D

View File

@ -12,4 +12,4 @@ http://xu1productions.com/3dstudio/index.html - 3D Game Resources
http://www.psionicdesign.com - My Main 2D/3D Digital Art site http://www.psionicdesign.com - My Main 2D/3D Digital Art site
Psionic 2002 Psionic 2002

View File

@ -9,4 +9,4 @@ http://www.elektrobar.com/lux/
or mail to: or mail to:
lux@elektrobar.com lux@elektrobar.com
have fun.....VIRLUX have fun.....VIRLUX

View File

@ -12,4 +12,4 @@ http://xu1productions.com/3dstudio/index.html - 3D Game Resources
http://www.psionicdesign.com - My Main 2D/3D Digital Art site http://www.psionicdesign.com - My Main 2D/3D Digital Art site
Psionic 2002 Psionic 2002

View File

@ -9,4 +9,4 @@ http://www.elektrobar.com/lux/
or mail to: or mail to:
lux@elektrobar.com lux@elektrobar.com
have fun.....VIRLUX have fun.....VIRLUX

View File

@ -1,4 +1,4 @@
Good IFC test cases Good IFC test cases
=================== ===================
http://www.iai.fzk.de/www-extern/index.php?id=1135 http://www.iai.fzk.de/www-extern/index.php?id=1135

View File

@ -28,4 +28,4 @@ INFO
These files belong to the QuickDraw model in the LWS folder - they are referenced These files belong to the QuickDraw model in the LWS folder - they are referenced
and loaded into the LWS scene. and loaded into the LWS scene.

View File

@ -21,4 +21,4 @@ tutorials.
INFO INFO
==== ====
CONVERTED FROM 3DS TO LWO2 WITH AC3D CONVERTED FROM 3DS TO LWO2 WITH AC3D

View File

@ -12,4 +12,4 @@ In the future more 3d formats will be added and some other sections such as wall
CHANGES: CHANGES:
Paths have been modified Paths have been modified

View File

@ -23,4 +23,4 @@ ID software, eskimo roll, EMSIPE, QkenneyQ
DISTRIBUTION DISTRIBUTION
as long as this readme is included...! as long as this readme is included...!
-------------------------------------------------------------------------- --------------------------------------------------------------------------

Some files were not shown because too many files have changed in this diff Show More