Merge branch 'master' into gltf2_fix_skin_recursion
commit
2438e1b52e
|
@ -79,6 +79,12 @@ test/gtest/src/gtest-stamp/Debug/
|
||||||
tools/assimp_view/assimp_viewer.vcxproj.user
|
tools/assimp_view/assimp_viewer.vcxproj.user
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
||||||
|
### Rust ###
|
||||||
|
# Generated by Cargo; will have compiled files and executables
|
||||||
|
port/assimp_rs/target/
|
||||||
|
# Backup files generated by rustfmt
|
||||||
|
port/assimp_rs/**/*.rs.bk
|
||||||
|
|
||||||
# Unix editor backups
|
# Unix editor backups
|
||||||
*~
|
*~
|
||||||
test/gtest/src/gtest-stamp/gtest-gitinfo.txt
|
test/gtest/src/gtest-stamp/gtest-gitinfo.txt
|
||||||
|
|
|
@ -73,6 +73,9 @@ else()
|
||||||
else()
|
else()
|
||||||
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
|
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Import target "assimp::assimp" for configuration "Debug"
|
||||||
|
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
|
IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
|
||||||
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
|
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
|
||||||
|
@ -81,6 +84,9 @@ else()
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
|
||||||
else()
|
else()
|
||||||
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
||||||
|
|
||||||
|
# Import target "assimp::assimp" for configuration "Debug"
|
||||||
|
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
|
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
|
||||||
)
|
)
|
||||||
|
|
|
@ -73,6 +73,9 @@ else()
|
||||||
else()
|
else()
|
||||||
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
|
set(sharedLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@.@ASSIMP_VERSION_MAJOR@")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Import target "assimp::assimp" for configuration "Release"
|
||||||
|
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
|
IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
|
||||||
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
|
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
|
||||||
|
@ -81,6 +84,9 @@ else()
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
|
||||||
else()
|
else()
|
||||||
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
||||||
|
|
||||||
|
# Import target "assimp::assimp" for configuration "Release"
|
||||||
|
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
|
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
|
||||||
)
|
)
|
||||||
|
|
|
@ -117,22 +117,37 @@ static const std::string XMLIDEncode(const std::string &name) {
|
||||||
return idEncoded.str();
|
return idEncoded.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Helper functions to create unique ids
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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),
|
mIOSystem(pIOSystem),
|
||||||
mPath(path),
|
mPath(path),
|
||||||
mFile(file) {
|
mFile(file),
|
||||||
|
mScene(pScene),
|
||||||
|
endstr("\n") {
|
||||||
// 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);
|
||||||
|
|
||||||
mScene = pScene;
|
|
||||||
mSceneOwned = false;
|
|
||||||
|
|
||||||
// set up strings
|
|
||||||
endstr = "\n";
|
|
||||||
|
|
||||||
// start writing the file
|
// start writing the file
|
||||||
WriteFile();
|
WriteFile();
|
||||||
}
|
}
|
||||||
|
@ -140,9 +155,6 @@ ColladaExporter::ColladaExporter(const aiScene *pScene, IOSystem *pIOSystem, con
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor
|
// Destructor
|
||||||
ColladaExporter::~ColladaExporter() {
|
ColladaExporter::~ColladaExporter() {
|
||||||
if (mSceneOwned) {
|
|
||||||
delete mScene;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -171,10 +183,11 @@ void ColladaExporter::WriteFile() {
|
||||||
// customized, Writes the animation library
|
// customized, Writes the animation library
|
||||||
WriteAnimationsLibrary();
|
WriteAnimationsLibrary();
|
||||||
|
|
||||||
// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
|
// instantiate the scene(s)
|
||||||
|
// For Assimp there will only ever be one
|
||||||
mOutput << startstr << "<scene>" << endstr;
|
mOutput << startstr << "<scene>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<instance_visual_scene url=\"#" + GetNodeUniqueId(mScene->mRootNode) + "\" />" << endstr;
|
mOutput << startstr << "<instance_visual_scene url=\"#" + mSceneId + "\" />" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</scene>" << endstr;
|
mOutput << startstr << "</scene>" << endstr;
|
||||||
PopTag();
|
PopTag();
|
||||||
|
@ -209,13 +222,13 @@ void ColladaExporter::WriteHeader() {
|
||||||
mScene->mRootNode->mTransformation.Decompose(scaling, rotation, position);
|
mScene->mRootNode->mTransformation.Decompose(scaling, rotation, position);
|
||||||
rotation.Normalize();
|
rotation.Normalize();
|
||||||
|
|
||||||
bool add_root_node = false;
|
mAdd_root_node = false;
|
||||||
|
|
||||||
ai_real scale = 1.0;
|
ai_real scale = 1.0;
|
||||||
if (std::abs(scaling.x - scaling.y) <= epsilon && std::abs(scaling.x - scaling.z) <= epsilon && std::abs(scaling.y - scaling.z) <= epsilon) {
|
if (std::abs(scaling.x - scaling.y) <= epsilon && std::abs(scaling.x - scaling.z) <= epsilon && std::abs(scaling.y - scaling.z) <= epsilon) {
|
||||||
scale = (ai_real)((((double)scaling.x) + ((double)scaling.y) + ((double)scaling.z)) / 3.0);
|
scale = (ai_real)((((double)scaling.x) + ((double)scaling.y) + ((double)scaling.z)) / 3.0);
|
||||||
} else {
|
} else {
|
||||||
add_root_node = true;
|
mAdd_root_node = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string up_axis = "Y_UP";
|
std::string up_axis = "Y_UP";
|
||||||
|
@ -226,33 +239,19 @@ void ColladaExporter::WriteHeader() {
|
||||||
} else if (rotation.Equal(z_rot, epsilon)) {
|
} else if (rotation.Equal(z_rot, epsilon)) {
|
||||||
up_axis = "Z_UP";
|
up_axis = "Z_UP";
|
||||||
} else {
|
} else {
|
||||||
add_root_node = true;
|
mAdd_root_node = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!position.Equal(aiVector3D(0, 0, 0))) {
|
if (!position.Equal(aiVector3D(0, 0, 0))) {
|
||||||
add_root_node = true;
|
mAdd_root_node = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mScene->mRootNode->mNumChildren == 0) {
|
// Assimp root nodes can have meshes, Collada Scenes cannot
|
||||||
add_root_node = true;
|
if (mScene->mRootNode->mNumChildren == 0 || mScene->mRootNode->mMeshes != 0) {
|
||||||
|
mAdd_root_node = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_root_node) {
|
if (mAdd_root_node) {
|
||||||
aiScene *scene;
|
|
||||||
SceneCombiner::CopyScene(&scene, mScene);
|
|
||||||
|
|
||||||
aiNode *root = new aiNode("Scene");
|
|
||||||
|
|
||||||
root->mNumChildren = 1;
|
|
||||||
root->mChildren = new aiNode *[root->mNumChildren];
|
|
||||||
|
|
||||||
root->mChildren[0] = scene->mRootNode;
|
|
||||||
scene->mRootNode->mParent = root;
|
|
||||||
scene->mRootNode = root;
|
|
||||||
|
|
||||||
mScene = scene;
|
|
||||||
mSceneOwned = true;
|
|
||||||
|
|
||||||
up_axis = "Y_UP";
|
up_axis = "Y_UP";
|
||||||
scale = 1.0;
|
scale = 1.0;
|
||||||
}
|
}
|
||||||
|
@ -1226,17 +1225,29 @@ 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 sceneId = GetNodeUniqueId(mScene->mRootNode);
|
// Determine if we are using the aiScene root or our own
|
||||||
const std::string sceneName = GetNodeName(mScene->mRootNode);
|
std::string sceneName("Scene");
|
||||||
|
if (mAdd_root_node) {
|
||||||
|
mSceneId = MakeUniqueId(mUniqueIds, sceneName, std::string());
|
||||||
|
mUniqueIds.insert(mSceneId);
|
||||||
|
} else {
|
||||||
|
mSceneId = GetNodeUniqueId(mScene->mRootNode);
|
||||||
|
sceneName = GetNodeName(mScene->mRootNode);
|
||||||
|
}
|
||||||
|
|
||||||
mOutput << startstr << "<library_visual_scenes>" << endstr;
|
mOutput << startstr << "<library_visual_scenes>" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
mOutput << startstr << "<visual_scene id=\"" + sceneId + "\" name=\"" + sceneName + "\">" << endstr;
|
mOutput << startstr << "<visual_scene id=\"" + mSceneId + "\" name=\"" + sceneName + "\">" << endstr;
|
||||||
PushTag();
|
PushTag();
|
||||||
|
|
||||||
// start recursive write at the root node
|
if (mAdd_root_node) {
|
||||||
|
// Export the root node
|
||||||
|
WriteNode(mScene->mRootNode);
|
||||||
|
} else {
|
||||||
|
// Have already exported 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->mRootNode->mChildren[a]);
|
WriteNode(mScene->mRootNode->mChildren[a]);
|
||||||
|
}
|
||||||
|
|
||||||
PopTag();
|
PopTag();
|
||||||
mOutput << startstr << "</visual_scene>" << endstr;
|
mOutput << startstr << "</visual_scene>" << endstr;
|
||||||
|
@ -1493,12 +1504,9 @@ void ColladaExporter::WriteNode(const aiNode *pNode) {
|
||||||
const std::string node_name = GetNodeName(pNode);
|
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.
|
mFoundSkeletonRootNodeID = node_id; // For now, only support one skeleton in a scene.
|
||||||
mFoundSkeletonRootNodeID = node_id;
|
|
||||||
} 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;
|
||||||
|
@ -1612,23 +1620,6 @@ void ColladaExporter::WriteNode(const aiNode *pNode) {
|
||||||
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) {
|
void ColladaExporter::CreateNodeIds(const aiNode *node) {
|
||||||
GetNodeUniqueId(node);
|
GetNodeUniqueId(node);
|
||||||
for (size_t a = 0; a < node->mNumChildren; ++a)
|
for (size_t a = 0; a < node->mNumChildren; ++a)
|
||||||
|
|
|
@ -196,13 +196,14 @@ public:
|
||||||
const std::string mFile;
|
const std::string mFile;
|
||||||
|
|
||||||
/// The scene to be written
|
/// The scene to be written
|
||||||
const aiScene *mScene;
|
const aiScene *const mScene;
|
||||||
bool mSceneOwned;
|
std::string mSceneId;
|
||||||
|
bool mAdd_root_node = false;
|
||||||
|
|
||||||
/// current line start string, contains the current indentation for simple stream insertion
|
/// current line start string, contains the current indentation for simple stream insertion
|
||||||
std::string startstr;
|
std::string startstr;
|
||||||
/// current line end string for simple stream insertion
|
/// current line end string for simple stream insertion
|
||||||
std::string endstr;
|
const std::string endstr;
|
||||||
|
|
||||||
// pair of color and texture - texture precedences color
|
// pair of color and texture - texture precedences color
|
||||||
struct Surface {
|
struct Surface {
|
||||||
|
|
|
@ -2479,7 +2479,7 @@ void ColladaParser::ReadSceneLibrary() {
|
||||||
|
|
||||||
// read name if given.
|
// read name if given.
|
||||||
int indexName = TestAttribute("name");
|
int indexName = TestAttribute("name");
|
||||||
const char *attrName = "unnamed";
|
const char *attrName = "Scene";
|
||||||
if (indexName > -1)
|
if (indexName > -1)
|
||||||
attrName = mReader->getAttributeValue(indexName);
|
attrName = mReader->getAttributeValue(indexName);
|
||||||
|
|
||||||
|
|
|
@ -530,7 +530,9 @@ namespace glTF {
|
||||||
StringBuffer docBuffer;
|
StringBuffer docBuffer;
|
||||||
|
|
||||||
PrettyWriter<StringBuffer> writer(docBuffer);
|
PrettyWriter<StringBuffer> writer(docBuffer);
|
||||||
mDoc.Accept(writer);
|
if (!mDoc.Accept(writer)) {
|
||||||
|
throw DeadlyExportError("Failed to write scene data!");
|
||||||
|
}
|
||||||
|
|
||||||
if (jsonOutFile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) {
|
if (jsonOutFile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) {
|
||||||
throw DeadlyExportError("Failed to write scene data!");
|
throw DeadlyExportError("Failed to write scene data!");
|
||||||
|
@ -569,7 +571,9 @@ namespace glTF {
|
||||||
|
|
||||||
StringBuffer docBuffer;
|
StringBuffer docBuffer;
|
||||||
Writer<StringBuffer> writer(docBuffer);
|
Writer<StringBuffer> writer(docBuffer);
|
||||||
mDoc.Accept(writer);
|
if (!mDoc.Accept(writer)) {
|
||||||
|
throw DeadlyExportError("Failed to write scene data!");
|
||||||
|
}
|
||||||
|
|
||||||
if (outfile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) {
|
if (outfile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) {
|
||||||
throw DeadlyExportError("Failed to write scene data!");
|
throw DeadlyExportError("Failed to write scene data!");
|
||||||
|
|
|
@ -145,13 +145,13 @@ bool ParseDataURI(const char *const_uri, size_t uriLen, DataURI &out) {
|
||||||
size_t i = 5, j;
|
size_t i = 5, j;
|
||||||
if (uri[i] != ';' && uri[i] != ',') { // has media type?
|
if (uri[i] != ';' && uri[i] != ',') { // has media type?
|
||||||
uri[1] = char(i);
|
uri[1] = char(i);
|
||||||
for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
|
for (;i < uriLen && uri[i] != ';' && uri[i] != ','; ++i) {
|
||||||
// nothing to do!
|
// nothing to do!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (uri[i] == ';' && i < uriLen) {
|
while (i < uriLen && uri[i] == ';') {
|
||||||
uri[i++] = '\0';
|
uri[i++] = '\0';
|
||||||
for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
|
for (j = i; i < uriLen && uri[i] != ';' && uri[i] != ','; ++i) {
|
||||||
// nothing to do!
|
// nothing to do!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -613,7 +613,9 @@ namespace glTF2 {
|
||||||
StringBuffer docBuffer;
|
StringBuffer docBuffer;
|
||||||
|
|
||||||
PrettyWriter<StringBuffer> writer(docBuffer);
|
PrettyWriter<StringBuffer> writer(docBuffer);
|
||||||
mDoc.Accept(writer);
|
if (!mDoc.Accept(writer)) {
|
||||||
|
throw DeadlyExportError("Failed to write scene data!");
|
||||||
|
}
|
||||||
|
|
||||||
if (jsonOutFile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) {
|
if (jsonOutFile->Write(docBuffer.GetString(), docBuffer.GetSize(), 1) != 1) {
|
||||||
throw DeadlyExportError("Failed to write scene data!");
|
throw DeadlyExportError("Failed to write scene data!");
|
||||||
|
@ -664,7 +666,9 @@ namespace glTF2 {
|
||||||
|
|
||||||
StringBuffer docBuffer;
|
StringBuffer docBuffer;
|
||||||
Writer<StringBuffer> writer(docBuffer);
|
Writer<StringBuffer> writer(docBuffer);
|
||||||
mDoc.Accept(writer);
|
if (!mDoc.Accept(writer)) {
|
||||||
|
throw DeadlyExportError("Failed to write scene data!");
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t jsonChunkLength = (docBuffer.GetSize() + 3) & ~3; // Round up to next multiple of 4
|
uint32_t jsonChunkLength = (docBuffer.GetSize() + 3) & ~3; // Round up to next multiple of 4
|
||||||
auto paddingLength = jsonChunkLength - docBuffer.GetSize();
|
auto paddingLength = jsonChunkLength - docBuffer.GetSize();
|
||||||
|
@ -816,5 +820,3 @@ namespace glTF2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -172,6 +172,13 @@ void SetAccessorRange(Ref<Accessor> acc, void* data, size_t count,
|
||||||
for (unsigned int j = 0 ; j < numCompsOut ; j++) {
|
for (unsigned int j = 0 ; j < numCompsOut ; j++) {
|
||||||
double valueTmp = buffer_ptr[j];
|
double valueTmp = buffer_ptr[j];
|
||||||
|
|
||||||
|
// Gracefully tolerate rogue NaN's in buffer data
|
||||||
|
// Any NaNs/Infs introduced in accessor bounds will end up in
|
||||||
|
// document and prevent rapidjson from writing out valid JSON
|
||||||
|
if (!std::isfinite(valueTmp)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (valueTmp < acc->min[j]) {
|
if (valueTmp < acc->min[j]) {
|
||||||
acc->min[j] = valueTmp;
|
acc->min[j] = valueTmp;
|
||||||
}
|
}
|
||||||
|
@ -751,7 +758,7 @@ void glTF2Exporter::ExportMeshes()
|
||||||
// Normalize all normals as the validator can emit a warning otherwise
|
// Normalize all normals as the validator can emit a warning otherwise
|
||||||
if ( nullptr != aim->mNormals) {
|
if ( nullptr != aim->mNormals) {
|
||||||
for ( auto i = 0u; i < aim->mNumVertices; ++i ) {
|
for ( auto i = 0u; i < aim->mNumVertices; ++i ) {
|
||||||
aim->mNormals[ i ].Normalize();
|
aim->mNormals[ i ].NormalizeSafe();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
[[package]]
|
||||||
|
name = "assimp_rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "assimp_rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["David Golembiowski <dmgolembiowski@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
|
@ -0,0 +1 @@
|
||||||
|
pub use self::structs::{Camera};
|
|
@ -0,0 +1,17 @@
|
||||||
|
pub mod camera;
|
||||||
|
pub mod core;
|
||||||
|
pub mod errors;
|
||||||
|
pub mod formats;
|
||||||
|
pub mod material;
|
||||||
|
pub mod postprocess;
|
||||||
|
pub mod shims;
|
||||||
|
pub mod socket;
|
||||||
|
pub mod structs;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
assert_eq!(true, true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
pub struct Animation<'mA, 'mMA, 'nA> {
|
||||||
|
/* The name of the animation. If the modeling package this data was
|
||||||
|
* exported from does support only a single animation channel, this
|
||||||
|
* name is usually empty (length is zero).
|
||||||
|
*/
|
||||||
|
m_name: Option<String>,
|
||||||
|
// Duration of the animation in ticks
|
||||||
|
m_duration: f64,
|
||||||
|
// Ticks per second. Zero (0.000... ticks/second) if not
|
||||||
|
// specified in the imported file
|
||||||
|
m_ticks_per_second: Option<f64>,
|
||||||
|
/* Number of bone animation channels.
|
||||||
|
Each channel affects a single node.
|
||||||
|
*/
|
||||||
|
m_num_channels: u64,
|
||||||
|
/* Node animation channels. Each channel
|
||||||
|
affects a single node.
|
||||||
|
?? -> The array is m_num_channels in size.
|
||||||
|
(maybe refine to a derivative type of usize?)
|
||||||
|
*/
|
||||||
|
m_channels: &'nA NodeAnim,
|
||||||
|
/* Number of mesh animation channels. Each
|
||||||
|
channel affects a single mesh and defines
|
||||||
|
vertex-based animation.
|
||||||
|
*/
|
||||||
|
m_num_mesh_channels: u64,
|
||||||
|
/* The mesh animation channels. Each channel
|
||||||
|
affects a single mesh.
|
||||||
|
The array is m_num_mesh_channels in size
|
||||||
|
(maybe refine to a derivative of usize?)
|
||||||
|
*/
|
||||||
|
m_mesh_channels: &'mA MeshAnim,
|
||||||
|
/* The number of mesh animation channels. Each channel
|
||||||
|
affects a single mesh and defines some morphing animation.
|
||||||
|
*/
|
||||||
|
m_num_morph_mesh_channels: u64,
|
||||||
|
/* The morph mesh animation channels. Each channel affects a single mesh.
|
||||||
|
The array is mNumMorphMeshChannels in size.
|
||||||
|
*/
|
||||||
|
m_morph_mesh_channels: &'mMA MeshMorphAnim
|
||||||
|
}
|
||||||
|
pub struct NodeAnim {}
|
||||||
|
pub struct MeshAnim {}
|
||||||
|
pub struct MeshMorphAnim {}
|
|
@ -0,0 +1,6 @@
|
||||||
|
mod anim;
|
||||||
|
pub use self::anim::{
|
||||||
|
Animation,
|
||||||
|
NodeAnim,
|
||||||
|
MeshAnim,
|
||||||
|
MeshMorphAnim};
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod blob;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod bone;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod camera;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
#[derive(Clone, Debug, Copy)]
|
||||||
|
struct Color3D {
|
||||||
|
r: f32,
|
||||||
|
g: f32,
|
||||||
|
b: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Color3D {
|
||||||
|
pub fn new(r_f32: f32, g_f32: f32, b_f32: f32) -> Color3D {
|
||||||
|
Color3D {r: r_f32, g: g_f32, b: b_f32 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Copy)]
|
||||||
|
struct Color4D {
|
||||||
|
r: f32,
|
||||||
|
g: f32,
|
||||||
|
b: f32,
|
||||||
|
a: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Color4D {
|
||||||
|
pub fn new(r_f32: f32, g_f32: f32, b_f32: f32, a_f32: f32) -> Color4D {
|
||||||
|
Color4D {r: r_f32, g: g_f32, b: b_f32, a: a_f32 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
mod color;
|
||||||
|
pub use self::color::{
|
||||||
|
Color3D,
|
||||||
|
Color4D
|
||||||
|
};
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod face;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod key;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod light;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod material;
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
#[derive(Clone, Debug, Copy)]
|
||||||
|
struct Matrix3x3 {
|
||||||
|
a1: f32,
|
||||||
|
a2: f32,
|
||||||
|
a3: f32,
|
||||||
|
b1: f32,
|
||||||
|
b2: f32,
|
||||||
|
b3: f32,
|
||||||
|
c1: f32,
|
||||||
|
c2: f32,
|
||||||
|
c3: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Copy)]
|
||||||
|
struct Matrix4x4 {
|
||||||
|
a1: f32,
|
||||||
|
a2: f32,
|
||||||
|
a3: f32,
|
||||||
|
a4: f32,
|
||||||
|
b1: f32,
|
||||||
|
b2: f32,
|
||||||
|
b3: f32,
|
||||||
|
b4: f32,
|
||||||
|
c1: f32,
|
||||||
|
c2: f32,
|
||||||
|
c3: f32,
|
||||||
|
c4: f32,
|
||||||
|
d1: f32,
|
||||||
|
d2: f32,
|
||||||
|
d3: f32,
|
||||||
|
d4: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Matrix3x3 {
|
||||||
|
pub fn new(
|
||||||
|
a1_f32: f32, a2_f32: f32, a3_f32: f32,
|
||||||
|
b1_f32: f32, b2_f32: f32, b3_f32: f32,
|
||||||
|
c1_f32: f32, c2_f32: f32, c3_f32: f32
|
||||||
|
) -> Matrix3x3 {
|
||||||
|
Matrix3x3 {
|
||||||
|
a1: a1_f32, a2: a2_f32, a3: a3_f32,
|
||||||
|
b1: b1_f32, b2: b2_f32, b3: b3_f32,
|
||||||
|
c1: c1_f32, c2: c2_f32, c3: c3_f32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Matrix4x4 {
|
||||||
|
pub fn new(
|
||||||
|
a1_f32: f32, a2_f32: f32, a3_f32: f32, a4_f32: f32,
|
||||||
|
b1_f32: f32, b2_f32: f32, b3_f32: f32, b4_f32: f32,
|
||||||
|
c1_f32: f32, c2_f32: f32, c3_f32: f32, c4_f32: f32,
|
||||||
|
d1_f32: f32, d2_f32: f32, d3_f32: f32, d4_f32: f32
|
||||||
|
) -> Matrix4x4 {
|
||||||
|
Matrix4x4 {
|
||||||
|
a1: a1_f32, a2: a2_f32, a3: a3_f32, a4: a4_f32,
|
||||||
|
b1: b1_f32, b2: b2_f32, b3: b3_f32, b4: b4_f32,
|
||||||
|
c1: c1_f32, c2: c2_f32, c3: c3_f32, c4: c4_f32,
|
||||||
|
d1: d1_f32, d2: d2_f32, d3: d3_f32, d4: d4_f32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
mod matrix;
|
||||||
|
pub use self::matrix::{
|
||||||
|
Matrix3x3,
|
||||||
|
Matrix4x4};
|
|
@ -0,0 +1,35 @@
|
||||||
|
#[derive(Clone, Debug, Copy)]
|
||||||
|
struct MemoryInfo {
|
||||||
|
textures: u32,
|
||||||
|
materials: u32,
|
||||||
|
meshes: u32,
|
||||||
|
nodes: u32,
|
||||||
|
animations: u32,
|
||||||
|
cameras: u32,
|
||||||
|
lights: u32,
|
||||||
|
total: u32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemoryInfo {
|
||||||
|
pub fn new(
|
||||||
|
textures_uint: u32,
|
||||||
|
materials_uint: u32,
|
||||||
|
meshes_uint: u32,
|
||||||
|
nodes_uint: u32,
|
||||||
|
animations_uint: u32,
|
||||||
|
cameras_uint: u32,
|
||||||
|
lights_uint: u32,
|
||||||
|
total_uint: u32) -> MemoryInfo {
|
||||||
|
|
||||||
|
MemoryInfo {
|
||||||
|
textures: textures_uint,
|
||||||
|
materials: materials_uint,
|
||||||
|
meshes: meshes_uint,
|
||||||
|
nodes: nodes_uint,
|
||||||
|
animations: animations_uint,
|
||||||
|
cameras: cameras_uint,
|
||||||
|
lights: lights_uint,
|
||||||
|
total: total_uint
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod memory;
|
||||||
|
pub use self::memory::MemoryInfo;
|
|
@ -0,0 +1,3 @@
|
||||||
|
mod mesh;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod meta;
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
mod anim;
|
||||||
|
/* Animation
|
||||||
|
* NodeAnim
|
||||||
|
* MeshAnim
|
||||||
|
* MeshMorphAnim
|
||||||
|
*/
|
||||||
|
mod blob;
|
||||||
|
/* ExportDataBlob
|
||||||
|
*/
|
||||||
|
mod vec;
|
||||||
|
/* Vector2d
|
||||||
|
* Vector3d
|
||||||
|
* */
|
||||||
|
mod matrix;
|
||||||
|
/* Matrix3by3
|
||||||
|
* Matrix4by4
|
||||||
|
*/
|
||||||
|
mod camera;
|
||||||
|
/* Camera */
|
||||||
|
mod color;
|
||||||
|
/* Color3d
|
||||||
|
* Color4d
|
||||||
|
*/
|
||||||
|
mod key;
|
||||||
|
/* MeshKey
|
||||||
|
* MeshMorphKey
|
||||||
|
* QuatKey
|
||||||
|
* VectorKey
|
||||||
|
*/
|
||||||
|
mod texel;
|
||||||
|
mod plane;
|
||||||
|
mod string;
|
||||||
|
/* String
|
||||||
|
*/
|
||||||
|
mod material;
|
||||||
|
/* Material
|
||||||
|
* MaterialPropery
|
||||||
|
* MaterialPropertyString
|
||||||
|
*/
|
||||||
|
mod mem;
|
||||||
|
mod quaternion;
|
||||||
|
mod face;
|
||||||
|
mod vertex_weight;
|
||||||
|
mod mesh;
|
||||||
|
/* Mesh
|
||||||
|
*/
|
||||||
|
mod meta;
|
||||||
|
/* Metadata
|
||||||
|
* MetadataEntry
|
||||||
|
*/
|
||||||
|
mod node;
|
||||||
|
/* Node
|
||||||
|
* */
|
||||||
|
mod light;
|
||||||
|
mod texture;
|
||||||
|
mod ray;
|
||||||
|
mod transform;
|
||||||
|
/* UVTransform */
|
||||||
|
mod bone;
|
||||||
|
mod scene;
|
||||||
|
/* Scene */
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod node;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod plane;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#[derive(Clone, Debug, Copy)]
|
||||||
|
struct Plane {
|
||||||
|
a: f32,
|
||||||
|
b: f32,
|
||||||
|
c: f32,
|
||||||
|
d: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Plane {
|
||||||
|
pub fn new(
|
||||||
|
a_f32: f32,
|
||||||
|
b_f32: f32,
|
||||||
|
c_f32: f32,
|
||||||
|
d_f32: f32
|
||||||
|
) -> Plane {
|
||||||
|
Plane {
|
||||||
|
a: a_f32,
|
||||||
|
b: b_f32,
|
||||||
|
c: b_f32,
|
||||||
|
d: d_f32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
mod quaternion;
|
||||||
|
|
||||||
|
pub use self::quaternion::Quaternion;
|
|
@ -0,0 +1,7 @@
|
||||||
|
use crate::vec;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Copy)]
|
||||||
|
pub struct Quaternion {
|
||||||
|
_coordinates: vec::Vector4d
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod ray;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod scene;
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
mod string;
|
||||||
|
pub use self::string::MAXLEN;
|
||||||
|
pub use self::string::Str;
|
|
@ -0,0 +1,41 @@
|
||||||
|
pub const MAXLEN: usize = 1024;
|
||||||
|
|
||||||
|
/// Want to consider replacing `Vec<char>`
|
||||||
|
/// with a comparable definition at
|
||||||
|
/// https://doc.rust-lang.org/src/alloc/string.rs.html#415-417
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct Str {
|
||||||
|
length: usize,
|
||||||
|
data: Vec<char>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Str {
|
||||||
|
pub fn new(len_u32: usize, data_string: String) -> Str {
|
||||||
|
Str {
|
||||||
|
length: len_u32,
|
||||||
|
data: data_string.chars().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// MaterialPropertyStr
|
||||||
|
/// The size of length is truncated to 4 bytes on a 64-bit platform when used as a
|
||||||
|
/// material property (see MaterialSystem.cpp, as aiMaterial::AddProperty() ).
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct MaterialPropertyStr {
|
||||||
|
length: usize,
|
||||||
|
data: Vec<char>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl MaterialPropertyStr {
|
||||||
|
pub fn new(len_u32: usize, data_string: String) -> MaterialPropertyStr {
|
||||||
|
MaterialPropertyStr {
|
||||||
|
length: len_u32,
|
||||||
|
data: data_string.chars().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
mod texture;
|
||||||
|
pub use self::texture::Texel;
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#[derive(Clone, Debug, Copy)]
|
||||||
|
struct Texel {
|
||||||
|
b: u32,
|
||||||
|
g: u32,
|
||||||
|
r: u32,
|
||||||
|
a: u32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Texel {
|
||||||
|
pub fn new(b_u32: u32, g_u32: u32,
|
||||||
|
r_u32: u32, a_u32: u32) -> Texel {
|
||||||
|
Texel {
|
||||||
|
b: b_u32,
|
||||||
|
g: g_u32,
|
||||||
|
r: r_u32,
|
||||||
|
a: a_u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod transform;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod vec;
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
struct Vector2d {
|
||||||
|
x: f32,
|
||||||
|
y: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Vector3d {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
z: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Vector4d {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
z: f32,
|
||||||
|
w: f32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vector2d {
|
||||||
|
pub fn new(x_f32: f32, y_f32: f32) -> Vector2d {
|
||||||
|
Vector2d {
|
||||||
|
x: x_f32,
|
||||||
|
y: y_f32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vector3d {
|
||||||
|
pub fn new(x_f32: f32, y_f32: f32, z_f32: f32) -> Vector3d {
|
||||||
|
Vector3d {
|
||||||
|
x: x_f32,
|
||||||
|
y: y_f32,
|
||||||
|
z: z_f32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Vector4d {
|
||||||
|
pub fn new(x_f32: f32, y_f32: f32, z_f32: f32, w_f32: f32) -> Vector4d {
|
||||||
|
Vector4d {
|
||||||
|
x: x_f32,
|
||||||
|
y: y_f32,
|
||||||
|
z: z_f32,
|
||||||
|
w: w_f32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
mod vertex;
|
||||||
|
// pub use self::vertex::
|
|
@ -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
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|
||||||
class ColladaExportLight : public ::testing::Test {
|
class utColladaExport : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
ex = new Assimp::Exporter();
|
ex = new Assimp::Exporter();
|
||||||
|
@ -58,7 +58,9 @@ public:
|
||||||
|
|
||||||
void TearDown() override {
|
void TearDown() override {
|
||||||
delete ex;
|
delete ex;
|
||||||
|
ex = nullptr;
|
||||||
delete im;
|
delete im;
|
||||||
|
im = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -66,8 +68,53 @@ protected:
|
||||||
Assimp::Importer *im;
|
Assimp::Importer *im;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TEST_F(utColladaExport, testExportCamera) {
|
||||||
|
const char *file = "cameraExp.dae";
|
||||||
|
|
||||||
|
const aiScene *pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/cameras.dae", aiProcess_ValidateDataStructure);
|
||||||
|
ASSERT_NE(nullptr, pTest);
|
||||||
|
ASSERT_TRUE(pTest->HasCameras());
|
||||||
|
|
||||||
|
EXPECT_EQ(AI_SUCCESS, ex->Export(pTest, "collada", file));
|
||||||
|
const unsigned int origNumCams(pTest->mNumCameras);
|
||||||
|
std::unique_ptr<float[]> origFOV(new float[origNumCams]);
|
||||||
|
std::unique_ptr<float[]> orifClipPlaneNear(new float[origNumCams]);
|
||||||
|
std::unique_ptr<float[]> orifClipPlaneFar(new float[origNumCams]);
|
||||||
|
std::unique_ptr<aiString[]> names(new aiString[origNumCams]);
|
||||||
|
std::unique_ptr<aiVector3D[]> pos(new aiVector3D[origNumCams]);
|
||||||
|
for (size_t i = 0; i < origNumCams; i++) {
|
||||||
|
const aiCamera *orig = pTest->mCameras[i];
|
||||||
|
ASSERT_NE(nullptr, orig);
|
||||||
|
|
||||||
|
origFOV[i] = orig->mHorizontalFOV;
|
||||||
|
orifClipPlaneNear[i] = orig->mClipPlaneNear;
|
||||||
|
orifClipPlaneFar[i] = orig->mClipPlaneFar;
|
||||||
|
names[i] = orig->mName;
|
||||||
|
pos[i] = orig->mPosition;
|
||||||
|
}
|
||||||
|
const aiScene *imported = im->ReadFile(file, aiProcess_ValidateDataStructure);
|
||||||
|
|
||||||
|
ASSERT_NE(nullptr, imported);
|
||||||
|
|
||||||
|
EXPECT_TRUE(imported->HasCameras());
|
||||||
|
EXPECT_EQ(origNumCams, imported->mNumCameras);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < imported->mNumCameras; i++) {
|
||||||
|
const aiCamera *read = imported->mCameras[i];
|
||||||
|
|
||||||
|
EXPECT_TRUE(names[i] == read->mName);
|
||||||
|
EXPECT_NEAR(origFOV[i], read->mHorizontalFOV, 0.0001f);
|
||||||
|
EXPECT_FLOAT_EQ(orifClipPlaneNear[i], read->mClipPlaneNear);
|
||||||
|
EXPECT_FLOAT_EQ(orifClipPlaneFar[i], read->mClipPlaneFar);
|
||||||
|
|
||||||
|
EXPECT_FLOAT_EQ(pos[i].x, read->mPosition.x);
|
||||||
|
EXPECT_FLOAT_EQ(pos[i].y, read->mPosition.y);
|
||||||
|
EXPECT_FLOAT_EQ(pos[i].z, read->mPosition.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
TEST_F(ColladaExportLight, testExportLight) {
|
TEST_F(utColladaExport, testExportLight) {
|
||||||
const char *file = "lightsExp.dae";
|
const char *file = "lightsExp.dae";
|
||||||
|
|
||||||
const aiScene *pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/lights.dae", aiProcess_ValidateDataStructure);
|
const aiScene *pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/lights.dae", aiProcess_ValidateDataStructure);
|
|
@ -1,115 +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.
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
#include "UnitTestPCH.h"
|
|
||||||
|
|
||||||
#include <assimp/cexport.h>
|
|
||||||
#include <assimp/postprocess.h>
|
|
||||||
#include <assimp/scene.h>
|
|
||||||
#include <assimp/Exporter.hpp>
|
|
||||||
#include <assimp/Importer.hpp>
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
|
||||||
|
|
||||||
class ColladaExportCamera : public ::testing::Test {
|
|
||||||
public:
|
|
||||||
void SetUp() override {
|
|
||||||
ex = new Assimp::Exporter();
|
|
||||||
im = new Assimp::Importer();
|
|
||||||
}
|
|
||||||
|
|
||||||
void TearDown() override {
|
|
||||||
delete ex;
|
|
||||||
ex = nullptr;
|
|
||||||
delete im;
|
|
||||||
im = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Assimp::Exporter *ex;
|
|
||||||
Assimp::Importer *im;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F(ColladaExportCamera, testExportCamera) {
|
|
||||||
const char *file = "cameraExp.dae";
|
|
||||||
|
|
||||||
const aiScene *pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/cameras.dae", aiProcess_ValidateDataStructure);
|
|
||||||
ASSERT_NE(nullptr, pTest);
|
|
||||||
ASSERT_TRUE(pTest->HasCameras());
|
|
||||||
|
|
||||||
EXPECT_EQ(AI_SUCCESS, ex->Export(pTest, "collada", file));
|
|
||||||
const unsigned int origNumCams(pTest->mNumCameras);
|
|
||||||
std::unique_ptr<float[]> origFOV(new float[origNumCams]);
|
|
||||||
std::unique_ptr<float[]> orifClipPlaneNear(new float[origNumCams]);
|
|
||||||
std::unique_ptr<float[]> orifClipPlaneFar(new float[origNumCams]);
|
|
||||||
std::unique_ptr<aiString[]> names(new aiString[origNumCams]);
|
|
||||||
std::unique_ptr<aiVector3D[]> pos(new aiVector3D[origNumCams]);
|
|
||||||
for (size_t i = 0; i < origNumCams; i++) {
|
|
||||||
const aiCamera *orig = pTest->mCameras[i];
|
|
||||||
ASSERT_NE(nullptr, orig);
|
|
||||||
|
|
||||||
origFOV[i] = orig->mHorizontalFOV;
|
|
||||||
orifClipPlaneNear[i] = orig->mClipPlaneNear;
|
|
||||||
orifClipPlaneFar[i] = orig->mClipPlaneFar;
|
|
||||||
names[i] = orig->mName;
|
|
||||||
pos[i] = orig->mPosition;
|
|
||||||
}
|
|
||||||
const aiScene *imported = im->ReadFile(file, aiProcess_ValidateDataStructure);
|
|
||||||
|
|
||||||
ASSERT_NE(nullptr, imported);
|
|
||||||
|
|
||||||
EXPECT_TRUE(imported->HasCameras());
|
|
||||||
EXPECT_EQ(origNumCams, imported->mNumCameras);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < imported->mNumCameras; i++) {
|
|
||||||
const aiCamera *read = imported->mCameras[i];
|
|
||||||
|
|
||||||
EXPECT_TRUE(names[i] == read->mName);
|
|
||||||
EXPECT_NEAR(origFOV[i], read->mHorizontalFOV, 0.0001f);
|
|
||||||
EXPECT_FLOAT_EQ(orifClipPlaneNear[i], read->mClipPlaneNear);
|
|
||||||
EXPECT_FLOAT_EQ(orifClipPlaneFar[i], read->mClipPlaneFar);
|
|
||||||
|
|
||||||
EXPECT_FLOAT_EQ(pos[i].x, read->mPosition.x);
|
|
||||||
EXPECT_FLOAT_EQ(pos[i].y, read->mPosition.y);
|
|
||||||
EXPECT_FLOAT_EQ(pos[i].z, read->mPosition.z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
|
|
@ -42,6 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
#include <assimp/ColladaMetaData.h>
|
#include <assimp/ColladaMetaData.h>
|
||||||
|
#include <assimp/SceneCombiner.h>
|
||||||
#include <assimp/commonMetaData.h>
|
#include <assimp/commonMetaData.h>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
@ -52,6 +53,20 @@ using namespace Assimp;
|
||||||
|
|
||||||
class utColladaImportExport : public AbstractImportExportBase {
|
class utColladaImportExport : public AbstractImportExportBase {
|
||||||
public:
|
public:
|
||||||
|
// Clones the scene in an exception-safe way
|
||||||
|
struct SceneCloner {
|
||||||
|
SceneCloner(const aiScene *scene) {
|
||||||
|
sceneCopy = nullptr;
|
||||||
|
SceneCombiner::CopyScene(&sceneCopy, scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
~SceneCloner() {
|
||||||
|
delete sceneCopy;
|
||||||
|
sceneCopy = nullptr;
|
||||||
|
}
|
||||||
|
aiScene *sceneCopy;
|
||||||
|
};
|
||||||
|
|
||||||
virtual bool importerTest() final {
|
virtual bool importerTest() final {
|
||||||
Assimp::Importer importer;
|
Assimp::Importer importer;
|
||||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck.dae", aiProcess_ValidateDataStructure);
|
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck.dae", aiProcess_ValidateDataStructure);
|
||||||
|
@ -211,6 +226,60 @@ TEST_F(utColladaImportExport, importDaeFromFileTest) {
|
||||||
EXPECT_TRUE(importerTest());
|
EXPECT_TRUE(importerTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int GetMeshUseCount(const aiNode *rootNode) {
|
||||||
|
unsigned int result = rootNode->mNumMeshes;
|
||||||
|
for (unsigned int i = 0; i < rootNode->mNumChildren; ++i) {
|
||||||
|
result += GetMeshUseCount(rootNode->mChildren[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(utColladaImportExport, exportRootNodeMeshTest) {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
Assimp::Exporter exporter;
|
||||||
|
const char *outFile = "exportRootNodeMeshTest_out.dae";
|
||||||
|
|
||||||
|
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/Collada/duck.dae", aiProcess_ValidateDataStructure);
|
||||||
|
ASSERT_TRUE(scene != nullptr) << "Fatal: could not import duck.dae!";
|
||||||
|
|
||||||
|
ASSERT_EQ(0u, scene->mRootNode->mNumMeshes) << "Collada import should not give the root node a mesh";
|
||||||
|
|
||||||
|
{
|
||||||
|
SceneCloner clone(scene);
|
||||||
|
ASSERT_TRUE(clone.sceneCopy != nullptr) << "Fatal: could not copy scene!";
|
||||||
|
// Do this by moving the meshes from the first child that has some
|
||||||
|
aiNode *rootNode = clone.sceneCopy->mRootNode;
|
||||||
|
ASSERT_TRUE(rootNode->mNumChildren > 0) << "Fatal: root has no children";
|
||||||
|
aiNode *meshNode = rootNode->mChildren[0];
|
||||||
|
ASSERT_EQ(1u, meshNode->mNumMeshes) << "Fatal: First child node has no duck mesh";
|
||||||
|
|
||||||
|
// Move the meshes to the parent
|
||||||
|
rootNode->mNumMeshes = meshNode->mNumMeshes;
|
||||||
|
rootNode->mMeshes = new unsigned int[rootNode->mNumMeshes];
|
||||||
|
for (unsigned int i = 0; i < rootNode->mNumMeshes; ++i) {
|
||||||
|
rootNode->mMeshes[i] = meshNode->mMeshes[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the meshes from the original node
|
||||||
|
meshNode->mNumMeshes = 0;
|
||||||
|
delete[] meshNode->mMeshes;
|
||||||
|
meshNode->mMeshes = nullptr;
|
||||||
|
|
||||||
|
ASSERT_EQ(AI_SUCCESS, exporter.Export(clone.sceneCopy, "collada", outFile)) << "Fatal: Could not export file";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reimport and look for meshes
|
||||||
|
scene = importer.ReadFile(outFile, aiProcess_ValidateDataStructure);
|
||||||
|
ASSERT_TRUE(scene != nullptr) << "Fatal: could not reimport!";
|
||||||
|
|
||||||
|
// A Collada root node is not allowed to have a mesh
|
||||||
|
ASSERT_EQ(0u, scene->mRootNode->mNumMeshes) << "Collada reimport should not give the root node a mesh";
|
||||||
|
|
||||||
|
// Walk nodes and counts used meshes
|
||||||
|
// Should be exactly one
|
||||||
|
EXPECT_EQ(1u, GetMeshUseCount(scene->mRootNode)) << "Nodes had unexpected number of meshes in use";
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(utColladaImportExport, exporterUniqueIdsTest) {
|
TEST_F(utColladaImportExport, exporterUniqueIdsTest) {
|
||||||
Assimp::Importer importer;
|
Assimp::Importer importer;
|
||||||
Assimp::Exporter exporter;
|
Assimp::Exporter exporter;
|
||||||
|
|
|
@ -436,6 +436,31 @@ TEST_F(utglTF2ImportExport, error_string_preserved) {
|
||||||
ASSERT_NE(error.find("BoxTextured0.bin"), std::string::npos) << "Error string should contain an error about missing .bin file";
|
ASSERT_NE(error.find("BoxTextured0.bin"), std::string::npos) << "Error string should contain an error about missing .bin file";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(utglTF2ImportExport, export_bad_accessor_bounds) {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
Assimp::Exporter exporter;
|
||||||
|
const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxWithInfinites-glTF-Binary/BoxWithInfinites.glb", aiProcess_ValidateDataStructure);
|
||||||
|
ASSERT_NE(scene, nullptr);
|
||||||
|
|
||||||
|
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxWithInfinites-glTF-Binary/BoxWithInfinites_out.glb"));
|
||||||
|
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "gltf2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxWithInfinites-glTF-Binary/BoxWithInfinites_out.gltf"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(utglTF2ImportExport, export_normalized_normals) {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
Assimp::Exporter exporter;
|
||||||
|
const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxBadNormals-glTF-Binary/BoxBadNormals.glb", aiProcess_ValidateDataStructure);
|
||||||
|
ASSERT_NE(scene, nullptr);
|
||||||
|
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxBadNormals-glTF-Binary/BoxBadNormals_out.glb"));
|
||||||
|
|
||||||
|
// load in again and ensure normal-length normals but no Nan's or Inf's introduced
|
||||||
|
scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxBadNormals-glTF-Binary/BoxBadNormals_out.glb", aiProcess_ValidateDataStructure);
|
||||||
|
for ( auto i = 0u; i < scene->mMeshes[0]->mNumVertices; ++i ) {
|
||||||
|
const auto length = scene->mMeshes[0]->mNormals[i].Length();
|
||||||
|
EXPECT_TRUE(abs(length) < 1e-6 || abs(length - 1) < 1e-6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|
||||||
TEST_F(utglTF2ImportExport, sceneMetadata) {
|
TEST_F(utglTF2ImportExport, sceneMetadata) {
|
||||||
|
|
Loading…
Reference in New Issue