|
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
|
|
|
|
|
Copyright (c) 2006-2019, assimp team
|
|
|
|
|
|
-
|
|
|
-
|
|
|
All rights reserved.
|
|
|
|
|
|
Redistribution and use of this software in source and binary forms,
|
|
@@ -43,7 +41,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
/** @file Implementation of the Collada loader */
|
|
|
|
|
|
-
|
|
|
#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
|
|
|
|
|
|
#include "ColladaLoader.h"
|
|
@@ -65,8 +62,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
#include "math.h"
|
|
|
#include <algorithm>
|
|
|
#include <numeric>
|
|
|
+#include <memory>
|
|
|
|
|
|
-using namespace Assimp;
|
|
|
+namespace Assimp {
|
|
|
+
|
|
|
using namespace Assimp::Formatter;
|
|
|
|
|
|
static const aiImporterDesc desc = {
|
|
@@ -111,7 +110,7 @@ ColladaLoader::~ColladaLoader() {
|
|
|
// Returns whether the class can handle the format of the given file.
|
|
|
bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
|
|
|
// check file extension
|
|
|
- std::string extension = GetExtension(pFile);
|
|
|
+ const std::string extension = GetExtension(pFile);
|
|
|
|
|
|
if (extension == "dae") {
|
|
|
return true;
|
|
@@ -126,7 +125,7 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
|
|
|
if (!pIOHandler) {
|
|
|
return true;
|
|
|
}
|
|
|
- const char* tokens[] = {"<collada"};
|
|
|
+ static const char* tokens[] = {"<collada"};
|
|
|
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
|
|
}
|
|
|
|
|
@@ -134,8 +133,7 @@ bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler, boo
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
-void ColladaLoader::SetupProperties(const Importer* pImp)
|
|
|
-{
|
|
|
+void ColladaLoader::SetupProperties(const Importer* pImp) {
|
|
|
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
|
|
|
ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION,0) != 0;
|
|
|
useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES,0) != 0;
|
|
@@ -143,8 +141,7 @@ void ColladaLoader::SetupProperties(const Importer* pImp)
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Get file extension list
|
|
|
-const aiImporterDesc* ColladaLoader::GetInfo () const
|
|
|
-{
|
|
|
+const aiImporterDesc* ColladaLoader::GetInfo () const {
|
|
|
return &desc;
|
|
|
}
|
|
|
|
|
@@ -167,12 +164,13 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
|
|
// parse the input file
|
|
|
ColladaParser parser( pIOHandler, pFile);
|
|
|
|
|
|
- if( !parser.mRootNode)
|
|
|
+ if( !parser.mRootNode) {
|
|
|
throw DeadlyImportError( "Collada: File came out empty. Something is wrong here.");
|
|
|
+ }
|
|
|
|
|
|
// reserve some storage to avoid unnecessary reallocs
|
|
|
- newMats.reserve(parser.mMaterialLibrary.size()*2);
|
|
|
- mMeshes.reserve(parser.mMeshLibrary.size()*2);
|
|
|
+ newMats.reserve(parser.mMaterialLibrary.size()*2u);
|
|
|
+ mMeshes.reserve(parser.mMeshLibrary.size()*2u);
|
|
|
|
|
|
mCameras.reserve(parser.mCameraLibrary.size());
|
|
|
mLights.reserve(parser.mLightLibrary.size());
|
|
@@ -192,19 +190,20 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
|
|
0, 0, parser.mUnitSize, 0,
|
|
|
0, 0, 0, 1);
|
|
|
if( !ignoreUpDirection ) {
|
|
|
- // Convert to Y_UP, if different orientation
|
|
|
- if( parser.mUpDirection == ColladaParser::UP_X)
|
|
|
- pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
|
|
- 0, -1, 0, 0,
|
|
|
- 1, 0, 0, 0,
|
|
|
- 0, 0, 1, 0,
|
|
|
- 0, 0, 0, 1);
|
|
|
- else if( parser.mUpDirection == ColladaParser::UP_Z)
|
|
|
- pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
|
|
- 1, 0, 0, 0,
|
|
|
- 0, 0, 1, 0,
|
|
|
- 0, -1, 0, 0,
|
|
|
- 0, 0, 0, 1);
|
|
|
+ // Convert to Y_UP, if different orientation
|
|
|
+ if( parser.mUpDirection == ColladaParser::UP_X) {
|
|
|
+ pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
|
|
+ 0, -1, 0, 0,
|
|
|
+ 1, 0, 0, 0,
|
|
|
+ 0, 0, 1, 0,
|
|
|
+ 0, 0, 0, 1);
|
|
|
+ } else if( parser.mUpDirection == ColladaParser::UP_Z) {
|
|
|
+ pScene->mRootNode->mTransformation *= aiMatrix4x4(
|
|
|
+ 1, 0, 0, 0,
|
|
|
+ 0, 0, 1, 0,
|
|
|
+ 0, -1, 0, 0,
|
|
|
+ 0, 0, 0, 1);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// Store scene metadata
|
|
@@ -212,8 +211,7 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
|
|
const size_t numMeta(parser.mAssetMetaData.size());
|
|
|
pScene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(numMeta));
|
|
|
size_t i = 0;
|
|
|
- for (auto it = parser.mAssetMetaData.cbegin(); it != parser.mAssetMetaData.cend(); ++it, ++i)
|
|
|
- {
|
|
|
+ for (auto it = parser.mAssetMetaData.cbegin(); it != parser.mAssetMetaData.cend(); ++it, ++i) {
|
|
|
pScene->mMetaData->Set(static_cast<unsigned int>(i), (*it).first, (*it).second);
|
|
|
}
|
|
|
}
|
|
@@ -233,9 +231,8 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
|
|
// store all animations
|
|
|
StoreAnimations( pScene, parser);
|
|
|
|
|
|
-
|
|
|
// If no meshes have been loaded, it's probably just an animated skeleton.
|
|
|
- if (!pScene->mNumMeshes) {
|
|
|
+ if ( 0u == pScene->mNumMeshes) {
|
|
|
|
|
|
if (!noSkeletonMesh) {
|
|
|
SkeletonMeshBuilder hero(pScene);
|
|
@@ -246,8 +243,7 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Recursively constructs a scene node for the given parser node and returns it.
|
|
|
-aiNode* ColladaLoader::BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode)
|
|
|
-{
|
|
|
+aiNode* ColladaLoader::BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode) {
|
|
|
// create a node for it
|
|
|
aiNode* node = new aiNode();
|
|
|
|
|
@@ -265,15 +261,13 @@ aiNode* ColladaLoader::BuildHierarchy( const ColladaParser& pParser, const Colla
|
|
|
node->mNumChildren = static_cast<unsigned int>(pNode->mChildren.size()+instances.size());
|
|
|
node->mChildren = new aiNode*[node->mNumChildren];
|
|
|
|
|
|
- for( size_t a = 0; a < pNode->mChildren.size(); a++)
|
|
|
- {
|
|
|
+ for( size_t a = 0; a < pNode->mChildren.size(); ++a) {
|
|
|
node->mChildren[a] = BuildHierarchy( pParser, pNode->mChildren[a]);
|
|
|
node->mChildren[a]->mParent = node;
|
|
|
}
|
|
|
|
|
|
// ... and finally the resolved node instances
|
|
|
- for( size_t a = 0; a < instances.size(); a++)
|
|
|
- {
|
|
|
+ for( size_t a = 0; a < instances.size(); ++a) {
|
|
|
node->mChildren[pNode->mChildren.size() + a] = BuildHierarchy( pParser, instances[a]);
|
|
|
node->mChildren[pNode->mChildren.size() + a]->mParent = node;
|
|
|
}
|
|
@@ -286,20 +280,19 @@ aiNode* ColladaLoader::BuildHierarchy( const ColladaParser& pParser, const Colla
|
|
|
|
|
|
// construct lights
|
|
|
BuildLightsForNode(pParser, pNode, node);
|
|
|
+
|
|
|
return node;
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Resolve node instances
|
|
|
void ColladaLoader::ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
|
|
|
- std::vector<const Collada::Node*>& resolved)
|
|
|
-{
|
|
|
+ std::vector<const Collada::Node*>& resolved) {
|
|
|
// reserve enough storage
|
|
|
resolved.reserve(pNode->mNodeInstances.size());
|
|
|
|
|
|
// ... and iterate through all nodes to be instanced as children of pNode
|
|
|
- for (const auto &nodeInst: pNode->mNodeInstances)
|
|
|
- {
|
|
|
+ for (const auto &nodeInst: pNode->mNodeInstances) {
|
|
|
// find the corresponding node in the library
|
|
|
const ColladaParser::NodeLibrary::const_iterator itt = pParser.mNodeLibrary.find(nodeInst.mNode);
|
|
|
const Collada::Node* nd = itt == pParser.mNodeLibrary.end() ? NULL : (*itt).second;
|
|
@@ -307,13 +300,12 @@ void ColladaLoader::ResolveNodeInstances( const ColladaParser& pParser, const Co
|
|
|
// FIX for http://sourceforge.net/tracker/?func=detail&aid=3054873&group_id=226462&atid=1067632
|
|
|
// need to check for both name and ID to catch all. To avoid breaking valid files,
|
|
|
// the workaround is only enabled when the first attempt to resolve the node has failed.
|
|
|
- if (!nd) {
|
|
|
+ if (nullptr == nd) {
|
|
|
nd = FindNode(pParser.mRootNode, nodeInst.mNode);
|
|
|
}
|
|
|
- if (!nd)
|
|
|
+ if (nullptr == nd) {
|
|
|
ASSIMP_LOG_ERROR_F("Collada: Unable to resolve reference to instanced node ", nodeInst.mNode);
|
|
|
-
|
|
|
- else {
|
|
|
+ } else {
|
|
|
// attach this node to the list of children
|
|
|
resolved.push_back(nd);
|
|
|
}
|
|
@@ -323,12 +315,12 @@ void ColladaLoader::ResolveNodeInstances( const ColladaParser& pParser, const Co
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Resolve UV channels
|
|
|
void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
|
|
|
- const Collada::SemanticMappingTable& table)
|
|
|
-{
|
|
|
+ const Collada::SemanticMappingTable& table) {
|
|
|
std::map<std::string, Collada::InputSemanticMapEntry>::const_iterator it = table.mMap.find(sampler.mUVChannel);
|
|
|
if (it != table.mMap.end()) {
|
|
|
- if (it->second.mType != Collada::IT_Texcoord)
|
|
|
+ if (it->second.mType != Collada::IT_Texcoord) {
|
|
|
ASSIMP_LOG_ERROR("Collada: Unexpected effect input mapping");
|
|
|
+ }
|
|
|
|
|
|
sampler.mUVId = it->second.mSet;
|
|
|
}
|
|
@@ -336,14 +328,11 @@ void ColladaLoader::ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Builds lights for the given node and references them
|
|
|
-void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget)
|
|
|
-{
|
|
|
- for( const Collada::LightInstance& lid : pNode->mLights)
|
|
|
- {
|
|
|
+void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget) {
|
|
|
+ for( const Collada::LightInstance& lid : pNode->mLights) {
|
|
|
// find the referred light
|
|
|
ColladaParser::LightLibrary::const_iterator srcLightIt = pParser.mLightLibrary.find( lid.mLight);
|
|
|
- if( srcLightIt == pParser.mLightLibrary.end())
|
|
|
- {
|
|
|
+ if( srcLightIt == pParser.mLightLibrary.end()) {
|
|
|
ASSIMP_LOG_WARN_F("Collada: Unable to find light for ID \"" , lid.mLight , "\". Skipping.");
|
|
|
continue;
|
|
|
}
|
|
@@ -365,8 +354,7 @@ void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Coll
|
|
|
if (out->mType == aiLightSource_AMBIENT) {
|
|
|
out->mColorDiffuse = out->mColorSpecular = aiColor3D(0, 0, 0);
|
|
|
out->mColorAmbient = srcLight->mColor*srcLight->mIntensity;
|
|
|
- }
|
|
|
- else {
|
|
|
+ } else {
|
|
|
// collada doesn't differentiate between these color types
|
|
|
out->mColorDiffuse = out->mColorSpecular = srcLight->mColor*srcLight->mIntensity;
|
|
|
out->mColorAmbient = aiColor3D(0, 0, 0);
|
|
@@ -374,27 +362,24 @@ void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Coll
|
|
|
|
|
|
// convert falloff angle and falloff exponent in our representation, if given
|
|
|
if (out->mType == aiLightSource_SPOT) {
|
|
|
-
|
|
|
out->mAngleInnerCone = AI_DEG_TO_RAD( srcLight->mFalloffAngle );
|
|
|
|
|
|
// ... some extension magic.
|
|
|
- if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET*(1-1e-6f))
|
|
|
- {
|
|
|
+ if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET*(1-1e-6f)) {
|
|
|
// ... some deprecation magic.
|
|
|
- if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET*(1-1e-6f))
|
|
|
- {
|
|
|
+ if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET*(1-1e-6f)) {
|
|
|
// Need to rely on falloff_exponent. I don't know how to interpret it, so I need to guess ....
|
|
|
// epsilon chosen to be 0.1
|
|
|
out->mAngleOuterCone = std::acos(std::pow(0.1f,1.f/srcLight->mFalloffExponent))+
|
|
|
out->mAngleInnerCone;
|
|
|
- }
|
|
|
- else {
|
|
|
+ } else {
|
|
|
out->mAngleOuterCone = out->mAngleInnerCone + AI_DEG_TO_RAD( srcLight->mPenumbraAngle );
|
|
|
if (out->mAngleOuterCone < out->mAngleInnerCone)
|
|
|
std::swap(out->mAngleInnerCone,out->mAngleOuterCone);
|
|
|
}
|
|
|
+ } else {
|
|
|
+ out->mAngleOuterCone = AI_DEG_TO_RAD( srcLight->mOuterAngle );
|
|
|
}
|
|
|
- else out->mAngleOuterCone = AI_DEG_TO_RAD( srcLight->mOuterAngle );
|
|
|
}
|
|
|
|
|
|
// add to light list
|
|
@@ -404,14 +389,11 @@ void ColladaLoader::BuildLightsForNode( const ColladaParser& pParser, const Coll
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Builds cameras for the given node and references them
|
|
|
-void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget)
|
|
|
-{
|
|
|
- for( const Collada::CameraInstance& cid : pNode->mCameras)
|
|
|
- {
|
|
|
+void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget) {
|
|
|
+ for( const Collada::CameraInstance& cid : pNode->mCameras) {
|
|
|
// find the referred light
|
|
|
ColladaParser::CameraLibrary::const_iterator srcCameraIt = pParser.mCameraLibrary.find( cid.mCamera);
|
|
|
- if( srcCameraIt == pParser.mCameraLibrary.end())
|
|
|
- {
|
|
|
+ if( srcCameraIt == pParser.mCameraLibrary.end()) {
|
|
|
ASSIMP_LOG_WARN_F("Collada: Unable to find camera for ID \"" , cid.mCamera , "\". Skipping.");
|
|
|
continue;
|
|
|
}
|
|
@@ -435,8 +417,9 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col
|
|
|
|
|
|
// ... but for the rest some values are optional
|
|
|
// and we need to compute the others in any combination.
|
|
|
- if (srcCamera->mAspect != 10e10f)
|
|
|
+ if (srcCamera->mAspect != 10e10f) {
|
|
|
out->mAspect = srcCamera->mAspect;
|
|
|
+ }
|
|
|
|
|
|
if (srcCamera->mHorFov != 10e10f) {
|
|
|
out->mHorizontalFOV = srcCamera->mHorFov;
|
|
@@ -445,8 +428,7 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col
|
|
|
out->mAspect = std::tan(AI_DEG_TO_RAD(srcCamera->mHorFov)) /
|
|
|
std::tan(AI_DEG_TO_RAD(srcCamera->mVerFov));
|
|
|
}
|
|
|
- }
|
|
|
- else if (srcCamera->mAspect != 10e10f && srcCamera->mVerFov != 10e10f) {
|
|
|
+ } else if (srcCamera->mAspect != 10e10f && srcCamera->mVerFov != 10e10f) {
|
|
|
out->mHorizontalFOV = 2.0f * AI_RAD_TO_DEG(std::atan(srcCamera->mAspect *
|
|
|
std::tan(AI_DEG_TO_RAD(srcCamera->mVerFov) * 0.5f)));
|
|
|
}
|
|
@@ -461,77 +443,69 @@ void ColladaLoader::BuildCamerasForNode( const ColladaParser& pParser, const Col
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Builds meshes for the given node and references them
|
|
|
-void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget)
|
|
|
-{
|
|
|
+void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode, aiNode* pTarget) {
|
|
|
// accumulated mesh references by this node
|
|
|
std::vector<size_t> newMeshRefs;
|
|
|
newMeshRefs.reserve(pNode->mMeshes.size());
|
|
|
|
|
|
// add a mesh for each subgroup in each collada mesh
|
|
|
- for( const Collada::MeshInstance& mid : pNode->mMeshes)
|
|
|
- {
|
|
|
- const Collada::Mesh* srcMesh = NULL;
|
|
|
- const Collada::Controller* srcController = NULL;
|
|
|
+ for( const Collada::MeshInstance& mid : pNode->mMeshes) {
|
|
|
+ const Collada::Mesh* srcMesh = nullptr;
|
|
|
+ const Collada::Controller* srcController = nullptr;
|
|
|
|
|
|
// find the referred mesh
|
|
|
ColladaParser::MeshLibrary::const_iterator srcMeshIt = pParser.mMeshLibrary.find( mid.mMeshOrController);
|
|
|
- if( srcMeshIt == pParser.mMeshLibrary.end())
|
|
|
- {
|
|
|
+ if( srcMeshIt == pParser.mMeshLibrary.end()) {
|
|
|
// if not found in the mesh-library, it might also be a controller referring to a mesh
|
|
|
ColladaParser::ControllerLibrary::const_iterator srcContrIt = pParser.mControllerLibrary.find( mid.mMeshOrController);
|
|
|
- if( srcContrIt != pParser.mControllerLibrary.end())
|
|
|
- {
|
|
|
+ if( srcContrIt != pParser.mControllerLibrary.end()) {
|
|
|
srcController = &srcContrIt->second;
|
|
|
srcMeshIt = pParser.mMeshLibrary.find( srcController->mMeshId);
|
|
|
- if( srcMeshIt != pParser.mMeshLibrary.end())
|
|
|
+ if( srcMeshIt != pParser.mMeshLibrary.end()) {
|
|
|
srcMesh = srcMeshIt->second;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- if( !srcMesh)
|
|
|
- {
|
|
|
+ if( nullptr == srcMesh) {
|
|
|
ASSIMP_LOG_WARN_F( "Collada: Unable to find geometry for ID \"", mid.mMeshOrController, "\". Skipping." );
|
|
|
continue;
|
|
|
}
|
|
|
- } else
|
|
|
- {
|
|
|
+ } else {
|
|
|
// ID found in the mesh library -> direct reference to an unskinned mesh
|
|
|
srcMesh = srcMeshIt->second;
|
|
|
}
|
|
|
|
|
|
// build a mesh for each of its subgroups
|
|
|
size_t vertexStart = 0, faceStart = 0;
|
|
|
- for( size_t sm = 0; sm < srcMesh->mSubMeshes.size(); ++sm)
|
|
|
- {
|
|
|
+ for( size_t sm = 0; sm < srcMesh->mSubMeshes.size(); ++sm) {
|
|
|
const Collada::SubMesh& submesh = srcMesh->mSubMeshes[sm];
|
|
|
- if( submesh.mNumFaces == 0)
|
|
|
+ if( submesh.mNumFaces == 0) {
|
|
|
continue;
|
|
|
+ }
|
|
|
|
|
|
// find material assigned to this submesh
|
|
|
std::string meshMaterial;
|
|
|
std::map<std::string, Collada::SemanticMappingTable >::const_iterator meshMatIt = mid.mMaterials.find( submesh.mMaterial);
|
|
|
|
|
|
- const Collada::SemanticMappingTable* table = NULL;
|
|
|
- if( meshMatIt != mid.mMaterials.end())
|
|
|
- {
|
|
|
+ const Collada::SemanticMappingTable* table = nullptr;
|
|
|
+ if( meshMatIt != mid.mMaterials.end()) {
|
|
|
table = &meshMatIt->second;
|
|
|
meshMaterial = table->mMatName;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
+ } else {
|
|
|
ASSIMP_LOG_WARN_F( "Collada: No material specified for subgroup <", submesh.mMaterial, "> in geometry <",
|
|
|
mid.mMeshOrController, ">." );
|
|
|
- if( !mid.mMaterials.empty() )
|
|
|
+ if( !mid.mMaterials.empty() ) {
|
|
|
meshMaterial = mid.mMaterials.begin()->second.mMatName;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// OK ... here the *real* fun starts ... we have the vertex-input-to-effect-semantic-table
|
|
|
// given. The only mapping stuff which we do actually support is the UV channel.
|
|
|
std::map<std::string, size_t>::const_iterator matIt = mMaterialIndexByName.find( meshMaterial);
|
|
|
- unsigned int matIdx;
|
|
|
- if( matIt != mMaterialIndexByName.end())
|
|
|
+ unsigned int matIdx = 0;
|
|
|
+ if( matIt != mMaterialIndexByName.end()) {
|
|
|
matIdx = static_cast<unsigned int>(matIt->second);
|
|
|
- else
|
|
|
- matIdx = 0;
|
|
|
+ }
|
|
|
|
|
|
if (table && !table->mMap.empty() ) {
|
|
|
std::pair<Collada::Effect*, aiMaterial*>& mat = newMats[matIdx];
|
|
@@ -553,9 +527,7 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
|
|
|
std::map<ColladaMeshIndex, size_t>::const_iterator dstMeshIt = mMeshIndexByID.find( index);
|
|
|
if( dstMeshIt != mMeshIndexByID.end()) {
|
|
|
newMeshRefs.push_back( dstMeshIt->second);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
+ } else {
|
|
|
// else we have to add the mesh to the collection and store its newly assigned index at the node
|
|
|
aiMesh* dstMesh = CreateMesh( pParser, srcMesh, submesh, srcController, vertexStart, faceStart);
|
|
|
|
|
@@ -567,22 +539,18 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
|
|
|
|
|
|
// assign the material index
|
|
|
dstMesh->mMaterialIndex = matIdx;
|
|
|
- if(dstMesh->mName.length == 0)
|
|
|
- {
|
|
|
+ if(dstMesh->mName.length == 0) {
|
|
|
dstMesh->mName = mid.mMeshOrController;
|
|
|
}
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// now place all mesh references we gathered in the target node
|
|
|
pTarget->mNumMeshes = static_cast<unsigned int>(newMeshRefs.size());
|
|
|
- if( newMeshRefs.size())
|
|
|
- {
|
|
|
- struct UIntTypeConverter
|
|
|
- {
|
|
|
- unsigned int operator()(const size_t& v) const
|
|
|
- {
|
|
|
+ if( newMeshRefs.size()) {
|
|
|
+ struct UIntTypeConverter {
|
|
|
+ unsigned int operator()(const size_t& v) const {
|
|
|
return static_cast<unsigned int>(v);
|
|
|
}
|
|
|
};
|
|
@@ -594,25 +562,27 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Find mesh from either meshes or morph target meshes
|
|
|
-aiMesh *ColladaLoader::findMesh(std::string meshid)
|
|
|
-{
|
|
|
- for (unsigned int i = 0; i < mMeshes.size(); i++)
|
|
|
- if (std::string(mMeshes[i]->mName.data) == meshid)
|
|
|
+aiMesh *ColladaLoader::findMesh(std::string meshid) {
|
|
|
+ for (unsigned int i = 0; i < mMeshes.size(); ++i ) {
|
|
|
+ if (std::string(mMeshes[i]->mName.data) == meshid) {
|
|
|
return mMeshes[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- for (unsigned int i = 0; i < mTargetMeshes.size(); i++)
|
|
|
- if (std::string(mTargetMeshes[i]->mName.data) == meshid)
|
|
|
+ for (unsigned int i = 0; i < mTargetMeshes.size(); ++i ) {
|
|
|
+ if (std::string(mTargetMeshes[i]->mName.data) == meshid) {
|
|
|
return mTargetMeshes[i];
|
|
|
-
|
|
|
- return NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nullptr;
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh
|
|
|
aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
|
|
|
- const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace)
|
|
|
-{
|
|
|
- aiMesh* dstMesh = new aiMesh;
|
|
|
+ const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace) {
|
|
|
+ std::unique_ptr<aiMesh> dstMesh(new aiMesh);
|
|
|
|
|
|
dstMesh->mName = pSrcMesh->mName;
|
|
|
|
|
@@ -629,24 +599,21 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|
|
// normals, if given. HACK: (thom) Due to the glorious Collada spec we never
|
|
|
// know if we have the same number of normals as there are positions. So we
|
|
|
// also ignore any vertex attribute if it has a different count
|
|
|
- if( pSrcMesh->mNormals.size() >= pStartVertex + numVertices)
|
|
|
- {
|
|
|
+ if( pSrcMesh->mNormals.size() >= pStartVertex + numVertices) {
|
|
|
dstMesh->mNormals = new aiVector3D[numVertices];
|
|
|
std::copy( pSrcMesh->mNormals.begin() + pStartVertex, pSrcMesh->mNormals.begin() +
|
|
|
pStartVertex + numVertices, dstMesh->mNormals);
|
|
|
}
|
|
|
|
|
|
// tangents, if given.
|
|
|
- if( pSrcMesh->mTangents.size() >= pStartVertex + numVertices)
|
|
|
- {
|
|
|
+ if( pSrcMesh->mTangents.size() >= pStartVertex + numVertices) {
|
|
|
dstMesh->mTangents = new aiVector3D[numVertices];
|
|
|
std::copy( pSrcMesh->mTangents.begin() + pStartVertex, pSrcMesh->mTangents.begin() +
|
|
|
pStartVertex + numVertices, dstMesh->mTangents);
|
|
|
}
|
|
|
|
|
|
// bitangents, if given.
|
|
|
- if( pSrcMesh->mBitangents.size() >= pStartVertex + numVertices)
|
|
|
- {
|
|
|
+ if( pSrcMesh->mBitangents.size() >= pStartVertex + numVertices) {
|
|
|
dstMesh->mBitangents = new aiVector3D[numVertices];
|
|
|
std::copy( pSrcMesh->mBitangents.begin() + pStartVertex, pSrcMesh->mBitangents.begin() +
|
|
|
pStartVertex + numVertices, dstMesh->mBitangents);
|
|
@@ -654,13 +621,12 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|
|
|
|
|
// same for texturecoords, as many as we have
|
|
|
// empty slots are not allowed, need to pack and adjust UV indexes accordingly
|
|
|
- for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
|
|
|
- {
|
|
|
- if( pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices)
|
|
|
- {
|
|
|
+ for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a ) {
|
|
|
+ if( pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices) {
|
|
|
dstMesh->mTextureCoords[real] = new aiVector3D[numVertices];
|
|
|
- for( size_t b = 0; b < numVertices; ++b)
|
|
|
+ for( size_t b = 0; b < numVertices; ++b) {
|
|
|
dstMesh->mTextureCoords[real][b] = pSrcMesh->mTexCoords[a][pStartVertex+b];
|
|
|
+ }
|
|
|
|
|
|
dstMesh->mNumUVComponents[real] = pSrcMesh->mNumUVComponents[a];
|
|
|
++real;
|
|
@@ -668,10 +634,8 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|
|
}
|
|
|
|
|
|
// same for vertex colors, as many as we have. again the same packing to avoid empty slots
|
|
|
- for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
|
|
|
- {
|
|
|
- if( pSrcMesh->mColors[a].size() >= pStartVertex + numVertices)
|
|
|
- {
|
|
|
+ for( size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a ) {
|
|
|
+ if( pSrcMesh->mColors[a].size() >= pStartVertex + numVertices) {
|
|
|
dstMesh->mColors[real] = new aiColor4D[numVertices];
|
|
|
std::copy( pSrcMesh->mColors[a].begin() + pStartVertex, pSrcMesh->mColors[a].begin() + pStartVertex + numVertices,dstMesh->mColors[real]);
|
|
|
++real;
|
|
@@ -682,14 +646,14 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|
|
size_t vertex = 0;
|
|
|
dstMesh->mNumFaces = static_cast<unsigned int>(pSubMesh.mNumFaces);
|
|
|
dstMesh->mFaces = new aiFace[dstMesh->mNumFaces];
|
|
|
- for( size_t a = 0; a < dstMesh->mNumFaces; ++a)
|
|
|
- {
|
|
|
+ for( size_t a = 0; a < dstMesh->mNumFaces; ++a) {
|
|
|
size_t s = pSrcMesh->mFaceSize[ pStartFace + a];
|
|
|
aiFace& face = dstMesh->mFaces[a];
|
|
|
face.mNumIndices = static_cast<unsigned int>(s);
|
|
|
face.mIndices = new unsigned int[s];
|
|
|
- for( size_t b = 0; b < s; ++b)
|
|
|
+ for( size_t b = 0; b < s; ++b) {
|
|
|
face.mIndices[b] = static_cast<unsigned int>(vertex++);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// create morph target meshes if any
|
|
@@ -697,14 +661,12 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|
|
std::vector<float> targetWeights;
|
|
|
Collada::MorphMethod method = Collada::Normalized;
|
|
|
|
|
|
- for(std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
|
|
|
- it != pParser.mControllerLibrary.end(); it++)
|
|
|
- {
|
|
|
+ for(std::map<std::string, Collada::Controller>::const_iterator it = pParser.mControllerLibrary.begin();
|
|
|
+ it != pParser.mControllerLibrary.end(); it++) {
|
|
|
const Collada::Controller &c = it->second;
|
|
|
const Collada::Mesh* baseMesh = pParser.ResolveLibraryReference( pParser.mMeshLibrary, c.mMeshId);
|
|
|
|
|
|
- if (c.mType == Collada::Morph && baseMesh->mName == pSrcMesh->mName)
|
|
|
- {
|
|
|
+ if (c.mType == Collada::Morph && baseMesh->mName == pSrcMesh->mName) {
|
|
|
const Collada::Accessor& targetAccessor = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, c.mMorphTarget);
|
|
|
const Collada::Accessor& weightAccessor = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, c.mMorphWeight);
|
|
|
const Collada::Data& targetData = pParser.ResolveLibraryReference( pParser.mDataLibrary, targetAccessor.mSource);
|
|
@@ -713,34 +675,34 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|
|
// take method
|
|
|
method = c.mMethod;
|
|
|
|
|
|
- if (!targetData.mIsStringArray)
|
|
|
+ if (!targetData.mIsStringArray) {
|
|
|
throw DeadlyImportError( "target data must contain id. ");
|
|
|
- if (weightData.mIsStringArray)
|
|
|
+ }
|
|
|
+ if (weightData.mIsStringArray) {
|
|
|
throw DeadlyImportError( "target weight data must not be textual ");
|
|
|
+ }
|
|
|
|
|
|
- for (unsigned int i = 0; i < targetData.mStrings.size(); ++i)
|
|
|
- {
|
|
|
+ for (unsigned int i = 0; i < targetData.mStrings.size(); ++i) {
|
|
|
const Collada::Mesh* targetMesh = pParser.ResolveLibraryReference(pParser.mMeshLibrary, targetData.mStrings.at(i));
|
|
|
|
|
|
aiMesh *aimesh = findMesh(targetMesh->mName);
|
|
|
- if (!aimesh)
|
|
|
- {
|
|
|
- if (targetMesh->mSubMeshes.size() > 1)
|
|
|
+ if (!aimesh) {
|
|
|
+ if (targetMesh->mSubMeshes.size() > 1) {
|
|
|
throw DeadlyImportError( "Morhing target mesh must be a single");
|
|
|
+ }
|
|
|
aimesh = CreateMesh(pParser, targetMesh, targetMesh->mSubMeshes.at(0), NULL, 0, 0);
|
|
|
mTargetMeshes.push_back(aimesh);
|
|
|
}
|
|
|
targetMeshes.push_back(aimesh);
|
|
|
}
|
|
|
- for (unsigned int i = 0; i < weightData.mValues.size(); ++i)
|
|
|
+ for (unsigned int i = 0; i < weightData.mValues.size(); ++i) {
|
|
|
targetWeights.push_back(weightData.mValues.at(i));
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- if (targetMeshes.size() > 0 && targetWeights.size() == targetMeshes.size())
|
|
|
- {
|
|
|
+ if (targetMeshes.size() > 0 && targetWeights.size() == targetMeshes.size()) {
|
|
|
std::vector<aiAnimMesh*> animMeshes;
|
|
|
- for (unsigned int i = 0; i < targetMeshes.size(); i++)
|
|
|
- {
|
|
|
+ for (unsigned int i = 0; i < targetMeshes.size(); ++i ) {
|
|
|
aiMesh* targetMesh = targetMeshes.at(i);
|
|
|
aiAnimMesh *animMesh = aiCreateAnimMesh(targetMesh);
|
|
|
float weight = targetWeights[i];
|
|
@@ -753,13 +715,13 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|
|
: aiMorphingMethod_MORPH_NORMALIZED;
|
|
|
dstMesh->mAnimMeshes = new aiAnimMesh*[animMeshes.size()];
|
|
|
dstMesh->mNumAnimMeshes = static_cast<unsigned int>(animMeshes.size());
|
|
|
- for (unsigned int i = 0; i < animMeshes.size(); i++)
|
|
|
+ for (unsigned int i = 0; i < animMeshes.size(); ++i ) {
|
|
|
dstMesh->mAnimMeshes[i] = animMeshes.at(i);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// create bones if given
|
|
|
- if( pSrcController && pSrcController->mType == Collada::Skin)
|
|
|
- {
|
|
|
+ if( pSrcController && pSrcController->mType == Collada::Skin) {
|
|
|
// resolve references - joint names
|
|
|
const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
|
|
|
const Collada::Data& jointNames = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointNamesAcc.mSource);
|
|
@@ -790,15 +752,13 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|
|
weightStartPerVertex.resize(pSrcController->mWeightCounts.size(),pSrcController->mWeights.end());
|
|
|
|
|
|
IndexPairVector::const_iterator pit = pSrcController->mWeights.begin();
|
|
|
- for( size_t a = 0; a < pSrcController->mWeightCounts.size(); ++a)
|
|
|
- {
|
|
|
+ for( size_t a = 0; a < pSrcController->mWeightCounts.size(); ++a) {
|
|
|
weightStartPerVertex[a] = pit;
|
|
|
pit += pSrcController->mWeightCounts[a];
|
|
|
}
|
|
|
|
|
|
// now for each vertex put the corresponding vertex weights into each bone's weight collection
|
|
|
- for( size_t a = pStartVertex; a < pStartVertex + numVertices; ++a)
|
|
|
- {
|
|
|
+ for( size_t a = pStartVertex; a < pStartVertex + numVertices; ++a) {
|
|
|
// which position index was responsible for this vertex? that's also the index by which
|
|
|
// the controller assigns the vertex weights
|
|
|
size_t orgIndex = pSrcMesh->mFacePosIndices[a];
|
|
@@ -806,12 +766,13 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|
|
IndexPairVector::const_iterator iit = weightStartPerVertex[orgIndex];
|
|
|
size_t pairCount = pSrcController->mWeightCounts[orgIndex];
|
|
|
|
|
|
- for( size_t b = 0; b < pairCount; ++b, ++iit)
|
|
|
- {
|
|
|
- size_t jointIndex = iit->first;
|
|
|
- size_t vertexIndex = iit->second;
|
|
|
-
|
|
|
- ai_real weight = ReadFloat( weightsAcc, weights, vertexIndex, 0);
|
|
|
+ for( size_t b = 0; b < pairCount; ++b, ++iit) {
|
|
|
+ const size_t jointIndex = iit->first;
|
|
|
+ const size_t vertexIndex = iit->second;
|
|
|
+ ai_real weight = 1.0f;
|
|
|
+ if (!weights.mValues.empty()) {
|
|
|
+ weight = ReadFloat(weightsAcc, weights, vertexIndex, 0);
|
|
|
+ }
|
|
|
|
|
|
// one day I gonna kill that XSI Collada exporter
|
|
|
if( weight > 0.0f)
|
|
@@ -826,19 +787,21 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|
|
|
|
|
// count the number of bones which influence vertices of the current submesh
|
|
|
size_t numRemainingBones = 0;
|
|
|
- for( std::vector<std::vector<aiVertexWeight> >::const_iterator it = dstBones.begin(); it != dstBones.end(); ++it)
|
|
|
- if( it->size() > 0)
|
|
|
- numRemainingBones++;
|
|
|
+ for( std::vector<std::vector<aiVertexWeight> >::const_iterator it = dstBones.begin(); it != dstBones.end(); ++it) {
|
|
|
+ if( it->size() > 0) {
|
|
|
+ ++numRemainingBones;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
// create bone array and copy bone weights one by one
|
|
|
dstMesh->mNumBones = static_cast<unsigned int>(numRemainingBones);
|
|
|
dstMesh->mBones = new aiBone*[numRemainingBones];
|
|
|
size_t boneCount = 0;
|
|
|
- for( size_t a = 0; a < numBones; ++a)
|
|
|
- {
|
|
|
+ for( size_t a = 0; a < numBones; ++a) {
|
|
|
// omit bones without weights
|
|
|
- if( dstBones[a].size() == 0)
|
|
|
+ if( dstBones[a].empty() ) {
|
|
|
continue;
|
|
|
+ }
|
|
|
|
|
|
// create bone with its weights
|
|
|
aiBone* bone = new aiBone;
|
|
@@ -884,108 +847,101 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
|
|
|
// and replace the bone's name by the node's name so that the user can use the standard
|
|
|
// find-by-name method to associate nodes with bones.
|
|
|
const Collada::Node* bnode = FindNode( pParser.mRootNode, bone->mName.data);
|
|
|
- if( !bnode)
|
|
|
+ if( !bnode) {
|
|
|
bnode = FindNodeBySID( pParser.mRootNode, bone->mName.data);
|
|
|
+ }
|
|
|
|
|
|
// assign the name that we would have assigned for the source node
|
|
|
- if( bnode)
|
|
|
+ if( bnode) {
|
|
|
bone->mName.Set( FindNameForNode( bnode));
|
|
|
- else
|
|
|
+ } else {
|
|
|
ASSIMP_LOG_WARN_F( "ColladaLoader::CreateMesh(): could not find corresponding node for joint \"", bone->mName.data, "\"." );
|
|
|
+ }
|
|
|
|
|
|
// and insert bone
|
|
|
dstMesh->mBones[boneCount++] = bone;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return dstMesh;
|
|
|
+ return dstMesh.release();
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Stores all meshes in the given scene
|
|
|
-void ColladaLoader::StoreSceneMeshes( aiScene* pScene)
|
|
|
-{
|
|
|
+void ColladaLoader::StoreSceneMeshes( aiScene* pScene) {
|
|
|
pScene->mNumMeshes = static_cast<unsigned int>(mMeshes.size());
|
|
|
- if( mMeshes.size() > 0)
|
|
|
- {
|
|
|
- pScene->mMeshes = new aiMesh*[mMeshes.size()];
|
|
|
- std::copy( mMeshes.begin(), mMeshes.end(), pScene->mMeshes);
|
|
|
- mMeshes.clear();
|
|
|
+ if( mMeshes.empty() ) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ pScene->mMeshes = new aiMesh*[mMeshes.size()];
|
|
|
+ std::copy( mMeshes.begin(), mMeshes.end(), pScene->mMeshes);
|
|
|
+ mMeshes.clear();
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Stores all cameras in the given scene
|
|
|
-void ColladaLoader::StoreSceneCameras( aiScene* pScene)
|
|
|
-{
|
|
|
+void ColladaLoader::StoreSceneCameras( aiScene* pScene) {
|
|
|
pScene->mNumCameras = static_cast<unsigned int>(mCameras.size());
|
|
|
- if( mCameras.size() > 0)
|
|
|
- {
|
|
|
- pScene->mCameras = new aiCamera*[mCameras.size()];
|
|
|
- std::copy( mCameras.begin(), mCameras.end(), pScene->mCameras);
|
|
|
- mCameras.clear();
|
|
|
+ if( mCameras.empty() ) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ pScene->mCameras = new aiCamera*[mCameras.size()];
|
|
|
+ std::copy( mCameras.begin(), mCameras.end(), pScene->mCameras);
|
|
|
+ mCameras.clear();
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Stores all lights in the given scene
|
|
|
-void ColladaLoader::StoreSceneLights( aiScene* pScene)
|
|
|
-{
|
|
|
+void ColladaLoader::StoreSceneLights( aiScene* pScene) {
|
|
|
pScene->mNumLights = static_cast<unsigned int>(mLights.size());
|
|
|
- if( mLights.size() > 0)
|
|
|
- {
|
|
|
- pScene->mLights = new aiLight*[mLights.size()];
|
|
|
- std::copy( mLights.begin(), mLights.end(), pScene->mLights);
|
|
|
- mLights.clear();
|
|
|
+ if( mLights.empty() ) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ pScene->mLights = new aiLight*[mLights.size()];
|
|
|
+ std::copy( mLights.begin(), mLights.end(), pScene->mLights);
|
|
|
+ mLights.clear();
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Stores all textures in the given scene
|
|
|
-void ColladaLoader::StoreSceneTextures( aiScene* pScene)
|
|
|
-{
|
|
|
+void ColladaLoader::StoreSceneTextures( aiScene* pScene) {
|
|
|
pScene->mNumTextures = static_cast<unsigned int>(mTextures.size());
|
|
|
- if( mTextures.size() > 0)
|
|
|
- {
|
|
|
- pScene->mTextures = new aiTexture*[mTextures.size()];
|
|
|
- std::copy( mTextures.begin(), mTextures.end(), pScene->mTextures);
|
|
|
- mTextures.clear();
|
|
|
+ if( mTextures.empty() ) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ pScene->mTextures = new aiTexture*[mTextures.size()];
|
|
|
+ std::copy( mTextures.begin(), mTextures.end(), pScene->mTextures);
|
|
|
+ mTextures.clear();
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Stores all materials in the given scene
|
|
|
-void ColladaLoader::StoreSceneMaterials( aiScene* pScene)
|
|
|
-{
|
|
|
+void ColladaLoader::StoreSceneMaterials( aiScene* pScene) {
|
|
|
pScene->mNumMaterials = static_cast<unsigned int>(newMats.size());
|
|
|
-
|
|
|
- if (newMats.size() > 0) {
|
|
|
- pScene->mMaterials = new aiMaterial*[newMats.size()];
|
|
|
- for (unsigned int i = 0; i < newMats.size();++i)
|
|
|
- pScene->mMaterials[i] = newMats[i].second;
|
|
|
-
|
|
|
- newMats.clear();
|
|
|
+ if (newMats.empty() ) {
|
|
|
+ return;
|
|
|
}
|
|
|
+ pScene->mMaterials = new aiMaterial*[newMats.size()];
|
|
|
+ for (unsigned int i = 0; i < newMats.size();++i) {
|
|
|
+ pScene->mMaterials[i] = newMats[i].second;
|
|
|
+ }
|
|
|
+ newMats.clear();
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Stores all animations
|
|
|
-void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser)
|
|
|
-{
|
|
|
+void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pParser) {
|
|
|
// recursively collect all animations from the collada scene
|
|
|
StoreAnimations( pScene, pParser, &pParser.mAnims, "");
|
|
|
|
|
|
// catch special case: many animations with the same length, each affecting only a single node.
|
|
|
// we need to unite all those single-node-anims to a proper combined animation
|
|
|
- for( size_t a = 0; a < mAnims.size(); ++a)
|
|
|
- {
|
|
|
+ for( size_t a = 0; a < mAnims.size(); ++a) {
|
|
|
aiAnimation* templateAnim = mAnims[a];
|
|
|
- if( templateAnim->mNumChannels == 1)
|
|
|
- {
|
|
|
+ if( templateAnim->mNumChannels == 1) {
|
|
|
// search for other single-channel-anims with the same duration
|
|
|
std::vector<size_t> collectedAnimIndices;
|
|
|
- for( size_t b = a+1; b < mAnims.size(); ++b)
|
|
|
- {
|
|
|
+ for( size_t b = a+1; b < mAnims.size(); ++b) {
|
|
|
aiAnimation* other = mAnims[b];
|
|
|
if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration &&
|
|
|
other->mTicksPerSecond == templateAnim->mTicksPerSecond )
|
|
@@ -1916,19 +1872,23 @@ const Collada::Node* ColladaLoader::FindNode( const Collada::Node* pNode, const
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
// Finds a node in the collada scene by the given SID
|
|
|
-const Collada::Node* ColladaLoader::FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const
|
|
|
-{
|
|
|
- if( pNode->mSID == pSID)
|
|
|
- return pNode;
|
|
|
+const Collada::Node* ColladaLoader::FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const {
|
|
|
+ if (nullptr == pNode) {
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
|
|
|
- for( size_t a = 0; a < pNode->mChildren.size(); ++a)
|
|
|
- {
|
|
|
- const Collada::Node* node = FindNodeBySID( pNode->mChildren[a], pSID);
|
|
|
- if( node)
|
|
|
- return node;
|
|
|
- }
|
|
|
+ if (pNode->mSID == pSID) {
|
|
|
+ return pNode;
|
|
|
+ }
|
|
|
+
|
|
|
+ for( size_t a = 0; a < pNode->mChildren.size(); ++a) {
|
|
|
+ const Collada::Node* node = FindNodeBySID( pNode->mChildren[a], pSID);
|
|
|
+ if (node) {
|
|
|
+ return node;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- return NULL;
|
|
|
+ return nullptr;
|
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
@@ -1962,4 +1922,6 @@ std::string ColladaLoader::FindNameForNode( const Collada::Node* pNode)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+} // Namespace Assimp
|
|
|
+
|
|
|
#endif // !! ASSIMP_BUILD_NO_DAE_IMPORTER
|