diff --git a/code/AssetLib/Collada/ColladaHelper.cpp b/code/AssetLib/Collada/ColladaHelper.cpp index 50d70e640..0a779e04e 100644 --- a/code/AssetLib/Collada/ColladaHelper.cpp +++ b/code/AssetLib/Collada/ColladaHelper.cpp @@ -1,5 +1,3 @@ -/** Helper structures for the Collada loader */ - /* Open Asset Import Library (assimp) ---------------------------------------------------------------------- @@ -40,6 +38,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ +/** Helper structures for the Collada loader */ #include "ColladaHelper.h" diff --git a/code/AssetLib/Collada/ColladaHelper.h b/code/AssetLib/Collada/ColladaHelper.h index bc93203aa..bfd57918e 100644 --- a/code/AssetLib/Collada/ColladaHelper.h +++ b/code/AssetLib/Collada/ColladaHelper.h @@ -1,12 +1,9 @@ -/** Helper structures for the Collada loader */ - /* 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, @@ -42,12 +39,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- */ +/** Helper structures for the Collada loader */ + #ifndef AI_COLLADAHELPER_H_INC #define AI_COLLADAHELPER_H_INC #include #include #include + #include #include #include @@ -58,14 +58,14 @@ struct aiMaterial; namespace Assimp { namespace Collada { -/** Collada file versions which evolved during the years ... */ +/// Collada file versions which evolved during the years ... enum FormatVersion { FV_1_5_n, FV_1_4_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 { TF_LOOKAT, TF_ROTATE, @@ -75,7 +75,7 @@ enum TransformType { TF_MATRIX }; -/** Different types of input data to a vertex or face */ +/// Different types of input data to a vertex or face enum InputType { IT_Invalid, IT_Vertex, // special type for per-index data referring to the element carrying the per-vertex data. @@ -87,38 +87,39 @@ enum InputType { IT_Bitangent }; -/** Supported controller types */ +/// Supported controller types enum ControllerType { Skin, Morph }; -/** Supported morph methods */ +/// Supported morph methods enum MorphMethod { Normalized, Relative }; -/** Common metadata keys as */ -typedef std::pair MetaKeyPair; -typedef std::vector MetaKeyPairVector; +/// Common metadata keys as +using MetaKeyPair = std::pair; +using MetaKeyPairVector = std::vector; -// Collada as lower_case (native) +/// Collada as lower_case (native) const MetaKeyPairVector &GetColladaAssimpMetaKeys(); + // Collada as CamelCase (used by Assimp for consistency) const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase(); -/** Convert underscore_separated to CamelCase "authoring_tool" becomes "AuthoringTool" */ +/// Convert underscore_separated to CamelCase "authoring_tool" becomes "AuthoringTool" 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 { std::string mID; ///< SID of the transform step, by which anim channels address their target node TransformType mType; ai_real f[16]; ///< Interpretation of data depends on the type of the transformation }; -/** A collada camera. */ +/// A collada camera. struct Camera { Camera() : mOrtho(false), @@ -128,22 +129,22 @@ struct Camera { mZNear(0.1f), mZFar(1000.f) {} - // Name of camera + /// Name of camera std::string mName; - // True if it is an orthografic camera + /// True if it is an orthographic camera bool mOrtho; - //! Horizontal field of view in degrees + /// Horizontal field of view in degrees ai_real mHorFov; - //! Vertical field of view in degrees + /// Vertical field of view in degrees ai_real mVerFov; - //! Screen aspect + /// Screen aspect ai_real mAspect; - //! Near& far z + /// Near& far z ai_real mZNear, mZFar; }; @@ -162,27 +163,27 @@ struct Light { mOuterAngle(ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET), mIntensity(1.f) {} - //! Type of the light source aiLightSourceType + ambient + /// Type of the light source aiLightSourceType + ambient unsigned int mType; - //! Color of the light + /// Color of the light aiColor3D mColor; - //! Light attenuation + /// Light attenuation ai_real mAttConstant, mAttLinear, mAttQuadratic; - //! Spot light falloff + /// Spot light falloff ai_real mFalloffAngle; ai_real mFalloffExponent; // ----------------------------------------------------- // FCOLLADA extension from here - //! ... related stuff from maja and max extensions + /// ... related stuff from maja and max extensions ai_real mPenumbraAngle; ai_real mOuterAngle; - //! Common light intensity + /// Common light intensity ai_real mIntensity; }; @@ -192,30 +193,29 @@ struct InputSemanticMapEntry { mSet(0), mType(IT_Invalid) {} - //! Index of set, optional + /// Index of set, optional unsigned int mSet; - //! Type of referenced vertex input + /// Type of referenced vertex input InputType mType; }; -/** Table to map from effect to vertex input semantics */ +/// Table to map from effect to vertex input semantics struct SemanticMappingTable { - //! Name of material + /// Name of material std::string mMatName; - //! List of semantic map commands, grouped by effect semantic name + /// List of semantic map commands, grouped by effect semantic name std::map mMap; - //! For std::find + /// For std::find bool operator==(const std::string &s) const { return s == mMatName; } }; -/** 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 - */ +/// 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 struct MeshInstance { ///< ID of the mesh or controller to be instanced std::string mMeshOrController; @@ -224,25 +224,25 @@ struct MeshInstance { std::map mMaterials; }; -/** A reference to a camera inside a node*/ +/// A reference to a camera inside a node struct CameraInstance { ///< ID of the camera std::string mCamera; }; -/** A reference to a light inside a node*/ +/// A reference to a light inside a node struct LightInstance { ///< ID of the camera std::string mLight; }; -/** A reference to a node inside a node*/ +/// A reference to a node inside a node struct NodeInstance { ///< ID of the node std::string mNode; }; -/** A node in a scene hierarchy */ +/// A node in a scene hierarchy struct Node { std::string mName; std::string mID; @@ -250,52 +250,53 @@ struct Node { Node *mParent; std::vector mChildren; - /** Operations in order to calculate the resulting transformation to parent. */ + /// Operations in order to calculate the resulting transformation to parent. std::vector mTransforms; - /** Meshes at this node */ + /// Meshes at this node std::vector mMeshes; - /** Lights at this node */ + /// Lights at this node std::vector mLights; - /** Cameras at this node */ + /// Cameras at this node std::vector mCameras; - /** Node instances at this node */ + /// Node instances at this node std::vector mNodeInstances; - /** Root-nodes: Name of primary camera, if any */ + /// Root-nodes: Name of primary camera, if any std::string mPrimaryCamera; - //! Constructor. Begin with a zero parent + /// Constructor. Begin with a zero parent Node() : mParent(nullptr) { // empty } - //! Destructor: delete all children subsequently + /// Destructor: delete all children subsequently ~Node() { - for (std::vector::iterator it = mChildren.begin(); it != mChildren.end(); ++it) + for (std::vector::iterator it = mChildren.begin(); it != mChildren.end(); ++it) { delete *it; + } } }; -/** Data source array: either floats or strings */ +/// Data source array: either floats or strings struct Data { bool mIsStringArray; std::vector mValues; std::vector mStrings; }; -/** Accessor to a data array */ +/// Accessor to a data array struct Accessor { size_t mCount; // in number of objects size_t mSize; // size of an object, in elements (floats or strings, mostly 1) size_t mOffset; // in number of values size_t mStride; // Stride in number of values std::vector 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]; // Sub-offset 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. std::string mSource; // URL of the source array mutable const Data *mData; // Pointer to the source array, if resolved. nullptr else @@ -310,12 +311,12 @@ struct Accessor { } }; -/** A single face in a mesh */ +/// A single face in a mesh struct Face { std::vector 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 { InputType mType; // Type of the data size_t mIndex; // Optional index, if multiple sets of the same data type are given @@ -331,18 +332,19 @@ struct InputChannel { } }; -/** Subset of a mesh with a certain material */ +/// Subset of a mesh with a certain material struct SubMesh { std::string mMaterial; ///< subgroup identifier - size_t mNumFaces; ///< number of faces in this submesh + size_t mNumFaces; ///< number of faces in this sub-mesh }; -/** Contains data for a single mesh */ +/// Contains data for a single mesh struct Mesh { Mesh(const std::string &id) : 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; + } } const std::string mId; @@ -373,11 +375,11 @@ struct Mesh { // necessary for bone weight assignment std::vector mFacePosIndices; - // Submeshes in this mesh, each with a given material + // Sub-meshes in this mesh, each with a given material std::vector mSubMeshes; }; -/** Which type of primitives the ReadPrimitives() function is going to read */ +/// Which type of primitives the ReadPrimitives() function is going to read enum PrimitiveType { Prim_Invalid, Prim_Lines, @@ -389,7 +391,7 @@ enum PrimitiveType { Prim_Polygon }; -/** 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 { // controller type ControllerType mType; @@ -424,25 +426,25 @@ struct Controller { 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 { std::string mName; std::string mEffect; }; -/** Type of the effect param */ +/// Type of the effect param enum ParamType { Param_Sampler, 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 { ParamType mType; 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 { Shade_Invalid, Shade_Constant, @@ -451,7 +453,7 @@ enum ShadeType { Shade_Blinn }; -/** Represents a texture sampler in collada */ +/// Represents a texture sampler in collada struct Sampler { Sampler() : mWrapU(true), @@ -463,77 +465,66 @@ struct Sampler { mWeighting(1.f), mMixWithPrevious(1.f) {} - /** Name of image reference - */ + /// Name of image reference std::string mName; - /** Wrap U? - */ + /// Wrap U? bool mWrapU; - /** Wrap V? - */ + /// Wrap V? bool mWrapV; - /** Mirror U? - */ + /// Mirror U? bool mMirrorU; - /** Mirror V? - */ + /// Mirror V? bool mMirrorV; - /** Blend mode - */ + /// Blend mode aiTextureOp mOp; - /** UV transformation - */ + /// UV transformation aiUVTransform mTransform; - /** Name of source UV channel - */ + /// Name of source UV channel std::string mUVChannel; - /** Resolved UV channel index or UINT_MAX if not known - */ + /// Resolved UV channel index or UINT_MAX if not known unsigned int mUVId; // OKINO/MAX3D extensions from here // ------------------------------------------------------- - /** Weighting factor - */ + /// Weighting factor ai_real mWeighting; - /** Mixing factor from OKINO - */ + /// Mixing factor from OKINO ai_real mMixWithPrevious; }; -/** A collada effect. Can contain about anything according to the Collada spec, - but we limit our version to a reasonable subset. */ +/// A collada effect. Can contain about anything according to the Collada spec, +/// but we limit our version to a reasonable subset. struct Effect { - // Shading mode + /// Shading mode ShadeType mShadeType; - // Colors + /// Colors aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular, mTransparent, mReflective; - // Textures + /// Textures Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular, mTexTransparent, mTexBump, mTexReflective; - // Scalar factory + /// Scalar factory ai_real mShininess, mRefractIndex, mReflectivity; ai_real mTransparency; bool mHasTransparency; bool mRGBTransparency; bool mInvertTransparency; - // local params referring to each other by their SID - typedef std::map ParamLibrary; + /// local params referring to each other by their SID + using ParamLibrary = std::map; ParamLibrary mParams; // MAX3D extensions @@ -561,65 +552,64 @@ struct Effect { } }; -/** An image, meaning texture */ +/// An image, meaning texture struct Image { std::string mFileName; - /** Embedded image data */ + /// Embedded image data std::vector mImageData; - /** File format hint of embedded image data */ + /// File format hint of embedded image data std::string mEmbeddedFormat; }; -/** An animation channel. */ +/// An animation channel. struct AnimationChannel { - /** URL of the data to animate. Could be about anything, but we support only the - * "NodeID/TransformID.SubElement" notation - */ + /// URL of the data to animate. Could be about anything, but we support only the + /// "NodeID/TransformID.SubElement" notation std::string mTarget; - /** Source URL of the time values. Collada calls them "input". Meh. */ + /// Source URL of the time values. Collada calls them "input". Meh. std::string mSourceTimes; - /** Source URL of the value values. Collada calls them "output". */ + /// Source URL of the value values. Collada calls them "output". std::string mSourceValues; - /** Source URL of the IN_TANGENT semantic values. */ + /// Source URL of the IN_TANGENT semantic values. std::string mInTanValues; - /** Source URL of the OUT_TANGENT semantic values. */ + /// Source URL of the OUT_TANGENT semantic values. std::string mOutTanValues; - /** Source URL of the INTERPOLATION semantic values. */ + /// Source URL of the INTERPOLATION semantic values. std::string mInterpolationValues; }; -/** 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 { - /** Anim name */ + /// Anim name std::string mName; - /** the animation channels, if any */ + /// the animation channels, if any std::vector mChannels; - /** the sub-animations, if any */ + /// the sub-animations, if any std::vector mSubAnims; - /** Destructor */ + /// Destructor ~Animation() { - for (std::vector::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) + for (std::vector::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++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 &channels) { channels.insert(channels.end(), mChannels.begin(), mChannels.end()); for (std::vector::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) { Animation *pAnim = (*it); - 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() { CombineSingleChannelAnimationsRecursively(this); } @@ -658,9 +648,9 @@ struct Animation { } }; -/** 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 { - const Collada::AnimationChannel *mChannel; ///> the source channel + const Collada::AnimationChannel *mChannel; ///< the source channel std::string mTargetId; 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 diff --git a/code/AssetLib/Collada/ColladaLoader.cpp b/code/AssetLib/Collada/ColladaLoader.cpp index 4beaf8431..99cb8c305 100644 --- a/code/AssetLib/Collada/ColladaLoader.cpp +++ b/code/AssetLib/Collada/ColladaLoader.cpp @@ -55,12 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include -#include -#include -#include #include #include -#include + #include namespace Assimp { @@ -331,13 +328,15 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Col // Resolve UV channels void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler, const Collada::SemanticMappingTable &table) { std::map::const_iterator it = table.mMap.find(sampler.mUVChannel); - if (it != table.mMap.end()) { - if (it->second.mType != Collada::IT_Texcoord) { - ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping"); - } - - sampler.mUVId = it->second.mSet; + if (it == table.mMap.end()) { + return; } + + if (it->second.mType != Collada::IT_Texcoord) { + ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping"); + } + + sampler.mUVId = it->second.mSet; } // ------------------------------------------------------------------------------------------------ diff --git a/code/AssetLib/Collada/ColladaParser.cpp b/code/AssetLib/Collada/ColladaParser.cpp index c5ca97b89..70f1f80f7 100644 --- a/code/AssetLib/Collada/ColladaParser.cpp +++ b/code/AssetLib/Collada/ColladaParser.cpp @@ -48,7 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "ColladaParser.h" #include #include -#include #include #include #include @@ -56,14 +55,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include -#include -#include -#include - using namespace Assimp; using namespace Assimp::Collada; using namespace Assimp::Formatter; +static void ReportWarning(const char *msg, ...) { + ai_assert(nullptr != msg); + + va_list args; + va_start(args, msg); + + char szBuffer[3000]; + const int iLen = vsprintf(szBuffer, msg, args); + ai_assert(iLen > 0); + + va_end(args); + ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer, iLen)); +} + // ------------------------------------------------------------------------------------------------ // Constructor to be privately used by Importer ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) : @@ -301,11 +310,8 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) { for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { const std::string name = currentNode.name(); if (name == "unit") { - pugi::xml_attribute attr = currentNode.attribute("meter"); mUnitSize = 1.f; - if (attr) { - mUnitSize = static_cast(attr.as_double()); - } + XmlParser::getFloatAttribute(node, "meter", mUnitSize); } else if (name == "up_axis") { std::string v; XmlParser::getValueAsString(currentNode, v); @@ -349,20 +355,22 @@ void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) { } std::string v; - if (XmlParser::getValueAsString(node, v)) { - trim(v); - aiString aistr; - aistr.Set(v); + if (!XmlParser::getValueAsString(node, v)) { + return; + } - std::string camel_key_str(name); - ToCamelCase(camel_key_str); + trim(v); + aiString aistr; + aistr.Set(v); - size_t found_index; - if (FindCommonKey(camel_key_str, key_renaming, found_index)) { - metadata.emplace(key_renaming[found_index].second, aistr); - } else { - metadata.emplace(camel_key_str, aistr); - } + std::string camel_key_str(name); + ToCamelCase(camel_key_str); + + size_t found_index; + if (FindCommonKey(camel_key_str, key_renaming, found_index)) { + metadata.emplace(key_renaming[found_index].second, aistr); + } else { + metadata.emplace(camel_key_str, aistr); } } @@ -469,7 +477,7 @@ void ColladaParser::ReadAnimationLibrary(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string currentName = currentNode.name(); if (currentName == "animation") { ReadAnimation(currentNode, &mAnims); @@ -506,7 +514,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) { animID = idAttr.as_string(); } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string currentName = currentNode.name(); if (currentName == "animation") { if (!anim) { @@ -563,7 +571,7 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) { // ------------------------------------------------------------------------------------------------ // Reads an animation sampler into the given anim channel void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) { - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string currentName = currentNode.name(); if (currentName == "input") { if (XmlParser::hasAttribute(currentNode, "semantic")) { @@ -618,7 +626,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll // initial values pController.mType = Skin; pController.mMethod = Normalized; - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "morph") { pController.mType = Morph; @@ -670,7 +678,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll // ------------------------------------------------------------------------------------------------ // Reads the joint definitions for the given controller void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pController) { - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string currentName = currentNode.name(); if (currentName == "input") { const char *attrSemantic = currentNode.attribute("semantic").as_string(); @@ -698,7 +706,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC int vertexCount=0; XmlParser::getIntAttribute(node, "count", vertexCount); - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { std::string currentName = currentNode.name(); if (currentName == "input") { InputChannel channel; @@ -763,9 +771,9 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string name = currentNode.name(); - if (name == "image") { + for (XmlNode currentNode : node.children()) { + const std::string ¤tName = currentNode.name(); + if (currentName == "image") { std::string id = currentNode.attribute("id").as_string(); mImageLibrary[id] = Image(); @@ -778,7 +786,7 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) { // ------------------------------------------------------------------------------------------------ // Reads an image entry into the given image void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) { - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string currentName = currentNode.name(); if (currentName == "image") { // Ignore @@ -861,8 +869,7 @@ void ColladaParser::ReadMaterialLibrary(XmlNode &node) { } std::map names; - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { - const std::string currentName = currentNode.name(); + for (XmlNode currentNode : node.children()) { std::string id = currentNode.attribute("id").as_string(); std::string name = currentNode.attribute("name").as_string(); mMaterialLibrary[id] = Material(); @@ -891,7 +898,7 @@ void ColladaParser::ReadLightLibrary(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "light") { std::string id = currentNode.attribute("id").as_string(); @@ -907,7 +914,7 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "camera") { std::string id = currentNode.attribute("id").as_string(); @@ -1032,7 +1039,7 @@ void ColladaParser::ReadEffectLibrary(XmlNode &node) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "effect") { // read ID. Do I have to repeat my ranting about "optional" attributes? @@ -1051,7 +1058,7 @@ void ColladaParser::ReadEffectLibrary(XmlNode &node) { // ------------------------------------------------------------------------------------------------ // Reads an effect entry into the given effect void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) { - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "profile_COMMON") { ReadEffectProfileCommon(currentNode, pEffect); @@ -1330,7 +1337,7 @@ void ColladaParser::ReadGeometryLibrary(XmlNode &node) { if (node.empty()) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "geometry") { // read ID. Another entry which is "optional" by design but obligatory in reality @@ -1359,7 +1366,7 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) { if (node.empty()) { return; } - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "mesh") { ReadMesh(currentNode, pMesh); @@ -1383,7 +1390,9 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) { ReadSource(currentNode); } else if (currentName == "vertices") { ReadVertexData(currentNode, pMesh); - } else if (currentName == "triangles" || currentName == "lines" || currentName == "linestrips" || currentName == "polygons" || currentName == "polylist" || currentName == "trifans" || currentName == "tristrips") { + } else if (currentName == "triangles" || currentName == "lines" || currentName == "linestrips" || + currentName == "polygons" || currentName == "polylist" || currentName == "trifans" || + currentName == "tristrips") { ReadIndexData(currentNode, pMesh); } } @@ -1575,7 +1584,7 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) { void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) { // extract the ID of the element. Not that we care, but to catch strange referencing schemes we should warn about XmlParser::getStdStrAttribute(node, "id", pMesh.mVertexID); - for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { + for (XmlNode currentNode : node.children()) { const std::string ¤tName = currentNode.name(); if (currentName == "input") { ReadInputChannel(currentNode, pMesh.mPerVertexData); @@ -1733,20 +1742,20 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector 0); - - va_end(args); - ASSIMP_LOG_WARN_F("Validation warning: ", std::string(szBuffer, iLen)); -} - // ------------------------------------------------------------------------------------------------ // Calculates the resulting transformation from all the given transform steps aiMatrix4x4 ColladaParser::CalculateResultTransform(const std::vector &pTransforms) const { diff --git a/code/AssetLib/Collada/ColladaParser.h b/code/AssetLib/Collada/ColladaParser.h index 4b26b179c..5b8526b47 100644 --- a/code/AssetLib/Collada/ColladaParser.h +++ b/code/AssetLib/Collada/ColladaParser.h @@ -243,8 +243,6 @@ protected: void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive); protected: - void ReportWarning(const char *msg, ...); - /** Calculates the resulting transformation from all the given transform steps */ aiMatrix4x4 CalculateResultTransform(const std::vector &pTransforms) const; @@ -260,56 +258,55 @@ protected: std::string mFileName; // XML reader, member for everyday use - //irr::io::IrrXMLReader *mReader; XmlParser mXmlParser; /** 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 DataLibrary; + using DataLibrary = std::map ; DataLibrary mDataLibrary; /** Same for accessors which define how the data in a data array is accessed. */ - typedef std::map AccessorLibrary; + using AccessorLibrary = std::map ; AccessorLibrary mAccessorLibrary; /** Mesh library: mesh by ID */ - typedef std::map MeshLibrary; + using MeshLibrary = std::map; MeshLibrary mMeshLibrary; /** node library: root node of the hierarchy part by ID */ - typedef std::map NodeLibrary; + using NodeLibrary = std::map; NodeLibrary mNodeLibrary; /** Image library: stores texture properties by ID */ - typedef std::map ImageLibrary; + using ImageLibrary = std::map ; ImageLibrary mImageLibrary; /** Effect library: surface attributes by ID */ - typedef std::map EffectLibrary; + using EffectLibrary = std::map ; EffectLibrary mEffectLibrary; /** Material library: surface material by ID */ - typedef std::map MaterialLibrary; + using MaterialLibrary = std::map ; MaterialLibrary mMaterialLibrary; /** Light library: surface light by ID */ - typedef std::map LightLibrary; + using LightLibrary = std::map ; LightLibrary mLightLibrary; /** Camera library: surface material by ID */ - typedef std::map CameraLibrary; + using CameraLibrary = std::map ; CameraLibrary mCameraLibrary; /** Controller library: joint controllers by ID */ - typedef std::map ControllerLibrary; + using ControllerLibrary = std::map ; ControllerLibrary mControllerLibrary; /** Animation library: animation references by ID */ - typedef std::map AnimationLibrary; + using AnimationLibrary = std::map ; AnimationLibrary mAnimationLibrary; /** Animation clip library: clip animation references by ID */ - typedef std::vector>> AnimationClipLibrary; + using AnimationClipLibrary = std::vector>> ; AnimationClipLibrary mAnimationClipLibrary; /** Pointer to the root node. Don't delete, it just points to one of @@ -334,13 +331,6 @@ protected: 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 diff --git a/include/assimp/StringUtils.h b/include/assimp/StringUtils.h index 3abf4ca20..21942eed4 100644 --- a/include/assimp/StringUtils.h +++ b/include/assimp/StringUtils.h @@ -44,22 +44,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define INCLUDED_AI_STRINGUTILS_H #ifdef __GNUC__ -# pragma GCC system_header +#pragma GCC system_header #endif #include -#include #include -#include -#include +#include #include +#include #include +#include #ifdef _MSC_VER -# define AI_SIZEFMT "%Iu" +#define AI_SIZEFMT "%Iu" #else -# define AI_SIZEFMT "%zu" +#define AI_SIZEFMT "%zu" #endif /// @fn ai_snprintf @@ -71,35 +71,35 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /// @return The number of written characters if the buffer size was big enough. If an encoding error occurs, a negative number is returned. #if defined(_MSC_VER) && _MSC_VER < 1900 - AI_FORCE_INLINE - int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) { - int count(-1); - if (0 != size) { - count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); - } - if (count == -1) { - count = _vscprintf(format, ap); - } +AI_FORCE_INLINE +int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) { + int count(-1); + if (0 != size) { + count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); + } + if (count == -1) { + count = _vscprintf(format, ap); + } - return count; - } + return count; +} - AI_FORCE_INLINE - int ai_snprintf(char *outBuf, size_t size, const char *format, ...) { - int count; - va_list ap; +AI_FORCE_INLINE +int ai_snprintf(char *outBuf, size_t size, const char *format, ...) { + int count; + va_list ap; - va_start(ap, format); - count = c99_ai_vsnprintf(outBuf, size, format, ap); - va_end(ap); + va_start(ap, format); + count = c99_ai_vsnprintf(outBuf, size, format, ap); + va_end(ap); - return count; - } + return count; +} #elif defined(__MINGW32__) -# define ai_snprintf __mingw_snprintf +#define ai_snprintf __mingw_snprintf #else -# define ai_snprintf snprintf +#define ai_snprintf snprintf #endif /// @fn to_string @@ -107,8 +107,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /// @param value The value to write into the std::string. /// @return The value as a std::string template -AI_FORCE_INLINE -std::string to_string( T value ) { +AI_FORCE_INLINE std::string to_string(T value) { std::ostringstream os; os << value; @@ -121,17 +120,17 @@ std::string to_string( T value ) { /// @param end The last character /// @return The float value, 0.0f in cas of an error. AI_FORCE_INLINE -float ai_strtof( const char *begin, const char *end ) { - if ( nullptr == begin ) { +float ai_strtof(const char *begin, const char *end) { + if (nullptr == begin) { return 0.0f; } - float val( 0.0f ); - if ( nullptr == end ) { - val = static_cast< float >( ::atof( begin ) ); + float val(0.0f); + if (nullptr == end) { + val = static_cast(::atof(begin)); } else { - std::string::size_type len( end - begin ); - std::string token( begin, len ); - val = static_cast< float >( ::atof( token.c_str() ) ); + std::string::size_type len(end - begin); + std::string token(begin, len); + val = static_cast(::atof(token.c_str())); } return val; @@ -141,16 +140,15 @@ float ai_strtof( const char *begin, const char *end ) { /// @brief The portable to convert a decimal value into a hexadecimal string. /// @param toConvert Value to convert /// @return The hexadecimal string, is empty in case of an error. -template -AI_FORCE_INLINE -std::string DecimalToHexa( T toConvert ) { +template +AI_FORCE_INLINE std::string DecimalToHexa(T toConvert) { std::string result; std::stringstream ss; ss << std::hex << toConvert; ss >> result; - for ( size_t i = 0; i < result.size(); ++i ) { - result[ i ] = (char) toupper( result[ i ] ); + for (size_t i = 0; i < result.size(); ++i) { + result[i] = (char)toupper(result[i]); } return result; @@ -164,31 +162,32 @@ std::string DecimalToHexa( T toConvert ) { /// @param with_head # /// @return The hexadecimal string, is empty in case of an error. AI_FORCE_INLINE std::string Rgba2Hex(int r, int g, int b, int a, bool with_head) { - std::stringstream ss; - if (with_head) { - ss << "#"; + std::stringstream ss; + if (with_head) { + ss << "#"; } - ss << std::hex << (r << 24 | g << 16 | b << 8 | a); + ss << std::hex << (r << 24 | g << 16 | b << 8 | a); return ss.str(); } // trim from start (in place) -inline void ltrim(std::string &s) { +AI_FORCE_INLINE void ltrim(std::string &s) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); })); } // trim from end (in place) -inline void rtrim(std::string &s) { +AI_FORCE_INLINE void rtrim(std::string &s) { s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); - }).base(), s.end()); + }).base(), + s.end()); } // trim from both ends (in place) -inline void trim(std::string &s) { +AI_FORCE_INLINE void trim(std::string &s) { ltrim(s); rtrim(s); } diff --git a/include/assimp/XmlParser.h b/include/assimp/XmlParser.h index 9dca314de..3d430a278 100644 --- a/include/assimp/XmlParser.h +++ b/include/assimp/XmlParser.h @@ -179,7 +179,7 @@ public: return true; } - static inline bool getFloatAttribute( XmlNode &xmlNode, const char *name, float &val ) { + static inline bool getFloatAttribute(XmlNode &xmlNode, const char *name, float &val ) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) { return false; @@ -190,6 +190,16 @@ public: } + static inline bool getDoubleAttribute( XmlNode &xmlNode, const char *name, double &val ) { + pugi::xml_attribute attr = xmlNode.attribute(name); + if (attr.empty()) { + return false; + } + + val = attr.as_double(); + return true; + } + static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) { pugi::xml_attribute attr = xmlNode.attribute(name); if (attr.empty()) {