Merge branch 'export_3mf' of https://github.com/assimp/assimp into export_3mf

This commit is contained in:
Kim Kulling
2017-11-28 19:05:00 +01:00
54 changed files with 286 additions and 162 deletions

View File

@@ -926,8 +926,27 @@ SET_TARGET_PROPERTIES( assimp PROPERTIES
)
if (APPLE)
SET_TARGET_PROPERTIES( assimp PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${ASSIMP_LIB_INSTALL_DIR}")
endif()
SET_TARGET_PROPERTIES( assimp PROPERTIES
INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${ASSIMP_LIB_INSTALL_DIR}"
)
if (BUILD_FRAMEWORK)
SET_TARGET_PROPERTIES( assimp PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION C
MACOSX_FRAMEWORK_IDENTIFIER net.sf.assimp
PUBLIC_HEADER "${PUBLIC_HEADERS}"
)
# PUBLIC_HEADER option does not support directory structure creation
# add ./Compiler/*.h to assimp.framework via copy command
ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E copy_directory
"../${HEADER_PATH}/Compiler"
assimp.framework/Headers/Compiler
COMMENT "Copying public ./Compiler/ header files to framework bundle's Headers/Compiler/")
endif(BUILD_FRAMEWORK)
endif(APPLE)
# Build against external unzip, or add ../contrib/unzip so
# assimp can #include "unzip.h"
@@ -947,9 +966,11 @@ INSTALL( TARGETS assimp
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
COMPONENT ${LIBASSIMP_COMPONENT})
INSTALL( FILES ${PUBLIC_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp COMPONENT assimp-dev)
INSTALL( FILES ${COMPILER_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp/Compiler COMPONENT assimp-dev)
if (ASSIMP_ANDROID_JNIIOSYSTEM)
INSTALL(FILES ${HEADER_PATH}/${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/AndroidJNIIOSystem.h
DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}

View File

@@ -1280,7 +1280,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
std::vector<ai_real> frames;
for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
frames.push_back(nodeAnim->mPositionKeys[i].mTime);
frames.push_back(static_cast<ai_real>(nodeAnim->mPositionKeys[i].mTime));
}
WriteFloatArray( node_idstr , FloatType_Time, (const ai_real*) frames.data(), frames.size());
@@ -1309,7 +1309,7 @@ void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
// Combine the above transformations
aiMatrix4x4 mat = TranslationM * RotationM * ScalingM;
for( size_t j = 0; j < 4; ++j) {
for( unsigned int j = 0; j < 4; ++j) {
keyframes.insert(keyframes.end(), mat[j], mat[j] + 4);
}
}

View File

@@ -55,6 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
void ExportScene3MF( const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/ ) {
if ( nullptr == pIOSystem ) {
throw DeadlyExportError( "Could not export 3MP archive: " + std::string( pFile ) );
}
D3MF::D3MFExporter myExporter( pFile, pScene );
if ( myExporter.validate() ) {
bool ok = myExporter.exportArchive(pFile);
@@ -248,6 +251,9 @@ void D3MFExporter::writeBuild() {
}
void D3MFExporter::writeModelToArchive( const std::string &folder, const std::string &modelName ) {
if ( nullptr == m_zipArchive ) {
throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." );
}
const std::string entry = folder + "/" + modelName;
zip_entry_open( m_zipArchive, entry.c_str() );
@@ -258,6 +264,9 @@ void D3MFExporter::writeModelToArchive( const std::string &folder, const std::st
}
void D3MFExporter::writeRelInfoToFile( const std::string &folder, const std::string &relName ) {
if ( nullptr == m_zipArchive ) {
throw DeadlyExportError( "3MF-Export: Zip archive not valid, nullptr." );
}
const std::string entry = folder + "/" + relName;
zip_entry_open( m_zipArchive, entry.c_str() );
@@ -271,3 +280,4 @@ void D3MFExporter::writeRelInfoToFile( const std::string &folder, const std::str
} // Namespace D3MF
} // Namespace Assimp

View File

@@ -55,7 +55,6 @@ struct zip_t;
namespace Assimp {
class IOStream;
class IOSystem;
namespace D3MF {

View File

@@ -60,6 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "MemoryIOWrapper.h"
#include "irrXMLWrapper.h"
#include "../contrib/utf8cpp/source/utf8.h"
#include "fast_atof.h"
#include <stack>
#include <map>
#include <iostream>
@@ -714,7 +715,8 @@ public:
if (floatValue) {
return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
}
return static_cast<float>( atof( attr->value->toString().c_str() ) );
return fast_atof(attr->value->toString().c_str());
}
virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
@@ -725,7 +727,7 @@ public:
if (floatValue) {
return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
}
return static_cast<float>( atof( attributes[ idx ].value->toString().c_str() ) );
return fast_atof(attributes[idx].value->toString().c_str());
}
virtual const char* getNodeName() const /*override*/ {
@@ -1790,7 +1792,8 @@ public:
return nullptr;
}
virtual void registerDecoder(const std::string &/*algorithmUri*/, std::unique_ptr<FIDecoder> /*decoder*/) /*override*/ {}
virtual void registerDecoder(const std::string & /*algorithmUri*/, std::unique_ptr<FIDecoder> /*decoder*/) /*override*/ {}
virtual void registerVocabulary(const std::string &/*vocabularyUri*/, const FIVocabulary * /*vocabulary*/) /*override*/ {}

View File

@@ -93,7 +93,7 @@ void FindDegeneratesProcess::Execute( aiScene* pScene) {
static ai_real heron( ai_real a, ai_real b, ai_real c ) {
ai_real s = (a + b + c) / 2;
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), 0.5 );
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
return area;
}
@@ -102,7 +102,7 @@ static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB ) {
const ai_real ly = ( vB.y - vA.y );
const ai_real lz = ( vB.z - vA.z );
ai_real a = lx*lx + ly*ly + lz*lz;
ai_real d = pow( a, 0.5 );
ai_real d = pow( a, (ai_real)0.5 );
return d;
}

View File

@@ -339,7 +339,7 @@ void FindInvalidDataProcess::ProcessAnimationChannel (aiNodeAnim* anim)
int FindInvalidDataProcess::ProcessMesh (aiMesh* pMesh)
{
bool ret = false;
std::vector<bool> dirtyMask(pMesh->mNumVertices, pMesh->mNumFaces);
std::vector<bool> dirtyMask(pMesh->mNumVertices, pMesh->mNumFaces != 0);
// Ignore elements that are not referenced by vertices.
// (they are, for example, caused by the FindDegenerates step)

View File

@@ -471,7 +471,7 @@ namespace pmx
stream->read((char*) &this->is_near, sizeof(uint8_t));
}
void PmxSoftBody::Read(std::istream */*stream*/, PmxSetting */*setting*/)
void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
{
// 未実装
std::cerr << "Not Implemented Exception" << std::endl;

View File

@@ -51,7 +51,7 @@ OpenGEXExporter::OpenGEXExporter() {
OpenGEXExporter::~OpenGEXExporter() {
}
bool OpenGEXExporter::exportScene( const char */*filename*/, const aiScene* /*pScene*/ ) {
bool OpenGEXExporter::exportScene( const char * /*filename*/, const aiScene* /*pScene*/ ) {
return true;
}

View File

@@ -248,7 +248,7 @@ void STLImporter::LoadASCIIFile( aiNode *root ) {
std::vector<unsigned int> meshIndices;
aiMesh* pMesh = new aiMesh();
pMesh->mMaterialIndex = 0;
meshIndices.push_back( meshes.size() );
meshIndices.push_back((unsigned int) meshes.size() );
meshes.push_back(pMesh);
aiNode *node = new aiNode;
node->mParent = root;
@@ -383,7 +383,7 @@ void STLImporter::LoadASCIIFile( aiNode *root ) {
pScene->mMeshes[ i ] = meshes[i];
}
root->mNumChildren = nodes.size();
root->mNumChildren = (unsigned int) nodes.size();
root->mChildren = new aiNode*[ root->mNumChildren ];
for ( size_t i=0; i<nodes.size(); ++i ) {
root->mChildren[ i ] = nodes[ i ];

View File

@@ -66,8 +66,8 @@ namespace Assimp {
// ------------------------------------------------------------------------------------------------
// Add a prefix to a string
inline void PrefixString(aiString& string,const char* prefix, unsigned int len)
{
inline
void PrefixString(aiString& string,const char* prefix, unsigned int len) {
// If the string is already prefixed, we won't prefix it a second time
if (string.length >= 1 && string.data[0] == '$')
return;
@@ -88,8 +88,7 @@ inline void PrefixString(aiString& string,const char* prefix, unsigned int len)
// ------------------------------------------------------------------------------------------------
// Add node identifiers to a hashing set
void SceneCombiner::AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes)
{
void SceneCombiner::AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes) {
// Add node name to hashing set if it is non-empty - empty nodes are allowed
// and they can't have any anims assigned so its absolutely safe to duplicate them.
if (node->mName.length) {
@@ -103,25 +102,23 @@ void SceneCombiner::AddNodeHashes(aiNode* node, std::set<unsigned int>& hashes)
// ------------------------------------------------------------------------------------------------
// Add a name prefix to all nodes in a hierarchy
void SceneCombiner::AddNodePrefixes(aiNode* node, const char* prefix, unsigned int len)
{
void SceneCombiner::AddNodePrefixes(aiNode* node, const char* prefix, unsigned int len) {
ai_assert(NULL != prefix);
PrefixString(node->mName,prefix,len);
// Process all children recursively
for (unsigned int i = 0; i < node->mNumChildren;++i)
AddNodePrefixes(node->mChildren[i],prefix,len);
for ( unsigned int i = 0; i < node->mNumChildren; ++i ) {
AddNodePrefixes( node->mChildren[ i ], prefix, len );
}
}
// ------------------------------------------------------------------------------------------------
// Search for matching names
bool SceneCombiner::FindNameMatch(const aiString& name, std::vector<SceneHelper>& input, unsigned int cur)
{
bool SceneCombiner::FindNameMatch(const aiString& name, std::vector<SceneHelper>& input, unsigned int cur) {
const unsigned int hash = SuperFastHash(name.data, static_cast<uint32_t>(name.length));
// Check whether we find a positive match in one of the given sets
for (unsigned int i = 0; i < input.size(); ++i) {
if (cur != i && input[i].hashes.find(hash) != input[i].hashes.end()) {
return true;
}
@@ -132,14 +129,12 @@ bool SceneCombiner::FindNameMatch(const aiString& name, std::vector<SceneHelper>
// ------------------------------------------------------------------------------------------------
// Add a name prefix to all nodes in a hierarchy if a hash match is found
void SceneCombiner::AddNodePrefixesChecked(aiNode* node, const char* prefix, unsigned int len,
std::vector<SceneHelper>& input, unsigned int cur)
{
std::vector<SceneHelper>& input, unsigned int cur) {
ai_assert(NULL != prefix);
const unsigned int hash = SuperFastHash(node->mName.data, static_cast<uint32_t>(node->mName.length));
// Check whether we find a positive match in one of the given sets
for (unsigned int i = 0; i < input.size(); ++i) {
if (cur != i && input[i].hashes.find(hash) != input[i].hashes.end()) {
PrefixString(node->mName,prefix,len);
break;
@@ -153,27 +148,25 @@ void SceneCombiner::AddNodePrefixesChecked(aiNode* node, const char* prefix, uns
// ------------------------------------------------------------------------------------------------
// Add an offset to all mesh indices in a node graph
void SceneCombiner::OffsetNodeMeshIndices (aiNode* node, unsigned int offset)
{
void SceneCombiner::OffsetNodeMeshIndices (aiNode* node, unsigned int offset) {
for (unsigned int i = 0; i < node->mNumMeshes;++i)
node->mMeshes[i] += offset;
for (unsigned int i = 0; i < node->mNumChildren;++i)
OffsetNodeMeshIndices(node->mChildren[i],offset);
for ( unsigned int i = 0; i < node->mNumChildren; ++i ) {
OffsetNodeMeshIndices( node->mChildren[ i ], offset );
}
}
// ------------------------------------------------------------------------------------------------
// Merges two scenes. Currently only used by the LWS loader.
void SceneCombiner::MergeScenes(aiScene** _dest,std::vector<aiScene*>& src,
unsigned int flags)
{
ai_assert(NULL != _dest);
void SceneCombiner::MergeScenes(aiScene** _dest,std::vector<aiScene*>& src, unsigned int flags) {
if ( nullptr == _dest ) {
return;
}
// if _dest points to NULL allocate a new scene. Otherwise clear the old and reuse it
if (src.empty())
{
if (*_dest)
{
if (src.empty()) {
if (*_dest) {
(*_dest)->~aiScene();
SceneCombiner::CopySceneFlat(_dest,src[0]);
}
@@ -198,8 +191,7 @@ void SceneCombiner::MergeScenes(aiScene** _dest,std::vector<aiScene*>& src,
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInfo>& srcList)
{
void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInfo>& srcList) {
unsigned int cnt;
for ( cnt = 0; cnt < attach->mNumChildren; ++cnt ) {
AttachToGraph( attach->mChildren[ cnt ], srcList );
@@ -239,19 +231,16 @@ void SceneCombiner::AttachToGraph (aiNode* attach, std::vector<NodeAttachmentInf
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::AttachToGraph ( aiScene* master,
std::vector<NodeAttachmentInfo>& src)
{
void SceneCombiner::AttachToGraph ( aiScene* master, std::vector<NodeAttachmentInfo>& src) {
ai_assert(NULL != master);
AttachToGraph(master->mRootNode,src);
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master,
std::vector<AttachmentInfo>& srcList,
unsigned int flags)
{
ai_assert(NULL != _dest);
void SceneCombiner::MergeScenes(aiScene** _dest, aiScene* master, std::vector<AttachmentInfo>& srcList, unsigned int flags) {
if ( nullptr == _dest ) {
return;
}
// if _dest points to NULL allocate a new scene. Otherwise clear the old and reuse it
if (srcList.empty()) {
@@ -708,7 +697,9 @@ void SceneCombiner::BuildUniqueBoneList(std::list<BoneWithHash>& asBones,
void SceneCombiner::MergeBones(aiMesh* out,std::vector<aiMesh*>::const_iterator it,
std::vector<aiMesh*>::const_iterator end)
{
ai_assert(NULL != out && !out->mNumBones);
if ( nullptr == out || out->mNumBones == 0 ) {
return;
}
// find we need to build an unique list of all bones.
// we work with hashes to make the comparisons MUCH faster,
@@ -762,7 +753,9 @@ void SceneCombiner::MergeMeshes(aiMesh** _out, unsigned int /*flags*/,
std::vector<aiMesh*>::const_iterator begin,
std::vector<aiMesh*>::const_iterator end)
{
ai_assert(NULL != _out);
if ( nullptr == _out ) {
return;
}
if (begin == end) {
*_out = NULL; // no meshes ...
@@ -903,7 +896,9 @@ void SceneCombiner::MergeMaterials(aiMaterial** dest,
std::vector<aiMaterial*>::const_iterator begin,
std::vector<aiMaterial*>::const_iterator end)
{
ai_assert(NULL != dest);
if ( nullptr == dest ) {
return;
}
if (begin == end) {
*dest = NULL; // no materials ...
@@ -953,10 +948,9 @@ void SceneCombiner::MergeMaterials(aiMaterial** dest,
// ------------------------------------------------------------------------------------------------
template <typename Type>
inline void CopyPtrArray (Type**& dest, const Type* const * src, ai_uint num)
{
if (!num)
{
inline
void CopyPtrArray (Type**& dest, const Type* const * src, ai_uint num) {
if (!num) {
dest = NULL;
return;
}
@@ -968,9 +962,11 @@ inline void CopyPtrArray (Type**& dest, const Type* const * src, ai_uint num)
// ------------------------------------------------------------------------------------------------
template <typename Type>
inline void GetArrayCopy (Type*& dest, ai_uint num )
{
if (!dest)return;
inline
void GetArrayCopy(Type*& dest, ai_uint num ) {
if ( !dest ) {
return;
}
Type* old = dest;
dest = new Type[num];
@@ -978,22 +974,27 @@ inline void GetArrayCopy (Type*& dest, ai_uint num )
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::CopySceneFlat(aiScene** _dest,const aiScene* src)
{
void SceneCombiner::CopySceneFlat(aiScene** _dest,const aiScene* src) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
// reuse the old scene or allocate a new?
if (*_dest) {
(*_dest)->~aiScene();
new (*_dest) aiScene();
} else {
*_dest = new aiScene();
}
else *_dest = new aiScene();
::memcpy(*_dest,src,sizeof(aiScene));
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::CopyScene(aiScene** _dest,const aiScene* src,bool allocate)
{
ai_assert(NULL != _dest && NULL != src);
void SceneCombiner::CopyScene(aiScene** _dest,const aiScene* src,bool allocate) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
if (allocate) {
*_dest = new aiScene();
@@ -1044,9 +1045,10 @@ void SceneCombiner::CopyScene(aiScene** _dest,const aiScene* src,bool allocate)
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy (aiMesh** _dest, const aiMesh* src)
{
ai_assert(NULL != _dest && NULL != src);
void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
aiMesh* dest = *_dest = new aiMesh();
@@ -1072,17 +1074,17 @@ void SceneCombiner::Copy (aiMesh** _dest, const aiMesh* src)
// make a deep copy of all faces
GetArrayCopy(dest->mFaces,dest->mNumFaces);
for (unsigned int i = 0; i < dest->mNumFaces;++i)
{
for (unsigned int i = 0; i < dest->mNumFaces;++i) {
aiFace& f = dest->mFaces[i];
GetArrayCopy(f.mIndices,f.mNumIndices);
}
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy (aiMaterial** _dest, const aiMaterial* src)
{
ai_assert(NULL != _dest && NULL != src);
void SceneCombiner::Copy (aiMaterial** _dest, const aiMaterial* src) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
aiMaterial* dest = (aiMaterial*) ( *_dest = new aiMaterial() );
@@ -1110,9 +1112,10 @@ void SceneCombiner::Copy (aiMaterial** _dest, const aiMaterial* src)
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy (aiTexture** _dest, const aiTexture* src)
{
ai_assert(NULL != _dest && NULL != src);
void SceneCombiner::Copy(aiTexture** _dest, const aiTexture* src) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
aiTexture* dest = *_dest = new aiTexture();
@@ -1139,10 +1142,10 @@ void SceneCombiner::Copy (aiTexture** _dest, const aiTexture* src)
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src )
{
ai_assert( NULL != _dest );
ai_assert( NULL != src );
void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src ) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
aiAnimation* dest = *_dest = new aiAnimation();
@@ -1154,9 +1157,10 @@ void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src )
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy (aiNodeAnim** _dest, const aiNodeAnim* src)
{
ai_assert(NULL != _dest && NULL != src);
void SceneCombiner::Copy(aiNodeAnim** _dest, const aiNodeAnim* src) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
aiNodeAnim* dest = *_dest = new aiNodeAnim();
@@ -1170,9 +1174,10 @@ void SceneCombiner::Copy (aiNodeAnim** _dest, const aiNodeAnim* src)
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy (aiCamera** _dest,const aiCamera* src)
{
ai_assert(NULL != _dest && NULL != src);
void SceneCombiner::Copy( aiCamera** _dest,const aiCamera* src) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
aiCamera* dest = *_dest = new aiCamera();
@@ -1181,9 +1186,10 @@ void SceneCombiner::Copy (aiCamera** _dest,const aiCamera* src)
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy (aiLight** _dest, const aiLight* src)
{
ai_assert(NULL != _dest && NULL != src);
void SceneCombiner::Copy(aiLight** _dest, const aiLight* src) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
aiLight* dest = *_dest = new aiLight();
@@ -1192,9 +1198,10 @@ void SceneCombiner::Copy (aiLight** _dest, const aiLight* src)
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy (aiBone** _dest, const aiBone* src)
{
ai_assert(NULL != _dest && NULL != src);
void SceneCombiner::Copy(aiBone** _dest, const aiBone* src) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
aiBone* dest = *_dest = new aiBone();
@@ -1230,10 +1237,14 @@ void SceneCombiner::Copy (aiNode** _dest, const aiNode* src)
}
// ------------------------------------------------------------------------------------------------
void SceneCombiner::Copy(aiMetadata** _dest, const aiMetadata* src)
{
ai_assert( NULL != _dest );
ai_assert( NULL != src);
void SceneCombiner::Copy(aiMetadata** _dest, const aiMetadata* src) {
if ( nullptr == _dest || nullptr == src ) {
return;
}
if ( 0 == src->mNumProperties ) {
return;
}
aiMetadata* dest = *_dest = aiMetadata::Alloc( src->mNumProperties );
std::copy(src->mKeys, src->mKeys + src->mNumProperties, dest->mKeys);
@@ -1271,4 +1282,5 @@ void SceneCombiner::Copy(aiMetadata** _dest, const aiMetadata* src)
}
}
}
} // Namespace Assimp

View File

@@ -165,7 +165,7 @@ private:
inline void DoValidation(T** array, unsigned int size,
const char* firstName, const char* secondName);
// extended version: checks whethr T::mName occurs twice
// extended version: checks whether T::mName occurs twice
template <typename T>
inline void DoValidationEx(T** array, unsigned int size,
const char* firstName, const char* secondName);

View File

@@ -775,7 +775,7 @@ namespace glTF2
PrimitiveMode mode;
struct Attributes {
AccessorList position, normal, texcoord, color, joint, jointmatrix, weight;
AccessorList position, normal, tangent, texcoord, color, joint, jointmatrix, weight;
} attributes;
Ref<Accessor> indices;

View File

@@ -212,7 +212,7 @@ unsigned int LazyDict<T>::Remove(const char* id)
mObjs.erase(mObjs.begin() + index);
//update index of object in mObjs;
for (size_t i = index; i < mObjs.size(); ++i) {
for (unsigned int i = index; i < mObjs.size(); ++i) {
T *obj = mObjs[i];
obj->index = i;
@@ -867,6 +867,9 @@ namespace {
else if ((pos = Compare(attr, "NORMAL"))) {
v = &(p.attributes.normal);
}
else if ((pos = Compare(attr, "TANGENT"))) {
v = &(p.attributes.tangent);
}
else if ((pos = Compare(attr, "TEXCOORD"))) {
v = &(p.attributes.texcoord);
}
@@ -906,7 +909,7 @@ inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
for (Value::MemberIterator it = attrs->MemberBegin(); it != attrs->MemberEnd(); ++it) {
if (!it->value.IsUint()) continue;
const char* attr = it->name.GetString();
// Valid attribute semantics include POSITION, NORMAL, TEXCOORD, COLOR, JOINT, JOINTMATRIX,
// Valid attribute semantics include POSITION, NORMAL, TANGENT, TEXCOORD, COLOR, JOINT, JOINTMATRIX,
// and WEIGHT.Attribute semantics can be of the form[semantic]_[set_index], e.g., TEXCOORD_0, TEXCOORD_1, etc.
int undPos = 0;
@@ -934,7 +937,7 @@ inline void Camera::Read(Value& obj, Asset& /*r*/)
{
type = MemberOrDefault(obj, "type", Camera::Perspective);
const char* subobjId = (type == Camera::Orthographic) ? "ortographic" : "perspective";
const char* subobjId = (type == Camera::Orthographic) ? "orthographic" : "perspective";
Value* it = FindObject(obj, subobjId);
if (!it) throw DeadlyImportError("GLTF: Camera missing its parameters");

View File

@@ -445,7 +445,7 @@ void glTF2Exporter::ExportMaterials()
mat->Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS
) {
// convert specular color to luminance
float specularIntensity = specularColor[0] * 0.2125 + specularColor[1] * 0.7154 + specularColor[2] * 0.0721;
float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f;
//normalize shininess (assuming max is 1000) with an inverse exponentional curve
float normalizedShininess = std::sqrt(shininess / 1000);

View File

@@ -362,7 +362,31 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
attr.position[0]->ExtractData(aim->mVertices);
}
if (attr.normal.size() > 0 && attr.normal[0]) attr.normal[0]->ExtractData(aim->mNormals);
if (attr.normal.size() > 0 && attr.normal[0]) {
attr.normal[0]->ExtractData(aim->mNormals);
// only extract tangents if normals are present
if (attr.tangent.size() > 0 && attr.tangent[0]) {
// generate bitangents from normals and tangents according to spec
struct Tangent
{
aiVector3D xyz;
ai_real w;
} *tangents = nullptr;
attr.tangent[0]->ExtractData(tangents);
aim->mTangents = new aiVector3D[aim->mNumVertices];
aim->mBitangents = new aiVector3D[aim->mNumVertices];
for (unsigned int i = 0; i < aim->mNumVertices; ++i) {
aim->mTangents[i] = tangents[i].xyz;
aim->mBitangents[i] = (aim->mNormals[i] ^ tangents[i].xyz) * tangents[i].w;
}
delete tangents;
}
}
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
attr.texcoord[tc]->ExtractData(aim->mTextureCoords[tc]);
@@ -492,7 +516,7 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
{
Node& node = *ptr;
aiNode* ainode = new aiNode(node.id);
aiNode* ainode = new aiNode(node.name);
if (!node.children.empty()) {
ainode->mNumChildren = unsigned(node.children.size());
@@ -515,7 +539,13 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
CopyValue(node.translation.value, trans);
aiMatrix4x4 t;
aiMatrix4x4::Translation(trans, t);
matrix = t * matrix;
matrix = matrix * t;
}
if (node.rotation.isPresent) {
aiQuaternion rot;
CopyValue(node.rotation.value, rot);
matrix = matrix * aiMatrix4x4(rot.GetMatrix());
}
if (node.scale.isPresent) {
@@ -523,14 +553,7 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
CopyValue(node.scale.value, scal);
aiMatrix4x4 s;
aiMatrix4x4::Scaling(scal, s);
matrix = s * matrix;
}
if (node.rotation.isPresent) {
aiQuaternion rot;
CopyValue(node.rotation.value, rot);
matrix = aiMatrix4x4(rot.GetMatrix()) * matrix;
matrix = matrix * s;
}
}