Merge branch 'master' into fbxReportAssetIssuesProperly
commit
b842b4a3c1
|
@ -1,3 +1,2 @@
|
||||||
patreon: assimp
|
patreon: assimp
|
||||||
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4
|
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4
|
||||||
open_collective: assimp
|
|
||||||
|
|
|
@ -353,7 +353,7 @@ ELSE()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# Only generate this target if no higher-level project already has
|
# Only generate this target if no higher-level project already has
|
||||||
IF (NOT TARGET uninstall)
|
IF (NOT TARGET uninstall AND ASSIMP_INSTALL)
|
||||||
# add make uninstall capability
|
# add make uninstall capability
|
||||||
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
|
||||||
ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||||
|
|
|
@ -16,5 +16,5 @@ set(RT_LIBRARIES ${RT_LIBRARY})
|
||||||
# handle the QUIETLY and REQUIRED arguments and set
|
# handle the QUIETLY and REQUIRED arguments and set
|
||||||
# RT_FOUND to TRUE if all listed variables are TRUE
|
# RT_FOUND to TRUE if all listed variables are TRUE
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
find_package_handle_standard_args(rt DEFAULT_MSG RT_LIBRARY)
|
find_package_handle_standard_args(RT DEFAULT_MSG RT_LIBRARY)
|
||||||
mark_as_advanced(RT_LIBRARY)
|
mark_as_advanced(RT_LIBRARY)
|
||||||
|
|
|
@ -8,6 +8,7 @@ find_package(openddlparser CONFIG REQUIRED)
|
||||||
find_package(poly2tri CONFIG REQUIRED)
|
find_package(poly2tri CONFIG REQUIRED)
|
||||||
find_package(polyclipping CONFIG REQUIRED)
|
find_package(polyclipping CONFIG REQUIRED)
|
||||||
find_package(zip CONFIG REQUIRED)
|
find_package(zip CONFIG REQUIRED)
|
||||||
|
find_package(pugixml CONFIG REQUIRED)
|
||||||
|
|
||||||
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
|
include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
|
||||||
check_required_components("@PROJECT_NAME@")
|
check_required_components("@PROJECT_NAME@")
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
/** Helper structures for the Collada loader */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Open Asset Import Library (assimp)
|
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"
|
#include "ColladaHelper.h"
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
/** Helper structures for the Collada loader */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -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
|
#ifndef AI_COLLADAHELPER_H_INC
|
||||||
#define AI_COLLADAHELPER_H_INC
|
#define AI_COLLADAHELPER_H_INC
|
||||||
|
|
||||||
#include <assimp/light.h>
|
#include <assimp/light.h>
|
||||||
#include <assimp/material.h>
|
#include <assimp/material.h>
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -58,14 +58,14 @@ struct aiMaterial;
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Collada {
|
namespace Collada {
|
||||||
|
|
||||||
/** Collada file versions which evolved during the years ... */
|
/// Collada file versions which evolved during the years ...
|
||||||
enum FormatVersion {
|
enum FormatVersion {
|
||||||
FV_1_5_n,
|
FV_1_5_n,
|
||||||
FV_1_4_n,
|
FV_1_4_n,
|
||||||
FV_1_3_n
|
FV_1_3_n
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Transformation types that can be applied to a node */
|
/// Transformation types that can be applied to a node
|
||||||
enum TransformType {
|
enum TransformType {
|
||||||
TF_LOOKAT,
|
TF_LOOKAT,
|
||||||
TF_ROTATE,
|
TF_ROTATE,
|
||||||
|
@ -75,7 +75,7 @@ enum TransformType {
|
||||||
TF_MATRIX
|
TF_MATRIX
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Different types of input data to a vertex or face */
|
/// Different types of input data to a vertex or face
|
||||||
enum InputType {
|
enum InputType {
|
||||||
IT_Invalid,
|
IT_Invalid,
|
||||||
IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data.
|
IT_Vertex, // special type for per-index data referring to the <vertices> element carrying the per-vertex data.
|
||||||
|
@ -87,38 +87,39 @@ enum InputType {
|
||||||
IT_Bitangent
|
IT_Bitangent
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Supported controller types */
|
/// Supported controller types
|
||||||
enum ControllerType {
|
enum ControllerType {
|
||||||
Skin,
|
Skin,
|
||||||
Morph
|
Morph
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Supported morph methods */
|
/// Supported morph methods
|
||||||
enum MorphMethod {
|
enum MorphMethod {
|
||||||
Normalized,
|
Normalized,
|
||||||
Relative
|
Relative
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Common metadata keys as <Collada, Assimp> */
|
/// Common metadata keys as <Collada, Assimp>
|
||||||
typedef std::pair<std::string, std::string> MetaKeyPair;
|
using MetaKeyPair = std::pair<std::string, std::string>;
|
||||||
typedef std::vector<MetaKeyPair> MetaKeyPairVector;
|
using MetaKeyPairVector = std::vector<MetaKeyPair>;
|
||||||
|
|
||||||
// Collada as lower_case (native)
|
/// Collada as lower_case (native)
|
||||||
const MetaKeyPairVector &GetColladaAssimpMetaKeys();
|
const MetaKeyPairVector &GetColladaAssimpMetaKeys();
|
||||||
|
|
||||||
// Collada as CamelCase (used by Assimp for consistency)
|
// Collada as CamelCase (used by Assimp for consistency)
|
||||||
const MetaKeyPairVector &GetColladaAssimpMetaKeysCamelCase();
|
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);
|
void ToCamelCase(std::string &text);
|
||||||
|
|
||||||
/** Contains all data for one of the different transformation types */
|
/// Contains all data for one of the different transformation types
|
||||||
struct Transform {
|
struct Transform {
|
||||||
std::string mID; ///< SID of the transform step, by which anim channels address their target node
|
std::string mID; ///< SID of the transform step, by which anim channels address their target node
|
||||||
TransformType mType;
|
TransformType mType;
|
||||||
ai_real f[16]; ///< Interpretation of data depends on the type of the transformation
|
ai_real f[16]; ///< Interpretation of data depends on the type of the transformation
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A collada camera. */
|
/// A collada camera.
|
||||||
struct Camera {
|
struct Camera {
|
||||||
Camera() :
|
Camera() :
|
||||||
mOrtho(false),
|
mOrtho(false),
|
||||||
|
@ -128,22 +129,22 @@ struct Camera {
|
||||||
mZNear(0.1f),
|
mZNear(0.1f),
|
||||||
mZFar(1000.f) {}
|
mZFar(1000.f) {}
|
||||||
|
|
||||||
// Name of camera
|
/// Name of camera
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
// True if it is an orthografic camera
|
/// True if it is an orthographic camera
|
||||||
bool mOrtho;
|
bool mOrtho;
|
||||||
|
|
||||||
//! Horizontal field of view in degrees
|
/// Horizontal field of view in degrees
|
||||||
ai_real mHorFov;
|
ai_real mHorFov;
|
||||||
|
|
||||||
//! Vertical field of view in degrees
|
/// Vertical field of view in degrees
|
||||||
ai_real mVerFov;
|
ai_real mVerFov;
|
||||||
|
|
||||||
//! Screen aspect
|
/// Screen aspect
|
||||||
ai_real mAspect;
|
ai_real mAspect;
|
||||||
|
|
||||||
//! Near& far z
|
/// Near& far z
|
||||||
ai_real mZNear, mZFar;
|
ai_real mZNear, mZFar;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -162,27 +163,27 @@ struct Light {
|
||||||
mOuterAngle(ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET),
|
mOuterAngle(ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET),
|
||||||
mIntensity(1.f) {}
|
mIntensity(1.f) {}
|
||||||
|
|
||||||
//! Type of the light source aiLightSourceType + ambient
|
/// Type of the light source aiLightSourceType + ambient
|
||||||
unsigned int mType;
|
unsigned int mType;
|
||||||
|
|
||||||
//! Color of the light
|
/// Color of the light
|
||||||
aiColor3D mColor;
|
aiColor3D mColor;
|
||||||
|
|
||||||
//! Light attenuation
|
/// Light attenuation
|
||||||
ai_real mAttConstant, mAttLinear, mAttQuadratic;
|
ai_real mAttConstant, mAttLinear, mAttQuadratic;
|
||||||
|
|
||||||
//! Spot light falloff
|
/// Spot light falloff
|
||||||
ai_real mFalloffAngle;
|
ai_real mFalloffAngle;
|
||||||
ai_real mFalloffExponent;
|
ai_real mFalloffExponent;
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
// FCOLLADA extension from here
|
// FCOLLADA extension from here
|
||||||
|
|
||||||
//! ... related stuff from maja and max extensions
|
/// ... related stuff from maja and max extensions
|
||||||
ai_real mPenumbraAngle;
|
ai_real mPenumbraAngle;
|
||||||
ai_real mOuterAngle;
|
ai_real mOuterAngle;
|
||||||
|
|
||||||
//! Common light intensity
|
/// Common light intensity
|
||||||
ai_real mIntensity;
|
ai_real mIntensity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -192,30 +193,29 @@ struct InputSemanticMapEntry {
|
||||||
mSet(0),
|
mSet(0),
|
||||||
mType(IT_Invalid) {}
|
mType(IT_Invalid) {}
|
||||||
|
|
||||||
//! Index of set, optional
|
/// Index of set, optional
|
||||||
unsigned int mSet;
|
unsigned int mSet;
|
||||||
|
|
||||||
//! Type of referenced vertex input
|
/// Type of referenced vertex input
|
||||||
InputType mType;
|
InputType mType;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Table to map from effect to vertex input semantics */
|
/// Table to map from effect to vertex input semantics
|
||||||
struct SemanticMappingTable {
|
struct SemanticMappingTable {
|
||||||
//! Name of material
|
/// Name of material
|
||||||
std::string mMatName;
|
std::string mMatName;
|
||||||
|
|
||||||
//! List of semantic map commands, grouped by effect semantic name
|
/// List of semantic map commands, grouped by effect semantic name
|
||||||
std::map<std::string, InputSemanticMapEntry> mMap;
|
std::map<std::string, InputSemanticMapEntry> mMap;
|
||||||
|
|
||||||
//! For std::find
|
/// For std::find
|
||||||
bool operator==(const std::string &s) const {
|
bool operator==(const std::string &s) const {
|
||||||
return s == mMatName;
|
return s == mMatName;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A reference to a mesh inside a node, including materials assigned to the various subgroups.
|
/// A reference to a mesh inside a node, including materials assigned to the various subgroups.
|
||||||
* The ID refers to either a mesh or a controller which specifies the mesh
|
/// The ID refers to either a mesh or a controller which specifies the mesh
|
||||||
*/
|
|
||||||
struct MeshInstance {
|
struct MeshInstance {
|
||||||
///< ID of the mesh or controller to be instanced
|
///< ID of the mesh or controller to be instanced
|
||||||
std::string mMeshOrController;
|
std::string mMeshOrController;
|
||||||
|
@ -224,25 +224,25 @@ struct MeshInstance {
|
||||||
std::map<std::string, SemanticMappingTable> mMaterials;
|
std::map<std::string, SemanticMappingTable> mMaterials;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A reference to a camera inside a node*/
|
/// A reference to a camera inside a node
|
||||||
struct CameraInstance {
|
struct CameraInstance {
|
||||||
///< ID of the camera
|
///< ID of the camera
|
||||||
std::string mCamera;
|
std::string mCamera;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A reference to a light inside a node*/
|
/// A reference to a light inside a node
|
||||||
struct LightInstance {
|
struct LightInstance {
|
||||||
///< ID of the camera
|
///< ID of the camera
|
||||||
std::string mLight;
|
std::string mLight;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A reference to a node inside a node*/
|
/// A reference to a node inside a node
|
||||||
struct NodeInstance {
|
struct NodeInstance {
|
||||||
///< ID of the node
|
///< ID of the node
|
||||||
std::string mNode;
|
std::string mNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A node in a scene hierarchy */
|
/// A node in a scene hierarchy
|
||||||
struct Node {
|
struct Node {
|
||||||
std::string mName;
|
std::string mName;
|
||||||
std::string mID;
|
std::string mID;
|
||||||
|
@ -250,52 +250,53 @@ struct Node {
|
||||||
Node *mParent;
|
Node *mParent;
|
||||||
std::vector<Node *> mChildren;
|
std::vector<Node *> mChildren;
|
||||||
|
|
||||||
/** Operations in order to calculate the resulting transformation to parent. */
|
/// Operations in order to calculate the resulting transformation to parent.
|
||||||
std::vector<Transform> mTransforms;
|
std::vector<Transform> mTransforms;
|
||||||
|
|
||||||
/** Meshes at this node */
|
/// Meshes at this node
|
||||||
std::vector<MeshInstance> mMeshes;
|
std::vector<MeshInstance> mMeshes;
|
||||||
|
|
||||||
/** Lights at this node */
|
/// Lights at this node
|
||||||
std::vector<LightInstance> mLights;
|
std::vector<LightInstance> mLights;
|
||||||
|
|
||||||
/** Cameras at this node */
|
/// Cameras at this node
|
||||||
std::vector<CameraInstance> mCameras;
|
std::vector<CameraInstance> mCameras;
|
||||||
|
|
||||||
/** Node instances at this node */
|
/// Node instances at this node
|
||||||
std::vector<NodeInstance> mNodeInstances;
|
std::vector<NodeInstance> mNodeInstances;
|
||||||
|
|
||||||
/** Root-nodes: Name of primary camera, if any */
|
/// Root-nodes: Name of primary camera, if any
|
||||||
std::string mPrimaryCamera;
|
std::string mPrimaryCamera;
|
||||||
|
|
||||||
//! Constructor. Begin with a zero parent
|
/// Constructor. Begin with a zero parent
|
||||||
Node() :
|
Node() :
|
||||||
mParent(nullptr) {
|
mParent(nullptr) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Destructor: delete all children subsequently
|
/// Destructor: delete all children subsequently
|
||||||
~Node() {
|
~Node() {
|
||||||
for (std::vector<Node *>::iterator it = mChildren.begin(); it != mChildren.end(); ++it)
|
for (std::vector<Node *>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) {
|
||||||
delete *it;
|
delete *it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Data source array: either floats or strings */
|
/// Data source array: either floats or strings
|
||||||
struct Data {
|
struct Data {
|
||||||
bool mIsStringArray;
|
bool mIsStringArray;
|
||||||
std::vector<ai_real> mValues;
|
std::vector<ai_real> mValues;
|
||||||
std::vector<std::string> mStrings;
|
std::vector<std::string> mStrings;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Accessor to a data array */
|
/// Accessor to a data array
|
||||||
struct Accessor {
|
struct Accessor {
|
||||||
size_t mCount; // in number of objects
|
size_t mCount; // in number of objects
|
||||||
size_t mSize; // size of an object, in elements (floats or strings, mostly 1)
|
size_t mSize; // size of an object, in elements (floats or strings, mostly 1)
|
||||||
size_t mOffset; // in number of values
|
size_t mOffset; // in number of values
|
||||||
size_t mStride; // Stride in number of values
|
size_t mStride; // Stride in number of values
|
||||||
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
|
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
|
||||||
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on.
|
size_t mSubOffset[4]; // 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.
|
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
|
||||||
std::string mSource; // URL of the source array
|
std::string mSource; // URL of the source array
|
||||||
mutable const Data *mData; // Pointer to the source array, if resolved. nullptr else
|
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 {
|
struct Face {
|
||||||
std::vector<size_t> mIndices;
|
std::vector<size_t> mIndices;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An input channel for mesh data, referring to a single accessor */
|
/// An input channel for mesh data, referring to a single accessor
|
||||||
struct InputChannel {
|
struct InputChannel {
|
||||||
InputType mType; // Type of the data
|
InputType mType; // Type of the data
|
||||||
size_t mIndex; // Optional index, if multiple sets of the same data type are given
|
size_t mIndex; // Optional index, if multiple sets of the same data type are given
|
||||||
|
@ -331,18 +332,19 @@ struct InputChannel {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Subset of a mesh with a certain material */
|
/// Subset of a mesh with a certain material
|
||||||
struct SubMesh {
|
struct SubMesh {
|
||||||
std::string mMaterial; ///< subgroup identifier
|
std::string mMaterial; ///< subgroup identifier
|
||||||
size_t mNumFaces; ///< number of faces in this submesh
|
size_t mNumFaces; ///< number of faces in this sub-mesh
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Contains data for a single mesh */
|
/// Contains data for a single mesh
|
||||||
struct Mesh {
|
struct Mesh {
|
||||||
Mesh(const std::string &id) :
|
Mesh(const std::string &id) :
|
||||||
mId(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;
|
mNumUVComponents[i] = 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string mId;
|
const std::string mId;
|
||||||
|
@ -373,11 +375,11 @@ struct Mesh {
|
||||||
// necessary for bone weight assignment
|
// necessary for bone weight assignment
|
||||||
std::vector<size_t> mFacePosIndices;
|
std::vector<size_t> mFacePosIndices;
|
||||||
|
|
||||||
// Submeshes in this mesh, each with a given material
|
// Sub-meshes in this mesh, each with a given material
|
||||||
std::vector<SubMesh> mSubMeshes;
|
std::vector<SubMesh> 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 {
|
enum PrimitiveType {
|
||||||
Prim_Invalid,
|
Prim_Invalid,
|
||||||
Prim_Lines,
|
Prim_Lines,
|
||||||
|
@ -389,7 +391,7 @@ enum PrimitiveType {
|
||||||
Prim_Polygon
|
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 {
|
struct Controller {
|
||||||
// controller type
|
// controller type
|
||||||
ControllerType mType;
|
ControllerType mType;
|
||||||
|
@ -424,25 +426,25 @@ struct Controller {
|
||||||
std::string mMorphWeight;
|
std::string mMorphWeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A collada material. Pretty much the only member is a reference to an effect. */
|
/// A collada material. Pretty much the only member is a reference to an effect.
|
||||||
struct Material {
|
struct Material {
|
||||||
std::string mName;
|
std::string mName;
|
||||||
std::string mEffect;
|
std::string mEffect;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Type of the effect param */
|
/// Type of the effect param
|
||||||
enum ParamType {
|
enum ParamType {
|
||||||
Param_Sampler,
|
Param_Sampler,
|
||||||
Param_Surface
|
Param_Surface
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them */
|
/// A param for an effect. Might be of several types, but they all just refer to each other, so I summarize them
|
||||||
struct EffectParam {
|
struct EffectParam {
|
||||||
ParamType mType;
|
ParamType mType;
|
||||||
std::string mReference; // to which other thing the param is referring to.
|
std::string mReference; // to which other thing the param is referring to.
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Shading type supported by the standard effect spec of Collada */
|
/// Shading type supported by the standard effect spec of Collada
|
||||||
enum ShadeType {
|
enum ShadeType {
|
||||||
Shade_Invalid,
|
Shade_Invalid,
|
||||||
Shade_Constant,
|
Shade_Constant,
|
||||||
|
@ -451,7 +453,7 @@ enum ShadeType {
|
||||||
Shade_Blinn
|
Shade_Blinn
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Represents a texture sampler in collada */
|
/// Represents a texture sampler in collada
|
||||||
struct Sampler {
|
struct Sampler {
|
||||||
Sampler() :
|
Sampler() :
|
||||||
mWrapU(true),
|
mWrapU(true),
|
||||||
|
@ -463,77 +465,66 @@ struct Sampler {
|
||||||
mWeighting(1.f),
|
mWeighting(1.f),
|
||||||
mMixWithPrevious(1.f) {}
|
mMixWithPrevious(1.f) {}
|
||||||
|
|
||||||
/** Name of image reference
|
/// Name of image reference
|
||||||
*/
|
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
/** Wrap U?
|
/// Wrap U?
|
||||||
*/
|
|
||||||
bool mWrapU;
|
bool mWrapU;
|
||||||
|
|
||||||
/** Wrap V?
|
/// Wrap V?
|
||||||
*/
|
|
||||||
bool mWrapV;
|
bool mWrapV;
|
||||||
|
|
||||||
/** Mirror U?
|
/// Mirror U?
|
||||||
*/
|
|
||||||
bool mMirrorU;
|
bool mMirrorU;
|
||||||
|
|
||||||
/** Mirror V?
|
/// Mirror V?
|
||||||
*/
|
|
||||||
bool mMirrorV;
|
bool mMirrorV;
|
||||||
|
|
||||||
/** Blend mode
|
/// Blend mode
|
||||||
*/
|
|
||||||
aiTextureOp mOp;
|
aiTextureOp mOp;
|
||||||
|
|
||||||
/** UV transformation
|
/// UV transformation
|
||||||
*/
|
|
||||||
aiUVTransform mTransform;
|
aiUVTransform mTransform;
|
||||||
|
|
||||||
/** Name of source UV channel
|
/// Name of source UV channel
|
||||||
*/
|
|
||||||
std::string mUVChannel;
|
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;
|
unsigned int mUVId;
|
||||||
|
|
||||||
// OKINO/MAX3D extensions from here
|
// OKINO/MAX3D extensions from here
|
||||||
// -------------------------------------------------------
|
// -------------------------------------------------------
|
||||||
|
|
||||||
/** Weighting factor
|
/// Weighting factor
|
||||||
*/
|
|
||||||
ai_real mWeighting;
|
ai_real mWeighting;
|
||||||
|
|
||||||
/** Mixing factor from OKINO
|
/// Mixing factor from OKINO
|
||||||
*/
|
|
||||||
ai_real mMixWithPrevious;
|
ai_real mMixWithPrevious;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A collada effect. Can contain about anything according to the Collada spec,
|
/// A collada effect. Can contain about anything according to the Collada spec,
|
||||||
but we limit our version to a reasonable subset. */
|
/// but we limit our version to a reasonable subset.
|
||||||
struct Effect {
|
struct Effect {
|
||||||
// Shading mode
|
/// Shading mode
|
||||||
ShadeType mShadeType;
|
ShadeType mShadeType;
|
||||||
|
|
||||||
// Colors
|
/// Colors
|
||||||
aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular,
|
aiColor4D mEmissive, mAmbient, mDiffuse, mSpecular,
|
||||||
mTransparent, mReflective;
|
mTransparent, mReflective;
|
||||||
|
|
||||||
// Textures
|
/// Textures
|
||||||
Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular,
|
Sampler mTexEmissive, mTexAmbient, mTexDiffuse, mTexSpecular,
|
||||||
mTexTransparent, mTexBump, mTexReflective;
|
mTexTransparent, mTexBump, mTexReflective;
|
||||||
|
|
||||||
// Scalar factory
|
/// Scalar factory
|
||||||
ai_real mShininess, mRefractIndex, mReflectivity;
|
ai_real mShininess, mRefractIndex, mReflectivity;
|
||||||
ai_real mTransparency;
|
ai_real mTransparency;
|
||||||
bool mHasTransparency;
|
bool mHasTransparency;
|
||||||
bool mRGBTransparency;
|
bool mRGBTransparency;
|
||||||
bool mInvertTransparency;
|
bool mInvertTransparency;
|
||||||
|
|
||||||
// local params referring to each other by their SID
|
/// local params referring to each other by their SID
|
||||||
typedef std::map<std::string, Collada::EffectParam> ParamLibrary;
|
using ParamLibrary = std::map<std::string, Collada::EffectParam>;
|
||||||
ParamLibrary mParams;
|
ParamLibrary mParams;
|
||||||
|
|
||||||
// MAX3D extensions
|
// MAX3D extensions
|
||||||
|
@ -561,65 +552,64 @@ struct Effect {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An image, meaning texture */
|
/// An image, meaning texture
|
||||||
struct Image {
|
struct Image {
|
||||||
std::string mFileName;
|
std::string mFileName;
|
||||||
|
|
||||||
/** Embedded image data */
|
/// Embedded image data
|
||||||
std::vector<uint8_t> mImageData;
|
std::vector<uint8_t> mImageData;
|
||||||
|
|
||||||
/** File format hint of embedded image data */
|
/// File format hint of embedded image data
|
||||||
std::string mEmbeddedFormat;
|
std::string mEmbeddedFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** An animation channel. */
|
/// An animation channel.
|
||||||
struct AnimationChannel {
|
struct AnimationChannel {
|
||||||
/** URL of the data to animate. Could be about anything, but we support only the
|
/// URL of the data to animate. Could be about anything, but we support only the
|
||||||
* "NodeID/TransformID.SubElement" notation
|
/// "NodeID/TransformID.SubElement" notation
|
||||||
*/
|
|
||||||
std::string mTarget;
|
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;
|
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;
|
std::string mSourceValues;
|
||||||
/** Source URL of the IN_TANGENT semantic values. */
|
/// Source URL of the IN_TANGENT semantic values.
|
||||||
std::string mInTanValues;
|
std::string mInTanValues;
|
||||||
/** Source URL of the OUT_TANGENT semantic values. */
|
/// Source URL of the OUT_TANGENT semantic values.
|
||||||
std::string mOutTanValues;
|
std::string mOutTanValues;
|
||||||
/** Source URL of the INTERPOLATION semantic values. */
|
/// Source URL of the INTERPOLATION semantic values.
|
||||||
std::string mInterpolationValues;
|
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 {
|
struct Animation {
|
||||||
/** Anim name */
|
/// Anim name
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
/** the animation channels, if any */
|
/// the animation channels, if any
|
||||||
std::vector<AnimationChannel> mChannels;
|
std::vector<AnimationChannel> mChannels;
|
||||||
|
|
||||||
/** the sub-animations, if any */
|
/// the sub-animations, if any
|
||||||
std::vector<Animation *> mSubAnims;
|
std::vector<Animation *> mSubAnims;
|
||||||
|
|
||||||
/** Destructor */
|
/// Destructor
|
||||||
~Animation() {
|
~Animation() {
|
||||||
for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
|
for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) {
|
||||||
delete *it;
|
delete *it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Collect all channels in the animation hierarchy into a single channel list. */
|
/// Collect all channels in the animation hierarchy into a single channel list.
|
||||||
void CollectChannelsRecursively(std::vector<AnimationChannel> &channels) {
|
void CollectChannelsRecursively(std::vector<AnimationChannel> &channels) {
|
||||||
channels.insert(channels.end(), mChannels.begin(), mChannels.end());
|
channels.insert(channels.end(), mChannels.begin(), mChannels.end());
|
||||||
|
|
||||||
for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) {
|
for (std::vector<Animation *>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it) {
|
||||||
Animation *pAnim = (*it);
|
Animation *pAnim = (*it);
|
||||||
|
|
||||||
pAnim->CollectChannelsRecursively(channels);
|
pAnim->CollectChannelsRecursively(channels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Combine all single-channel animations' channel into the same (parent) animation channel list. */
|
/// Combine all single-channel animations' channel into the same (parent) animation channel list.
|
||||||
void CombineSingleChannelAnimations() {
|
void CombineSingleChannelAnimations() {
|
||||||
CombineSingleChannelAnimationsRecursively(this);
|
CombineSingleChannelAnimationsRecursively(this);
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
struct ChannelEntry {
|
||||||
const Collada::AnimationChannel *mChannel; ///> the source channel
|
const Collada::AnimationChannel *mChannel; ///< the source channel
|
||||||
std::string mTargetId;
|
std::string mTargetId;
|
||||||
std::string mTransformId; // the ID of the transformation step of the node which is influenced
|
std::string mTransformId; // the ID of the transformation step of the node which is influenced
|
||||||
size_t mTransformIndex; // Index into the node's transform chain to apply the channel to
|
size_t mTransformIndex; // Index into the node's transform chain to apply the channel to
|
||||||
|
|
|
@ -55,12 +55,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <math.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <memory>
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
@ -331,13 +328,15 @@ void ColladaLoader::ResolveNodeInstances(const ColladaParser &pParser, const Col
|
||||||
// Resolve UV channels
|
// Resolve UV channels
|
||||||
void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler, const Collada::SemanticMappingTable &table) {
|
void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler &sampler, const Collada::SemanticMappingTable &table) {
|
||||||
std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel);
|
std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel);
|
||||||
if (it != table.mMap.end()) {
|
if (it == table.mMap.end()) {
|
||||||
if (it->second.mType != Collada::IT_Texcoord) {
|
return;
|
||||||
ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping");
|
|
||||||
}
|
|
||||||
|
|
||||||
sampler.mUVId = it->second.mSet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (it->second.mType != Collada::IT_Texcoord) {
|
||||||
|
ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping");
|
||||||
|
}
|
||||||
|
|
||||||
|
sampler.mUVId = it->second.mSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -48,7 +48,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "ColladaParser.h"
|
#include "ColladaParser.h"
|
||||||
#include <assimp/ParsingUtils.h>
|
#include <assimp/ParsingUtils.h>
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
#include <assimp/TinyFormatter.h>
|
|
||||||
#include <assimp/ZipArchiveIOSystem.h>
|
#include <assimp/ZipArchiveIOSystem.h>
|
||||||
#include <assimp/commonMetaData.h>
|
#include <assimp/commonMetaData.h>
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
|
@ -56,14 +55,47 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <memory>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace Assimp::Collada;
|
using namespace Assimp::Collada;
|
||||||
using namespace Assimp::Formatter;
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) {
|
||||||
|
for (size_t i = 0; i < key_renaming.size(); ++i) {
|
||||||
|
if (key_renaming[i].first == collada_key) {
|
||||||
|
found_index = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found_index = std::numeric_limits<size_t>::max();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void readUrlAttribute(XmlNode &node, std::string &url) {
|
||||||
|
url.clear();
|
||||||
|
if (!XmlParser::getStdStrAttribute(node, "url", url)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (url[0] != '#') {
|
||||||
|
throw DeadlyImportError("Unknown reference format");
|
||||||
|
}
|
||||||
|
url = url.c_str() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
|
ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
|
||||||
|
@ -137,10 +169,12 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
ColladaParser::~ColladaParser() {
|
ColladaParser::~ColladaParser() {
|
||||||
for (NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it)
|
for (NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it) {
|
||||||
delete it->second;
|
delete it->second;
|
||||||
for (MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it)
|
}
|
||||||
|
for (MeshLibrary::iterator it = mMeshLibrary.begin(); it != mMeshLibrary.end(); ++it) {
|
||||||
delete it->second;
|
delete it->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -254,35 +288,35 @@ void ColladaParser::ReadContents(XmlNode &node) {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads the structure of the file
|
// Reads the structure of the file
|
||||||
void ColladaParser::ReadStructure(XmlNode &node) {
|
void ColladaParser::ReadStructure(XmlNode &node) {
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string name = std::string(currentNode.name());
|
const std::string ¤tName = std::string(currentNode.name());
|
||||||
ASSIMP_LOG_DEBUG("last name" + name);
|
if (currentName == "asset") {
|
||||||
if (name == "asset")
|
|
||||||
ReadAssetInfo(currentNode);
|
ReadAssetInfo(currentNode);
|
||||||
else if (name == "library_animations")
|
} else if (currentName == "library_animations") {
|
||||||
ReadAnimationLibrary(currentNode);
|
ReadAnimationLibrary(currentNode);
|
||||||
else if (name == "library_animation_clips")
|
} else if (currentName == "library_animation_clips") {
|
||||||
ReadAnimationClipLibrary(currentNode);
|
ReadAnimationClipLibrary(currentNode);
|
||||||
else if (name == "library_controllers")
|
} else if (currentName == "library_controllers") {
|
||||||
ReadControllerLibrary(currentNode);
|
ReadControllerLibrary(currentNode);
|
||||||
else if (name == "library_images")
|
} else if (currentName == "library_images") {
|
||||||
ReadImageLibrary(currentNode);
|
ReadImageLibrary(currentNode);
|
||||||
else if (name == "library_materials")
|
} else if (currentName == "library_materials") {
|
||||||
ReadMaterialLibrary(currentNode);
|
ReadMaterialLibrary(currentNode);
|
||||||
else if (name == "library_effects")
|
} else if (currentName == "library_effects") {
|
||||||
ReadEffectLibrary(currentNode);
|
ReadEffectLibrary(currentNode);
|
||||||
else if (name == "library_geometries")
|
} else if (currentName == "library_geometries") {
|
||||||
ReadGeometryLibrary(currentNode);
|
ReadGeometryLibrary(currentNode);
|
||||||
else if (name == "library_visual_scenes")
|
} else if (currentName == "library_visual_scenes") {
|
||||||
ReadSceneLibrary(currentNode);
|
ReadSceneLibrary(currentNode);
|
||||||
else if (name == "library_lights")
|
} else if (currentName == "library_lights") {
|
||||||
ReadLightLibrary(currentNode);
|
ReadLightLibrary(currentNode);
|
||||||
else if (name == "library_cameras")
|
} else if (currentName == "library_cameras") {
|
||||||
ReadCameraLibrary(currentNode);
|
ReadCameraLibrary(currentNode);
|
||||||
else if (name == "library_nodes")
|
} else if (currentName == "library_nodes") {
|
||||||
ReadSceneNode(currentNode, nullptr); /* some hacking to reuse this piece of code */
|
ReadSceneNode(currentNode, nullptr); /* some hacking to reuse this piece of code */
|
||||||
else if (name == "scene")
|
} else if (currentName == "scene") {
|
||||||
ReadScene(currentNode);
|
ReadScene(currentNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PostProcessRootAnimations();
|
PostProcessRootAnimations();
|
||||||
|
@ -296,17 +330,16 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string name = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (name == "unit") {
|
if (currentName == "unit") {
|
||||||
pugi::xml_attribute attr = currentNode.attribute("meter");
|
|
||||||
mUnitSize = 1.f;
|
mUnitSize = 1.f;
|
||||||
if (attr) {
|
XmlParser::getFloatAttribute(node, "meter", mUnitSize);
|
||||||
mUnitSize = static_cast<ai_real>(attr.as_double());
|
} else if (currentName == "up_axis") {
|
||||||
}
|
|
||||||
} else if (name == "up_axis") {
|
|
||||||
std::string v;
|
std::string v;
|
||||||
XmlParser::getValueAsString(currentNode, v);
|
if (!XmlParser::getValueAsString(currentNode, v)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (v == "X_UP") {
|
if (v == "X_UP") {
|
||||||
mUpDirection = UP_X;
|
mUpDirection = UP_X;
|
||||||
} else if (v == "Z_UP") {
|
} else if (v == "Z_UP") {
|
||||||
|
@ -314,9 +347,9 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
|
||||||
} else {
|
} else {
|
||||||
mUpDirection = UP_Y;
|
mUpDirection = UP_Y;
|
||||||
}
|
}
|
||||||
} else if (name == "contributor") {
|
} else if (currentName == "contributor") {
|
||||||
for (XmlNode currentChldNode : currentNode.children()) {
|
for (XmlNode currentChildNode : currentNode.children()) {
|
||||||
ReadMetaDataItem(currentChldNode, mAssetMetaData);
|
ReadMetaDataItem(currentChildNode, mAssetMetaData);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ReadMetaDataItem(currentNode, mAssetMetaData);
|
ReadMetaDataItem(currentNode, mAssetMetaData);
|
||||||
|
@ -324,43 +357,32 @@ void ColladaParser::ReadAssetInfo(XmlNode &node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool FindCommonKey(const std::string &collada_key, const MetaKeyPairVector &key_renaming, size_t &found_index) {
|
|
||||||
for (size_t i = 0; i < key_renaming.size(); ++i) {
|
|
||||||
if (key_renaming[i].first == collada_key) {
|
|
||||||
found_index = i;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
found_index = std::numeric_limits<size_t>::max();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads a single string metadata item
|
// Reads a single string metadata item
|
||||||
void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) {
|
void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) {
|
||||||
const Collada::MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase();
|
const Collada::MetaKeyPairVector &key_renaming = GetColladaAssimpMetaKeysCamelCase();
|
||||||
|
|
||||||
const std::string name = node.name();
|
const std::string name = node.name();
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string v;
|
std::string v;
|
||||||
if (XmlParser::getValueAsString(node, v)) {
|
if (!XmlParser::getValueAsString(node, v)) {
|
||||||
trim(v);
|
return;
|
||||||
aiString aistr;
|
}
|
||||||
aistr.Set(v);
|
|
||||||
|
|
||||||
std::string camel_key_str(name);
|
trim(v);
|
||||||
ToCamelCase(camel_key_str);
|
aiString aistr;
|
||||||
|
aistr.Set(v);
|
||||||
|
|
||||||
size_t found_index;
|
std::string camel_key_str(name);
|
||||||
if (FindCommonKey(camel_key_str, key_renaming, found_index)) {
|
ToCamelCase(camel_key_str);
|
||||||
metadata.emplace(key_renaming[found_index].second, aistr);
|
|
||||||
} else {
|
size_t found_index;
|
||||||
metadata.emplace(camel_key_str, aistr);
|
if (FindCommonKey(camel_key_str, key_renaming, found_index)) {
|
||||||
}
|
metadata.emplace(key_renaming[found_index].second, aistr);
|
||||||
|
} else {
|
||||||
|
metadata.emplace(camel_key_str, aistr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,14 +394,8 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string animName;
|
std::string animName;
|
||||||
pugi::xml_attribute nameAttr = node.attribute("name");
|
if (!XmlParser::getStdStrAttribute(node, "name", animName)) {
|
||||||
if (nameAttr) {
|
if (!XmlParser::getStdStrAttribute( node, "id", animName )) {
|
||||||
animName = nameAttr.as_string();
|
|
||||||
} else {
|
|
||||||
pugi::xml_attribute idAttr = node.attribute("id");
|
|
||||||
if (idAttr) {
|
|
||||||
animName = idAttr.as_string();
|
|
||||||
} else {
|
|
||||||
animName = std::string("animation_") + to_string(mAnimationClipLibrary.size());
|
animName = std::string("animation_") + to_string(mAnimationClipLibrary.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -387,17 +403,12 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
|
||||||
std::pair<std::string, std::vector<std::string>> clip;
|
std::pair<std::string, std::vector<std::string>> clip;
|
||||||
clip.first = animName;
|
clip.first = animName;
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string currentName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "instance_animation") {
|
if (currentName == "instance_animation") {
|
||||||
pugi::xml_attribute url = currentNode.attribute("url");
|
std::string url;
|
||||||
if (url) {
|
readUrlAttribute(node, url);
|
||||||
const std::string urlName = url.as_string();
|
clip.second.push_back(url);
|
||||||
if (urlName[0] != '#') {
|
|
||||||
throw DeadlyImportError("Unknown reference format");
|
|
||||||
}
|
|
||||||
clip.second.push_back(url.as_string());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clip.second.size() > 0) {
|
if (clip.second.size() > 0) {
|
||||||
|
@ -467,8 +478,8 @@ void ColladaParser::ReadAnimationLibrary(XmlNode &node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string currentName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "animation") {
|
if (currentName == "animation") {
|
||||||
ReadAnimation(currentNode, &mAnims);
|
ReadAnimation(currentNode, &mAnims);
|
||||||
}
|
}
|
||||||
|
@ -484,17 +495,14 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
|
||||||
|
|
||||||
// an <animation> element may be a container for grouping sub-elements or an animation channel
|
// an <animation> element may be a container for grouping sub-elements or an animation channel
|
||||||
// this is the channel collection by ID, in case it has channels
|
// this is the channel collection by ID, in case it has channels
|
||||||
typedef std::map<std::string, AnimationChannel> ChannelMap;
|
using ChannelMap = std::map<std::string, AnimationChannel> ;
|
||||||
ChannelMap channels;
|
ChannelMap channels;
|
||||||
// this is the anim container in case we're a container
|
// this is the anim container in case we're a container
|
||||||
Animation *anim = nullptr;
|
Animation *anim = nullptr;
|
||||||
|
|
||||||
// optional name given as an attribute
|
// optional name given as an attribute
|
||||||
std::string animName;
|
std::string animName;
|
||||||
pugi::xml_attribute nameAttr = node.attribute("name");
|
if (!XmlParser::getStdStrAttribute(node, "name", animName)) {
|
||||||
if (nameAttr) {
|
|
||||||
animName = nameAttr.as_string();
|
|
||||||
} else {
|
|
||||||
animName = "animation";
|
animName = "animation";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,8 +512,8 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
|
||||||
animID = idAttr.as_string();
|
animID = idAttr.as_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string currentName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "animation") {
|
if (currentName == "animation") {
|
||||||
if (!anim) {
|
if (!anim) {
|
||||||
anim = new Animation;
|
anim = new Animation;
|
||||||
|
@ -518,23 +526,21 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
|
||||||
} else if (currentName == "source") {
|
} else if (currentName == "source") {
|
||||||
ReadSource(currentNode);
|
ReadSource(currentNode);
|
||||||
} else if (currentName == "sampler") {
|
} else if (currentName == "sampler") {
|
||||||
pugi::xml_attribute sampler_id = currentNode.attribute("id");
|
std::string id;
|
||||||
if (sampler_id) {
|
if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
|
||||||
std::string id = sampler_id.as_string();
|
|
||||||
ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
|
|
||||||
|
|
||||||
// have it read into a channel
|
// have it read into a channel
|
||||||
|
ChannelMap::iterator newChannel = channels.insert(std::make_pair(id, AnimationChannel())).first;
|
||||||
ReadAnimationSampler(currentNode, newChannel->second);
|
ReadAnimationSampler(currentNode, newChannel->second);
|
||||||
} else if (currentName == "channel") {
|
} else if (currentName == "channel") {
|
||||||
pugi::xml_attribute target = currentNode.attribute("target");
|
std::string source_name, target;
|
||||||
pugi::xml_attribute source = currentNode.attribute("source");
|
XmlParser::getStdStrAttribute(currentNode, "source", source_name);
|
||||||
std::string source_name = source.as_string();
|
XmlParser::getStdStrAttribute(currentNode, "target", target);
|
||||||
if (source_name[0] == '#') {
|
if (source_name[0] == '#') {
|
||||||
source_name = source_name.substr(1, source_name.size() - 1);
|
source_name = source_name.substr(1, source_name.size() - 1);
|
||||||
}
|
}
|
||||||
ChannelMap::iterator cit = channels.find(source_name);
|
ChannelMap::iterator cit = channels.find(source_name);
|
||||||
if (cit != channels.end()) {
|
if (cit != channels.end()) {
|
||||||
cit->second.mTarget = target.as_string();
|
cit->second.mTarget = target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,8 +567,8 @@ void ColladaParser::ReadAnimation(XmlNode &node, Collada::Animation *pParent) {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads an animation sampler into the given anim channel
|
// Reads an animation sampler into the given anim channel
|
||||||
void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) {
|
void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChannel &pChannel) {
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string currentName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "input") {
|
if (currentName == "input") {
|
||||||
if (XmlParser::hasAttribute(currentNode, "semantic")) {
|
if (XmlParser::hasAttribute(currentNode, "semantic")) {
|
||||||
std::string semantic, sourceAttr;
|
std::string semantic, sourceAttr;
|
||||||
|
@ -575,16 +581,17 @@ void ColladaParser::ReadAnimationSampler(XmlNode &node, Collada::AnimationChanne
|
||||||
}
|
}
|
||||||
source++;
|
source++;
|
||||||
|
|
||||||
if (semantic == "INPUT")
|
if (semantic == "INPUT") {
|
||||||
pChannel.mSourceTimes = source;
|
pChannel.mSourceTimes = source;
|
||||||
else if (semantic == "OUTPUT")
|
} else if (semantic == "OUTPUT") {
|
||||||
pChannel.mSourceValues = source;
|
pChannel.mSourceValues = source;
|
||||||
else if (semantic == "IN_TANGENT")
|
} else if (semantic == "IN_TANGENT") {
|
||||||
pChannel.mInTanValues = source;
|
pChannel.mInTanValues = source;
|
||||||
else if (semantic == "OUT_TANGENT")
|
} else if (semantic == "OUT_TANGENT") {
|
||||||
pChannel.mOutTanValues = source;
|
pChannel.mOutTanValues = source;
|
||||||
else if (semantic == "INTERPOLATION")
|
} else if (semantic == "INTERPOLATION") {
|
||||||
pChannel.mInterpolationValues = source;
|
pChannel.mInterpolationValues = source;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -602,7 +609,6 @@ void ColladaParser::ReadControllerLibrary(XmlNode &node) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName != "controller") {
|
if (currentName != "controller") {
|
||||||
continue;
|
continue;
|
||||||
;
|
|
||||||
}
|
}
|
||||||
std::string id = node.attribute("id").as_string();
|
std::string id = node.attribute("id").as_string();
|
||||||
mControllerLibrary[id] = Controller();
|
mControllerLibrary[id] = Controller();
|
||||||
|
@ -616,7 +622,7 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll
|
||||||
// initial values
|
// initial values
|
||||||
pController.mType = Skin;
|
pController.mType = Skin;
|
||||||
pController.mMethod = Normalized;
|
pController.mMethod = Normalized;
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "morph") {
|
if (currentName == "morph") {
|
||||||
pController.mType = Morph;
|
pController.mType = Morph;
|
||||||
|
@ -668,8 +674,8 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &pControll
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads the joint definitions for the given controller
|
// Reads the joint definitions for the given controller
|
||||||
void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pController) {
|
void ColladaParser::ReadControllerJoints(XmlNode &node, Collada::Controller &pController) {
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string currentName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "input") {
|
if (currentName == "input") {
|
||||||
const char *attrSemantic = currentNode.attribute("semantic").as_string();
|
const char *attrSemantic = currentNode.attribute("semantic").as_string();
|
||||||
const char *attrSource = currentNode.attribute("source").as_string();
|
const char *attrSource = currentNode.attribute("source").as_string();
|
||||||
|
@ -696,8 +702,8 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
|
||||||
int vertexCount=0;
|
int vertexCount=0;
|
||||||
XmlParser::getIntAttribute(node, "count", vertexCount);
|
XmlParser::getIntAttribute(node, "count", vertexCount);
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
std::string currentName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "input") {
|
if (currentName == "input") {
|
||||||
InputChannel channel;
|
InputChannel channel;
|
||||||
|
|
||||||
|
@ -761,9 +767,9 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string name = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (name == "image") {
|
if (currentName == "image") {
|
||||||
std::string id = currentNode.attribute("id").as_string();
|
std::string id = currentNode.attribute("id").as_string();
|
||||||
mImageLibrary[id] = Image();
|
mImageLibrary[id] = Image();
|
||||||
|
|
||||||
|
@ -776,7 +782,7 @@ void ColladaParser::ReadImageLibrary(XmlNode &node) {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads an image entry into the given image
|
// Reads an image entry into the given image
|
||||||
void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
|
void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string currentName = currentNode.name();
|
const std::string currentName = currentNode.name();
|
||||||
if (currentName == "image") {
|
if (currentName == "image") {
|
||||||
// Ignore
|
// Ignore
|
||||||
|
@ -796,23 +802,6 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
|
||||||
if (!pImage.mFileName.length()) {
|
if (!pImage.mFileName.length()) {
|
||||||
pImage.mFileName = "unknown_texture";
|
pImage.mFileName = "unknown_texture";
|
||||||
}
|
}
|
||||||
} else if (mFormat == FV_1_5_n) {
|
|
||||||
// make sure we skip over mip and array initializations, which
|
|
||||||
// we don't support, but which could confuse the loader if
|
|
||||||
// they're not skipped.
|
|
||||||
//int v = currentNode.attribute("ref").as_int();
|
|
||||||
/* if (v y) {
|
|
||||||
ASSIMP_LOG_WARN("Collada: Ignoring texture array index");
|
|
||||||
continue;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//v = currentNode.attribute("mip_index").as_int();
|
|
||||||
/*if (attrib != -1 && v > 0) {
|
|
||||||
ASSIMP_LOG_WARN("Collada: Ignoring MIP map layer");
|
|
||||||
continue;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// TODO: correctly jump over cube and volume maps?
|
|
||||||
}
|
}
|
||||||
} else if (mFormat == FV_1_5_n) {
|
} else if (mFormat == FV_1_5_n) {
|
||||||
std::string value;
|
std::string value;
|
||||||
|
@ -859,8 +848,7 @@ void ColladaParser::ReadMaterialLibrary(XmlNode &node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, int> names;
|
std::map<std::string, int> names;
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string currentName = currentNode.name();
|
|
||||||
std::string id = currentNode.attribute("id").as_string();
|
std::string id = currentNode.attribute("id").as_string();
|
||||||
std::string name = currentNode.attribute("name").as_string();
|
std::string name = currentNode.attribute("name").as_string();
|
||||||
mMaterialLibrary[id] = Material();
|
mMaterialLibrary[id] = Material();
|
||||||
|
@ -889,11 +877,13 @@ void ColladaParser::ReadLightLibrary(XmlNode &node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "light") {
|
if (currentName == "light") {
|
||||||
std::string id = currentNode.attribute("id").as_string();
|
std::string id;
|
||||||
ReadLight(currentNode, mLightLibrary[id] = Light());
|
if (XmlParser::getStdStrAttribute(currentNode, "id", id)) {
|
||||||
|
ReadLight(currentNode, mLightLibrary[id] = Light());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -905,18 +895,24 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "camera") {
|
if (currentName == "camera") {
|
||||||
std::string id = currentNode.attribute("id").as_string();
|
std::string id;
|
||||||
|
if (!XmlParser::getStdStrAttribute(currentNode, "id", id)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// create an entry and store it in the library under its ID
|
// create an entry and store it in the library under its ID
|
||||||
Camera &cam = mCameraLibrary[id];
|
Camera &cam = mCameraLibrary[id];
|
||||||
std::string name = currentNode.attribute("name").as_string();
|
std::string name;
|
||||||
|
if (!XmlParser::getStdStrAttribute(currentNode, "name", name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (!name.empty()) {
|
if (!name.empty()) {
|
||||||
cam.mName = name;
|
cam.mName = name;
|
||||||
}
|
}
|
||||||
ReadCamera(currentNode, cam);
|
ReadCamera(currentNode, cam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -924,14 +920,12 @@ void ColladaParser::ReadCameraLibrary(XmlNode &node) {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads a material entry into the given material
|
// Reads a material entry into the given material
|
||||||
void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
|
void ColladaParser::ReadMaterial(XmlNode &node, Collada::Material &pMaterial) {
|
||||||
for (XmlNode currentNode : node.children()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "instance_effect") {
|
if (currentName == "instance_effect") {
|
||||||
const char *url = currentNode.attribute("url").as_string();
|
std::string url;
|
||||||
if (url[0] != '#') {
|
readUrlAttribute(currentNode, url);
|
||||||
throw DeadlyImportError("Unknown reference format");
|
pMaterial.mEffect = url.c_str();
|
||||||
}
|
|
||||||
pMaterial.mEffect = url + 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1030,7 +1024,7 @@ void ColladaParser::ReadEffectLibrary(XmlNode &node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "effect") {
|
if (currentName == "effect") {
|
||||||
// read ID. Do I have to repeat my ranting about "optional" attributes?
|
// read ID. Do I have to repeat my ranting about "optional" attributes?
|
||||||
|
@ -1049,7 +1043,7 @@ void ColladaParser::ReadEffectLibrary(XmlNode &node) {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Reads an effect entry into the given effect
|
// Reads an effect entry into the given effect
|
||||||
void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) {
|
void ColladaParser::ReadEffect(XmlNode &node, Collada::Effect &pEffect) {
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "profile_COMMON") {
|
if (currentName == "profile_COMMON") {
|
||||||
ReadEffectProfileCommon(currentNode, pEffect);
|
ReadEffectProfileCommon(currentNode, pEffect);
|
||||||
|
@ -1254,8 +1248,6 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
|
||||||
} else if (currentName == "technique") {
|
} else if (currentName == "technique") {
|
||||||
std::string profile;
|
std::string profile;
|
||||||
XmlParser::getStdStrAttribute(currentNode, "profile", profile);
|
XmlParser::getStdStrAttribute(currentNode, "profile", profile);
|
||||||
//const int _profile = GetAttribute("profile");
|
|
||||||
//const char *profile = mReader->getAttributeValue(_profile);
|
|
||||||
|
|
||||||
// Some extensions are quite useful ... ReadSamplerProperties processes
|
// Some extensions are quite useful ... ReadSamplerProperties processes
|
||||||
// several extensions in MAYA, OKINO and MAX3D profiles.
|
// several extensions in MAYA, OKINO and MAX3D profiles.
|
||||||
|
@ -1284,10 +1276,10 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
|
||||||
if (node.empty()) {
|
if (node.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlNodeIterator xmlIt(node);
|
XmlNodeIterator xmlIt(node);
|
||||||
xmlIt.collectChildrenPreOrder(node);
|
xmlIt.collectChildrenPreOrder(node);
|
||||||
XmlNode currentNode;
|
XmlNode currentNode;
|
||||||
|
|
||||||
while (xmlIt.getNext(currentNode)) {
|
while (xmlIt.getNext(currentNode)) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "surface") {
|
if (currentName == "surface") {
|
||||||
|
@ -1313,6 +1305,11 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
|
||||||
}
|
}
|
||||||
pParam.mType = Param_Sampler;
|
pParam.mType = Param_Sampler;
|
||||||
pParam.mReference = url.c_str() + 1;
|
pParam.mReference = url.c_str() + 1;
|
||||||
|
} else if (currentName == "source") {
|
||||||
|
const char *source = currentNode.child_value();
|
||||||
|
if (nullptr != source) {
|
||||||
|
pParam.mReference = source;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1323,7 +1320,7 @@ void ColladaParser::ReadGeometryLibrary(XmlNode &node) {
|
||||||
if (node.empty()) {
|
if (node.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "geometry") {
|
if (currentName == "geometry") {
|
||||||
// read ID. Another entry which is "optional" by design but obligatory in reality
|
// read ID. Another entry which is "optional" by design but obligatory in reality
|
||||||
|
@ -1352,7 +1349,7 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) {
|
||||||
if (node.empty()) {
|
if (node.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "mesh") {
|
if (currentName == "mesh") {
|
||||||
ReadMesh(currentNode, pMesh);
|
ReadMesh(currentNode, pMesh);
|
||||||
|
@ -1376,7 +1373,9 @@ void ColladaParser::ReadMesh(XmlNode &node, Mesh &pMesh) {
|
||||||
ReadSource(currentNode);
|
ReadSource(currentNode);
|
||||||
} else if (currentName == "vertices") {
|
} else if (currentName == "vertices") {
|
||||||
ReadVertexData(currentNode, pMesh);
|
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);
|
ReadIndexData(currentNode, pMesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1534,16 +1533,11 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
|
||||||
acc.mSubOffset[1] = acc.mParams.size();
|
acc.mSubOffset[1] = acc.mParams.size();
|
||||||
else if (name == "P")
|
else if (name == "P")
|
||||||
acc.mSubOffset[2] = acc.mParams.size();
|
acc.mSubOffset[2] = acc.mParams.size();
|
||||||
// else if( name == "Q") acc.mSubOffset[3] = acc.mParams.size();
|
|
||||||
/* 4D uv coordinates are not supported in Assimp */
|
|
||||||
|
|
||||||
/* Generic extra data, interpreted as UV data, too*/
|
/* Generic extra data, interpreted as UV data, too*/
|
||||||
else if (name == "U")
|
else if (name == "U")
|
||||||
acc.mSubOffset[0] = acc.mParams.size();
|
acc.mSubOffset[0] = acc.mParams.size();
|
||||||
else if (name == "V")
|
else if (name == "V")
|
||||||
acc.mSubOffset[1] = acc.mParams.size();
|
acc.mSubOffset[1] = acc.mParams.size();
|
||||||
//else
|
|
||||||
// DefaultLogger::get()->warn( format() << "Unknown accessor parameter \"" << name << "\". Ignoring data channel." );
|
|
||||||
}
|
}
|
||||||
if (XmlParser::hasAttribute(currentNode, "type")) {
|
if (XmlParser::hasAttribute(currentNode, "type")) {
|
||||||
// read data type
|
// read data type
|
||||||
|
@ -1568,7 +1562,7 @@ void ColladaParser::ReadAccessor(XmlNode &node, const std::string &pID) {
|
||||||
void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) {
|
void ColladaParser::ReadVertexData(XmlNode &node, Mesh &pMesh) {
|
||||||
// extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about
|
// extract the ID of the <vertices> element. Not that we care, but to catch strange referencing schemes we should warn about
|
||||||
XmlParser::getStdStrAttribute(node, "id", pMesh.mVertexID);
|
XmlParser::getStdStrAttribute(node, "id", pMesh.mVertexID);
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "input") {
|
if (currentName == "input") {
|
||||||
ReadInputChannel(currentNode, pMesh.mPerVertexData);
|
ReadInputChannel(currentNode, pMesh.mPerVertexData);
|
||||||
|
@ -1726,20 +1720,20 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
||||||
// determine the expected number of indices
|
// determine the expected number of indices
|
||||||
size_t expectedPointCount = 0;
|
size_t expectedPointCount = 0;
|
||||||
switch (pPrimType) {
|
switch (pPrimType) {
|
||||||
case Prim_Polylist: {
|
case Prim_Polylist: {
|
||||||
for (size_t i : pVCount)
|
for (size_t i : pVCount)
|
||||||
expectedPointCount += i;
|
expectedPointCount += i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Prim_Lines:
|
case Prim_Lines:
|
||||||
expectedPointCount = 2 * pNumPrimitives;
|
expectedPointCount = 2 * pNumPrimitives;
|
||||||
break;
|
break;
|
||||||
case Prim_Triangles:
|
case Prim_Triangles:
|
||||||
expectedPointCount = 3 * pNumPrimitives;
|
expectedPointCount = 3 * pNumPrimitives;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// other primitive types don't state the index count upfront... we need to guess
|
// other primitive types don't state the index count upfront... we need to guess
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// and read all indices into a temporary array
|
// and read all indices into a temporary array
|
||||||
|
@ -1771,7 +1765,6 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
|
||||||
} else {
|
} else {
|
||||||
throw DeadlyImportError("Expected different index count in <p> element.");
|
throw DeadlyImportError("Expected different index count in <p> element.");
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (expectedPointCount == 0 && (indices.size() % numOffsets) != 0) {
|
} else if (expectedPointCount == 0 && (indices.size() % numOffsets) != 0) {
|
||||||
throw DeadlyImportError("Expected different index count in <p> element.");
|
throw DeadlyImportError("Expected different index count in <p> element.");
|
||||||
}
|
}
|
||||||
|
@ -2023,7 +2016,7 @@ void ColladaParser::ReadSceneLibrary(XmlNode &node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (XmlNode currentNode : node.children()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "visual_scene") {
|
if (currentName == "visual_scene") {
|
||||||
// read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then?
|
// read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then?
|
||||||
|
@ -2190,11 +2183,8 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Processes bind_vertex_input and bind elements
|
// Processes bind_vertex_input and bind elements
|
||||||
void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl) {
|
void ColladaParser::ReadMaterialVertexInputBinding(XmlNode &node, Collada::SemanticMappingTable &tbl) {
|
||||||
//XmlNodeIterator xmlIt(node);
|
|
||||||
//xmlIt.collectChildrenPreOrder(node);
|
|
||||||
//XmlNode currentNode;
|
|
||||||
std::string name = node.name();
|
std::string name = node.name();
|
||||||
for (XmlNode currentNode : node.children()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "bind_vertex_input") {
|
if (currentName == "bind_vertex_input") {
|
||||||
Collada::InputSemanticMapEntry vn;
|
Collada::InputSemanticMapEntry vn;
|
||||||
|
@ -2289,8 +2279,8 @@ void ColladaParser::ReadScene(XmlNode &node) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string currentName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == "instance_visual_scene") {
|
if (currentName == "instance_visual_scene") {
|
||||||
// should be the first and only occurrence
|
// should be the first and only occurrence
|
||||||
if (mRootNode) {
|
if (mRootNode) {
|
||||||
|
@ -2314,20 +2304,6 @@ void ColladaParser::ReadScene(XmlNode &node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaParser::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));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Calculates the resulting transformation from all the given transform steps
|
// Calculates the resulting transformation from all the given transform steps
|
||||||
aiMatrix4x4 ColladaParser::CalculateResultTransform(const std::vector<Transform> &pTransforms) const {
|
aiMatrix4x4 ColladaParser::CalculateResultTransform(const std::vector<Transform> &pTransforms) const {
|
||||||
|
|
|
@ -243,8 +243,6 @@ protected:
|
||||||
void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
|
void ReadEmbeddedTextures(ZipArchiveIOSystem &zip_archive);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ReportWarning(const char *msg, ...);
|
|
||||||
|
|
||||||
/** Calculates the resulting transformation from all the given transform steps */
|
/** Calculates the resulting transformation from all the given transform steps */
|
||||||
aiMatrix4x4 CalculateResultTransform(const std::vector<Collada::Transform> &pTransforms) const;
|
aiMatrix4x4 CalculateResultTransform(const std::vector<Collada::Transform> &pTransforms) const;
|
||||||
|
|
||||||
|
@ -260,56 +258,55 @@ protected:
|
||||||
std::string mFileName;
|
std::string mFileName;
|
||||||
|
|
||||||
// XML reader, member for everyday use
|
// XML reader, member for everyday use
|
||||||
//irr::io::IrrXMLReader *mReader;
|
|
||||||
XmlParser mXmlParser;
|
XmlParser mXmlParser;
|
||||||
|
|
||||||
/** All data arrays found in the file by ID. Might be referred to by actually
|
/** All data arrays found in the file by ID. Might be referred to by actually
|
||||||
everyone. Collada, you are a steaming pile of indirection. */
|
everyone. Collada, you are a steaming pile of indirection. */
|
||||||
typedef std::map<std::string, Collada::Data> DataLibrary;
|
using DataLibrary = std::map<std::string, Collada::Data> ;
|
||||||
DataLibrary mDataLibrary;
|
DataLibrary mDataLibrary;
|
||||||
|
|
||||||
/** Same for accessors which define how the data in a data array is accessed. */
|
/** Same for accessors which define how the data in a data array is accessed. */
|
||||||
typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
|
using AccessorLibrary = std::map<std::string, Collada::Accessor> ;
|
||||||
AccessorLibrary mAccessorLibrary;
|
AccessorLibrary mAccessorLibrary;
|
||||||
|
|
||||||
/** Mesh library: mesh by ID */
|
/** Mesh library: mesh by ID */
|
||||||
typedef std::map<std::string, Collada::Mesh *> MeshLibrary;
|
using MeshLibrary = std::map<std::string, Collada::Mesh *>;
|
||||||
MeshLibrary mMeshLibrary;
|
MeshLibrary mMeshLibrary;
|
||||||
|
|
||||||
/** node library: root node of the hierarchy part by ID */
|
/** node library: root node of the hierarchy part by ID */
|
||||||
typedef std::map<std::string, Collada::Node *> NodeLibrary;
|
using NodeLibrary = std::map<std::string, Collada::Node *>;
|
||||||
NodeLibrary mNodeLibrary;
|
NodeLibrary mNodeLibrary;
|
||||||
|
|
||||||
/** Image library: stores texture properties by ID */
|
/** Image library: stores texture properties by ID */
|
||||||
typedef std::map<std::string, Collada::Image> ImageLibrary;
|
using ImageLibrary = std::map<std::string, Collada::Image> ;
|
||||||
ImageLibrary mImageLibrary;
|
ImageLibrary mImageLibrary;
|
||||||
|
|
||||||
/** Effect library: surface attributes by ID */
|
/** Effect library: surface attributes by ID */
|
||||||
typedef std::map<std::string, Collada::Effect> EffectLibrary;
|
using EffectLibrary = std::map<std::string, Collada::Effect> ;
|
||||||
EffectLibrary mEffectLibrary;
|
EffectLibrary mEffectLibrary;
|
||||||
|
|
||||||
/** Material library: surface material by ID */
|
/** Material library: surface material by ID */
|
||||||
typedef std::map<std::string, Collada::Material> MaterialLibrary;
|
using MaterialLibrary = std::map<std::string, Collada::Material> ;
|
||||||
MaterialLibrary mMaterialLibrary;
|
MaterialLibrary mMaterialLibrary;
|
||||||
|
|
||||||
/** Light library: surface light by ID */
|
/** Light library: surface light by ID */
|
||||||
typedef std::map<std::string, Collada::Light> LightLibrary;
|
using LightLibrary = std::map<std::string, Collada::Light> ;
|
||||||
LightLibrary mLightLibrary;
|
LightLibrary mLightLibrary;
|
||||||
|
|
||||||
/** Camera library: surface material by ID */
|
/** Camera library: surface material by ID */
|
||||||
typedef std::map<std::string, Collada::Camera> CameraLibrary;
|
using CameraLibrary = std::map<std::string, Collada::Camera> ;
|
||||||
CameraLibrary mCameraLibrary;
|
CameraLibrary mCameraLibrary;
|
||||||
|
|
||||||
/** Controller library: joint controllers by ID */
|
/** Controller library: joint controllers by ID */
|
||||||
typedef std::map<std::string, Collada::Controller> ControllerLibrary;
|
using ControllerLibrary = std::map<std::string, Collada::Controller> ;
|
||||||
ControllerLibrary mControllerLibrary;
|
ControllerLibrary mControllerLibrary;
|
||||||
|
|
||||||
/** Animation library: animation references by ID */
|
/** Animation library: animation references by ID */
|
||||||
typedef std::map<std::string, Collada::Animation *> AnimationLibrary;
|
using AnimationLibrary = std::map<std::string, Collada::Animation *> ;
|
||||||
AnimationLibrary mAnimationLibrary;
|
AnimationLibrary mAnimationLibrary;
|
||||||
|
|
||||||
/** Animation clip library: clip animation references by ID */
|
/** Animation clip library: clip animation references by ID */
|
||||||
typedef std::vector<std::pair<std::string, std::vector<std::string>>> AnimationClipLibrary;
|
using AnimationClipLibrary = std::vector<std::pair<std::string, std::vector<std::string>>> ;
|
||||||
AnimationClipLibrary mAnimationClipLibrary;
|
AnimationClipLibrary mAnimationClipLibrary;
|
||||||
|
|
||||||
/** Pointer to the root node. Don't delete, it just points to one of
|
/** Pointer to the root node. Don't delete, it just points to one of
|
||||||
|
@ -334,13 +331,6 @@ protected:
|
||||||
Collada::FormatVersion mFormat;
|
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
|
// Finds the item in the given library by its reference, throws if not found
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
|
|
|
@ -598,7 +598,7 @@ bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally extract output meshes and add them to the scope
|
// finally extract output meshes and add them to the scope
|
||||||
typedef std::pair<unsigned int, TempMaterialMesh> pairt;
|
typedef std::pair<const unsigned int, TempMaterialMesh> pairt;
|
||||||
for (const pairt &p : bymat) {
|
for (const pairt &p : bymat) {
|
||||||
aiMesh *const m = ToOutputMesh(p.second);
|
aiMesh *const m = ToOutputMesh(p.second);
|
||||||
scope.meshes_linear.push_back(m);
|
scope.meshes_linear.push_back(m);
|
||||||
|
|
|
@ -1060,7 +1060,7 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
|
||||||
inline void Camera::Read(Value &obj, Asset & /*r*/) {
|
inline void Camera::Read(Value &obj, Asset & /*r*/) {
|
||||||
type = MemberOrDefault(obj, "type", Camera::Perspective);
|
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);
|
Value *it = FindObject(obj, subobjId);
|
||||||
if (!it) throw DeadlyImportError("GLTF: Camera missing its parameters");
|
if (!it) throw DeadlyImportError("GLTF: Camera missing its parameters");
|
||||||
|
@ -1071,10 +1071,10 @@ inline void Camera::Read(Value &obj, Asset & /*r*/) {
|
||||||
perspective.zfar = MemberOrDefault(*it, "zfar", 100.f);
|
perspective.zfar = MemberOrDefault(*it, "zfar", 100.f);
|
||||||
perspective.znear = MemberOrDefault(*it, "znear", 0.01f);
|
perspective.znear = MemberOrDefault(*it, "znear", 0.01f);
|
||||||
} else {
|
} else {
|
||||||
ortographic.xmag = MemberOrDefault(obj, "xmag", 1.f);
|
ortographic.xmag = MemberOrDefault(*it, "xmag", 1.f);
|
||||||
ortographic.ymag = MemberOrDefault(obj, "ymag", 1.f);
|
ortographic.ymag = MemberOrDefault(*it, "ymag", 1.f);
|
||||||
ortographic.zfar = MemberOrDefault(obj, "zfar", 100.f);
|
ortographic.zfar = MemberOrDefault(*it, "zfar", 100.f);
|
||||||
ortographic.znear = MemberOrDefault(obj, "znear", 0.01f);
|
ortographic.znear = MemberOrDefault(*it, "znear", 0.01f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
|
|
@ -44,22 +44,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define INCLUDED_AI_STRINGUTILS_H
|
#define INCLUDED_AI_STRINGUTILS_H
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# pragma GCC system_header
|
#pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assimp/defs.h>
|
#include <assimp/defs.h>
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <cstdlib>
|
#include <algorithm>
|
||||||
#include <algorithm>
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <cstdlib>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# define AI_SIZEFMT "%Iu"
|
#define AI_SIZEFMT "%Iu"
|
||||||
#else
|
#else
|
||||||
# define AI_SIZEFMT "%zu"
|
#define AI_SIZEFMT "%zu"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// @fn ai_snprintf
|
/// @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.
|
/// @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
|
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||||
|
|
||||||
AI_FORCE_INLINE
|
AI_FORCE_INLINE
|
||||||
int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) {
|
int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) {
|
||||||
int count(-1);
|
int count(-1);
|
||||||
if (0 != size) {
|
if (0 != size) {
|
||||||
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
|
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
|
||||||
}
|
}
|
||||||
if (count == -1) {
|
if (count == -1) {
|
||||||
count = _vscprintf(format, ap);
|
count = _vscprintf(format, ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
AI_FORCE_INLINE
|
AI_FORCE_INLINE
|
||||||
int ai_snprintf(char *outBuf, size_t size, const char *format, ...) {
|
int ai_snprintf(char *outBuf, size_t size, const char *format, ...) {
|
||||||
int count;
|
int count;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
count = c99_ai_vsnprintf(outBuf, size, format, ap);
|
count = c99_ai_vsnprintf(outBuf, size, format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__MINGW32__)
|
#elif defined(__MINGW32__)
|
||||||
# define ai_snprintf __mingw_snprintf
|
#define ai_snprintf __mingw_snprintf
|
||||||
#else
|
#else
|
||||||
# define ai_snprintf snprintf
|
#define ai_snprintf snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// @fn to_string
|
/// @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.
|
/// @param value The value to write into the std::string.
|
||||||
/// @return The value as a std::string
|
/// @return The value as a std::string
|
||||||
template <typename T>
|
template <typename T>
|
||||||
AI_FORCE_INLINE
|
AI_FORCE_INLINE std::string to_string(T value) {
|
||||||
std::string to_string( T value ) {
|
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << value;
|
os << value;
|
||||||
|
|
||||||
|
@ -121,17 +120,17 @@ std::string to_string( T value ) {
|
||||||
/// @param end The last character
|
/// @param end The last character
|
||||||
/// @return The float value, 0.0f in cas of an error.
|
/// @return The float value, 0.0f in cas of an error.
|
||||||
AI_FORCE_INLINE
|
AI_FORCE_INLINE
|
||||||
float ai_strtof( const char *begin, const char *end ) {
|
float ai_strtof(const char *begin, const char *end) {
|
||||||
if ( nullptr == begin ) {
|
if (nullptr == begin) {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
float val( 0.0f );
|
float val(0.0f);
|
||||||
if ( nullptr == end ) {
|
if (nullptr == end) {
|
||||||
val = static_cast< float >( ::atof( begin ) );
|
val = static_cast<float>(::atof(begin));
|
||||||
} else {
|
} else {
|
||||||
std::string::size_type len( end - begin );
|
std::string::size_type len(end - begin);
|
||||||
std::string token( begin, len );
|
std::string token(begin, len);
|
||||||
val = static_cast< float >( ::atof( token.c_str() ) );
|
val = static_cast<float>(::atof(token.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
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.
|
/// @brief The portable to convert a decimal value into a hexadecimal string.
|
||||||
/// @param toConvert Value to convert
|
/// @param toConvert Value to convert
|
||||||
/// @return The hexadecimal string, is empty in case of an error.
|
/// @return The hexadecimal string, is empty in case of an error.
|
||||||
template<class T>
|
template <class T>
|
||||||
AI_FORCE_INLINE
|
AI_FORCE_INLINE std::string DecimalToHexa(T toConvert) {
|
||||||
std::string DecimalToHexa( T toConvert ) {
|
|
||||||
std::string result;
|
std::string result;
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << std::hex << toConvert;
|
ss << std::hex << toConvert;
|
||||||
ss >> result;
|
ss >> result;
|
||||||
|
|
||||||
for ( size_t i = 0; i < result.size(); ++i ) {
|
for (size_t i = 0; i < result.size(); ++i) {
|
||||||
result[ i ] = (char) toupper( result[ i ] );
|
result[i] = (char)toupper(result[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -164,31 +162,32 @@ std::string DecimalToHexa( T toConvert ) {
|
||||||
/// @param with_head #
|
/// @param with_head #
|
||||||
/// @return The hexadecimal string, is empty in case of an error.
|
/// @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) {
|
AI_FORCE_INLINE std::string Rgba2Hex(int r, int g, int b, int a, bool with_head) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
if (with_head) {
|
if (with_head) {
|
||||||
ss << "#";
|
ss << "#";
|
||||||
}
|
}
|
||||||
ss << std::hex << (r << 24 | g << 16 | b << 8 | a);
|
ss << std::hex << (r << 24 | g << 16 | b << 8 | a);
|
||||||
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim from start (in place)
|
// 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) {
|
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
|
||||||
return !std::isspace(ch);
|
return !std::isspace(ch);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim from end (in place)
|
// 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) {
|
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
|
||||||
return !std::isspace(ch);
|
return !std::isspace(ch);
|
||||||
}).base(), s.end());
|
}).base(),
|
||||||
|
s.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim from both ends (in place)
|
// trim from both ends (in place)
|
||||||
inline void trim(std::string &s) {
|
AI_FORCE_INLINE void trim(std::string &s) {
|
||||||
ltrim(s);
|
ltrim(s);
|
||||||
rtrim(s);
|
rtrim(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,7 +179,7 @@ public:
|
||||||
return true;
|
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);
|
pugi::xml_attribute attr = xmlNode.attribute(name);
|
||||||
if (attr.empty()) {
|
if (attr.empty()) {
|
||||||
return false;
|
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) {
|
static inline bool getStdStrAttribute(XmlNode &xmlNode, const char *name, std::string &val) {
|
||||||
pugi::xml_attribute attr = xmlNode.attribute(name);
|
pugi::xml_attribute attr = xmlNode.attribute(name);
|
||||||
if (attr.empty()) {
|
if (attr.empty()) {
|
||||||
|
|
Loading…
Reference in New Issue